{"thread":{"id":"16651","subject":"Forcing --no-ff on pull","startedAt":"2008-12-09T09:34:00Z","lastAt":"2008-12-10T19:07:38Z","messageCount":15,"participants":["R. Tyler Ballance","Jakub Narebski","Lars Hjemli","Johannes Sixt","Nanako Shiraishi","Jeff King","Boyd Stephen Smith Jr.","Stephen Haberman","Daniel Barkalow"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"97412","messageId":"1228815240.18611.48.camel@starfruit.local","threadId":"16651","inReplyTo":null,"subject":"Forcing --no-ff on pull","fromName":"R. Tyler Ballance","fromEmail":"tyler@slide.com","sentAt":"2008-12-09T09:34:00Z","receivedAt":"2008-12-09T09:34:00Z","isPatch":false,"sender":{"key":"tyler@slide.com","avatar":null},"body":"While I'm in the email writing mood tonight, I figured I'd ask this\nquestion.\n\nWe've recently moved a giant tree with a number of developers over to\nGit from Subversion. One of the biggest stumbling points we have right\nnow is the concept of a \"fast-forward\", insofar that it's \"screwed\" us a\ncouple times (see: people not RTFM'ing then crying that Git is broken\nbecause they cannot RTFM ;))\n\nThe most common use-case involves a user merging a project branch into a\nstabilization branch (`git checkout stable && git pull . project`) in\nsuch a way that no merge commit is generated. Of course, without\nthinking they'll push these changes up to the centralized repository.\nNot 15 minutes later they realize \"ruh roh! I didn't want to do that\"\nand become very frustrated that they have to resort to asking for help\nor hand-reverting N number of commits. \n\nIs there a header macro I can define or a config option I could define\nto make --no-ff on `git pull` implicit instead of explicit? Making sure\nwe are always generating merge commits as a \"just-in-case\" safe guard\nabout merge-happy developers who think after hitting enter? :)\n\n\nCheers\n-- \n-R. Tyler Ballance\nSlide, Inc.\n"},{"id":"97416","messageId":"m3vdtthebu.fsf@localhost.localdomain","threadId":"16651","inReplyTo":"1228815240.18611.48.camel@starfruit.local","subject":"Re: Forcing --no-ff on pull","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2008-12-09T09:46:05Z","receivedAt":"2008-12-09T09:46:05Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"\"R. Tyler Ballance\" <tyler@slide.com> writes:\n\n> Is there a header macro I can define or a config option I could define\n> to make --no-ff on `git pull` implicit instead of explicit? Making sure\n> we are always generating merge commits as a \"just-in-case\" safe guard\n> about merge-happy developers who think after hitting enter? :)\n\nbranch.<name>.mergeoptions ?\n-- \nJakub Narebski\nPoland\nShadeHawk on #git\n"},{"id":"97418","messageId":"8c5c35580812090149lc6dd79cj60a9d23c18089557@mail.gmail.com","threadId":"16651","inReplyTo":"1228815240.18611.48.camel@starfruit.local","subject":"Re: Forcing --no-ff on pull","fromName":"Lars Hjemli","fromEmail":"lh@elementstorage.no","sentAt":"2008-12-09T09:49:54Z","receivedAt":"2008-12-09T09:49:54Z","isPatch":false,"sender":{"key":"lh@elementstorage.no","avatar":null},"body":"On Tue, Dec 9, 2008 at 10:34, R. Tyler Ballance <tyler@slide.com> wrote:\n> Is there a header macro I can define or a config option I could define\n> to make --no-ff on `git pull` implicit instead of explicit?\n\nTry this:\n$ git config branch.stable.mergeoptions \"--no-ff\"\n\n--\nlh\n"},{"id":"97419","messageId":"493E41BE.4050809@viscovery.net","threadId":"16651","inReplyTo":"1228815240.18611.48.camel@starfruit.local","subject":"Re: Forcing --no-ff on pull","fromName":"Johannes Sixt","fromEmail":"j.sixt@viscovery.net","sentAt":"2008-12-09T10:00:30Z","receivedAt":"2008-12-09T10:00:30Z","isPatch":false,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"R. Tyler Ballance schrieb:\n> The most common use-case involves a user merging a project branch into a\n> stabilization branch (`git checkout stable && git pull . project`) in\n> such a way that no merge commit is generated. Of course, without\n> thinking they'll push these changes up to the centralized repository.\n> Not 15 minutes later they realize \"ruh roh! I didn't want to do that\"\n> and become very frustrated that they have to resort to asking for help\n> or hand-reverting N number of commits. \n\nIs the problem\n\n * that there is no merge commit, or\n\n * that you have to undo N commits instead of just one?\n\nThe latter is probably helped by\n\n   $ git reset --hard ORIG_HEAD && git push -f origin\n\n-- Hannes\n"},{"id":"97421","messageId":"1228817565.18611.54.camel@starfruit.local","threadId":"16651","inReplyTo":"8c5c35580812090149lc6dd79cj60a9d23c18089557@mail.gmail.com","subject":"Re: Forcing --no-ff on pull","fromName":"R. Tyler Ballance","fromEmail":"tyler@slide.com","sentAt":"2008-12-09T10:12:45Z","receivedAt":"2008-12-09T10:12:45Z","isPatch":false,"sender":{"key":"tyler@slide.com","avatar":null},"body":"On Tue, 2008-12-09 at 10:49 +0100, Lars Hjemli wrote:\n> On Tue, Dec 9, 2008 at 10:34, R. Tyler Ballance <tyler@slide.com> wrote:\n> > Is there a header macro I can define or a config option I could define\n> > to make --no-ff on `git pull` implicit instead of explicit?\n> \n> Try this:\n> $ git config branch.stable.mergeoptions \"--no-ff\"\n\nI recall stumbling across this a while ago looking at the git-config(1)\nman page, but this isn't /quite/ what we need.\n\nI'm talking about forcing for *every* pull, it's a safe assumption to\nmake that we want a merge commit every time somebody fast-forwards a\nbranch. \n\nThe only way I could think to make use of branch.<name>.mergeoptions\nwould be to automagically set it up in a \"pre-merge\" hook, but alas\npost-merge exists but not pre-merge.\n\nI could certainly patch to support a pre-merge, but that seems like the\nlongest possible route to my desired destination ;)\n\n\nCheers\n-- \n-R. Tyler Ballance\nSlide, Inc.\n"},{"id":"97422","messageId":"20081209191704.6117@nanako3.lavabit.com","threadId":"16651","inReplyTo":"1228815240.18611.48.camel@starfruit.local","subject":"Re: Forcing --no-ff on pull","fromName":"Nanako Shiraishi","fromEmail":"nanako3@lavabit.com","sentAt":"2008-12-09T10:17:04Z","receivedAt":"2008-12-09T10:17:04Z","isPatch":false,"sender":{"key":"nanako3@lavabit.com","avatar":"https://gravatar.com/avatar/3777b9e201c5883a62b1a6fdf7c53f2d712d1d80989146063ea861e33aad72a8?d=mp&s=160"},"body":"Quoting \"R. Tyler Ballance\" <tyler@slide.com>:\n\n> The most common use-case involves a user merging a project branch into a\n> stabilization branch (`git checkout stable && git pull . project`) in\n> such a way that no merge commit is generated. Of course, without\n> thinking they'll push these changes up to the centralized repository.\n> Not 15 minutes later they realize \"ruh roh! I didn't want to do that\"\n\nWhy does the user not want to fast-forward, if the merge she wants to do is actually a fast-forward?\n\nIf you mean that the user merged branches in a wrong direction, how does it help her avoid such a mistake to unconditionally forbid fast-forward merges?  Doesn't people often do:\n\n Start on a topic branch, have a potentially bright idea...\n % git checkout -b experiment\n Hack on experiment branch.\n Happy because it indeed was an excellent idea.\n % git checkout topic\n % git pull . experiment\n % git branch -d experiement\n\nIf you forbid fast-forward merges, when they merge their successful experiment back to the original topic, it will leave an unwanted merge in the history.\n\nIn other words, I do not think --no-ff is a right solution for the problem you are trying to solve.  Perhaps you would need a hook that prevents a merge from certain direction from taking place instead?\n\n-- \nNanako Shiraishi\nhttp://ivory.ap.teacup.com/nanako3/\n"},{"id":"97424","messageId":"8c5c35580812090231u28076844nf5a9225349c20801@mail.gmail.com","threadId":"16651","inReplyTo":"1228817565.18611.54.camel@starfruit.local","subject":"Re: Forcing --no-ff on pull","fromName":"Lars Hjemli","fromEmail":"lh@elementstorage.no","sentAt":"2008-12-09T10:31:50Z","receivedAt":"2008-12-09T10:31:50Z","isPatch":false,"sender":{"key":"lh@elementstorage.no","avatar":null},"body":"On Tue, Dec 9, 2008 at 11:12, R. Tyler Ballance <tyler@slide.com> wrote:\n> On Tue, 2008-12-09 at 10:49 +0100, Lars Hjemli wrote:\n>> On Tue, Dec 9, 2008 at 10:34, R. Tyler Ballance <tyler@slide.com> wrote:\n>> > Is there a header macro I can define or a config option I could define\n>> > to make --no-ff on `git pull` implicit instead of explicit?\n>>\n>> Try this:\n>> $ git config branch.stable.mergeoptions \"--no-ff\"\n>\n> I recall stumbling across this a while ago looking at the git-config(1)\n> man page, but this isn't /quite/ what we need.\n>\n> I'm talking about forcing for *every* pull, it's a safe assumption to\n> make that we want a merge commit every time somebody fast-forwards a\n> branch.\n\n$ git config alias.xpull \"pull --no-ff\" ?\n\nBut are you sure you never want a fast-forward on _any_ branch? I use\n--no-ff unconditionally on the master and stable branches as $dayjob,\nto make sure that the merging of feature/bugfix-branches are\nexplicitly noted in history, but I almost never use it on other\nbranches.\n\n--\nlarsh\n"},{"id":"97425","messageId":"1228819087.18611.73.camel@starfruit.local","threadId":"16651","inReplyTo":"20081209191704.6117@nanako3.lavabit.com","subject":"Re: Forcing --no-ff on pull","fromName":"R. Tyler Ballance","fromEmail":"tyler@slide.com","sentAt":"2008-12-09T10:38:07Z","receivedAt":"2008-12-09T10:38:07Z","isPatch":false,"sender":{"key":"tyler@slide.com","avatar":null},"body":"On Tue, 2008-12-09 at 19:17 +0900, Nanako Shiraishi wrote:\n> Quoting \"R. Tyler Ballance\" <tyler@slide.com>:\n> \n> > The most common use-case involves a user merging a project branch into a\n> > stabilization branch (`git checkout stable && git pull . project`) in\n> > such a way that no merge commit is generated. Of course, without\n> > thinking they'll push these changes up to the centralized repository.\n> > Not 15 minutes later they realize \"ruh roh! I didn't want to do that\"\n> \n> Why does the user not want to fast-forward, if the merge she wants to do is actually a fast-forward?\n\nI agree with you, this is more about preventing coworkers who are too\nlazy to understand the entirety of what they're doing from hurting the\nworkflow of \"the rest of us\". It's a technically solution to a people\nproblem (I understand technology far more than people ;))\n\nConsider the following scenarion:\n  % git checkout -b project﻿\n﻿  % <work>\n﻿  % git commit -am \"A\"﻿\n﻿  % <work>\n﻿  % git commit -am \"B\"﻿\n﻿  % <work>\n﻿  % git commit -am \"C\"﻿\n﻿  % <work>\n﻿  % git commit -am \"D\"\n﻿﻿  % git checkout stable\n﻿﻿  % git pull . project\n﻿﻿  % <fast-forward>\n﻿﻿  % git push origin stable\n﻿﻿\nAt this point, QA is involved and what can happen is that QA realizes\nthat this code is *not* stable and *never* should have been brought into\nthe stable branch.\n\nNow we have two options \"block\" the stable branch until LazyDeveloper\nmakes the appropriate changes to stabilize the branch again *OR* back\nout LazyDeveloper's changes (A, B, C, D) and beat them up in the\nalleyway :)\n\nGiven the nature of our work, we have a stable branch per-team, and one\nfunneling stable branch for the entire company (master), that branch\nbeing used to push the live web site with. \n\nThe first option (block) is not feasible as it will block the 40+ other\ndevelopers from pushing code until LazyDeveloper sufficiently gets their\ncrap together.\n\nThe second option is why I want to force --no-ff on *all* pulls if\npossible. With --no-ff we can simply `git revert -sn <hash> -m 1 && git\ncommit -a` in order to back out A, B, C, D. With a true fast-forward,\nwe've had to use git-rev-list(1) trickery and some bash scriptery to\nproperly revert a series of commits from a given time frame from a given\ndeveloper.\n\n\n> If you forbid fast-forward merges, when they merge their successful\n> experiment back to the original topic, it will leave an unwanted merge\n> in the history.\n\nI'm less concerned at this point, the company switched entirely to Git\ntwo weeks ago, with the history containing possible unwanted merges. I'm\nmore concerned however with LazyDeveloper inadvertently polluting stable\nbranches as LazyDeveloper does not yet fully grasp the concepts that Git\noffers\n\n> \n> In other words, I do not think --no-ff is a right solution for the problem you are trying to solve.  Perhaps you would need a hook that prevents a merge from certain direction from taking place instead?\n\nIf you do have a better solution to this problem (I dislike git push -f\norigin[1]) I'm all ears, I'm more concerned with the end result at this\npoint ;)\n\nCheers\n\n\n[1] We've stressed with our developers as much as possible that the\n\"origin\" repository is to remain\" pristine\", that every action should be\n\"auditable\" insofar that if you rollback a change, we want to see a\nRevert commit, merges should create merge commits to where we can replay\nor unwind the revision history correctly at any point in time or slice\nof time. I *really* don't want \"origin\" to \"lose commits\".\n-- \n-R. Tyler Ballance\nSlide, Inc.\n"},{"id":"97426","messageId":"1228819557.18611.80.camel@starfruit.local","threadId":"16651","inReplyTo":"8c5c35580812090231u28076844nf5a9225349c20801@mail.gmail.com","subject":"Re: Forcing --no-ff on pull","fromName":"R. Tyler Ballance","fromEmail":"tyler@slide.com","sentAt":"2008-12-09T10:45:57Z","receivedAt":"2008-12-09T10:45:57Z","isPatch":false,"sender":{"key":"tyler@slide.com","avatar":null},"body":"On Tue, 2008-12-09 at 11:31 +0100, Lars Hjemli wrote:\n> On Tue, Dec 9, 2008 at 11:12, R. Tyler Ballance <tyler@slide.com> wrote:\n> > On Tue, 2008-12-09 at 10:49 +0100, Lars Hjemli wrote:\n> >> On Tue, Dec 9, 2008 at 10:34, R. Tyler Ballance <tyler@slide.com> wrote:\n> >> > Is there a header macro I can define or a config option I could define\n> >> > to make --no-ff on `git pull` implicit instead of explicit?\n> >>\n> >> Try this:\n> >> $ git config branch.stable.mergeoptions \"--no-ff\"\n> >\n> > I recall stumbling across this a while ago looking at the git-config(1)\n> > man page, but this isn't /quite/ what we need.\n> >\n> > I'm talking about forcing for *every* pull, it's a safe assumption to\n> > make that we want a merge commit every time somebody fast-forwards a\n> > branch.\n> \n> $ git config alias.xpull \"pull --no-ff\" ?\n\nInteresting, I might have to try that out (wasn't aware of `git config\nalias.<alias>`)\n\n> \n> But are you sure you never want a fast-forward on _any_ branch? I use\n> --no-ff unconditionally on the master and stable branches as $dayjob,\n> to make sure that the merging of feature/bugfix-branches are\n> explicitly noted in history, but I almost never use it on other\n> branches.\n\nI understand this, it's a funny situation. When we were evaluating Git\nmy team *never* had these issues because we all kept our trees in good\ncondition such that we never accidentally merged down to a stable\nbranch, but we also almost always generated merge commits because of the\nvariety of changes that would be going into stable at any given time.\n\nI agree that I wouldn't want/need to use it on WIP branches or purely\nlocal branches for development, so if I were able to restrict --no-ff to\nonly be forced on tracked branches I would be happy enough :)\n\nReally hate to take this much bandwidth up on the mailing list over such\na silly problem, but after spending a week trying to /talk/ and educate\nsome folks, I feel drastic measures need to be taken ;)\n\nCheers \n-- \n-R. Tyler Ballance\nSlide, Inc.\n"},{"id":"97427","messageId":"20081209105703.GA21536@coredump.intra.peff.net","threadId":"16651","inReplyTo":"1228819087.18611.73.camel@starfruit.local","subject":"Re: Forcing --no-ff on pull","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2008-12-09T10:57:03Z","receivedAt":"2008-12-09T10:57:03Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Tue, Dec 09, 2008 at 02:38:07AM -0800, R. Tyler Ballance wrote:\n\n> At this point, QA is involved and what can happen is that QA realizes\n> that this code is *not* stable and *never* should have been brought into\n> the stable branch.\n> \n> Now we have two options \"block\" the stable branch until LazyDeveloper\n> makes the appropriate changes to stabilize the branch again *OR* back\n> out LazyDeveloper's changes (A, B, C, D) and beat them up in the\n> alleyway :)\n\nIt sounds like the problem is that LazyDeveloper has the authority to\npush to the stable branch that everyone else pulls from, but can't be\ntrusted with that authority (because he is pushing bad work).\n\nMaybe you would do better to invert your workflow:\n\n  1. LazyDeveloper does some work on the 'foo' branch locally. Either\n     his work repo is accessible to everyone, or he pushes it to a\n     personal public repo (or a personal namespace within a shared\n     repo).\n\n  2. LazyDeveloper tells QA \"check out foo, which should be ready for\n     integration.\"\n\n  3. QA pulls LazyDeveloper's foo. If it is OK, they merge and push to\n     the official \"stable\" branch. If it isn't, they reject and\n     LazyDeveloper fixes and goes back to step 2. LazyDeveloper is free\n     to reset, rewind, or rebase as appropriate, since nobody but QA has\n     ever even looked at this branch (and once they reached the \"reject\"\n     conclusion, they don't care anymore).\n\nSo everyone builds off of the official \"stable\" branch, which by\ndefinition is stuff that has passed through QA.\n\n> Given the nature of our work, we have a stable branch per-team, and one\n> funneling stable branch for the entire company (master), that branch\n> being used to push the live web site with. \n\nAnd you could of course have per-team QA if you wanted to organize it\nthat way.\n\n> The second option is why I want to force --no-ff on *all* pulls if\n> possible. With --no-ff we can simply `git revert -sn <hash> -m 1 && git\n> commit -a` in order to back out A, B, C, D. With a true fast-forward,\n> we've had to use git-rev-list(1) trickery and some bash scriptery to\n> properly revert a series of commits from a given time frame from a given\n> developer.\n\nThere isn't good support for multiple reverts, but you can do the moral\nequivalent with a big patch (note that revert can actually be more\nclever about resolving the three way merge, but if you are close to the\ntip, you shouldn't find any conflicts):\n\n  git diff HEAD last-good-commit | git apply\n\nIf they are the tip commits, then you can always just make a new commit\nwith the pre-breakage state. This is sort of a mix of \"git reset\" and\n\"git revert\" in that it throws away changes, but not history.\n\nI don't think there is good porcelain support for this, but you can do:\n\n  GIT_INDEX_FILE=index.tmp; export GIT_INDEX_FILE\n  git read-tree last-good-commit\n  git commit -m 'revert crappy commits'\n\n-Peff\n"},{"id":"97428","messageId":"8c5c35580812090257w46dc3b75mc8f300ab396c82bd@mail.gmail.com","threadId":"16651","inReplyTo":"1228819557.18611.80.camel@starfruit.local","subject":"Re: Forcing --no-ff on pull","fromName":"Lars Hjemli","fromEmail":"lh@elementstorage.no","sentAt":"2008-12-09T10:57:33Z","receivedAt":"2008-12-09T10:57:33Z","isPatch":false,"sender":{"key":"lh@elementstorage.no","avatar":null},"body":"On Tue, Dec 9, 2008 at 11:45, R. Tyler Ballance <tyler@slide.com> wrote:\n> Really hate to take this much bandwidth up on the mailing list over such\n> a silly problem, but after spending a week trying to /talk/ and educate\n> some folks, I feel drastic measures need to be taken ;)\n\nA possible solution could be the \"Integration manager workflow\" described here:\n\n  http://whygitisbetterthanx.com/#any-workflow\n\nBut it has the potential of confusing your co-devs ;-)\n\n--\nlarsh\n"},{"id":"97433","messageId":"200812090836.31012.bss03@volumehost.net","threadId":"16651","inReplyTo":"1228819087.18611.73.camel@starfruit.local","subject":"Re: Forcing --no-ff on pull","fromName":"Boyd Stephen Smith Jr.","fromEmail":"bss03@volumehost.net","sentAt":"2008-12-09T14:36:26Z","receivedAt":"2008-12-09T14:36:26Z","isPatch":false,"sender":{"key":"bss03@volumehost.net","avatar":"https://gravatar.com/avatar/74fa10b37dfd44462a6a30c4d4e3bda26ab7991ddb0d8ab24b022714a8ecb918?d=mp&s=160"},"body":"On Tuesday 09 December 2008, \"R. Tyler Ballance\" <tyler@slide.com> wrote \nabout 'Re: Forcing --no-ff on pull':\n>On Tue, 2008-12-09 at 19:17 +0900, Nanako Shiraishi wrote:\n>> Quoting \"R. Tyler Ballance\" <tyler@slide.com>:\n>> > The most common use-case involves a user merging a project branch\n>> > into a stabilization branch (`git checkout stable && git pull .\n>> > project`) in such a way that no merge commit is generated. Of course,\n>> > without thinking they'll push these changes up to the centralized\n>> > repository. Not 15 minutes later they realize \"ruh roh! I didn't want\n>> > to do that\"\n>>\n>> Why does the user not want to fast-forward, if the merge she wants to\n>> do is actually a fast-forward?\n>\n>I agree with you, this is more about preventing coworkers who are too\n>lazy to understand the entirety of what they're doing from hurting the\n>workflow of \"the rest of us\". It's a technically solution to a people\n>problem (I understand technology far more than people ;))\n>\n>Consider the following scenarion:\n>  % git checkout -b project﻿\n>﻿  % <work>\n>﻿  % git commit -am \"A\"﻿\n>﻿  % <work>\n>﻿  % git commit -am \"B\"﻿\n>﻿  % <work>\n>﻿  % git commit -am \"C\"﻿\n>﻿  % <work>\n>﻿  % git commit -am \"D\"\n>﻿﻿  % git checkout stable\n>﻿﻿  % git pull . project\n>﻿﻿  % <fast-forward>\n>﻿﻿  % git push origin stable\n>﻿﻿\n>At this point, QA is involved and what can happen is that QA realizes\n>that this code is *not* stable and *never* should have been brought into\n>the stable branch.\n>\n>Now we have two options \"block\" the stable branch until LazyDeveloper\n>makes the appropriate changes to stabilize the branch again *OR* back\n>out LazyDeveloper's changes (A, B, C, D) and beat them up in the\n>alleyway :)\n>\n>Given the nature of our work, we have a stable branch per-team, and one\n>funneling stable branch for the entire company (master), that branch\n>being used to push the live web site with.\n\nIn the words of 4chan: \"You're doing it wrong.\"\n\nIf QA decides what is appropriate for the stable branch, only QA should be \npushing to stable (not just any dev. or team) and this should be enforced.\n\nQA can retrieve commits from individual developers or teams, via email, by \npulling from their private repositories, or pulling from \"private\" \nbranches in the public repository.  The last seems most appropriate for \nyour organization.\n\nI think a better workflow would be for developers to pull from \"stable\" but \npush to \"<username>-tbr\" (TBR = to be reviewed).  Team leads would review \ncode by pulling from \"<developer>-tbr\" and if it looked okay would push \nto \"<team>-tbt\" (TBT = to be tested).  Of course, if they needed to \noriginate a change they could pull from \"stable\" instead of any individual \ndeveloper's branch.  QA would pull from \"<team>-tbt\", build, deploy, and \ntest and if it's good push to \"stable\".  Some automated process would \nwatch \"stable\" and update production from it.\n\nThis way bad commits are generally rejected before they become part of \nhistory.  Hooks can be used to notify team leads and QA about new commits \nfor review or testing.\n\n>[1] We've stressed with our developers as much as possible that the\n>\"origin\" repository is to remain\" pristine\", that every action should be\n>\"auditable\" insofar that if you rollback a change, we want to see a\n>Revert commit, merges should create merge commits to where we can replay\n>or unwind the revision history correctly at any point in time or slice\n>of time. I *really* don't want \"origin\" to \"lose commits\".\n\nTo this end, I'd probably forbid non-ff commits to \"stable\".\n-- \nBoyd Stephen Smith Jr.                     ,= ,-_-. =. \nbss03@volumehost.net                      ((_/)o o(\\_))\nICQ: 514984 YM/AIM: DaTwinkDaddy           `-'(. .)`-' \nhttp://iguanasuicide.org/                      \\_/     \n"},{"id":"97440","messageId":"20081209103950.46c0cc00.stephen@exigencecorp.com","threadId":"16651","inReplyTo":"1228817565.18611.54.camel@starfruit.local","subject":"Re: Forcing --no-ff on pull","fromName":"Stephen Haberman","fromEmail":"stephen@exigencecorp.com","sentAt":"2008-12-09T16:39:50Z","receivedAt":"2008-12-09T16:39:50Z","isPatch":false,"sender":{"key":"stephen@exigencecorp.com","avatar":"https://gravatar.com/avatar/23b93ad70a06ce53505f17ddba65176edbcfb6588e7a4c1a2dca04aaf0a6aff1?d=mp&s=160"},"body":"\n> > $ git config branch.stable.mergeoptions \"--no-ff\"\n> \n> I recall stumbling across this a while ago looking at the git-config(1)\n> man page, but this isn't /quite/ what we need.\n> \n> I'm talking about forcing for *every* pull, it's a safe assumption to\n> make that we want a merge commit every time somebody fast-forwards a\n> branch. \n> \n> The only way I could think to make use of branch.<name>.mergeoptions\n> would be to automagically set it up in a \"pre-merge\" hook, but alas\n> post-merge exists but not pre-merge.\n\nI had done something like this with a post-checkout hook. After checking\nout any branch, the hook sets various branch.<name>.options.\n\nAlso, I wrote a hook to enforce \"only no-ff commits can move stable\" and\nother fun stuff. It's out on github, in a semi-documented/unannounced\nproject with the email/trac/etc. hooks we put in place:\n\nhttp://github.com/stephenh/gc/tree/master/server/update-stable\n\n- Stephen\n"},{"id":"97456","messageId":"alpine.LNX.1.00.0812091651360.19665@iabervon.org","threadId":"16651","inReplyTo":"1228819087.18611.73.camel@starfruit.local","subject":"Re: Forcing --no-ff on pull","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2008-12-09T22:32:36Z","receivedAt":"2008-12-09T22:32:36Z","isPatch":false,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Tue, 9 Dec 2008, R. Tyler Ballance wrote:\n\n> On Tue, 2008-12-09 at 19:17 +0900, Nanako Shiraishi wrote:\n> > Quoting \"R. Tyler Ballance\" <tyler@slide.com>:\n> > \n> > > The most common use-case involves a user merging a project branch into a\n> > > stabilization branch (`git checkout stable && git pull . project`) in\n> > > such a way that no merge commit is generated. Of course, without\n> > > thinking they'll push these changes up to the centralized repository.\n> > > Not 15 minutes later they realize \"ruh roh! I didn't want to do that\"\n> > \n> > Why does the user not want to fast-forward, if the merge she wants to do is actually a fast-forward?\n> \n> I agree with you, this is more about preventing coworkers who are too\n> lazy to understand the entirety of what they're doing from hurting the\n> workflow of \"the rest of us\". It's a technically solution to a people\n> problem (I understand technology far more than people ;))\n> \n> Consider the following scenarion:\n>   % git checkout -b project﻿\n> ﻿  % <work>\n> ﻿  % git commit -am \"A\"﻿\n> ﻿  % <work>\n> ﻿  % git commit -am \"B\"﻿\n> ﻿  % <work>\n> ﻿  % git commit -am \"C\"﻿\n> ﻿  % <work>\n> ﻿  % git commit -am \"D\"\n> ﻿﻿  % git checkout stable\n> ﻿﻿  % git pull . project\n> ﻿﻿  % <fast-forward>\n> ﻿﻿  % git push origin stable\n> ﻿﻿\n> At this point, QA is involved and what can happen is that QA realizes\n> that this code is *not* stable and *never* should have been brought into\n> the stable branch.\n\nHow do you prevent the (IMHO more likely) case of:\n\n% git checkout -b project\n% git checkout stable\n<fix some bug in stable>\n% git commit -a\n<forget to switch branches back>\n<work>\n% git commit -am \"A\"\n<work>\n% git commit -am \"B\"\n...\n% git push origin stable\n\nThat is, the developer makes a whole bunch of inappropriate commits on \ntheir stable branch instead of their project branch and then pushes it out \n(perhaps as part of a push rule, or thinking only the bug fix went there). \nI suspect that \"pull\" step there isn't the point where things are going \nwrong.\n\nIf you've actually got QA in the process, have developers push to a \nper-developer location and send a pull request to QA. QA can reject bad \nchanges instead of putting them into the stable branch at all, and then \nthey can reply to the pull requests with snide comments instead of having \nto beat up the developers, because the developer doesn't inconvenience \nanybody (except QA, whose job is to be inconvenienced by developers).\n\n> I'm less concerned at this point, the company switched entirely to Git\n> two weeks ago, with the history containing possible unwanted merges. I'm\n> more concerned however with LazyDeveloper inadvertently polluting stable\n> branches as LazyDeveloper does not yet fully grasp the concepts that Git\n> offers\n\nI think such developers are more likely to push some bad commits to \n\"stable\" directly than they are to make their bad commits on a branch, \nmerge it (fast-forward or otherwise) and push the result. It's also easy \nto discover:\n\n% git push origin project:stable\n\nAnd not generate a merge commit simply by virtue of not merging branches.\n\n\t-Daniel\n*This .sig left intentionally blank*"},{"id":"97500","messageId":"20081210130738.0662082f.stephen@exigencecorp.com","threadId":"16651","inReplyTo":"alpine.LNX.1.00.0812091651360.19665@iabervon.org","subject":"Re: Forcing --no-ff on pull","fromName":"Stephen Haberman","fromEmail":"stephen@exigencecorp.com","sentAt":"2008-12-10T19:07:38Z","receivedAt":"2008-12-10T19:07:38Z","isPatch":false,"sender":{"key":"stephen@exigencecorp.com","avatar":"https://gravatar.com/avatar/23b93ad70a06ce53505f17ddba65176edbcfb6588e7a4c1a2dca04aaf0a6aff1?d=mp&s=160"},"body":"On Tue, 9 Dec 2008 17:32:36 -0500 (EST)\nDaniel Barkalow <barkalow@iabervon.org> wrote:\n\n> > At this point, QA is involved and what can happen is that QA realizes\n> > that this code is *not* stable and *never* should have been brought into\n> > the stable branch.\n>\n> How do you prevent the (IMHO more likely) case of:\n> \n> % git checkout -b project\n> % git checkout stable\n> <fix some bug in stable>\n> % git commit -a\n> <forget to switch branches back>\n> <work>\n> % git commit -am \"A\"\n> <work>\n> % git commit -am \"B\"\n> ...\n> % git push origin stable\n> \n> That is, the developer makes a whole bunch of inappropriate commits on \n> their stable branch instead of their project branch and then pushes it out \n> (perhaps as part of a push rule, or thinking only the bug fix went there). \n> I suspect that \"pull\" step there isn't the point where things are going \n> wrong.\n\nWell, two things:\n\n1) The hook script at [1] really would prevent this from getting published.\n   Although it only looks for \"stable\"--if you have per-team stable branches,\n   you might need to match on \"*-stable\" or something like that. But it does\n   (copy/paste from [1]):\n\n# * stable must move by only 1 commit-per-push\n# * the stable commit must have 2 and only 2 parents\n#   * The first parent must be the previous stable commit\n#   * The second parent is the tip of the candidate branch being released\n# * the stable commit must have the same contents as the candidate tip\n#   * Any merge conflicts should have been resolved in the candidate tip\n#     by pulling stable into the candidate and having qa/tests done--pulling\n#     candidate into stable should then apply cleanly\n\nSo, no fast forwards, no direct commits, only \"good\"/empty merges of\ntopic branches can move stable. Anything else is rejected and LazyDev\nhas to try again.\n\n2) As far as \"pull\" isn't where things are going wrong, that is not\n   entirely true, as even with the server-side enforcement like [1],\n   I think you'd still like to help LazyDev out and have `git pull`\n   \"just work\" for your given setup. Especially if you don't have full\n   management buy-in to git, pacifying LazyDev's can be necessary.\n\n- Stephen\n\n1: http://github.com/stephenh/gc/tree/master/server/update-stable\n"}]}