My team is using gerrit code review, essentially this means the default push behaviour bypasses the standard workflow so instead we need to use git push origin HEAD:refs/for/feature
to correctly push our code to get reviewed.
The default push behaviour looks like this:
user$ git push --dry-run
To https://gerrit.company.url/project
83fa2a5..aca3a22 feature -> feature
This would bypass the review process which is undesired.
When I set the push ref-spec (reference here) to be refs/heads/*:refs/for/*
this takes a step in the right direction:
user $ git config remote.origin.push refs/heads/*:refs/for/*
user$ git push --dry-run
To https://gerrit.company.url/project
* [new branch] master -> refs/for/master
* [new branch] old_stuff -> refs/for/old_stuff
* [new branch] feature -> refs/for/feature
Now it is trying to push feature
to refs/for/feature
which is what I want but it's also trying to push all my branches to origin. Gerrit rejects more than one request so I get an output like this:
user$ git push
....
To https://gerrit.company.url/project
! [remote rejected] master -> refs/for/master (no new changes)
! [remote rejected] old_stuff -> refs/for/old_stuff (duplicate request)
! [remote rejected] feature -> refs/for/feature (duplicate request)
but I found that if I name the current branch it does what I'm expecting:
user $ git push origin feature --dry-run
To https://gerrit.company.url/project
* [new branch] feature -> refs/for/feature
This is great and I will be able to use this but I'd like to narrow it more. I figured if I set push.default
to current
it will mean that git push
will only push the current branch in this way, but to my disappointment:
user$ git config push.default current
user$ git push origin --dry-run
To https://gerrit.company.url/project
* [new branch] master -> refs/for/master
* [new branch] old_stuff -> refs/for/old_stuff
* [new branch] feature -> refs/for/feature
This seems to be ignoring the push.default
setting, From the git config documentation:
push.default
Defines the action
git push
should take if no refspec is explicitly given
So the remote.origin.push
config gets interpreted as an explicit ref spec? Even when setting the default push behaviour to nothing
it still tries to push all branches:
user$ git config push.default nothing
user$ git push
fatal: You didn't specify any refspecs to push, and push.default is "nothing".
user$ git config remote.origin.push refs/heads/*:refs/for/*
user$ git push origin --dry-run
To https://gerrit.company.url/project
* [new branch] master -> refs/for/master
* [new branch] old_stuff -> refs/for/old_stuff
* [new branch] feature -> refs/for/feature
What am I missing here? How do I get git push
to only push the current branch like feature -> refs/for/feature
?
By default, Git chooses origin for the remote and your current branch as the branch to push. If your current branch is main , the command git push will supply the two default parameters—effectively running git push origin main .
push may overwrite refs other than the current branch (including local refs that are strictly behind their remote counterpart). To force a push to only one branch, use a + in front of the refspec to push (e.g git push origin +master to force a push to the master branch).
Simply, we can say that git push command updates the remote repository with local commits. And origin represents a remote name where the user wants to push the changes.
I don't believe what you want to do can be done with just git currently.
I've been able to narrow it down one level further by defining remote server aliases in my config file like below, one for each branch I might want to push, but this is obviously tedious and obnoxious, and I still have to type something like git push masterrev
.
[remote "origin"]
url = ssh://gerritserver/product
fetch = +refs/heads/*:refs/remotes/origin/*
[remote "masterrev"]
url = ssh://gerritserver/product
fetch = +refs/heads/*:refs/remotes/origin/*
push = HEAD:refs/for/master
The only equivalent I know to provide your original goal is with 3rd party tools like the git-review tool that the OpenStack developers put together for their own use. It might be worth it if your team is planning to use gerrit, since it provides other functionality like easy access to cherry-picking or checkout of reviews.
As an aside, I believe the push.default setting of "current" means just to assume that the local branch name(s) should be pushed through the remote.*.push modification even if they aren't already known to exist on the server. It does not limit which branches are pushed to just the "current" one, but rather to use the "current" name(s).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With