1

In order to develop a feature, I created a feature branch (called feature/a).

During development of feature/a, I found there is a existing bug, so I create a bug branch (called fix/b) based from master.

After fixed this bug and committed, I checked out feature/a again, and ran git rebase origin/master. But because it depends on fix/b, so I ran git rebase origin/fix/b. During both rebasing, I fixed some conflicts.

Then I kept working on feature/a, after I finished feature/a, just before I request pull request, I realised there were many duplicated commits. Why there are many commits duplicated? I thought it might because it is because I rebased from mixed sources, but I tried to reproduce locally but not happening.

Another questions, In this case, what is the right strategy? Anyone have some thoughts?


Update #1

Sorry I forgot to mention, at that moment fix/b still didn't merge back to master yet. So the situation is more like the below:

master --> m1 --> m2
 |\
 | \
 |  feature/a --> a1 --> a2
 |
fix/b --> b1 --> b2

Supposing I was at a2 on feature/a, Ideally I expected the following will happen: * git rebase master, and the diagram should become: --> m1 --> m2 --> a1 --> a2 * git rebase fix/b, and the diagram should become: --> m1 --> m2 --> b1 --> b2 --> a1 --> a2

However, in my case the diagram is more like the below: --> m1 --> m2 --> b1 --> b2 --> m1 --> m2 --> b1 --> b2 --> a1 --> a2

I couldn't reproduce in my local git repository.

My question actually is: if there are two branches (A and B), both didn't merged to master, and one depend on the other (branch A depends on branch B). In this case, to keep developing branch A, should I rebase from master and branch B?

Ron
  • 6,037
  • 4
  • 33
  • 52
  • You should _not_ have run `git rebase origin/fix/b`. Assuming you did in fact commit your bug fix directly to `master`, then `git rebase origin/master` should have brought that bug fix into `feature/a`. This is the source of your problem, I think. – Tim Biegeleisen Oct 26 '18 at 04:19
  • Sorry I forgot to mention, after I fixed `fix/b`, I request pull request, but it take time to merge back to master, meaning at this moment, `fix/b` didn't merge back to `master` yet. – Ron Oct 26 '18 at 09:32
  • That doesn't really change my comment much. You should not have rebased twice I think. – Tim Biegeleisen Oct 26 '18 at 09:33

3 Answers3

1

Whenever you do rebasing, there are new commits created in the target branch(feature/a), from the rebasing branches (origin/master) & (origin/fix/b). As origin/master is already having origin/fix/b commits, you are seeing duplicate commits in your target branch feature/a, when you rebase from origin/master.

What you should have done is, you should have considered origin/master as the shared branch for all your merging/rebasing. So, after merging fix/b to origin/master, you should have just rebased origin/master to target branch feature/a.

If you want to preserve history, you should go for merge. If you want cleaner history go for rebase. Either case, you should just keep origin/master as the shared branch and rebase/merge from origin/master into your branch. here, it is feature/a.

git checkout feature/a
git merge origin/master #if you are fond of merge, to keep history accurately
git rebase origin/master #if you are fond of rebase, to keep history cleaner
Venkataraman R
  • 12,181
  • 2
  • 31
  • 58
  • Thanks for you input. Actually I just realised I didn't mention that `fix/b` didn't merge back to `master` yet. I updated my question, could you have a look, thanks. – Ron Oct 26 '18 at 09:56
1

Let's have a look at your rebase sequence, because similar commits are not supposed to be rebased twice, considering the patch id mechanism.
Meaning, you shouldn't see m1/m2 repeated twice. And yet, you see them.

Supposing I was at a2 on feature/a, Ideally I expected the following will happen: git rebase master, and the diagram should become

     (master)
 m1 --> m2 --> a1' --> a2' (feature/a)
   \
     -> b1 --> b2 (fix/b)

git rebase fix/b, and the diagram should become:

m1 --> m2 --> b1 --> b2 --> a1 --> a2

Well... no: you are replaying feature/a (which now include master commits) on top of fix/b, but master still exists.

 m1 --> m2 (master)
   \
     -> b1 --> b2 --> m1' --> m2' --> a1'' --> a2'' (feature/a)

Hence the repetition of m1/m2.

Generally, commits from master should not be rebased.

Simply merging fix/b to feature/a is best to quickly go on developing on feature/a while benefiting from fix/b.

     (master)
 m1 --> m2 --> a1' --> a2' --> M (feature/a)
   \                          /
     -> b1 ----------------> b2 (fix/b)
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
0

I think this question&answer explains very well.

Basically, the last step push, we should git push --force-with-lease. If we do git push, it will generate duplicated commits.

Ron
  • 6,037
  • 4
  • 33
  • 52