tags:

views:

88

answers:

3

I've just rebased a feature branch onto another feature branch (in preparation for rebasing everything to the head of my master), and it involved quite a few tricky merge resolutions.

Is the rebase automatically saved as a commit somewhere?

Just where do those modifications live? I can't see anything in gitk, or git log --oneline.

(Same question for when I merge back my branch after rebasing.)

A: 

Yes, successful rebases and merges make commits. They only won't make a commit of there are conflicts that need resolving, but then the output of the rebase (or merge) will tell you that this has happened and how to resolve it.

For a rebase, you just need to resolve the conflicts in the index and then git rebase --continue.

For a merge, you need to make the commit (git commit), but the fact that it's a merge will be remembered and a suitable default commit message will be supplied for you to edit.

Charles Bailey
+1  A: 

Rebase is moving commits on top of another branch. If a commit that is moved causes merge conflict, this commit is changed to reflect merge resolution.

The purpose of rebase is make your commits look as if they were changes to the branch you rebase onto. So the most logical way is to incorporate merge conflicts into these commits. No additional commits is required thus.

Merge is different, because it's an explicit action of merging diverged branches together. No commits in each of branches is changed. Conflict resolution is reflected in the merge commit.

Pavel Shved
+1  A: 

In the old days (2006, before 1.5.3 and its user manual), git rebase was presented like so:

A special case of cherry-picking is if you want to move a whole branch to a newer "base" commit.
This is done by git-rebase.
You specify the branch to move (default HEAD) and where to move it to (no default), and:

  • git cherry-picks every patch out of that branch,
  • applies it on top of the target,
  • and moves the refs/heads/<branch> pointer to the newly created commits.

So by definition, commits will be made (and no commit need to be done)

A special case of rebase is when you want to divide your work, moving (and recreating new) commits.
From the same tutorial (as an illustration of not needing any further commit after a rebase):

Suppose you've mixed up development of two features in the current HEAD, a branch called "dev".

x-x-x-x  (master)
       \ 
        -f1a-f1b-f1c-f2a-f2b-f2c (dev, HEAD)

You want to divide them up into "dev1" and "dev2". Assuming that HEAD is a branch off master, then you can either look through

git log master..HEAD

or just get a raw list of the commits with

git rev-list master..HEAD

Either way, suppose you figure out a list of commits that you want in dev1 and create that branch:

git checkout -b dev1 master
for i in `cat commit_list`; do
    git-cherry-pick $i
done

        -f1a'-f1b'-f1c' (dev1, HEAD)
       /
x-x-x-x  (master)
       \ 
        -f1a-f1b-f1c-f2a-f2b-f2c (dev)

You can use the other half of the list you edited to generate the dev2 branch, but if you're not sure if you forgot something, or just don't feel like doing that manual work, then you can use git-rebase to do it for you.

git checkout -b dev2 dev    # Create dev2 branch
git-rebase --onto master dev1   # Subreact dev1 and rebase

This will find all patches that are in dev and not in dev1, apply them on top of master, and call the result dev2.

        -f1a'-f1b'-f1c' (dev1, HEAD)
       /
x-x-x-x  (master)
       \ 
        -f2a-f2b-f2c (dev2, HEAD)
VonC
Wow! that is mind-blowing, in both senses (amazingly powerful, and difficult to get my head round)
Benjol