How to Minimize Git Pain When Working on Master Branch

bitbucketgit

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?

Best Answer

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. ;)