threads / discuss / 30979

On using receive.denyNonFastForwards and advice.pushNonFastForward

Subject: On using receive.denyNonFastForwards and advice.pushNonFastForward

## tl;dr

3 messages between Jul 8, 2012 and Jul 9, 2012.

replies: 2people: 3as markdown or json

Hilco Wijbenga· Jul 8, 2012, 21:26 UTC · lore
Hi all,

I was wondering how hard it would be to make "git push" more adamant about not pushing non-ff updates. So I wanted to see the effects of receive.denyNonFastForwards and advice.pushNonFastForward. (By the way, why is one plural and the other singular? That doesn't seem consistent?)

HERE=$(pwd) && git init --bare remote-repo && cd remote-repo/ && git config --add receive.denyNonFastForwards true && cd .. && git clone file://$HERE/remote-repo local-repo && cd local-repo/ && git config --add advice.pushNonFastForward true && echo "1" > one.txt && git add -A . && git commit -m 1 && git push origin master && git checkout -b next && echo "a" > two.txt && git add -A . && git commit -m 2 && git checkout master && echo "2" > one.txt && git add -A . && git commit -m 3 && git push origin master && git merge next && git push

To my surprise there was neither warning nor error. Does this last push really qualify as a FF update? Apparently, linear history and FF-only updates are not the same thing?

Cheers, Hilco

Christopher Tiwald· Jul 9, 2012, 05:13 UTC · re: Hilco Wijbenga · lore

Re: On using receive.denyNonFastForwards and advice.pushNonFastForward

From: Christopher Tiwald <christiwald@gmail.com>
To: Hilco Wijbenga <hilco.wijbenga@gmail.com>
Cc: Git Users <git@vger.kernel.org>
Bcc: 
Subject: Re: On using receive.denyNonFastForwards and
 advice.pushNonFastForward
Reply-To: 
In-Reply-To: <CAE1pOi1M-fdMJtZw9MNL2R6zWvpXvWVo4ros_NSCQtLmQb6TOQ@mail.gmail.com>
On Sun, Jul 08, 2012 at 02:26:50PM -0700, Hilco Wijbenga wrote:
Show 5 quoted lines
> I was wondering how hard it would be to make "git push" more adamant
> about not pushing non-ff updates. So I wanted to see the effects of
> receive.denyNonFastForwards and advice.pushNonFastForward. (By the
> way, why is one plural and the other singular? That doesn't seem
> consistent?)

'advice.pushNonFastForward' doesn't control whether or not the remote accepts non-fast-forward updates. Rather, it controls whether or not advice displays when 'git push' errors because the user attempted a non-fast-forward update. As of 1.7.11 (f25950f3), it was supplemented with 'advice.pushNonFFCurrent', 'advice.pushNonFFDefault', and 'pushNonFFMatching'. Setting the original 'advice.pushNonFastForward' config option to 'false' will disable all three of these situational hints. None of them will affect the actual operation of 'git push'.

As for this series of commands, none of these are non-fast-forward updates (i.e. a situation where a pushed branch tip is behind its remote counterpart):

Show 10 quoted lines
> HERE=$(pwd) &&
> git init --bare remote-repo &&
> cd remote-repo/ &&
> git config --add receive.denyNonFastForwards true &&
> cd .. &&
> git clone file://$HERE/remote-repo local-repo &&
> cd local-repo/ &&
> git config --add advice.pushNonFastForward true &&
> echo "1" > one.txt &&
> git add -A . && git commit -m 1 && git push origin master &&
This is the inital push to the remote:
$ git log --graph --oneline
* 32bbda2 1
$ git diff master origin/master ;# noop
Show 6 quoted lines
> git checkout -b next &&
> echo "a" > two.txt &&
> git add -A . && git commit -m 2 &&
> git checkout master &&
> echo "2" > one.txt &&
> git add -A . && git commit -m 3 && git push origin master &&
This is a standard fast-forward update to the remote:
$ git log --graph --oneline
* 0176f87 3
* 32bbda2 1
$ git diff master origin/master ;# noop
> git merge next &&
> git push
This is also a standard fast-forward update to the remote:
$ git log --graph --oneline
*   b881618 Merge branch 'next'
|\
| * 843a285 2
* | 0176f87 3
|/
* 32bbda2 1
$ git diff master origin/master ;# noop

If you want to see a true non-fast-forward error from this point, try this:

git reset --hard HEAD~1 && echo "non-ff" > one.txt && git add . && git commit -m 4 && git push origin master

You should get something like this (the advice will change based on your version of git):

[master cf28ce8] 4
1 file changed, 1 insertion(+), 1 deletion(-)
To /tmp/remote-repo
 ! [rejected]        master -> master (non-fast-forward)
error: failed to push some refs to '/tmp/remote-repo'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Merge the remote changes (e.g. 'git pull')
hint: before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for
details.

The "hint" lines at the end are configured by the 'advice' options described above.

-- Christopher Tiwald

Matthieu Moy· Jul 9, 2012, 08:36 UTC · re: Hilco Wijbenga · lore

Re: On using receive.denyNonFastForwards and advice.pushNonFastForward

Hilco Wijbenga <hilco.wijbenga@gmail.com> writes:
> I was wondering how hard it would be to make "git push" more adamant
> about not pushing non-ff updates. So I wanted to see the effects of
> receive.denyNonFastForwards

This changes the behavior only if you use --force (or some magic refspec starting with +). If you never used --force or +refspecs, you never did a non-fast-forward push.

> and advice.pushNonFastForward.

Activated by default, so if you never did anything about it, it was already active.

> Apparently, linear history and FF-only updates are not the same thing?

No, they are not. non-FF means you're trying to push a commit which is not a direct descendant of the remote one, i.e. you're trying to override the remote history with yours. See 'NOTE ABOUT FAST-FORWARDS' in "man git-push".

-- 
Matthieu Moy
http://www-verimag.imag.fr/~moy/

← back to recent threads