25

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.

  • 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? – candied_orange Nov 8 '16 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 '16 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 '16 at 10:13
  • ...how big is the team? – ZJR Nov 9 '16 at 12:00
  • @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. – Marnen Laibow-Koser May 18 '18 at 0:56
57

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
  • 11
    Hey look! You actually answered the question, unlike basically everyone else. ++ Welcome to SE.SE! – RubberDuck Nov 9 '16 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 '17 at 11:42
  • 1
    @AntP which problems could be prevented from your point of view? – Gernot May 10 '17 at 7:25
10

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.

  • "You can't deploy half-completed features to production" - this is not true at all - it is entirely possible to work directly on the main branch, ship code every commit, frequently deploy "half-completed features" and never break anything. Continuous delivery is about doing exactly this: decoupling deployment from release. Which also happens to solve lots of other organisational problems that people normally address with half-broken technical solutions. Sometimes this involves feature toggles but usually it's possible to build and deploy 90% of a feature with no visible behavioural change. – Ant P May 8 '17 at 11:46
  • @AntP: The process that you're describing is not what I would call "half-completed features." Such features are either tested, production-ready and usable, or they're hidden by a feature switch or something similar until such time as they are tested, production-ready and usable. You're not shipping features that don't work. – Robert Harvey May 8 '17 at 19:05
  • You asserted that new features need to be developed on non-master branches because you can't deploy half-finished ones: that's not the case. You absolutely can develop new features directly on master and ship any and all code related to those features to production before the feature is complete and without holding up other development. – Ant P May 8 '17 at 19:58
  • 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. – Robert Harvey May 18 '18 at 18:15
  • 1
    @AntP If I understand you correctly, I would consider that a step backwards. I love good issue trackers, and I use them extensively, but I want the VCS to tell me the development history of any feature or line of code. The issue tracker can tell the story of the business side of a change, but if the VCS can't help me track and audit the code by itself, then it's not doing its job. This is one reason I object to trunk-based development: it makes the VCS stupid, for no compensating advantage that I can see. (Also: brittle coupling? A feature is a code change.) – Marnen Laibow-Koser May 18 '18 at 19:13
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.

  • 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)? – Marnen Laibow-Koser May 18 '18 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. – Esben Skov Pedersen May 18 '18 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. :) – Marnen Laibow-Koser May 18 '18 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). – Marnen Laibow-Koser May 18 '18 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. – Esben Skov Pedersen May 18 '18 at 21:52
2
  • 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.
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.

  • 1
    Also pushing of the developers his/her branch machine each day is a good backup. – Ian Nov 9 '16 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 '16 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 '16 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 '16 at 18:52
  • @mkrieger1 you need to consider the direction of the merge as well. – RubberDuck Nov 17 '16 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.

2

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.

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".

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