How to configure specific upstream push refspec for Git when used with Gerrit?
Asked Answered
R

4

17

I'm setting up Git with Gerrit Code Review and am looking for a way to make the necessary Git commands relatively straightforward for users who might be new to Git.

The commands I currently have for starting a new feature branch are essentially (assuming Gerrit is origin):

git checkout baseline
git pull
git checkout -b work1234
git push -u origin work1234

This starts a new work package work1234 branched from some baseline, and the final push creates the branch in Gerrit and sets the upstream. So .git/config looks something like:

[branch "work1234"]
        remote = origin
        merge = refs/heads/work1234

Now, Gerrit wants new commits for review to be pushed to a special refspec, refs/for/work1234 for example. I can do this manually with:

git push origin work1234:refs/for/work1234

What I would like to do is find some way to set up .git/config so that a plain git push will push the current branch to the refspec on the remote that Gerrit requires. I have looked at the following git config areas:

  • branch.<name>.* - doesn't seem to have any specific option for setting the push refspec
  • push.default - I sort of want upstream here
  • remote.<name>.push - I tried refs/heads/*:refs/for/* here but git push always wants to push all local branches in this case, while I just want the current branch

If I can't make Git do this by itself, I'll write a small wrapper script that fully specifies the refspecs. However, it would be better if Git could push to the right place natively.

Rivas answered 18/8, 2011 at 0:41 Comment(0)
R
8

I ended up writing a new git-submit script:

#!/bin/sh -e

if [ -z "$1" ]; then
    REMOTE=origin
else
    REMOTE=$1
fi

BRANCH=`git symbolic-ref HEAD`
case $BRANCH in
    refs/heads/*)
        BRANCH=`basename $BRANCH`
        ;;
    *)
        echo "I can't figure out which branch you are on."
        exit 1
        ;;
esac

git push $REMOTE HEAD:refs/for/$BRANCH

I put this script in /usr/local/libexec/git-core/git-submit and now there's one command to submit new code to Gerrit for review:

$ git submit

If Gerrit is not the origin remote, then use git submit <remote> as appropriate.

Rivas answered 21/8, 2011 at 23:5 Comment(1)
Would there be a simpler git-only solution if I always want to push to a fixed destination, say refs/for/master? (Here's my SO question asking that simpler version of your problem.)Saundra
E
4

Two options I've found:

1) Check out a project I made, ggh: https://github.com/hobbs/ggh

2) You can configure the default push refspec in your remote. I've only figured out how to do this with a hardcoded remote branch, still trying to figure out how to wildcard the remote refspec so that it always pushes to the remote you're tracking:

[remote "origin"]
    fetch = +refs/heads/*:refs/remotes/origin/*
    url = ssh://gerrit/repo
    push =  HEAD:refs/for/master
Eley answered 16/2, 2012 at 17:48 Comment(0)
M
2

Here is an improvement of Greg Hewgill answer.

Create a script somewhere on the path, like on your profile bin folder (create one if necessary, even on Windows):

$ mkdir ~/bin
$ vi ~/bin/git-submit

With the following content:

#!/bin/sh -e

if [ -z "$1" ]; then
    REMOTE=origin
else
    REMOTE=$1
fi

BRANCH=`git symbolic-ref HEAD`
case $BRANCH in
    refs/heads/*)
        BRANCH=`basename $BRANCH`
        ;;
    *)
        echo "I can't figure out which branch you are on."
        exit 1
        ;;
esac

REMOTE_BRANCH=`git config --get "branch.$BRANCH.merge"`
if [ -z $REMOTE_BRANCH ]
then
    echo "There is no tracking information for the current branch."
    echo "If you wish to set tracking information for this branch you can do so with:"
    echo ""
    echo "    git branch --set-upstream $BRANCH <remote>/<branch>"
    echo ""
    exit 1
fi

git push $REMOTE HEAD:refs/for/$REMOTE_BRANCH

Supposing you create a remote tracking branch like:

$ git checkout -b MyBranch origin/master

You can simply call:

$ git submit

... to push to refs/for/master in this case.

Milissa answered 8/8, 2012 at 16:10 Comment(0)
P
0
git config push.default upstream
git config branch.work1234.merge refs/for/work1234
git config branch.work1234.remote origin

or .git/config:

[push]
        default = upstream
[branch "work1234"]
        merge = refs/for/work1234
        remote = origin

I'm not sure if there's a way to put a wildcard in there anywhere to make it work for all branches.

Puerperium answered 22/8, 2011 at 2:52 Comment(1)
This would break the git-pull as it'd try to pull from refs/for/* which fails. The remote is probably not needed as default is "origin".Milissa

© 2022 - 2024 — McMap. All rights reserved.