[dev] Fwd: Rebase vs. Merge

Michael M Slusarz slusarz at horde.org
Wed Jan 13 21:15:05 UTC 2010


Quoting Ben Klang <ben at alkaloid.net>:

> I can re-create the problem pretty easily, so it's probably a  
> user-education problem.  Here's what I did:
>
> 1) Create a local branch ("TestBranch") and push it up to the remote  
> server.  (To be sure my local branch is tracking the remote branch I  
> deleted the original branch and then explicitly told it to checkout  
> a copy of the remote-tracking branch).

Here's what we have:

o (master; origin/master; TestBranch; origin/TestBranch)

> 2) Make some changes to my checkout of the remote-tracking branch  
> and commit them.  My local (remote-tracking) branch is now one  
> commit ahead of upstream.

o (master; origin/master; origin/TestBranch)
  \
   A (TestBranch)

> 3) Something gets committed to origin/master.

o (master; origin/TestBranch) - B (origin/master)
  \
   A (TestBranch)

> 4) "git fetch" to pull in the changes.

o (master; origin/TestBranch) - B (origin/master)
  \
   A (TestBranch)

A 'fetch' doesn't do anything by itself.  It just downloads the commit  
objects to your local DB, but doesn't change any pointers.  You should  
be doing a git pull --rebase on your local master instead, which would  
result in this:

o (origin/TestBranch) - B (master; origin/master)
  \
   A (TestBranch)

> 5) "git rebase origin/master" to roll forward the changes to my  
> local branch.  This completes successfully.

If you did a git pull --rebase in #4, you have the following:

o (origin/TestBranch) - B (master; origin/master)
                          \
                           A (TestBranch)

In your example, nobody committed anything to origin/TestBranch in the  
meantime.  But if they did, you would need to use git pull --rebase to  
grab and incorporate these changes. (And you need to eventually use  
git pull --rebase anyway; see #6 below).

> 6) "git push" to send my now-rebased local branch changes up to the  
> server.  Here's where my problem begins.  > Git reports:
> $ git push
> To /Users/bklang/src/horde
>  ! [rejected]        TestBranch -> TestBranch (non-fast-forward)
> error: failed to push some refs to '/Users/bklang/src/horde'
> To prevent you from losing history, non-fast-forward updates were rejected
> Merge the remote changes before pushing again.  See the 'non-fast-forward'
> section of 'git push --help' for details.

See:
http://git.or.cz/gitwiki/GitFaq#Whywon.27t.22gitpush.22workafterIrebasedabranch.3F

Doing a git pull on the remote branch will update the pointer and will  
allow you to do a push.  The result should be:

o - B (master; origin/master)
      \
       A (TestBranch; origin/TestBranch)


Still confused on your description of duplicate messages in the commit  
history through git log.  I do not see duplicate commits on topic  
branches (i.e. doing a git log o..A in the above example would give me  
log entries for B and A).  AFAIK, the only way duplicate commits  
could/would appear is if you did a merge somewhere along the line  
instead of a rebase.

michael

-- 
___________________________________
Michael Slusarz [slusarz at horde.org]



More information about the dev mailing list