Gerrit/merge submodule

If you want to merge a submodule into the parent project (i.e. when it makes no sense to have them separate) in Gerrit, follow this process. Note that you will need the gerrit permission to push merge commits in order to successfully push your merge to gerrit.

First, you need to get the revisions from the submodule into the main module's repository, otherwise Gerrit will try to interpret them all as new changesets when you try to push your merged tree. Probably the easiest way to do this is to create a personal sandbox containing those revisions. To do this, add a remote for the submodule to your local repository and then create and push the sandbox branch based on that:

$ git remote add -f submodule ssh://username@gerrit.wikimedia.org/submodule/name.git $ git checkout -b sandbox/username/merge-submodule submodule/master $ git push --set-upstream origin sandbox/username/merge-submodule

Next, you'll probably want to check out a clean copy of the main module. This will include the personal sandbox you just created.

$ git clone ssh://username@gerrit.wikimedia.org:29418/mainmodule/name.git mainmodule $ cd mainmodule $ git review -s

Note we don't update submodules in this clean copy. Now, begin the merge:

$ git merge -s ours --no-commit remotes/origin/sandbox/username/merge-submodule

Next we have to remove the record of the submodule from the main module. If there are no other submodules, it's simple enough:

$ git rm .gitmodules

If there are other submodules, you'll need to edit .gitmodules to remove the stanza for this submodule:

$ vi .gitmodules $ git add .gitmodules

Then we need to import the revisions from the submodule into the subdirectory formerly used for the submodule. Note that git will interpret this as a rename of all the files from the submodule, so diffs and the output in gerrit's interface may look a little odd.

$ git read-tree --prefix=submodule/ -u remotes/origin/sandbox/username/merge-submodule

Perform any additional cleanup that may be necessary, for example removing the submodule's .gitreview file, and commit.

$ git rm submodule/.gitreview $ git commit -m "Merge submodule/name into submodule/"

To push to gerrit, do not use. It will get hopelessly confused. Instead, use the following command:

$ git push gerrit HEAD:refs/for/master

You will need to use the same command again when submitting any revised patch sets for the change.

Note that anyone reviewing this change in an existing local repository that has the submodules checked out (or anyone pulling this change after it is merged) will be prompted to manually remove all the old submodule files from their local  directory, as the new main module files would overwrite them.