27

I have seen lots of advice about git branching models and the most common opinion seems to be that making changes directly on the master branch is a bad idea.

One of our co-workers is quite happy making changes directly on the master branch, and despite several conversations, they seem not likely to change this.

At this point in time, I can't convince a co-worker that is a bad practice to work directly on master, but I would like to understand the things that will conflict with his way of working, to know when I need to revisit this issue.

7
  • 2
    Define "working directly". Master exists because it's meant to be used. What do you think it's for and what isn't it for? Nov 8, 2016 at 20:04
  • 3
    Is working off of master working for you? If it is, why do you feel the need to change right now? If it's not working, what problem(s) are you experiencing? Instead of asking for people to point you to other people's arguments, we can help you solve your problems.
    – Thomas Owens
    Nov 8, 2016 at 20:16
  • 1
    Sounds like he's doing trunk development, which, along with continuous integration, is pretty normal in an Agile team. If he wants to work like this, you will need to enforce WIP to ensure that there's never too much work going on against one product at a time - and also use feature switching to ensure that master can be released with incomplete features turned off.
    – Mr Cochese
    Nov 9, 2016 at 10:13
  • ...how big is the team?
    – ZJR
    Nov 9, 2016 at 12:00
  • 1
    @MrCochese I wouldn't call trunk development in the sense here "normal". Certainly none of the many places I've used Git has worked that way, and I would discourage it. Feature branches just work better. May 18, 2018 at 0:56

8 Answers 8

60

There are several problems when commits are directly pushed to master

  • If you push a work-in-progress state to remote, the master is potentially broken
  • If another developer starts work for a new feature from master, she starts with a potentially broken state. This slows down development
  • Different features/bugfixes are not isolated, so that the complexity of all ongoing development tasks is combined in one branch. This increases the amount of communication necessary between all developers
  • You cannot do pull requests which are very good mechanism for code reviews
  • You cannot squash commits/change git history in general, as other developers might already have pulled the master branch in the meantime
3
  • 13
    Hey look! You actually answered the question, unlike basically everyone else. ++ Welcome to SE.SE!
    – RubberDuck
    Nov 9, 2016 at 10:52
  • Most of these are problems derived from working directly on master badly, not from working directly on master per se.
    – Ant P
    May 8, 2017 at 11:42
  • 2
    @AntP which problems could be prevented from your point of view?
    – Gernot
    May 10, 2017 at 7:25
13

Explain to him that new features need their own development branch that can be deployed to a test environment before it is pushed to production.

Otherwise, you're in a perpetual state of half-completed features. You can't deploy half-completed features to production, so if you're working directly on the master branch, everyone else must wait for you to finish your feature before anyone else's changes can go to production, including bug fixes.

Using independent branches for features means that each new feature can be tested and deployed independently of the others.

19
  • 2
    @AntP: What I said (perhaps unclearly) was that, if you have multiple people developing on the master branch directly, and you need to ship before one of these people has completed their work, then you need a way to keep the unfinished work out of the shipment build. One way to do that is to not check in your work until it is done, but that's risky. Another way is to have feature switches. The best way (if your features are more than a day's work or two) is to have feature branches and merge each feature branch into the main branch when it is completed. May 8, 2017 at 22:04
  • 1
    @AntP: In my experience, that can work for very small teams that have the capacity to closely coordinate, and I've worked that way before. So to further clarify, my statement says "don't deploy broken features to the end user." Whatever mechanism you use to prevent that from happening is entirely up to you, but in general, separate feature branches are quite effective in that regard. May 8, 2017 at 22:24
  • 1
    @AntP Let's not play maturity chicken here. Every team I've worked on, at least, has converged toward feature branches (and a pull-request workflow). I don't see how not branching would improve productivity or quality; quite the reverse, since it would result in a lot of half-finished dead code making it into a release. I used to do trunk-based development in SVN. It had no advantages whatsoever over the feature branch workflow I now use with Git. May 18, 2018 at 16:28
  • 1
    @AntP "provides many benefits - not least that it does a very good job of encouraging the discipline of small, incremental, non-breaking commits towards a new feature." Small commits are a good thing. But a policy of non-breaking ones is not. When I create a feature, I want the freedom to temporarily break things on my feature branch if necessary. (Broken code doesn't get pushed to a remote, of course.) I do a lot of experimental work as I develop, and that has no place on trunk until the whole feature is ready to merge. I stand by my statement that trunk-based dev is a mistake. May 18, 2018 at 16:33
  • 1
    @AntP: The one thing that feature branches have that your technique cannot provide is a complete accounting of the work done on a particular feature. In some shops (mine in particular) that kind of accountability is not a luxury but rather a requirement. May 18, 2018 at 18:15
3
  • Master should reflect a production branch, a working final version.
  • Working directly in master means that if you create bugs you have no other option for "going back" than to reverse/delete/reset commits, which is not a clean way of working and can cause you to lose the parts of the new code that were OK.
  • Of course, in the very first stages of development perhaps you can begin working directly on master, but after you have something to deliver, you should use development, test or experiment branches to not touch the published, complete, working version.
3

One of our co-workers is quite happy making changes directly on the master branch, and despite several conversations, they seem not likely to change this.

This leads me to believe there are more issues. Working on master or not is mostly part of a bigger philosophy about how, what and when you release products.

So in tandem with a "you should never work on master", do you have tests of features, do you test each-others work do you review each-others code. Acceptation and integration tests.

If you have none of the above and you're just doing it to "do git", you might as well work on master.

2

Master should be potentially releasable. Period. There should not be any half finished work in master(unless disabled with a feature flag)

With that said Ive seen some teams complicate their flow.

Not using PR when integrating to master is a mistake since developers will not have the power to choose when integration occurs.

A single development branch brings very little value. Usually it just complicates things. Many feature branches brings much value.

Making branches for each environment(dev, test, prod) is a mistake. This is out of scope for git and should be handled by the release pipeline. The exact same build should be deployed to all environments which is impossible if there are branches for each environment.

If a feature is so big it cannot be done in a day or two all work to a feature branch should be in separate branches and integrated with PR.

16
  • I agree with most of what you've said, except for this: "The exact same build should be deployed to all environments". In fact, a release pipeline should generally be able to deploy different builds to different environments and then promote them as tests pass. How do you handle this, if not with different branches (or at least different tags)? May 18, 2018 at 20:05
  • Maybe I wasn't completely clear. Once a build is deployed to an environment. The same artifacts should be deployed to the next environment without a rebuild. May 18, 2018 at 21:01
  • If you have repeatable builds, it shouldn't matter whether you rebuild. If you don't have repeatable builds, you've got bigger problems. :) May 18, 2018 at 21:07
  • ...but yes, I do think you should tag your deployed commits so you can promote the same code (regardless of whether you rebuild). May 18, 2018 at 21:11
  • Yes but most CI servers can link builds to releases out of the box making it easy to track deployments. When setup correctly it is not really needed to track deployments in git. Git is a scm. Not a deployment tool. May 18, 2018 at 21:52
2

First, I want to point out that in git, every pull is quite literally a branching operation, and every push is a merge. The master on a developer's machine is a completely separate branch from the master on a central repo you share, with equal standing from a technical perspective. I will occasionally rename my local version to upstream or something if it suits my purposes better.

I point this out because many organizations think they are using branches more effectively than your colleague, when really they are doing little more than creating an additional name for a branch along the way, that won't be saved in the history anyway. If your colleague is committing features in one atomic commit, it is just as easy to back out as a merge commit of a feature branch. The vast majority of feature branches should be very short-lived and frequently merged anyway.

That being said, the main drawbacks of his style of working are twofold. First, it makes it very difficult to collaborate on an unfinished feature. However, it wouldn't be difficult to create a branch on just those times when collaboration is needed.

Second, it makes review before merge very difficult. On this point, you don't actually need to convince him. You can adopt a tool like github, gerrit, or gitlab, and require pull request code reviews and passed automated tests for all merges. If you're not doing something like this, frankly you are not using git to its full potential, and it's no wonder your colleague doesn't see that potential.

6
  • 1
    Also pushing of the developers his/her branch machine each day is a good backup.
    – Ian
    Nov 9, 2016 at 17:48
  • I don't understand your first sencence. I don't see how a pull would create a new branch or how a push would be a merging operation. Rather, a pull is quite literally a fetch followed by a merge!
    – mkrieger1
    Nov 16, 2016 at 15:35
  • @mkrieger1 I can easily see how one could consider the local master to be a different branch from origin master. Technically, they are different branches on two different remotes, each with their own history.
    – RubberDuck
    Nov 17, 2016 at 0:40
  • @RubberDuck Yes, exactly. With pull: Before: two branches potentially pointing at different commits - After: two branches pointing at equivalent commits - No branches created, therefore I wouldn't call it a "branching operation". If any of the two commands, I would call push that, because it potentially creates a new branch in the remote. What it does not do, is a merge.
    – mkrieger1
    Nov 17, 2016 at 18:52
  • @mkrieger1 you need to consider the direction of the merge as well.
    – RubberDuck
    Nov 17, 2016 at 18:54
2

Other answers have already mentioned various advantages (isolated features, always shippable code on master, etc) for working NOT on master directly.

For me you seem to have a different issue. Obviously you don't have a development process, which is agreed or used by all of your developers (or your developer in question is totally ignoring the process).

Do you have feature branches, which are merged into master or do you have different releases branches as well or do you use a totally different process?

"Don't use the master branch" is not sufficient.

1

There is no "bad practise" around working directly on the branch. But you have to decide what supports your process best:

Question 1: Should your master represent the current release state of your software? Then you should introduce a global development branch and merge the develop at the end of a release development.

Question 2: Do you want to have a code review process? Then you should have "feature branches" that will be merged into master (or develop, if you have one) via pull requests.

Question 3: Is there need to share intermediate code state to other developers that should not be published into production (or test) yet? That is the the case more than one developer develops a feature. Then you should introduce "feature branches".

1
  • Tags are a very viable way to represent the state of a code base at release. Git makes it very easy to checkout a specific tag. Makes a dev branch kind of moot.
    – RubberDuck
    Nov 17, 2016 at 0:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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