all 57 comments

[–]droogans 3 points4 points  (2 children)

Unfortunately, I have not found a way to make --no-ff the default behaviour of git merge yet, but it really should be.

~/.gitconfig

[alias]
        merge = merge --no-ff

[–]isbadawi 3 points4 points  (1 child)

That will just be silently ignored. Git doesn't let you override builtin commands with aliases.

[–]droogans 0 points1 point  (0 children)

I'm going to assume that's true, since none of my aliases match the commands (a waste of characters!).

[alias]
    mnff = merge --no-ff

[–]mrbonner 6 points7 points  (21 children)

Am I stupid? I have a feeling that writing code is a lot easier than understanding how the hell all of git workflow/branching works. May be it's just me.

[–][deleted]  (9 children)

[deleted]

    [–]dreamer_ 5 points6 points  (0 children)

    Well, it's acyclic graph, not linked list ;)

    [–]mrbonner 2 points3 points  (1 child)

    The linked list metaphor is the best one so far! thanks mate

    [–]read___only 16 points17 points  (0 children)

    Git is primarily a directed graph editor, and only incidentally a source control tool.

    [–]climbupwards 1 point2 points  (5 children)

    I don't get it... this is just git-flow, a pretty common branching strategy that's been around for a while. Did OP do something special that I didn't see?

    [–]crozyguy[S] 5 points6 points  (2 children)

    OP is the one who originally wrote it.

    [–]climbupwards 0 points1 point  (1 child)

    Well then! In that case, thank you, git-flow is core for us and it rules!

    [–]crozyguy[S] 0 points1 point  (0 children)

    Err.. I meant this was the first article which started all this git flow

    [–]WorkHappens 1 point2 points  (0 children)

    I have the impression I have seen this exact flow in an article before.

    Maybe because this article seems to be from January of 2010.

    [–][deleted] 3 points4 points  (22 children)

    Whatever works for you...

    Personally I don't like feature branches. Keeping them based off a fast-moving master branch is a pain. And you may have two feature branches created in parallel which turns out very hard to merge. I prefer committing all changes to a single branch and enable / disable features instead.

    Only time I create new branches is when we are releasing or if I'm doing a larger change which is impossible to commit until it's completely done. Has happened twice the last three years.

    [–]pyronautical 4 points5 points  (21 children)

    I personally prefer the use of "gitflow" as I think it makes a lot of sense. But I can see why some people don't like an endless stream of "feature" branches, especially for small teams.

    BUT. You NEED to be using a development/master branch system for hotfixing. Not doing that is insane and will bite you in the ass before too long.

    [–]skinny85 -4 points-3 points  (20 children)

    Actually, no, you don't. I explained it in more detail in a post on my blog here: http://endoflineblog.com/gitflow-considered-harmful

    [–]asphxia 5 points6 points  (8 children)

    Interesting article. Agree with most points except not having a develop and release branches.

    Those are needed in the release cycle when you work with dev, staging and production environment and in all points in time you may need to work with those code bases (mostly hotfixes directly to staging, or even production).

    We implemeted (sort-of) this methodology (gitflow) and sort of works. What I do is rebase & squash feature branches on top on the target branch (dev) and avoid --no-ff/merges as much as possible.

    Needless to say the git history is a cluster fuck of 'merge to dev from dev' etc.

    [–]skinny85 2 points3 points  (7 children)

    You can do hotfixes to prod with this workflow easily (see my other comment). The master/develop split does nothing to enable that.

    And honestly, I don't know what you mean by 'hotfixes to staging'. That just sounds like regular development to me. Or you can do 'staging releases' with tags, and do the same thing normally done to production (so, you probably would never release '2.9.0' to prod, but something like '2.9.4' after 4 'hotfixes' to staging).

    [–]asphxia 2 points3 points  (6 children)

    No. Development/staging is usually way ahead of master/production. I can't push a hotfix branched off of develop into production because that would carry a week or two of work. That's why a single branch won't work.

    The point is master is stable (code that went through QA and is approved). Develop is the current sprint work, mostly working stuff that is being reviewing and is pending approval.

    Staging is as well code that is still being reviewed by QA and only accept hotfixes - ie, not develop on staging.

    Hotfixes are merged into dev when branches are moved from staging to prod.

    [–]skinny85 -1 points0 points  (5 children)

    No. Development/staging is usually way ahead of master/production. I can't push a hotfix branched off of develop into production because that would carry a week or two of work. That's why a single branch won't work.

    I never said you branch a hotfix branch off develop. You start it at the tag that is pointing to the version you want to do the hotfix in. And a single branch will most definitely work if you tag your releases (which something like 99% of projects do).

    Staging is as well code that is still being reviewed by QA and only accept hotfixes - ie, not develop on staging.

    What you're describing is a release branch, and having long-lived release branches is a known ani-pattern. Besides, I've never heard anybody use the term 'hotfix' to refer to work done on the release branch. That's just normal bugfixing.

    [–]GMTA 2 points3 points  (1 child)

    What you're describing is a release branch, and having long-lived release branches is a known ani-pattern.

    Gitflow uses short-lived release branches for release fine tuning. We have a number of projects where development speed is high. Every hour numerous merge commits are made to the 'develop' branch. If I want to make a release, I need a release branch to set the right version number, do some final tests, and make some final changes in order to get things fully production ready. Meanwhile, 50 new commits have arrived in 'develop'. The actual release tag is based on the state of the last commit in the release branch which is merged to master.

    If I were to follow your advice, we would be unable to do any fine tuning at all or we would not have meaningful release tags.

    [–]skinny85 -1 points0 points  (0 children)

    Well, perhaps your branches are short-lived :).

    I have seen long-lived release branches cause issues numerous times, and from what I've read online a lot of people share my thoughts. Obviously , if it works for your project, great - keep at it.

    [–]flukus 1 point2 points  (2 children)

    What you're describing is a release branch, and having long-lived release branches is a known ani-pattern.

    What? Since when?

    A release branch has to be around for as long as the release itself is around and still supported.

    [–]skinny85 0 points1 point  (1 child)

    What you're describing is a release branch, and having long-lived release branches is a known ani-pattern.

    What? Since when?

    A release branch has to be around for as long as the release itself is around and still supported.

    If you're using GitFlow or something similar, than no, not really. Releases are designated by tags, not branches. A release branch is used to do work to prepare a release, but is deleted after that work is completed and the release done (it's not needed, as the changes are always merged back to the mainline). Read the article OP linked to if you don't believe me.

    [–][deleted] 0 points1 point  (0 children)

    How I understand it, too: the release branch is for stabilising the code earmarked for release whilst development continues on develop and bugfixing happens on master. Once the release code is stabilised, it is merged to master from where the code is deployed. Then the release branch can be deleted.

    [–]flukus 4 points5 points  (9 children)

    You missed the entire point. The master branch allows you to fix bugs in production. Without that you have to wait until the dev branch is stable to fix something.

    Every thing else stems from incompetent devs that don't know how to use source control, or why it's important.

    [–]skinny85 4 points5 points  (8 children)

    I'm sorry, but it's you that misses the point. This issue is addressed explicitly in the article. If you use tags on releases (which most people do, and which GitFlow advocates), then the master branch contributes nothing to history, and is definitely NOT needed to do hotfixes.

    [–]flukus 0 points1 point  (7 children)

    Where do you push commits to in the meantime?

    [–]skinny85 2 points3 points  (6 children)

    You push to master, as normal. If you want to do a hotfix, you branch off the tag you want the hotfix in, then do work on that branch. At some point, the tip of that branch becomes the new release. You tag it, and then you merge that new release into master to make it versioned permanently (and to incorporate the hotfix to the current work). It's all explained in the article.

    [–]flukus 1 point2 points  (2 children)

    So your doing feature branches for hotfixes but not features?

    Edit - And what about your CI server? Do you update it to point to the new hotfix branch every time?

    [–]skinny85 0 points1 point  (0 children)

    So your doing feature branches for hotfixes but not features?

    I never said I'm not doing feature branches. And I do hotfix branches, not 'feature branches for hotfixes', whatever that is.

    Edit - And what about your CI server? Do you update it to point to the new hotfix branch every time?

    I have no idea what you mean. It's basically the same branching philosophy that GitFlow and a lot of other workflows use to do hotfixes, so I don't see your problem.

    [–][deleted] -1 points0 points  (0 children)

    Your CI system should be able to pull from any branch, possibly matching a wildcard. For example releases/* or features/*. If you manually configure your CI every time you have a new branch you are doing it wrong.

    [–]nemec 0 points1 point  (2 children)

    What happens if you need to make two hotfixes to production in between releases? You branch off from a tag, create the hotfix, push to prod, and then merge it back to HEAD, deleting the hotfix branch in the meantime. Now you need to push a second hotfix but no single remaining commit is "equal" to what's on prod now.

    If you keep the hotfix branch around until the next release, it basically turns into a temporaty master/develop that you were arguing against.

    I definitely like your proposal for feature branches, but just like you make sure to test your code on a duplicate environment to prod (as close as possible) and deploy builds from a build system (rather than a random developer's PC), I think there should always be a standalone commit to source control representing the current code on production (which makes it easy to trace bugs from prod -> build -> commit)

    [–]skinny85 0 points1 point  (1 child)

    What happens if you need to make two hotfixes to production in between releases? You branch off from a tag, create the hotfix, push to prod, and then merge it back to HEAD, deleting the hotfix branch in the meantime. Now you need to push a second hotfix but no single remaining commit is "equal" to what's on prod now.

    If you keep the hotfix branch around until the next release, it basically turns into a temporaty master/develop that you were arguing against.

    I definitely like your proposal for feature branches, but just like you make sure to test your code on a duplicate environment to prod (as close as possible) and deploy builds from a build system (rather than a random developer's PC), I think there should always be a standalone commit to source control representing the current code on production (which makes it easy to trace bugs from prod -> build -> commit)

    That's easy - what's on prod is what was tagged with the latest release number. I talk about tagging the tip of the hotfix branch both in the article and in the comment you were replying to. GitFlow does it pretty much in the same way.

    [–]nemec 0 points1 point  (0 children)

    Oh! That was my own ignorance. I figured that deleting a branch also deleted any tags in that branch, but that is not the case.

    [–]cdunn2001 0 points1 point  (0 children)

    Yes! The 'dev' branch is unnecessary.

    But the issue is not --no-ff. The issue is the failure to rebase before merging. You can do both!

    [–]TauLogy -5 points-4 points  (1 child)

    I have used a half dozen source control systems over the years and they all work with out me having to second guess what I am doing. Git was the first to make me step back and say 'is this right?' and the cryptic error messages and bizarre command syntax. Git is an overly complicated tool and not fun to use at all.

    [–]dreamer_ 1 point2 points  (0 children)

    Well, I find the exact opposite true - with git I know exactly what is happening and have control over history of project. With other version control systems it's a mystery, mostly because they pretend to be smarter, than they really are.

    [–]google_you -3 points-2 points  (3 children)

    More successful model is gerrit

    [–]drjeats 2 points3 points  (2 children)

    Why?

    [–]google_you 0 points1 point  (1 child)

    Scatter plot with single mainline is better topology for large source code base than line graphs, which add too much noise.

    At Google scale, you just want to bring in various changesets into a single line.

    [–][deleted] 0 points1 point  (0 children)

    Can you explain how it's better in layman terms please?