{"thread":{"id":"30979","subject":"On using receive.denyNonFastForwards and advice.pushNonFastForward","startedAt":"2012-07-08T21:26:50Z","lastAt":"2012-07-09T08:36:55Z","messageCount":3,"participants":["Hilco Wijbenga","Christopher Tiwald","Matthieu Moy"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"194792","messageId":"CAE1pOi1M-fdMJtZw9MNL2R6zWvpXvWVo4ros_NSCQtLmQb6TOQ@mail.gmail.com","threadId":"30979","inReplyTo":null,"subject":"On using receive.denyNonFastForwards and advice.pushNonFastForward","fromName":"Hilco Wijbenga","fromEmail":"hilco.wijbenga@gmail.com","sentAt":"2012-07-08T21:26:50Z","receivedAt":"2012-07-08T21:26:50Z","isPatch":false,"sender":{"key":"hilco.wijbenga@gmail.com","avatar":null},"body":"Hi all,\n\nI was wondering how hard it would be to make \"git push\" more adamant\nabout not pushing non-ff updates. So I wanted to see the effects of\nreceive.denyNonFastForwards and advice.pushNonFastForward. (By the\nway, why is one plural and the other singular? That doesn't seem\nconsistent?)\n\nHERE=$(pwd) &&\ngit init --bare remote-repo &&\ncd remote-repo/ &&\ngit config --add receive.denyNonFastForwards true &&\ncd .. &&\ngit clone file://$HERE/remote-repo local-repo &&\ncd local-repo/ &&\ngit config --add advice.pushNonFastForward true &&\necho \"1\" > one.txt &&\ngit add -A . && git commit -m 1 && git push origin master &&\ngit checkout -b next &&\necho \"a\" > two.txt &&\ngit add -A . && git commit -m 2 &&\ngit checkout master &&\necho \"2\" > one.txt &&\ngit add -A . && git commit -m 3 && git push origin master &&\ngit merge next &&\ngit push\n\nTo my surprise there was neither warning nor error. Does this last\npush really qualify as a FF update? Apparently, linear history and\nFF-only updates are not the same thing?\n\nCheers,\nHilco\n"},{"id":"194801","messageId":"20120709051315.GA62124@gmail.com","threadId":"30979","inReplyTo":"CAE1pOi1M-fdMJtZw9MNL2R6zWvpXvWVo4ros_NSCQtLmQb6TOQ@mail.gmail.com","subject":"Re: On using receive.denyNonFastForwards and advice.pushNonFastForward","fromName":"Christopher Tiwald","fromEmail":"christiwald@gmail.com","sentAt":"2012-07-09T05:13:15Z","receivedAt":"2012-07-09T05:13:15Z","isPatch":false,"sender":{"key":"christiwald@gmail.com","avatar":"https://avatars.githubusercontent.com/u/667276?v=4"},"body":"From: Christopher Tiwald <christiwald@gmail.com>\nTo: Hilco Wijbenga <hilco.wijbenga@gmail.com>\nCc: Git Users <git@vger.kernel.org>\nBcc: \nSubject: Re: On using receive.denyNonFastForwards and\n advice.pushNonFastForward\nReply-To: \nIn-Reply-To: <CAE1pOi1M-fdMJtZw9MNL2R6zWvpXvWVo4ros_NSCQtLmQb6TOQ@mail.gmail.com>\n\nOn Sun, Jul 08, 2012 at 02:26:50PM -0700, Hilco Wijbenga wrote:\n> I was wondering how hard it would be to make \"git push\" more adamant\n> about not pushing non-ff updates. So I wanted to see the effects of\n> receive.denyNonFastForwards and advice.pushNonFastForward. (By the\n> way, why is one plural and the other singular? That doesn't seem\n> consistent?)\n\n'advice.pushNonFastForward' doesn't control whether or not\nthe remote accepts non-fast-forward updates. Rather, it controls whether\nor not advice displays when 'git push' errors because the user attempted\na non-fast-forward update. As of 1.7.11 (f25950f3), it was supplemented\nwith 'advice.pushNonFFCurrent', 'advice.pushNonFFDefault', and\n'pushNonFFMatching'. Setting the original 'advice.pushNonFastForward'\nconfig option to 'false' will disable all three of these situational\nhints. None of them will affect the actual operation of 'git push'.\n\nAs for this series of commands, none of these are non-fast-forward\nupdates (i.e. a situation where a pushed branch tip is behind its remote\ncounterpart):\n\n> HERE=$(pwd) &&\n> git init --bare remote-repo &&\n> cd remote-repo/ &&\n> git config --add receive.denyNonFastForwards true &&\n> cd .. &&\n> git clone file://$HERE/remote-repo local-repo &&\n> cd local-repo/ &&\n> git config --add advice.pushNonFastForward true &&\n> echo \"1\" > one.txt &&\n> git add -A . && git commit -m 1 && git push origin master &&\n\nThis is the inital push to the remote:\n\n$ git log --graph --oneline\n* 32bbda2 1\n\n$ git diff master origin/master ;# noop\n\n> git checkout -b next &&\n> echo \"a\" > two.txt &&\n> git add -A . && git commit -m 2 &&\n> git checkout master &&\n> echo \"2\" > one.txt &&\n> git add -A . && git commit -m 3 && git push origin master &&\n\nThis is a standard fast-forward update to the remote:\n\n$ git log --graph --oneline\n* 0176f87 3\n* 32bbda2 1\n\n$ git diff master origin/master ;# noop\n\n> git merge next &&\n> git push\n\nThis is also a standard fast-forward update to the remote:\n\n$ git log --graph --oneline\n*   b881618 Merge branch 'next'\n|\\\n| * 843a285 2\n* | 0176f87 3\n|/\n* 32bbda2 1\n\n$ git diff master origin/master ;# noop\n\nIf you want to see a true non-fast-forward error from this point, try\nthis:\n\ngit reset --hard HEAD~1 &&\necho \"non-ff\" > one.txt &&\ngit add . && git commit -m 4 && git push origin master\n\nYou should get something like this (the advice will change based on your\nversion of git):\n\n[master cf28ce8] 4\n1 file changed, 1 insertion(+), 1 deletion(-)\nTo /tmp/remote-repo\n ! [rejected]        master -> master (non-fast-forward)\nerror: failed to push some refs to '/tmp/remote-repo'\nhint: Updates were rejected because the tip of your current branch is behind\nhint: its remote counterpart. Merge the remote changes (e.g. 'git pull')\nhint: before pushing again.\nhint: See the 'Note about fast-forwards' in 'git push --help' for\ndetails.\n\nThe \"hint\" lines at the end are configured by the 'advice' options\ndescribed above.\n\n--\nChristopher Tiwald\n"},{"id":"194804","messageId":"vpqobnpz5y0.fsf@bauges.imag.fr","threadId":"30979","inReplyTo":"CAE1pOi1M-fdMJtZw9MNL2R6zWvpXvWVo4ros_NSCQtLmQb6TOQ@mail.gmail.com","subject":"Re: On using receive.denyNonFastForwards and advice.pushNonFastForward","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@grenoble-inp.fr","sentAt":"2012-07-09T08:36:55Z","receivedAt":"2012-07-09T08:36:55Z","isPatch":false,"sender":{"key":"matthieu.moy@grenoble-inp.fr","avatar":"https://gravatar.com/avatar/72c8a2705971a25dfaff23cece15130d405685845d911aedd5667ace277f3fc5?d=mp&s=160"},"body":"Hilco Wijbenga <hilco.wijbenga@gmail.com> writes:\n\n> I was wondering how hard it would be to make \"git push\" more adamant\n> about not pushing non-ff updates. So I wanted to see the effects of\n> receive.denyNonFastForwards\n\nThis changes the behavior only if you use --force (or some magic refspec\nstarting with +). If you never used --force or +refspecs, you never did\na non-fast-forward push.\n\n> and advice.pushNonFastForward.\n\nActivated by default, so if you never did anything about it, it was\nalready active.\n\n> Apparently, linear history and FF-only updates are not the same thing?\n\nNo, they are not. non-FF means you're trying to push a commit which is\nnot a direct descendant of the remote one, i.e. you're trying to\noverride the remote history with yours. See 'NOTE ABOUT FAST-FORWARDS'\nin \"man git-push\".\n\n-- \nMatthieu Moy\nhttp://www-verimag.imag.fr/~moy/\n"}]}