Why is git push gerrit HEAD:refs/for/master used instead of git push origin master

GitGerrit

Git Problem Overview


I've just started using gerrit and I want to know why we need to do git push gerrit HEAD:refs/for/master instead of doing git push origin master

If I do git push origin master I get the error saying ! [remote rejected] master -> master (prohibited by Gerrit)

Git Solutions


Solution 1 - Git

The documentation for Gerrit, in particular the "Push changes" section, explains that you push to the "magical refs/for/'branch' ref using any Git client tool".

The following image is taken from the Intro to Gerrit. When you push to Gerrit, you do git push gerrit HEAD:refs/for/<BRANCH>. This pushes your changes to the staging area (in the diagram, "Pending Changes"). Gerrit doesn't actually have a branch called <BRANCH>; it lies to the git client.

Internally, Gerrit has its own implementation for the Git and SSH stacks. This allows it to provide the "magical" refs/for/<BRANCH> refs. >When a push request is received to create a ref in one of these namespaces Gerrit performs its own logic to update the database, and then lies to the client about the result of the operation. A successful result causes the client to believe that Gerrit has created the ref, but in reality Gerrit hasn’t created the ref at all. [Link - Gerrit, "Gritty Details"].

The Gerrit workflow

After a successful patch (i.e, the patch has been pushed to Gerrit, [putting it into the "Pending Changes" staging area], reviewed, and the review has passed), Gerrit pushes the change from the "Pending Changes" into the "Authoritative Repository", calculating which branch to push it into based on the magic it did when you pushed to refs/for/<BRANCH>. This way, successfully reviewed patches can be pulled directly from the correct branches of the Authoritative Repository.

Solution 2 - Git

In order to avoid having to fully specify the git push command you could alternatively modify your git config file:

[remote "gerrit"]
    url = https://your.gerrit.repo:44444/repo
    fetch = +refs/heads/master:refs/remotes/origin/master
    push = refs/heads/master:refs/for/master

Now you can simply:

git fetch gerrit
git push gerrit

This is according to Gerrit

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionShrayasView Question on Stackoverflow
Solution 1 - GitsimontView Answer on Stackoverflow
Solution 2 - GitSean MurphyView Answer on Stackoverflow