30

Whenever a new project starts, it usually makes sense to start by committing straight to master until you've got something "stable", and then you start working in branches.

At least, this is how I normally do it. Is there a way to immediately start branches from second commit? Does it make sense to do it this way? Obviously, "Initial Commit" will always be on master, but after that, when will I know it's the right time to start making branches for new features?

6 Answers 6

25

Immediately.

The key is the question of what the policy for Master is. With git, typically, the branch policy on Master is the buildable stable release. Sometimes, Master is the 'mainline' where branches are made from and merged to prior to merging to a Release branch. These are two different role/policy approaches.

It is often a source of errors for people to change the role or the policy of a branch part way through the project. It is easier for a solo developer to communicate these changes out to contributors, but trying to get a dozen programmers to all recognize "Master is now at 1.0, please branch features rather than everyone pushing to it"

I touched on the policy approach above. The policy for Master is that it is the buildable stable release. Checking in small incremental changes into this means you don't have something buildable stable at all times. Not checking in small changes goes against the "lots of small (but complete) checkins" that tends to be the best policy (and encouraged by easy branching).

From a role based perspective, you've started out with master being mainline, release, maintenance, and development roles, and then some point down the road the development and maintenance role moves to branches. This again means a change in what is allowed on master and can confuse contributors as to where things belong. It can also (slightly) confuse the branch history, encouraging large commits that mean bigger and harder to understand merges.

Key the roles and policies on the branches simple and consistent from the start.

This "branch on policy change" can be seen in the Branching Patterns. The idea of each branch having roles, can be read in Advanced SCM Branching Strategies. Both of these are very good reads.

3
  • 5
    I agree mostly with this, but I wouldn't just say buildable, I'd say releasable (stable). The master shouldn't contain code that merely builds, it should contain code that's actually been thoroughly tested. You should be able to pull from master at any time, confident in the knowledge that there won't be any serious defects.
    – Aaronaught
    Jan 7, 2014 at 21:54
  • I agree fully to Aaronaught, since IMHO its perfectly possible (and best practice) to work in a way where the step from one buildable state to the next is always only a small incremental change, never a big one.
    – Doc Brown
    Jan 7, 2014 at 22:02
  • 1
    @MichaelT I have seen 'dev' branches plenty of times, but never heard them explained in the context of an "early master" before. I think I'll use this, thanks.
    – yurisich
    Jan 8, 2014 at 15:38
13

If you follow git-flow - and, quite frankly, I think you're insane if you use Git and don't use that branching model - then you should never commit to master until you're actually ready for a public release.

Your first commit to master should be an empty repository. Your next commit to master should be a merge commit from the develop branch or a temporary release branch, and it should be stable, tested, and ready for deployment (if it's an application) or public distribution (if it's a library).

There are other branching models for Git, but most of them have are derived from older centralized SCM models and can lead to serious problems in a DVCS environment. You don't have to actually use the git-flow extension, and you don't necessarily need all those release/hotfix/feature branches, but the bare bones is develop and master, and unstable code goes in develop.

3
  • You don't even need that first commit to master. Remember that master isn't anything special to git, it doesn't need to be there. You can just have a development branch until you want to make a release.
    – Miles Rout
    Jan 16, 2014 at 0:57
  • 3
    @MilesRout: While that's true in principle, you can't merge unless the branch already exists, and the process dictates that every commit to master should be a non-fast-forward merge. Unless I'm missing something, the only alternative to an initial empty commit would be to branch master off of some arbitrary develop commit or release branch, which would mean that they'd be sharing the same commit, which is something you're supposed to avoid.
    – Aaronaught
    Jan 16, 2014 at 3:20
  • 1
    Ah, that is indeed a good point. +1 to post and comment.
    – Miles Rout
    Jan 16, 2014 at 3:24
13

There are mainly two situations where you typically want to start working with branches:

  • when you or your team has to start a new feature which has the slightest chance not to be added to the next release (which may be the first release ever), then start the development in a separate feature branch

  • when you have to provide fixes for severe bugs to the latest release, and you want to create a new bugfix release containing only those fixes, but no newly developed (and probably unstable) features

For such kind of decisions, I think its helpful to think always in terms of "new features" or "bugfixes", from the point where you have a first compilable / runnable version of your program.

Michael Feathers lists four reasons to change in his famous book, but I would put "optimize resources" under "new feature branch" (for a non-functional feature) and "improving the design" most times under "new feature branch" as well, since IMHO one should never improve the design when this is not intended for the purpose of making the implementation of a specific feature easier.

1

Neal Ford of Thoughtworks advocates the use of feature toggles over branching to avoid the problem of "merge hell". Consider the case in which two programmers dutifully merge daily from the main branch and one of the makes considerable changes over somes weeks and then commits. The other programmer could very well end up in merge hell. To avoid this problem, Ford recommends "bringing the pain forward" (a well-known agile attribute) by having only one branch and committing to it daily. Additional feature are added via feature toggles which disable the feature until it's been fully tested.

This methodology would seem to work best in an environment that implements continuous delivery as problems with a commit would be immediately caught.

1

It's been two year since the last answer to this question and I think now the story changes. To me the answer is "Whenever you use source code control to track versions."

To elaborate, these days tracking project versions with source code control doesn't always work. (for example using npm to manage dependency and specify semantic versions with '^') In that case project artifacts changes every time a build happens, with not necessary correspond to source code changes every time. To handle this kind of new challenges, some teams choose to have already built 'artifacts' saved in artifact control system (eg. JFrog Artifactory) for track project versions.

Obviously when you already have artifacts version control in place, you wouldn't pull 'production code' from a GIT branch and build/deploy to production, instead you consult to artifacts control system for a directly runnable versions for deployment. In such cases the concept of 'release branch' suddenly loose its meaning. And whenever your team decides not to associate git branch with release version, committing/pushing directly to master become a sound choice once again: it comes as default branch whenever the repo is cloned, hence automatically given the semantics widely-accepted and well-communicated changes. Still, as accepted answer suggests, you should probably go head an assign role to branches including master, and use those branches only for those particular roles.

Last, I'm going one step further and suggesting to use master as development branch in projects with only handful of core committers. Which is the case for my team and probably same for most micro-services shops. Committing on master removes the communication of changes process and potentially avoid 'merge hell' when working on features across multiple sprints. Furthermore, code in master branch doesn't even has to 'work', automated build/test process will tell you what went wrong and it's anyway easy enough to check git history and contact the author who broke the build/test :-)

0

I am going to take a radical position: branch on every idea. First in git branches are cheap, the main cost of a branch is remembering what is is for. I also agree that the first commit to master is a release candidate. I recommend starting with a proof of concept branch. When you have proven your concept you can merge it with your empty devel branch or rewrite depending on how good your first try is. from this point you branch from devel for every bug, feature, abstraction, etc.

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