Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I rebase as one commit using Git

Tags:

git

rebase

squash

My history looks somewhat like this but times 10:

                i - j - e'- k - h'- l - m  feature-branch
              /
    a - b - c - d - e - f - g - h  master

(the apostrophes meaning cherry picks) I want to rebase to this:

                                  i - j - k - l - m  feature-branch
                                 / 
    a - b - c - d - e - f - g - h  master

I don't mind if the feature gets squashed into 1 commit. The main problem with a regular rebase is that it tries to rebase one commit at a time, and i have to fix and re-fix similar conflicts over and over.

All I want is to take the difference between the tip of my branch and the tip of master and apply those on top of master.

like image 206
ZMitton Avatar asked May 12 '15 17:05

ZMitton


2 Answers

This is actually quite easy.

  1. Merge master into feature-branch. You will solve all of your merge conflicts here at once. (I highly recommend stopping here.)

                i - j - e'- k - h'- l - m - n    feature-branch
              /                           /
    a - b - c - d - e - f - g - h --------       master
    
  2. Then, git reset --soft master. This will make it so that feature-branch points at master, but it will keep all of your changes in the index, ready to be committed.

                i - j - e'- k - h'- l - m - n    (orphaned)
              /                           /
    a - b - c - d - e - f - g - h --------       master, feature-branch
                                  \
                                    (index)
    
  3. git commit

                i - j - e'- k - h'- l - m - n    (orphaned)
              /                           /
    a - b - c - d - e - f - g - h --------       master
                                  \
                                    n'           feature-branch
    

The only purpose of #2 and #3 is to destroy the history of feature-branch. If you are certain you will never ever need that history, that's fine. But it seems like a waste to go to all this extra trouble just to delete an accurate record of what actually happened.

like image 169
Dietrich Epp Avatar answered Sep 28 '22 02:09

Dietrich Epp


I'm assuming e' and h' are cherry-picks of e and h, respectively. I'm also assuming that the conflicts appear when Git tries to apply e' and h', but not any of the other commits. Please correct me if I'm wrong.

You have a few options:

  • When git rebase drops to a prompt saying that it couldn't apply e' or h', run git rebase --skip to tell Git to skip that commit.

    Once the rebase is done, if you then want to squash the commits together into one:

    git reset --soft master
    git commit
    
  • Do an interactive rebase and tell Git to not apply e' and h':

    git checkout feature-branch
    git rebase -i master
    # Git will launch an editor containing an interactive rebase recipe:
    #   1. Delete the e' and h' lines.
    #   2. Optionally change the j through m lines to 'squash' if you
    #      want to squash all of those commits into one.
    #   3. Save the recipe and exit.
    
  • git rebase is an easier way to do a series of git cherry-pick commands. You can do these commands manually yourself:

    git checkout -b temp-branch master
    git cherry-pick i j k l m
    # optionally, if you want to squash i through m into a single commit:
    #   git reset --soft master
    #   git commit
    git checkout feature-branch
    git reset --hard temp-branch
    git branch -D temp-branch
    
like image 43
Richard Hansen Avatar answered Sep 28 '22 00:09

Richard Hansen