127

Our documentation team of about ten people recently moved from SVN to Git. In SVN, everybody worked on master -- a model I've always hated, but I wasn't able to bring about that change. As part of the move to Git we've agreed to fix that, but we can't do it just yet (waiting on build changes that will allow builds from arbitrary branches). Meanwhile, everybody is working on master. Yes I know this is terrible, believe me.

We're seeing a lot more hiccups now than when we were using SVN, some of which are caused by Git's two-stage model (local and remote). Sometimes people commit but fail to push, or they pull and get conflicts with their pending local changes. Yesterday somebody clobbered recent changes -- somehow -- with a merge gone wrong, which I think was the merge that Git does when you pull and have outstanding changes. (He has not been able to tell me exactly what he did, and because he's using a GUI I can't just inspect his shell history.)

As the most-proficient Git user (read: I've used it before, though not for anything super-complicated), I'm the person setting policy, teaching the tools, and cleaning up messes. What changes can I make to how we are using the tools to make a shared, active master less error-prone until we can switch to doing development on branches?

The team is using Tortoise Git on Windows. We're using Tortoise Git because we used Tortoise SVN before. (I personally use the command line under Cygwin for some operations, but the team has made it clear they need a GUI and we're going with this one.) Answers should work with this tool, not propose replacements.

Tortoise Git has "Commit & Push" available as a single operation and I've told them to always do that. However, it's not atomic -- it can happen that the commit (which after all is local) works just fine but the push doesn't (say, due to a conflict, or a network issue). When that happens they get an ambiguous error; I've told them to check the BitBucket commit log if they have any doubts about a recent commit and, if they don't see it, to push. (And to resolve the conflict if that's the problem, or ask for help if they don't know what to do.)

The team already has the good habit of "pull early and often". However, it appears that pull can cause conflicts, which I think is new? If not new, much more frequent than in SVN. I've heard that I can change how Git does pulls (rebase instead of merge), but I don't have a good understanding of the trade-offs there (or how to do it in our environment).

The server is BitBucket (not Github). I have full administrative control over our repository but none on the server more generally. None of that is changeable.

The source files are XML. There are also graphics files, which everybody knows you can't merge, but we also almost never have collisions there. The merge conflicts come from the XML files, not the graphics.

What changes can I make to our use of Git to make sharing master go more smoothly for the team until we can move to using feature branches with reviewed, test-validated pull requests?

Monica Cellio
  • 1,327
  • 2
  • 11
  • 17
  • 1
    A practical solution for until you re ready to make the move to branches would be : if people work on separate files to stash/commit their work locally, pull to make sure they are up to date then push their commit. This will obviously wont work if people work simultaneously on the same files. – Leon Sep 06 '17 at 07:11
  • 52
    Don't use tortoise, use Git Extensions. Tortoise tries to hide that Git isn't SVN and destroys most of the git greatness. I went through the SVN->Git transistion twice, and Git Extension was a great tool to get people to think the git way. – Wilbert Sep 06 '17 at 08:45
  • 1
    `git pull` is `git fetch` followed by `git merge`, and the latter part can cause merge conflicts. – el.pescado - нет войне Sep 06 '17 at 09:24
  • 3
    Is it an option to use a separate branch locally, and merge to master just before pushing to remote? It might make it slightly easier to deal with conflicts that way. – Buhb Sep 06 '17 at 10:42
  • 92
    Git is not SVN. If you try to replicate SVN with Git, you just get all the pain points of SVN with all the pain points of Git combined, with none of the benefits of either, it's just never going to work. The biggest problem you have is a social problem, you've got team members that are refusing to learn new concepts. You can't solve that with technical solution, you need to start by getting buy ins from your team members to learn Git concepts rather than trying to convince them that it's just like SVN. – Lie Ryan Sep 06 '17 at 11:55
  • 10
    I know you said not to recommend other apps, but @Wilbert has it right. TortoiseGit tries to hide things, which actually makes them more painful in my experience. If a UI is desired, I have found the easiest transition (read: I train non-traditional software teams on tooling and DevOps) has been via Atlassian's SourceTree (with proper training, of course). I have also used GitFlow to help them understand the model of Git (though, this does not fit all teams). – JasCav Sep 06 '17 at 12:38
  • 3
    What was the reason for moving to Git, if the developers were already comfortable working with SVN? Wouldn't it have been easier just to get people to start using branches more *within SVN*? I realize the workflow is much better in Git, and I'm a fan of it myself, but minimizing the amount of disruptive changes in production seems like a desirable goal. – Cody Gray - on strike Sep 06 '17 at 13:56
  • @CodyGray the dev team moved from SVN to Git about a year ago, and SVN's days are numbered in the company. We moved the doc group now, while we could control the scheduling and allow time for people to learn, instead of being faced with a "move *now*" problem in the next few months. Also, once we've got the group moved over to using branches (same as dev does), it'll be easier for people to learn from each other, benefit from the wiki pages dev has already created for tips and tricks, etc. – Monica Cellio Sep 06 '17 at 14:27
  • 3
    IMHO sooner or later everybody using Git needs to learn how to use the CLI. Better to go through that pain now, than have to learn it down the line when you encounter a situation the GUI you are using isn't equipped to handle. – JMK Sep 06 '17 at 14:28
  • 2
    My gut feeling is that its bizarre that developers are developing off of master directly. [GitFlow](https://danielkummer.github.io/git-flow-cheatsheet/) usually has almost all work occurring on branches. I almost never use the CLI, I use tortoiseGit/SourceTree/other clients. Most of the clients these days can do most of the functions that might require the use of the CLI. – Mark Rogers Sep 06 '17 at 15:33
  • 28
    I'm kind of surprised everyone is poo-pooing working on the master, which is the central tenet of [Continuous Integration](https://martinfowler.com/articles/continuousIntegration.html). As long as you have a robust test suite and everyone is aware when the build is broken, working from the master can be advantageous to team collaboration. [Feature branching](https://martinfowler.com/bliki/FeatureBranch.html) (which pretty much all other workflows rely on to some degree) can be equally destructive without protections in place. You probably have some deeper root issues at play here. –  Sep 06 '17 at 15:46
  • @MarkRogers the dev team, which is a separate group, uses branches and controlled PRs. This question is about the *doc* team in the same organization, which historically used SVN with everybody working on master. That team has now moved to git and will use branches (like dev) but can't yet, hence the current problem. – Monica Cellio Sep 06 '17 at 15:56
  • 3
    @MonicaCellio just change everyone's settings so that pull will also rebase by default. (You can do this for the whole repo by adding a .gitconfig file to it) That will take care of 90% of your conflicts. The other 10%... well, they're going to have to learn how to resolve a conflict. I'm honestly shocked conflicts weren't an issue with SVN too. Surely they've had to resolve conflicts before. – RubberDuck Sep 06 '17 at 16:03
  • @RubberDuck they had to resolve conflicts in SVN too, but way less frequently and with clearer workflow. (Of course they knew the tool better.) I think merge as part of *pull* is causing some of the confusion. And we've had one big failure that I spent hours investigating and cleaning up, and we still don't know how the person did it. So that all made me suspect we're not doing this in the best way possible, hence this question. – Monica Cellio Sep 06 '17 at 16:24
  • 14
    @DanK, I also think the op misidentified the root of the problem. If you have people clobbering changes on master and you switch to a branch, you will have people clobbering changes on the branch. If you move to individual branches, you will have people who have problems merging in their branches (or who develop on their branch without merging for months on end). – user3067860 Sep 06 '17 at 19:13
  • BTW. What file types doc team works with? Are those HTML files? Word documents? How well merge tools handle those files? – el.pescado - нет войне Sep 07 '17 at 08:04
  • @el.pescado the source files are XML. There are also graphics, but nobody expects to be able to merge those -- if two people changed the same PNG file (super-rare for us) they'll just have to talk to each other. – Monica Cellio Sep 07 '17 at 13:01
  • @user3067860 my expectation is that feature branches will live for a few weeks, not for months. – Monica Cellio Sep 07 '17 at 13:03
  • 1
    I don't find tortoise causes these problems, but maybe that's because while I had used tortoise cvs before, I never used tortoise svn, and it was pretty obvious moving from cvs to git that they were not the same and I shouldn't expect them to be. – Jon Hanna Sep 07 '17 at 13:29
  • 1
    I've worked with SVN before and I think the problems are only due to inexperience with Git and not with your workflow(committing to master). For example, svn update and git pull are almost identical, except uncommitted changes in git are always merge conflicts, so you would want to git commit/stash + git pull. I think the best course of action would be to maintain your current workflow and just ask for patience from your colleagues while you work out the individual kinks. That, and perhaps a git cheatsheet :) – Sacho Sep 07 '17 at 13:50
  • Did you consider setting up permissions e.g. via [gitolite](http://gitolite.com/gitolite/index.html)? – Tobias Kienzler Sep 07 '17 at 14:10
  • 2
    I would also suggest "git pull --ff-only", which avoids generating spurious commits on pull. – pjc50 Sep 07 '17 at 15:52
  • 2
    @Wilbert kind of a side question but what sorts of things does TortoiseGit hide? For day to day use it seemed to do alright, it's mildly convenient. I tend to fall back to command line for certain merge operations though. [Do you have anything in addition to the points raised here?](https://stackoverflow.com/q/5645732/4975230) If so want to talk in chat? I'd like to know if I missed something, I don't know every command line option for git yet. – jrh Sep 07 '17 at 20:28
  • 1
    @MonicaCellio I dont have enough Rep to answer, so a comment will have to do. My development team is in almost the exact same situation as OP, however, we migrated from SVN to Gogs (git go service ... which is a privately host-able github clone). Regardless of the tool, the short term solution is simple ... teach your users about FORK ( https://confluence.atlassian.com/bitbucket/forking-a-repository-221449527.html ) ... this way they have there own master till it is time for a pull request (merge) which you pair with a code review. – CaffeineAddiction Sep 07 '17 at 20:50
  • 1
    `because he's using a GUI` - Theory based on what some of my team-members have done with svn: Open file, make some changes, svn up/git pull (modifies the same file they're been touching), make some more changes, save. Their editors don't notify them that the file has been touched since it was opened, and happily replaces the updated file with what it was before the update. – Izkata Sep 08 '17 at 04:25
  • Regardless the branching model you choose, you'll end up resolving conflicts upon committing/pushing. Working on master offers you chances to do that earlier than working on branches because team members are supposed to resolve conflicts whenever they commit/push to master (or a milestone specific branch) while in the feature/developer specific branches model, they only do that after pull-request which happens after they've all done their tasks. So the question for you is, how much does it cost to troubleshoot an issue occurs near deadline/release? Should it be addressed earlier? – Bob Dust Sep 08 '17 at 05:58
  • "He has not been able to tell me exactly what he did,..." I think I can guess. He solved a conflict without really solving it but just by using stuff from one side. Happened to me too by accident. – NoDataDumpNoContribution Sep 08 '17 at 07:36
  • 2
    @jrh Git Extensions is a Git Gui . Because it shows the staging process incl. explicit commiting of some files and not others, explicit rebase and pushing and the branches etc all visually, it in my experience helps people understand the important concepts like 'lightweight branches' and that you can commit all the time without ruining other people's day. It's hard to pin point a single thing, but I've made the transition twice with different teams and just having tortoise in the windows shell the same as tortoise svn keeps people using the same patterns (which are now bad). – Wilbert Sep 08 '17 at 10:12
  • 2
    @jrh ... while moving to Git Extensions helps them learn the good new ways of dealing with versioning and the git concepts. I've managed to get a team of git newbies to go from 'I don't like this' to them squash-rebasing, cleaning up all their pull requests, grouping changes and making nice commits within half a year, and I attribute this mainly to Git Extensions and also GitHub Enterprise. – Wilbert Sep 08 '17 at 10:14
  • What file formats are you using for your documentation? If you're using binary file formats like MS Word docs, your pain will be exponentially bigger than if you use a plain text format. – jpmc26 Sep 08 '17 at 18:19
  • 4
    `git pain` sounds like a great command to have. It'd save so much time. – user2357112 Sep 08 '17 at 18:35
  • 1
    @jpmc26 merge + binary-format files would be a terrible mess (calling into question the utility of advanced source-control to begin with). The source is XML. I'll update the question since this has come up a couple times in comments. – Monica Cellio Sep 08 '17 at 19:09
  • @Wilbert: TortoiseGit is awesome though. It's just not meant for learning, meaning the caveat is you just have to know how to use git on the command line before you start using the GUI. I don't think the problem is the software itself compared to Git Extensions; I just think it's that people are using it before they're comfortable with git itself. – user541686 Sep 08 '17 at 23:01
  • Consider using github to its fullest. Everyone has an account. The global master lives in your organization account and everybody forks it to his/her own account and works _there_ on master in their own repository. Then they create pull requests to have it merged up into the organizational master which you can either let them do themselves or have a gatekeeper to ensure that nobody messes things up. If your sources are private, consider paying github. With your current problems this might be the cheapest solution. – Thorbjørn Ravn Andersen Sep 10 '17 at 20:40
  • @ThorbjørnRavnAndersen our organization uses Bitbucket. We don't have the authority to change that (even just for us). – Monica Cellio Sep 10 '17 at 20:46
  • @MonicaCellio It may be possible to do the same with Bitbucket. I do not know it so well, but the idea of getting people to work in separate repositories instead of separate branches may be feasible. – Thorbjørn Ravn Andersen Sep 10 '17 at 21:07
  • `He has not been able to tell me exactly what he did`. This happened on my team. A developer committed changes and pulled. Got a conflict, resolved the conflict, and then committed only the conflicted files. And then pushed everything to master. So the other changes that came in the pull request got lost. Source tree has an option to `commit merged changes immediately` while doing a pull. But I had to instruct the whole team that after resolving a conflict after a pull request, EVERYTHING has to be committed and pushed. – One-One Sep 11 '17 at 03:50
  • @Mehrdad Well, lets agree to disagree. Personally, I still strongly feel that the 'natural' way to interact with a git repository is captured much better with Git Extensions that TortoiseGit, and that it's therefore more conductive for learning git. But as always, YMMV. – Wilbert Sep 11 '17 at 09:56
  • @Wilbert: Wait but if that's what you think then I think we agree? :) You just confirmed TortoiseGit isn't for learning which is what I said too haha. I was saying it's awesome once you've already learned to use git properly =P – user541686 Sep 11 '17 at 10:04
  • @Mehrdad Well I guess we disagree on the awesomness of TortoiseGit. That it's _also_ better for learning (as opposed to just using it) is just a side effect of Git Extensions natural (for me) approach to git. :) – Wilbert Sep 11 '17 at 10:42
  • @MonicaCellio, your teammate isn't the first I've heard of inadvertently wiping out changes while attempting to merge with TortoiseGit. Your colleagues would be best off using the command line. If they refuse (unfortunately some developers have a fear of command lines), they'd still be better off with just about anything instead of TortoiseGit. – Kyralessa Sep 15 '17 at 15:06
  • If all you're working on is documentation then I strongly recommend looking at Mercurial. I like to call it "Git for Human Beings". For your purposes, there is not much difference but the workflows are slightly more intuitive and it will protect you against some mistakes. Even if moving to Git is your strategic direction, you can still use Mercurial as a step in that direction. (And you can configure TortoiseHg to work with a Git repository.) – Hosam Aly Jan 01 '18 at 19:01
  • @MonicaCellio Now years later - how did this end? – Thorbjørn Ravn Andersen Nov 16 '20 at 18:21

11 Answers11

98

There are three main things to remember when you are working out of the same branch as someone else:

  • Never use --force unless you really know what you are doing.
  • Either commit or stash your work in progress before every pull.
  • It usually goes easier if you pull right before a push.

Aside from that, I will point out that with distributed version control it doesn't matter if your "official" repo uses branches or not. That has no bearing whatsoever on what individual users do in their local repos. I used to use git to get local branches when my company used a completely different central VCS. If they create local branches for their features and make merging mistakes to their local master, it's a lot easier to fix without going into the reflog or some other magic.

Karl Bielefeldt
  • 146,727
  • 38
  • 279
  • 479
  • OP said that they're using Tortoise git. How does this map to it? – Worse_Username Sep 06 '17 at 08:51
  • 51
    Always `pull` before `push` is great advice, but I'd go one step further and suggest that you consider whether you can `pull --rebase` when you do. – anaximander Sep 06 '17 at 09:33
  • 20
    @anaximander, I would recommend that either everybody uses --rebase or nobody... – keuleJ Sep 06 '17 at 12:29
  • 4
    @keuleJ It's good to be consistent with that sort of thing, yes, but it can work fine doing it both ways. Sometimes you have small changes that can be happily rebased without losing anything noteworthy, and sometimes you have larger ongoing work where the merge is non-trivial and best kept in its own commit. For a team that's comfortable with git and a non-linear workflow, choosing whether to use `--rebase` on a case-by-case basis is probably fine. – anaximander Sep 06 '17 at 12:46
  • @anaximander that's one of the things I'm wondering about (and hoping answers will address). By default pull is fetch + merge; how would our situation change if we had everybody pull by rebasing? – Monica Cellio Sep 06 '17 at 15:59
  • 1
    @anaximander Introducing large amounts of additional complexity to improve (and even the git community at large does not have a single preference or guideline when to use rebase and when not) something rather superficial is almost certainly one the worst thing one can do when dealing with absolute beginners. They have a hard enough time with the basics - what they need are simple rules. You can think about some guidelines for rebase and fast-forward merges and all the other stuff when they've gotten used to the basics. – Voo Sep 06 '17 at 17:31
  • 2
    @anaximander There are those who would say [rebasing is a lie](http://paul.stadig.name/2010/12/thou-shalt-not-lie-git-rebase-ammend.html) and should be used sparingly. – TemporalWolf Sep 06 '17 at 18:36
  • 12
    @TemporalWolf That's what they told me about the cake too... – BlackVegetable Sep 06 '17 at 18:54
  • 4
    @TemporalWolf These people are probably rebasing incorrectly. If you rebase, and you get a conflict, and you resolve that conflict, and you end up with a commit that won't build, or fails tests, then you did not resolve the conflict, and you are Doing It Wrong. In this case, they cannot be trusted with rebase, and so I agree, they should probably use it sparingly. What I take from that article is not "don't rebase", it's "don't rebase lazily and break commits". – anaximander Sep 06 '17 at 19:09
  • 1
    @MonicaCellio In short, `pull --rebase` rearranges commits (undoes your whole branch, updates the branch it was branched from, and redoes your branch again) to avoid the merge commit that you'd get otherwise. It's a very useful and powerful tool, **if** you're comfortable with rebase and how to properly resolve the conflicts that come up while doing it. If you're very new to git, perhaps stick to pull with merge until you're a little more familiar with it. – anaximander Sep 06 '17 at 19:13
  • 16
    @anaximander "then you did not resolve the conflict, and you are Doing It Wrong. In this case, they cannot be trusted with rebase". So you're saying you never even once, messed up a merge conflict? Must be nice working on simple enough code bases that you can make that generalisation. [Here's](https://www.mail-archive.com/dri-devel@lists.sourceforge.net/msg39091.html) Linus' take on rebase, which I personally find quite more agreeable than any of those black and white approaches. – Voo Sep 06 '17 at 19:33
  • 2
    @anaximander people who won't learn how to do fairly basic git things should absolutely not be using rebase... – enderland Sep 07 '17 at 02:05
  • 2
    @Voo I'm not saying I've never messed up a conflict; I've certainly broken a few in my time - and when I did that, it was *my* fault, not rebase's fault. The article that was linked said that rebase is bad because it breaks commits; my argument is simply that rebase doesn't break commits, developers break commits. As such, I wouldn't say "don't use rebase", I'd say "learn to not break commits". If the code is complex enough that you can't reliably resolve conflicts without breaking things, don't rebase. That's why I originally said "consider whether you can rebase", and not "always rebase". – anaximander Sep 07 '17 at 07:48
  • 1
    FWIW, `--force-with-lease` is generally a saner choice than `--force`. It prevents overriding changes you've never "seen" locally. – Cedric Reichenbach Sep 07 '17 at 08:38
  • 2
    @anaximander The point about `git rebase` lying is, that `git` can only signal *textual* conflicts, not *semantical* ones. It's perfectly possible to have a good history, to `git rebase` that without any conflicts, and get a broken history non-the-less. Even to the point that the final rebased commit compiles and tests fine, but its rebased parents are broken to the point of not compiling. **You won't know unless you actually build and test every single commit created by `git bisect`.** – cmaster - reinstate monica Sep 07 '17 at 11:18
  • 1
    @anaximander I second your recommendation to use `pull` before every `push` since it reveals conflicts before they happen. Continuous integration is broken by dynamic languages like JavaScript and JSP so you need to resolve the source conflicts yourself. – Michael Shopsin Sep 07 '17 at 15:18
  • @Michael If you think CI is broken for dynamic languages, your test coverage has some improving to do. – Voo Sep 07 '17 at 16:03
  • @cmaster I get what you're saying, but wouldn't it be better to avoid that by some combination of pushing frequently and squashing small, related commits together, so you don't end up with long chains of rebased commits? – user3067860 Sep 07 '17 at 22:26
  • @anaximander I've been considering the opposite, actually. `git pull --rebase` is closer to what `svn up` does than `git pull`, so I've been wondering if it would be easier to understand for people moving from svn to git. Rebasing in general certainly not, just this one case I've been thinking about. – Izkata Sep 08 '17 at 04:29
  • 11
    "Never use `--force` unless you really know what you are doing." I'd go further. *Disallow* rewriting history in the "main" repository from everyone except the most trusted individuals. Whether you can do that at least partly depends on your hosting, but BitBucket does have the option. – jpmc26 Sep 08 '17 at 04:50
  • @user3067860 You won't see me applauding to lying with `git`, I just don't believe that any good comes from a lie. Of course, there are ways to reduce the impact of lying, but the truth remains that lies are just wrong. Thus, the only advice I would ever give to would-be liers is: Make sure that you at least run the full test suite on all rewritten commits. If that's asking too much, just don't lie. – cmaster - reinstate monica Sep 08 '17 at 08:27
  • I *heard* that rebase is very, very evil because it effectively changes the context of a change and makes it harder to understand the change history later, but I never actually took time to really understand that. – sharptooth Sep 08 '17 at 10:17
  • 2
    @cmaster "I just don't believe that any good comes from a lie". You should give rational for such statements. Why not rebase if the only thing you're doing is change your own private history? You certainly don't want to change other people's history, but cleaning up your own history does very limited damage. Also you shouldn't just pull random crap at random times - that can work in small environments, but if you're working on larger projects you have to realise that a pull is a synchronization point: "Merge v1.15 into dev" is good, "Merge 'main'" very much isn't. – Voo Sep 08 '17 at 11:47
  • There's basically no semantic reason for the merge and chances are that if you pull at random points you'll get an untested mess with some changes included while others that are also necessary still missing. Now if you're working in a highly structured environment (day job in a small team) you can deal with that, but even there it rarely makes sense. – Voo Sep 08 '17 at 11:49
  • @Voo As anyone else who emphasizes truthfulness with `git`, my reason is that I want tools like `git bisect` to just work correctly, and to point me at a reasonably small commit that I can easily understand. If I squash commits, I do get large commits that are much harder to understand, and which cannot be bisected by `git` anymore. If I rebase commits (and skip on the obligatory retesting of every single commit), I may create sequences of commits that won't even compile, that are again impossible to bisect. Good luck when you have to locate a regression within such a mess. – cmaster - reinstate monica Sep 08 '17 at 12:42
  • @jpmc26, so does GitLab, including GitLab CE (community edition). (Free and open source.) IMO, BitBucket is a pain, though I don't think it's quite as bad as JIRA. (GitLab's issue tracking is immeasurably more pleasant than JIRA.) – Wildcard Sep 09 '17 at 04:31
67

Is it possible to take a day for everyone to learn git?

Computer using professionals should really be expected to learn a new tool and although possible to make many mistakes in any VCS they should be using the tool as it is designed to be used.

The best way to introduce this is to get every one to work on their own branch when they make a change (as short as possible) and rebase then merge back into master when they are done. This isn't too far off the current way of working and introduces a simple workflow that they can get used to until they feel confident enough to do more complicated operations.

I don't use windows but if Tortoise is basically hiding git from them and pretending that it is SVN then maybe Tortoise is the wrong tool.

MarkJL
  • 751
  • 4
  • 6
  • 38
    "if Tortoise is basically hiding git from them and pretending that it is SVN then maybe Tortoise is the wrong tool." this. I know OP said not to replace the tool but if it is obscuring how git works in any way then it is a detriment to your developers' personal growth and to your operational efficiency. Your team will continue to misuse your VCS if they don't understand it. – 2rs2ts Sep 06 '17 at 16:30
  • To learn Git, I highly recommend http://gitimmersion.com/. When I was a lowly intern, this website taught me how to use Git passably within less than a day, and i became rather competent with it, including understanding branches thoroughly, within a couple of weeks of practice and occasionally rereading parts of Git Immersion. – Kevin Sep 06 '17 at 17:02
  • 3
    Another helpful git learning resource is [Learn Git Branching](http://learngitbranching.js.org/). It shows a visual tree and additionally has a sandbox so you can mock a bunch of commands and see what sort of tree results. – TemporalWolf Sep 06 '17 at 18:46
  • @2rs2ts is correct, especially about the potential for personal growth within the company. This should be a priority for companies employing high level computer users, the company will get much more out of them and their work. – MarkJL Sep 07 '17 at 07:08
  • 4
    It took a lot longer than a day for everyone on the dev team to learn git (and they're not dim or slackers), so I assumed that'd be true for the doc team too. I'll take a look at the sites mentioned here in comments (maybe they should be in this or another answer?). – Monica Cellio Sep 07 '17 at 13:05
  • 3
    You won't learn git until you've made all the mistakes and had the pain of conflicting merges and rebases, they just need to learn the short flow above of making a branch, rebasing that branch to include any of the changes from master and merging their branch back into master. Any other learning they can do as they try to resolve any of the pain they encounter in this flow (there will be some). At least the doc team does not have the concern of breaking the code base. – MarkJL Sep 07 '17 at 13:13
  • @MonicaCellio good idea. Do your research and see what you think will work best for your team. I am not saying everyone needs to use the CLI with cygwin like you do and I am not saying anything negative about Tortoise, I was just talking in general. You know your own team and your tools better than I do, so I trust you'll be able to make an informed decision with the links people have been so kind as to provide. – 2rs2ts Sep 07 '17 at 19:34
  • 1
    @2rs2ts Tortoise Git is an exceptional git gui. I install it on all my windows boxes and I am very familiar with the git command line. Its mergetool is one of the best I have ever used. I have introduced a lot of novice users to git using Tortoise Git. Its largest issue is that it exposes some of the advanced git options with just a simple check box. So an option like --force push could be done by just checking a box in the push gui. This is likely what the what was done that lost the work. I don't use Tortoise much but there are a few things it really makes simpler. – gnash117 Sep 13 '17 at 00:05
26

Sometimes, what you're doing has to change.

The biggest issue is that everyone is working on master. This is not typical for code development, and could be the wrong model in your case as well. If you can change that, by asking/requiring that changes be done on separate branches, you'll be in much better shape. With branches, you can gain the following:

  • Enforce that no pushes directly to master are allowed.
  • Enforce through Bitbucket that pull requests are created and have at least one approval prior to merging. This ensures someone is looking at the changes, and also makes the merge itself less painful, as the UI will show conflicts against the remote version of the code, not whatever the user has on the desktop. This prevents the commit-succeeded-but-push-failed scenario.
  • Execute "builds" against your repo prior to merging. I realize it's a doc repo, but maybe there's spell-checking, legalese scraping or even automated translation (export STRING_DEF things to a csv file) that could be built off this build. Or maybe not, depends on your work.
  • Allow folks to work on multiple different things concurrently more easily. Yes this can be done with stashes as well, but it's a bit messier and something tells me you're not using those either.

If you can't use branching, you might consider writing a merge-and-push script that could automate some of the pain points away. Maybe it would check that the user is not behind on master, do a fetch and pull, and then attempt the merge (possibly with --no-commit --no-ff), and so on.

Dan1701
  • 3,118
  • 1
  • 15
  • 24
  • 3
    We're going to move to branching, for all the reasons you mentioned (but most especially, controlled PRs and the ability to mandate that conflicts be resolved on the branch prior to merge). Could you say more about how to attack a merge-and-push script? – Monica Cellio Sep 06 '17 at 02:46
  • Also, if you can, execute the build on the *result* of merging, not on the thing being merged in. Then you know that if it passes, the merge won't break the software (or at least won't make the tests fail). – user253751 Sep 06 '17 at 04:48
  • 6
    I disagree with this advice. Long running feature branches can be much more devastating than working from the master (which if you don't have a good workflow in place is what is going to happen). Martin Fowler has a [great article](https://martinfowler.com/bliki/FeatureBranch.html) on this topic. At then end of the day, the OPs team has a workflow collaboration issue not a Git issue.. I would argue that more branches will simply compound this problem. –  Sep 06 '17 at 15:51
  • 6
    Long-running feature branches are not what I was advocating (nor mentioned). I agree they're bad for "regular" development, and would be no better here. Regular, "ravioli" branches with small sets of changes that can be reviewed/tested prior to merging are very useful, and would be no less useful here just because it's a documentation repo for all the reasons outlined in the answer. – Dan1701 Sep 06 '17 at 16:26
  • 3
    Sure, I understand what you are saying and I don't disagree *in theory* but with the collaboration issues currently being described here, even with the best of intentions, I think the OP team's branches will all inadvertently *turn into* long running branches. At the end of the day, working on a mainline vs. feature branch isn't the root problem here. The problem is a general lack of understanding of the ins/outs of a distributed VCS and a lack of collaboration/cohesion among the developers. Feature branching by itself won't fix that but IMO exacerbate it. –  Sep 06 '17 at 17:11
  • @Dan1701 I really don't see much difference between working on master or having short-lived feature branches. Yes there are some advantages, but the problem described here is about not understanding the basic tools (commit but no push) or troubles merging changes - neither of those two is fixed by using additional branches and if anything makes it more complicated. – Voo Sep 06 '17 at 17:37
  • 2
    We're getting close to needing to move this to chat, but, if you're always on a feature branch then you're not finishing your work. They have to be merged to the shipped branch (or published, in this case). This allows the introduction of automated checks and safeguards around the problems their team is experiencing. A feature branch is wholly different from working on master in that most tools (at least Bitbucket) are setup to allow pull requests with required approvals and pre-merge builds as part of the branching model, which is not something that happens when only working on `master`. – Dan1701 Sep 06 '17 at 18:10
  • 1
    @Dan Yeah getting a bit far off. My point is that gated check ins require changes to the build system which are in-work. Until they have those in place, there aren't real advantages to branches and they might as well focus on getting the basics figured out. – Voo Sep 06 '17 at 19:43
  • "no pushes directly to master are allowed" means code-freeze if the master branch is chosen for builds. Code reviews do not necessarily have to be done via branches (shelveset, stash,... can do it, too). "builds prior to merging" means integration test cannot be done on that build. Source control, in general, allows team members to work in parallel; it's just your choice on model/process of resolving conflict, milestoning; not only branches can do it. – Bob Dust Sep 08 '17 at 06:08
  • @BobDust I don't understand the point about code freeze. You can prevent direct pushes to `master` yet still allow merges from branches. CI & CD still work just fine in this model, you're just adding checks around when and how code gets into `master`. On the other points, sure, there are other ways to do things; I'm definitely not saying this is the only option. But it is effective, and I've also found that the automation acts as a guide for less experience contributors to help them learn the ropes. – Dan1701 Sep 08 '17 at 06:28
  • @Dan1701, I had an experience about "code freeze" working with feature branching model: after release for test, the team was supposed to fix bugs; available resources (developers who didn't have to fix bugs) implemented new features and those new feature branches could not be merged into master until all bugs were fixed & passed. Did that mean "code freeze"? And if you release on milestone specific branch (regardless you're working on feature branches or master branch model), that "freeze" will never happen. – Bob Dust Sep 08 '17 at 06:43
  • 1
    This, in my opinion, is the best advice here. `git` really shines when you use multiple branches. Everyone working on master is a recipe for disaster. This would be my suggested workflow whenever they're working on a new feature: 1) checkout master, and pull new changes. 2) branch from there. 3) make changes (teach them the benefit of multiple commits: one commit for each meaningful unit of work). 4) push new branch to repo. 5) create a pull request to merge in changes. 6) you (not them) merge in the PR. 7) build master. If your code is versioned, consider git-flow. – Dan Jones Sep 12 '17 at 19:29
12

Emphasize that you can redo merges

It may be obvious to you but former SVN users might not be aware they can try to solve a merge multiple times. This might cut down the number of help flags your receive.

In SVN when working off of trunk you'd have changes uncommitted sitting around. Then you'd do an svn update. At which point your changes would mix with other peoples changes forever. There was no way to undo it (afaik), so you had no choice but to just manually check everything and hope the repo was in a good state. When really you'd be much more comfortable just redoing the merge.

People would have the same mentality even when we moved to git. Leading to a lot of unintentional errors.

Luckily with git there is a way back, specifically because you can make local commits. (I describe later on how this is expressed in the commandline)

Though how this is done will vary based on tooling. I find redoing a pull isn't something exposed in many GUIs as a single button but is probably possible. I like you use cygwin. My co-workers use sourcetree. Since you use BitBucket it would make sense to use that as your GUI since it is managed by the same company : Atlassian. I suspect there's some tighter integration.

Regarding pulls

I think you are right that the merge in pull is whats messing people up. A pull is actually git fetch which retrieves the changes from the server, followed by git merge origin/<branchname>* which merges the remote changes into your local branch. (https://git-scm.com/docs/git-pull)

The upshot is all standard merge commands work with pull. If that merge has conflicts you can abort by git merge --abort. Which should take you back to before your merge. Then you can try again with either git pull or git merge origin/<branchname>.

If you can somehow learn how to do the above using your co-workers' GUI tool of choice I think that'll solve most of your problems. Sorry I can't be more specific.

* I understand that origin is not always the case here.

Use git reflog to diagnose problems

I, like you, have to diagnose problems mostly created by misuse of GUI tools. I find that git reflog can sometimes be helpful as that is a fairly consistent trail of actions on the repository. Though it is hard to read at times.

An alternative

Since your situation is temporary, you could just go back to SVN until you have the process in place to roll out. I'd be hesitant to do this as many places would go on saying 'We tried git once but it just didnt work...' and never really pick it back up.

Some other common transitional problems

  • People would often delete and reclone their repo, being convinced their repo was in an unusable state. Usually this was caused by losing track of the local and remote difference. Both GUI tools and the CLI fail at showing this well. In the CLI I find git log --decorate the easiest way to overview the differences. But if things get too hairy on master (for example) you can git reset --hard origin/master
jmathew
  • 226
  • 1
  • 5
  • 2
    On your last point: For a real quick, structural overview, I find `git log --oneline --decorate --graph` ideal. So much so, that I have defined a shell alias for that precise combination. – cmaster - reinstate monica Sep 07 '17 at 11:35
  • 1
    +1 for your answer, I just find the suggested alternative is bad, because of the reason you mentioned. You will have pain even if you go back to SVN and then in the future go to git. People in the team will only learn the new, different, painful tool if they have no other option. Only after usage and doing stupid mistakes will they start appreciating what git can do. – CodeMonkey Sep 08 '17 at 07:04
11

So far SourceTree was the best IDE to learn the concepts, because it shows all the relevant dialogs and options you have on each stage, the default options are usually fine, don't mess around with rebase, etc. Just follow the normal flow:

  • Pull from master, just to be sure you are up to date
  • Modify your files
  • Commit your changes (that is only locally)
  • Pull again from master (this will cause conflicts to appear)
  • Edit all files until the conflicts are resolved, meaning the file is in the propper state you want to commit (no <<<<< HEAD and >>>> master messages in the raw file)
  • Commit the merge changes
  • Push

If everyone follows this recipe, they should be fine.

Each time someone does a bigger or central change, inform the other users to commit locally and pull from master, so they don't get too many conflicts later on and the first person is still around to resolve the conflicts together with them.

Invest a lot of time in getting everyone to understand the flow, otherwise they might get around a while and then feel comfortable with it while actually screwing the master branch, for example "use my file instead of remote" to resolve a conflict will just kick out all changes made by other people.

Git is a hard to learn system, especially if you grew up with Svn, be patient and give them time to learn it properly, with new users you can sometimes spend a day cleaning up some mess, that is normal. ;)

Mike M.
  • 134
  • 2
  • 10
    nitpick: SourceTree isn't an *Integrated Development Environment*... – Mathieu Guindon Sep 07 '17 at 19:09
  • I've got somebody (other than me) test-driving this workflow now (with Tortoise Git, I mean) to shake out any surprises/problems. Assuming none, I plan to roll this out to the team in a couple days. – Monica Cellio Sep 10 '17 at 21:06
  • I know that [this highly-voted answer](https://softwareengineering.stackexchange.com/a/356889/124448) covers a lot of the same territory as this one, but it wasn't until I saw the recipe laid out step-by-step in this answer that I really understood how to apply it, so I'm accepting this one (for the recipe, not the IDE :-) ). We've been following this process for a few days now without further issues. We will also focus more on exploring and understanding the "git way". – Monica Cellio Sep 12 '17 at 18:37
8

One possible mechanism, that a lot of open source teams have adopted, is to use the forking model - https://www.atlassian.com/git/tutorials/comparing-workflows (be sure to enunciate clearly when discussing a forking git workflow).

In this each developer or sub-team has their own fork of the repository that they check out from BitBucket does provide a mechanism for this, setting an "upstream" origin in addition to the default remote - they will have to remember to "fetch upstream" and "merge remote/upstream/master" on a regular basis.

It will possibly resolve your build mechanism problems as the build tools would possibly be pointed to the master on a different project, i.e. the fork.

You could then remove from most people the ability to push directly to the master project and make that a smaller team of people with review & approve roles. See https://www.atlassian.com/git/tutorials/making-a-pull-request

The place to read up on ensuring that just about any desirable checks are done before pushes is in the git book section on hooks - https://git-scm.com/book/gr/v2/Customizing-Git-Git-Hooks - you can use pre-commit and pre-push hooks to do things like running some tests on the proposed commit to ensure that the work is valid, etc. - the only problem with client side hooks is that developers can disable them or fail to enable them.

Both upstream fetch/merge & hooks are available in TortoiseGit.

Steve Barnes
  • 5,270
  • 1
  • 16
  • 18
  • Not a bad idea, really. It also sounds like this team would benefit from a Merge Master until they are more comfortable. +1 – Greg Burghardt Sep 06 '17 at 13:06
  • 2
    BitBucket has a fork syncing feature which automatically fast forwards forks when possible. It's very convenient to fork today and pull from origin next week without ever worrying about upstream. – piedar Sep 06 '17 at 15:24
3

This is going to sound counterintuitive, but hear me out:

Encourage them to start experimenting with git

One of the interesting things about git is that it's surprisingly easy to make any local operation completely safe. When I first started using git, one of the things I found myself doing was zipping up the entire directory as a back up in case I screwed something up. I later discovered that this is an enormous kludge and is almost never actually necessary to protect your work, but it has the virtue of being very safe and very simple, even if you don't know what in the heck you're doing and how the command you want to try will turn out. The only thing you have to avoid when you're doing this is push. If you don't push anything, this is a 100% safe way to try out anything you want.

Fear of trying stuff is one of the biggest hindrances to learning git. It gives you so much control over everything that it's kind of daunting. The reality is that you can stick to a few very safe operations for most of your daily use, but finding which commands those are takes some exploring.

By giving them a sense of safety, they'll be far more willing to try to figure out how to do things on their own. And they'll be far more empowered to find a personal work flow on their local machine that works for them. And if not everyone does the same thing locally, that's fine, as long as they adhere to standards with what they push. If it takes zipping up the entire repo before doing an operation to make them feel that way, it's fine; they can pick up on better ways of doing things as they go and as they try stuff. Anything to get yourself to start trying stuff and seeing what it does.

This doesn't mean training is worthless. On the contrary, training can help introduce you to features and patterns and norms. But it isn't a replacement for sitting down and actually doing stuff in your daily work. Neither git nor SVN are things that you can just go to a class and then you know everything about. You have to use them to solve your problems to get familiar with them and which features are well suited for which problems.

Stop discouraging them from learning the ins and outs of git

I mentioned not pushing anything, which actually goes against one of the things you've been teaching them: to always "Commit & Push". I believe you should stop telling them to do this and tell them to start doing the opposite. Git has basically 5 "places" where your changes can be:

  • On disk, uncommitted
  • Staged but not committed
  • In a local commit
  • In a local stash
  • Remote repositories (Only commits and tags are ever pushed and pulled between different repositories)

Instead of encouraging them to pull and push everything in a single step, encourage them to leverage these 5 different places. Encourage them to:

  • Fetch changes before they commit anything.
  • Make a decision how to handle the fetched changes. Options are:

    • Commit their local changes, then rebase them on top of the fetched changes.
    • Commit their local changes and then do a merge with the fetched changes.
    • Stash their changes, merge, and then unstash and resolve any conflicts.

      There's other stuff, but I won't get into it here. Note that a pull is literally just a fetch and a merge. It's not like them; it is them. (Passing --rebase changes pull from fetch+merge to fetch+rebase.)

  • Stage their changes and then review them.
  • Commit their staged changes and then review the commit.
  • Push separately.

This will encourage them to check their work before it's made publicly available to everyone, which means they'll catch their mistakes sooner. They'll see the commit and think, "Wait, that's not what I wanted," and unlike in SVN, they can go back and try again before they push.

Once they get used to the idea of understanding where their changes are, then they can start deciding when to skip steps and combine certain operations (when to pull because you already know you want fetch+merge or when to click that Commit & Push option).

This is actually one of the enormous benefits of git over SVN, and git is designed with this usage pattern in mind. SVN, by contrast, assumes a central repository, so it's unsurprising if the tooling for git isn't as optimized for the same workflow. In SVN, if your commit is wrong, your only real recourse is a new commit to undo the mistake.

Doing this will actually naturally lead to the next strategy:

Encourage them to use local branches

Local branches actually ease a lot of the pain points of working on shared files. I can make all the changes I want in my own branch, and it will never affect anyone since I'm not pushing them. Then when the time comes, I can use all of the same merge and rebase strategies, only easier:

  • I can rebase my local branch, which makes merging it into master trivial.
  • I could use a plain merge (create a new commit) in master to bring my local branch's changes into it.
  • I can squash merge my entire local branch into a single commit on master if I think my branch is too much of a mess to salvage.

Using local branches is also a good start to figuring out a systematic branching strategy. It helps your users understand their own branching needs better, so you can choose a strategy based on needs and the team's current understanding/skill level and not just drop in Gitflow because everyone has heard of it.

Summary

In brief, git is not SVN and cannot be treated like it. You need to:

  • Eliminate the fear by encouraging safe experimentation.
  • Help them understand how git is different so they can see how that changes their normal workflow.
  • Help them understand the features available to help them solve their problems more easily.

This will all help you gradually adopt better git usage, until you reach the point where you can start implementing a set of standards.

Specific features

In the immediate term, the following ideas might help.

Rebase

You mentioned rebase and that you don't really understand it in your question. So here's my advice: try out what I just described. Make some changes locally while someone else pushes some changes. Commit your changes locally. Zip up your repository directory as a back up. Fetch the other person's changes. Now try running a rebase command and see what happens to your commits! You can read endless blog posts or receive training about rebase and how you should or shouldn't use it, but none of that is a replacement for seeing it live in action. So try it out.

merge.ff=only

This one is going to be a matter of personal taste, but I'm going to recommend it at least temporarily since you've mentioned you already have trouble with conflict handling. I recommend setting merge.ff to only:

git config --global merge.ff only

"ff" stands for "fast forward." A fast forward merge is when git doesn't need to combine changes from different commits. It just moves the branch's pointer up to a new commit along a straight line in the graph.

What this does in practice is prevent git from ever automatically trying to create merge commits. So if I commit something locally and then pull someone else's changes, instead of trying to create a merge commit (and potentially forcing the user to deal with conflicts), the merge will just fail. In effect, git will have only performed a fetch. When you have no local commits, the merge proceeds normally.

This gives users users a chance to review the different commits before attempting to merge them and forces them to make a decision about how to best handle combining them. I can rebase, go ahead with the merge (using git merge --no-ff to bypass the configuration), or I can even just put off merging my changes for now and handle it later. I think this small speed bump will help your team avoid making the wrong decisions about merges. You can let your team turn it off once they get better at handling merges.

jpmc26
  • 5,389
  • 4
  • 25
  • 37
2

I went through the exact same SVN -> git experience at my company and from my experience, the only remedy is time. Let people get used to the tools, let them make mistakes, show them how to fix them. Your velocity will suffer for a while, and people will lose work, and everyone will be a bit tetchy, but that is the nature of changing something as fundamental as your VCS.

That said, I agree with everyone who is of the opinion that TortoiseGit is a hindrance, rather than a help, so early in the transition period. TortoiseGit is... not a great GUI at the best of times, and by obscuring how git actually works in the name of simplicity, it's also preventing your coworkers from gaining an understanding of core git concepts such as the two-phase commit.

We made the (rather drastic) decision to force devs to use the command-line (git bash or posh-git) for a week, and that worked wonders for comprehension of how git actually operates and how it differs from SVN. It may sound drastic, but I'd suggest you try it simply because it creates that understanding of the git model - and once they have that down, your coworkers can start using whatever GUI facades over git they like.

Final note: there will be some of your coworkers who grok how git works almost immediately, and there will be some who never will. The latter group, you just have to teach the mystical incantations to make their code get from their local machine to the server so that everyone can see it.

Ian Kemp
  • 379
  • 1
  • 11
1

Well, recently I adapted the following workflow to never f*ck up the master branch:

1) Everyone uses their own branch, which is intially a copy from the master branch.

Let's name the master branch "master", and my own branch "my_master".

I just made my branch from the master, so it's exactly the same. I start working on a new feature on my own branch, and when it's done I do the following.

Currenly on my branch, just finished coding

git add . && git commit -m "Message" && git push

Go back to the master branch

git checkout master

Pull if it is not up to date

git pull

Go back to my own branch

git checkout my_master

Merge the latest master to my own branch

git merge master

Fix conflicts & merges

Test everything again

When everything is merged & fixed on my own branch, push it

git push

Go back to the master branch

git checkout master

Merge with my branch

git merge my_master

Impossible to have conflicts as they are resolved on your own branch with previous merge

Push master

git push

If everybody follows this, the master branch will be clean.

TanguyB
  • 437
  • 3
  • 14
0

So we have a team that switched from TFS to git and retained the old ways of thinking. The general rules of operation are more or less the same.

Yes, this means everybody works on master. This isn't that bad; and a team used to TFS or SVN will find this most natural.

General procedures to make this as painless as possible:

  1. do git stash && git pull --rebase && git stash pop every morning
  2. commit early and often (don't need to push immediately; we can at least start taking this advantage of git early)
  3. for pushing do the following loop:

    git add git commit git pull --rebase fix any merges compile git push loop until you don't get the can't fast forward error message.

Joshua
  • 1,438
  • 11
  • 11
  • If you do this, you might as well stay with SVN. In the same was as you may stay with horse carriages in the days of automobiles. Of course, you can drive your car at the same speed as you could do with a horse carriage. But, all you achieve with this is to impede yourself, and make the people who are able to drive a car mad at you. Learn to drive your car. Now. – cmaster - reinstate monica Sep 07 '17 at 11:45
  • @cmaster: For us the #1 advantage of git was loss of the server doesn't lose the entire source control history. (It happened to us--we had backups but the tape drive started eating tapes when we tried to restore.) – Joshua Sep 07 '17 at 15:26
  • @cmaster: We've started introducing some other useful git features since, but change branching probably won't be used. – Joshua Sep 07 '17 at 15:27
  • @cmaster The difference between driving a car slowly and riding a horse is that driving the car prepares you for driving it faster. Riding the horse doesn't. Not everyone who hops into a car needs to hit the gas to go 60 mph the first few times they're in it. – jpmc26 Sep 08 '17 at 21:55
  • @jpmc26 When I took my very first driving lessons, I was asked to drive 30 km/h for sure, and I believe that that lesson also included a short distance at 50 km/h. That's definitely more than a typical horse carriage does. And the same goes for `git`: You generally learn to fork and merge from day one. That's an integral part of using `git`. Avoid that, and you are abusing the tool in the same way as you are abusing a car when going no more than 15 km/h. – cmaster - reinstate monica Sep 11 '17 at 10:54
-3

If everyone is working on master, there's nothing that you can do. Things will inevitably get messed up.

You should use master for completed products that get sent to a customer. You should use development for ongoing development, and you should not allow anyone to push to development. The standard is that everyone branches from dev, makes their changes, pushes them from local to their branch on the server, and issues a push request. Then someone reviews the change and merges it into development.

To avoid conflicts, everyone merges development into their own branch before pushing, and solves conflicts at that stage (so it only affects one developer locally). If merging into development would cause conflicts, then it isn't merged - the developer merges development into their branch again, and pushes to the server again, and then it is reviewed again.

You can use sourcetree for example to make this work without any pain.

gnasher729
  • 42,090
  • 4
  • 59
  • 119
  • 4
    That's just replacing "master" with "development", with the added risk of people not switching to the development branch after a default checkout. I prefer [GitLab Flow](https://about.gitlab.com/2014/09/29/gitlab-flow/), which is a happy medium between the heavy GitFlow and sparse GitHub Flow. – Cees Timmerman Sep 06 '17 at 08:41
  • @CeesTimmerman If you don't like Gitflow, you might be interested in [Oneflow](http://endoflineblog.com/oneflow-a-git-branching-model-and-workflow), too. – jpmc26 Sep 08 '17 at 05:03