spraff spraff - 18 days ago 7
Git Question

Why does this git rebase think there's nothing to do?

In this example, git doesn't think it needs to rebase, but it clearly does.

Here's a quick script to create a mini test git repository

#!/bin/bash
rm -rf testgit
mkdir testgit
cd testgit
git init
echo -e "a\nb\nc" > file
git add file
git commit -am 'first'

git checkout -b lineA
echo -e "A\nb\nc" > file
git commit -am 'A'

git checkout -b lineB
echo -e "a\nB\nc" > file
git commit -am 'B'

git checkout -b lineC
echo -e "a\nb\nC" > file
git commit -am 'C'


After this runs, here's what
file
looks like in each branch

master | lineA | lineB | lineC
------------------------------

a A a a
b b B b
c c c C


Now let's merge all the branches into master, after which each letter in
file
should be capitalised

$ git checkout master
$ git merge lineA


Okay.

$ git checkout lineB
$ git rebase master
Current branch lineB is up to date.


What? No, master changed.

$ git checkout master
$ cat file
A
b
c

$ git checkout lineB
$ cat file
a
B
c


It seems to me that branch lineB needs to rebase to incorporate the change to master made by merging lineA.

Why doesn't git think this needs to be done?

Additionally, if you do this

$ git checkout master
$ git merge lineA
Already up-to-date.
$ git merge lineB
...
1 file changed, 2 insertions(+), 2 deletions(-)
$ cat file
a
B
c
$ git merge lineC
...
1 file changed, 2 insertions(+), 2 deletions(-)
$ cat file
a
b
C


Here the merges should conflict, but git is quietly clobbering them. I'm don't know if this is relevant, but it seems weird.

Answer

After the script we have (abbreviating the line branch names...):

master   lA   lB   lC
  ↓      ↓    ↓    ↓
first----A----B----C

These commands:

$ git checkout master
$ git merge lineA

results in a fast-forward merge, which just moves master to point to the same commit as lineA.

Giving:

        master 
         lA   lB   lC
         ↓    ↓    ↓
first----A----B----C

So this sequence of commands:

$ git checkout lineB
$ git rebase master

is saying move the lineB branch on top of master.

...but it is already on top of master.

master would have to have some commits in its history that lineB does not have for the rebase command to have any work to do.

Comments