Search code examples
gitgerritgit-subtree

Is git subtree compatible with Gerrit?


Our git repositories are hosted in Gerrit. A colleague maintains 2 repos main and sub. He wants to include sub inside main as a subtree. Here's so far what we have tried:

git clone repo_url_main -b dev main
cd main
git subtree add -P foo/bar repo_url_sub master
touch foo/bar/baz.txt
git add .
git commit -m 'foo.bar.baz.tt'
git subtree push -P foo/bar repo_url_sub master

The first problem is that git subtree push fails because his account does not have the permission to directly push the commits without review. The review is what he wants.

For a non-subtree repo, we use git push origin HEAD:refs/for/master to create a review change. So we try git subtree push -P foo/bar repo_url_sub master:refs/for/master and it fails too. Git complains that master:refs/for/master is not a valid ref. I find git subtree push -P <prefix> <repository> <ref> in the manual. The last part is ref instead of refspec. So master:refs/for/master is not expected here.

And then we try git subtree push -P foo/bar repo_url_sub refs/for/master. The push succeeds but the result is not expected. A branch refs/for/master instead of a review change is created. After several tries, we find it seems whatever the last ref is, it's always expanded to refs/heads/.... Even refs/heads/master is expanded to refs/heads/refs/heads/master.

The workarounds we've thought of so far:

  1. Use Google's REPO tool to manage the 2 repos as it's done for AOSP, which needs extra skills and is a bit of overkill.

  2. Use git submodule, which is more troublesome.

  3. Include a local transfer sub repo as the subtree in main. First git subtree push to update master in the transfer repo, and then in the transfer repo use git push repo_url_sub HEAD:refs/for/master to create review changes. But we can foresee the chaos when many maintainers are involved.

Are there any git options or configs that can instruct git subtree push to correctly create review changes in Gerrit? Thanks for any ideas.


Solution

  • Accordingly with the "git help subtree":

    push

    Does a split using the supplied and then does a git push to push the result to the repository and ref

    So I think you could first execute a "git subtree split" followed by a "git push", something like:

    git subtree split --prefix=foo/bar -b split
    git push repo_url_sub split:refs/for/master