1

Just as the title illustrates. I recently tried to run a git rebase command that had the reverse effect from what the Git pro's section on rebasing had. Maybe I interpreted it wrong, but its driving me crazy because what I thought was supposed to happen failed and I need to know what went wrong.

The section that I refer to is under More Interesting Rebases, particularly with the example when you rebase the server work branch onto the master branch. Git Rebasing.

enter image description here

The way how I interpreted was that the server work would be pasted on top of the master work, which is clearly what it happening based on the illustration.

I had two branches named OTWO-3196 (Capistrano configurations) and origin/orgs_phase_2 on my local machine. What I intended to do was to have the origin/orgs_phase_2 work rebase on top of my OTWO-3196 (Capistrano configurations) work. I typed into the terminal this command:

git rebase OTWO-3196(basebranch) origin/orgs_phase_2(topicbranch)

What I thought would place the orgs_phase_2 work on OTWO-3196 (Capistrano work) instead placed the OTWO-3196 (Capistrano work) onto orgs_phase_2. This was the exact reverse of what I wanted.

This command however worked:

git rebase origin/orgs_phase_2 OTWO-3196

This placed the work of origin/orgs_phase_2 onto OTWO-3196.

Did I interpret the command wrong? Is the book incorrect? What exactly happened? An extra pair of eyes would be helpful. Thanks.

jub0bs
  • 60,866
  • 25
  • 183
  • 186
Dan Rubio
  • 4,709
  • 10
  • 49
  • 106

1 Answers1

3

I don't know what you did, or think you did, but origin/orgs_phase_2 is a remote-tracking branch. Its only purpose is to indicate where the branch reference called orgs_phase_2 pointed to in the remote repo called origin the last time you communicated with the latter. The only way such a reference can move is via a fetch or a push. In particular, you can't rebase a remote-tracking branch.

Besides, the Pro Git book is correct. You have got the git-rebase syntax backwards. Git's rebase works as advertised in that book,

git rebase [basebranch] [topicbranch]

checks out the topic branch [...] for you and replays it onto the base branch [...]

and in the git-rebase man page,

Assume the following history exists and the current branch is "topic":

      A---B---C topic
     /
D---E---F---G master

From this point, the result of either of the following commands:

git rebase master
git rebase master topic

would be:

              A'--B'--C' topic
             /
D---E---F---G master

To fix ideas, here is a baby example that you can reproduce at home:

#!/bin/bash

# set things up
cd ~/Desktop
mkdir test
cd test
git init

# write an initial shopping list
printf "4 pears\n" > shopping.txt
printf "3 lemons\n" >> shopping.txt 
printf "1 stalk of celery\n" >> shopping.txt 
printf "4 bananas\n" >> shopping.txt 

# make a first commit on master
git add shopping.txt
git commit -m "add shopping list"

# modify the shopping list and make a second commit on master
sed -i '' 's/4 pears/4 apples/' shopping.txt 
git add shopping.txt
git commit -m "replace pears by apples"

# create and check out a new branch called "kidscominghome"
git checkout -b kidscominghome

# make two more commits on kidscominghome
printf "16 pots of yoghurt\n" >> shopping.txt
git add shopping.txt
git commit -m "add yoghurt"
printf "beer\n" >> shopping.txt 
git add shopping.txt
git commit -m "add beer"

# check out master, modify the file, and make one more commit
git checkout master
sed -i '' 's/stalk of celery/cauliflower/' shopping.txt 
git add shopping.txt
git commit -m "replace celery by cauliflower"

At this stage, the output of

git log --graph --decorate --oneline --all

should be

* 5a0e340 (HEAD, master) replace celery by cauliflower
| * d3d22d0 (kidscominghome) add beer
| * edd730d add yoghurt
|/  
* 7dc55b7 replace pears by apples
* 7079948 add shopping list

Here is a nicer-looking graph showing the same history:

enter image description here

Now, if you run

git rebase master kidscominghome

and then run the same git log command, you should see

* 2acf37d (HEAD, kidscominghome) add beer
* dfac4a8 add yoghurt
* 5a0e340 (master) replace celery by cauliflower
* 7dc55b7 replace pears by apples
* 7079948 add shopping list

Again, here is a nicer-looking graph showing the same history:

enter image description here

As advertised, the kidscominghome branch has been checked out, and the commits that were only reachable from kidcominghome have been replayed on top of master; not the other way around!

jub0bs
  • 60,866
  • 25
  • 183
  • 186
  • Hey @Jubobs, I have a followup question. So by following your example and running git log, am I suppose to see 5 commits under the master branch or kidscominghome? As it stands right now, I am able to see 5 commits for kidscominghome but only three for master. This is where I think I'm getting confused. If kidscominghome was rebased onto master, wouldn't the master branch show 5 commits? Can you help clarify this for me please. – Dan Rubio Aug 28 '14 at 15:20
  • Nevermind, I did figure it out. All I needed to do was to move master forward by running git merge so now master has caught up with kidscominghome. Thanks for clarifying that up with that example. The book was right after all. – Dan Rubio Aug 28 '14 at 15:33
  • @DanRubio Glad everything is alright. Don't beat yourself up about getting mixed up, though. I remember being confused by the syntax of `rebase`, at the beginning. However, experimenting with a then esoteric Git command in a dummy repository (as I do in my answer) is always good to fix ideas `:)` – jub0bs Aug 28 '14 at 15:37