0

I have a branch feature1 with commits A,B,C. Now I like to start a new feature2 based on feature1.C to continue work for commit D..K. At this time the feature1 is not merged into the develop branch. It will take some time to review its pull request of feature1. Finally both features should go into the develop branch.

Merging feature2 back to develop is a mess because it's based on feature1.C and not develop. Creating a new branch feature2again based on develop and cherry-pick commit D..K works better.

Is this the best solution? Does git rebase not work here?

r2d2
  • 592
  • 5
  • 15
  • 1
    If feature2 is based on feature1, you can't merge it into develop without merging also feature1. If feature2 is independent of feature1, its branch should not be based on the feature1 branch. – mkrieger1 Dec 21 '21 at 14:54
  • Why is merging feature2 back to develop a mess? It sounds to like you want to bring the changes from feature1 into develop before feature1 was reviewed. Is this really what you want to do? The logical choice is to wait with merging feature2 until feature1 is completed and merged back into develop. – Lasse V. Karlsen Dec 21 '21 at 14:54
  • Let me put it another way. Basing feature2 on feature1, or cherry-picking everything on feature1 into a fresh feature2, and then merging feature2 into develop **will merge all the changes from feature1 into develop as well**. – Lasse V. Karlsen Dec 21 '21 at 14:55
  • The merge of feature2 to develop will give a lot of unnecessary conflicts like "2 similar new files added on both branches". Merging those would be no problem if I could base feature2 on the develop branch after merging feature1 to it. But then I'm not able to start the work before completing feature1 =) – r2d2 Dec 21 '21 at 15:53
  • What remote server are you using? Is it GitHub? – matt Dec 21 '21 at 17:52
  • 2
    Related: [Temporarily use commits from another feature branch](https://stackoverflow.com/q/67334184/184546) – TTT Dec 21 '21 at 19:48
  • @TTT Thanks for pointing out the related question. It's the same problem I have but with a nice graphic. – r2d2 Jan 19 '22 at 10:47
  • @r2d2 I think I realized it was pretty close to being a dup after I answered this question. I actually like my answer to this one slightly better than my answer to the other one, so there's that. – TTT Jan 19 '22 at 14:51
  • We use Azure devops. – r2d2 Jan 19 '22 at 15:02

1 Answers1

2

Now I like to start a new feature2 based on feature1.C to continue work for commit D..K.

Since the work you intend to do on branch feature2 requires the commits on feature1 but are not yet in develop, then you can start working by creating feature2 off of feature1 as you proposed. The only caveat is that you cannot merge feature2 into develop until after feature1 is merged in, unless you are willing to merge in both all at once and skip the separate merge of feature1 into develop on its own. Based on the comments we will assume you wish to wait so you can do a separate merge of feature2 commits.

After feature1 is merged into develop, you can simply rewrite your branch similar to how you proposed:

Creating a new branch feature2 based on develop and cherry-pick commit D..K

Note you have a minor error there: you need to start with C instead of D (parent of the first commit) for the cherry pick range. You could also use D^..K.

There are a few different ways to accomplish this. With cherry-pick you'll need at least 2 (or 3) commands if you currently have feature2 checked out, or you can do the same thing with a single fancy rebase command. The end result should be the same so it doesn't matter which you choose:

# Assuming you've already done these first two commands
# git switch feature2
# git fetch

# Option: cherry-pick
git reset --hard origin/develop # or create a new branch like feature2.1 from origin/develop
git cherry-pick D^..K

# Option: rebase
git rebase --onto origin/develop feature1

Side Note 1: if you already created feature2 off of feature1 but later realized feature2 does not depend on feature1 and you could have started from develop but didn't for some reason, then you could rewrite your branch as described above immediately, and wouldn't need to wait for feature1 to be merged into develop before merging feature2.

Side Note 2: I tend to use origin/develop instead of develop so you don't have to keep your local copy of develop up to date all the time. In fact I usually recommend deleting the local copy of develop just so you don't accidentally use an old version of it when making new branches.

Side Note 3: It's possible that you will be able to do a regular rebase (git rebase origin/develop) instead of a "fancy" one using --onto. Whether a regular rebase will work depends on what happened to feature1 after you branched off of it. If the final version of it is identical to yours such that the commit IDs did not change and no additional commits were added, then you definitely can do this. But if anything about it changed, it will depend on what those changes are. You could always try it if you wish, or just skip directly to the "fancy" rebase which you may have to do anyway. Also, if you know feature1 is changing before it's finally merged into develop, you could rebase feature2 onto origin/feature1 to keep up to date with it so that your final rebase before you create the PR for feature2 into develop is more likely to go cleanly. However, you may also have to use rebase --onto for rebasing feature2 onto feature1, depending on how feature1 is changing.

By the way, the (perhaps minor) inconvenience of possibly needing to rewrite your branch like this is one of the reasons people try to avoid basing new work off of incomplete existing work, when possible.

TTT
  • 22,611
  • 8
  • 63
  • 69
  • feature2 requires feature1. I like to have a separate pull-request to merge feature2 to develop with only commits D..K in it. – r2d2 Dec 21 '21 at 16:09
  • @r2d2 OK. Both the `cherry-pick` and `rebase --onto` will solve your problem, but you just need to wait to do it until after `feature1` is merged into `develop`. – TTT Dec 21 '21 at 16:12
  • @r2d2 I'm curious, are you asking how to do this without waiting for `feature1` to get merged into `develop` first? (If yes, unfortunately that's not possible, since by your definition `feature2` depends on `feature1`, so it wouldn't work if `feature1` doesn't exist.) – TTT Dec 21 '21 at 17:09
  • @r2d2 I just noticed your other comment "But then I'm not able to start the work before completing feature1" and based on that I think I captured what you're looking for in the updated answer. – TTT Dec 21 '21 at 17:37
  • 1 like for "avoid basing new work off of incomplete existing work". But I like to split big tasks into smaller task too. It's easier to review too. – r2d2 Jan 19 '22 at 15:00
  • @r2d2 agreed! By default I think most people code review PRs as a whole, and look at the file diffs one by one. To avoid this question's scenario, if it's just me working on multiple features that are chained, I might do one big PR with many commits, and in that case I instruct the reviewers to review each commit in order, rather than all the files separately for the entire PR. This enables the reviewer to keep some mental context for each change and is less daunting of a review. That said, when necessary I'll still branch off of a teammate's incomplete branch knowing it's gonna change... – TTT Jan 19 '22 at 15:15