123

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?

  • 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 6 '17 at 8:45
  • 91
    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 6 '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 6 '17 at 12:38
  • 28
    I'm kind of surprised everyone is poo-pooing working on the master, which is the central tenet of Continuous Integration. 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 (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. – DanK Sep 6 '17 at 15:46
  • 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 6 '17 at 19:13

11 Answers 11

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

  • 9
    nitpick: SourceTree isn't an Integrated Development Environment... – Mathieu Guindon Sep 7 '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 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
100

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.

  • 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 6 '17 at 9:33
  • 20
    @anaximander, I would recommend that either everybody uses --rebase or nobody... – keuleJ Sep 6 '17 at 12:29
  • 12
    @TemporalWolf That's what they told me about the cake too... – BlackVegetable Sep 6 '17 at 18:54
  • 15
    @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 Linus' take on rebase, which I personally find quite more agreeable than any of those black and white approaches. – Voo Sep 6 '17 at 19:33
  • 10
    "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 8 '17 at 4:50
68

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.

  • 37
    "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 6 '17 at 16:30
  • 3
    Another helpful git learning resource is Learn Git Branching. 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 6 '17 at 18:46
  • 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 7 '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 7 '17 at 13:13
  • 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 0: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.

  • 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 6 '17 at 2:46
  • 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 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. – DanK Sep 6 '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 6 '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. – DanK Sep 6 '17 at 17:11
  • 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 6 '17 at 18:10
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
  • 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 Sep 7 '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 8 '17 at 7:04
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.

  • 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 6 '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 6 '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.

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.

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.

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.

  • 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 Sep 7 '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 7 '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 7 '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 8 '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 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.

  • 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, which is a happy medium between the heavy GitFlow and sparse GitHub Flow. – Cees Timmerman Sep 6 '17 at 8:41
  • @CeesTimmerman If you don't like Gitflow, you might be interested in Oneflow, too. – jpmc26 Sep 8 '17 at 5:03

protected by gnat Sep 7 '17 at 4:50

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.