22

We use GitHub Flow in our project and most of the time, we open a new feature branch from master, do some work there, open a PR, review the code and merge back into master.

However, my current work depends on another issue that is being worked on in feature-branch-A. Is it kosher to create my branch from that other branch or is that against the spirit of GitHub Flow?

The alternative would be to base my branch on master and merge-in the changes from feature-branch-A (frequently).

Which option is preferred in GitHub flow?

24

Here is the workflow that I follow when I branch from a feature branch:

  1. Create feature-branch-B from feature-branch-A
  2. Work on feature-branch-B
  3. If more commits are added to feature-branch-A after branching, rebase feature-branch-B onto feature-branch-A
  4. Finish work on feature-branch-B and wait till feature-branch-A is merged into master.
  5. After feature-branch-A is merged into master, rebase feature-branch-B onto master
  6. Merge feature-branch-B into master

By following the above workflow it will appear that you branched from master after feature-branch-A was merged. You don't have to wait till feature-branch-A is merged to start work on feature-branch-B. Yet, you will get a clean history without any complicated trees.

  • This was exactly the answer I was looking for! You saved me the headache of sorting that out, thanks! – Vance Palacio Mar 22 at 19:18
8

I think this is completely ok if you create the feature at another feature.

But don't do it quite often. I see one developer who made this and week or two he throw 10 PR out for merging. That was completely exhausting for others members for review and hard for merging too. Try don't make trees in git. That helps with bisect for finding errors.

6

A key thing that git-flow was intended to address was the ability to reason about the role of a given branch, and what it branches from and merges to.

Ideally, all branches merge back to the codeline they were merged from. This is typically a merge from the mainline (in git-flow this is dev). Feature branches branch and merge from dev, release branches branch and merge from dev (with an additional merge to master). Hot fixes branch and merge from master (with that additional merge back to dev).

Each codeline branches from and merges back to its parent. A codeline may pull in code from other codelines at any time if it is necessary.

If the branch from a feature branch is a "I want to explore this way of fixing a problem in that feature branch" - perfectly fine. It branches from the feature branch, commits some code and merges back to the feature branch (or is discarded).

  1. branch from feature
  2. explore idea
  3. merge to feature

What you want to avoid however is something that looks like:

  1. branch from required-feature
  2. work on code
  3. merge from dev once required-feature is complete
  4. verify functionality (and additional commits) in feature branch
  5. merge to dev

The reason is that the start and the end don't match - it makes it a little bit harder to understand what this is and was. Not impossible, but it just makes it take a little bit more time for someone to understand its role.

However, if this is new feature that depends code that isn't yet found in dev, the flow should be:

  1. branch from dev
  2. merge from required-feature
  3. work on code
  4. merge from dev once required-feature is complete
  5. verify functionality (and additional commits) in feature branch
  6. merge to dev

Note that this starts with a branch from dev and ends with a merge to dev.

All that said, probably the best thing to do is to avoid doing a merge from one feature to another feature. Branch the feature, do whatever preliminaries are needed... and wait.

  1. branch from dev
  2. work on code
  3. merge from dev once required-feature is complete
  4. verify functionality (and additional commits) in feature branch
  5. merge to dev

This provides the most stable set of branches and code.

Something to consider for future work would be to have a feature to publish the necessary interfaces for interoperability with other features - even if the implementation code isn't complete. This would be merged to dev, and then required-feature could work off of those interfaces as could the future-feature. This would likely allow future-feature to progress further (coding against the interfaces, testing against stubbs that implement the interfaces) than it would if it had to wait for required-feature to merge to dev.

  • In your third set of steps, the downside is that step 1 needs to contain some "dummy commit". In my situation, I don't have anything useful to commit until required-feature is merged in. – Borek Bernard Feb 18 '16 at 16:07
  • I still point to it as one of my favorite articles on branching: Advanced SCM Branching Strategies. While it focuses on a centralized version control system, the ideas of the roles that it presents exactly map to git-flow. – user40980 Feb 18 '16 at 16:08
  • And as to the dummy commit, that is why that last paragraph is there. What would have been useful is a feature that ran and completed as "provide interfaces for doing stuff". Then both required-feature and future-feature could work off of those interfaces. While required-feature worked on the implementation of the interfaces, future-feature would be able to stub them out and do tests against them - waiting for required-feature to get merged to dev. – user40980 Feb 18 '16 at 16:10
  • Wondering how bad your second set of steps are. Is it a problem in practice that a branch doesn't have a "same" start and end? I don't think it would bother me too much but maybe it's a major mess factor? – Borek Bernard Feb 18 '16 at 16:15
  • It is a matter of clearly describing through the branch, commit and merge history as to which branch is the parent branch. Within git-flow, you should be following the system described in git flow feature branches. The feature branch branches from the develop branch and merges back to develop. When you start branching from other feature branches, it becomes less clear what the role of that branch is. I would encourage you to wait until the required-feature is done if you can't progress on the code without it now. – user40980 Feb 18 '16 at 16:28
1

A feature branch is normally considered less stable than the trunk (develop/master), so you possibly subject yourself to more underlying changes than normal if you base your work off of one.

Also, while normally frowned upon if the branch has been pushed, it is not uncommon to rebase feature branches onto their parent branch, to get a nicer history, but that would be extra complicated if there were additional branches hanging off of it, so you're essentially creating a new restriction for the parent branch owner, as well as potential headaches for yourself.

That said, there's no strict rule against it. These are just patterns and best-practices after all.

Edit: missed part of your question. Merging the feature branch into your own, which is based off of master doesn't really avoid any of the problems mentioned above, and might actually create an even more convoluted history.

Thus if I were in your shoes and I could defer work until feature a was done, or do something else first, I would do that.

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.