How do I use 'git rebase -i' to rebase all changes in a branch?

Here’s an example:

>git status
# On branch master
nothing to commit (working directory clean)
>git checkout -b test-branch
>vi test.c
>git add test.c
>git commit -m "modified test.c"
>vi README
>git add README
>git commit -m "modified README"

Now I want to do a ‘git rebase -i‘ that will let me rebase all commits for this branch. Is there something like ‘git rebase -i HEAD~MASTER‘ or similar. I figure I could do ‘git rebase -i HEAD~2‘, but I really don’t want to have to count how many commits have been made. I could also do ‘git rebase -i sha1‘ but I don’t want to comb through git log to find the first commit sha1. Any ideas?

  • Git remote branches not listed
  • How to configure GIT on Windows 7 to push project to Google Code
  • Strategy for preventing or catching git history rewrite
  • Managing Git Users and Passwords
  • Git: always fetch only from one remote but always push to two remotes?
  • Can't push new git repository to github
  • BitBucket: Cross Reference between commits and issues not working
  • Temporarily lock a git repository
  • How can I find out what commit(s) git bisect would try next?
  • How to get msysgit to clone a repository where I want it to go?
  • Adding Git Commit Hashes to Email-ext Plugin in Jenkins
  • Commit to multiple branches at the same time with git
  • 8 Solutions collect form web for “How do I use 'git rebase -i' to rebase all changes in a branch?”

    Have you tried: git rebase -i master?

    Ok, I’m asuming the branch is called “feature” and it was branched from “master”.

    There’s this little git command called merge-base. It takes two commits and gives you the first common ancestor of both of those. So…

    git merge-base feature master
    

    …will give you the first common ancestor of those two commits. Guess what happens when you pass that commit to git rebase -i, like…

    git rebase -i `git merge-base feature master`
    

    Interactive rebase from the first common ancestor of both master and feature branch.
    Profit! 😉

    The issue with all provided solutions is, they do not allow you to rebase from the very first commit.
    If the first commit hash is XYZ and you do:

    git rebase -i XYZ
    

    You only rebase starting from the 2nd commit.

    If you want to rebase from the first commit you do:

    git rebase -i --root
    

    Use gitk (*nix), or gitx (OS X) or similar on other platforms, and have a look at which commit was the root of your branch. Then run:

    git rebase -i <the SHA hash of the root commit>
    

    For example, I have a repository that I inspected using gitx:

    gitx screencap http://img.skitch.com/20081213-mq7qpp5nhceksdhfx14rerjgyx.jpg

    Now that I know the root hash I can run this:

    git rebase -i 38965ed29d89a4136e47b688ca10b522b6bc335f
    

    And my editor pops up with this and I can rearrange/squash/whatever as I please.

    pick 50b2cff File 1 changes.
    pick 345df08 File 2 changes.
    pick 9894931 File 3 changes.
    pick 9a62b92 File 4 changes.
    pick 640b1f8 File 5 changes.
    pick 1c437f7 File 6 changes.
    pick b014597 File 7 changes.
    pick b1f52bc File 8 changes.
    pick 40ae0fc File 9 changes.
    
    # Rebase 38965ed..40ae0fc onto 38965ed
    #
    # Commands:
    #  pick = use commit
    #  edit = use commit, but stop for amending
    #  squash = use commit, but meld into previous commit
    #
    # If you remove a line here THAT COMMIT WILL BE LOST.
    # However, if you remove everything, the rebase will be aborted.
    #
    

    I’m sure there’s some magic way to convince git to figure out the root of the tree automatically, but I don’t know what it is.

    EDIT: That magic is this:

    git log master..other_feature | cat
    

    Which will show you all the commits on that branch, and piping to cat will disable the pager so you see the first commit immediately.

    Since Git v1.7.10, you can just run git rebase without argument, and it will find the fork point and rebase your local changes on the upstream branch.

    You need to have configured the upstream branch for this to work (i.e. git pull without argument should work).

    For more details, see the docs for git rebase:

    If is not specified, the upstream configured in
    branch..remote and branch..merge options will be used (see
    git-config[1] for details) and the –fork-point option is assumed. If
    you are currently not on any branch or if the current branch does not
    have a configured upstream, the rebase will abort.

    The problem with rebasing from a different branch

    The problem with git rebase -i master is that you may have merge conflicts that you don’t necessarily want to deal with at the moment, or you may fix a conflict in one commit, only to fix it again in another commit during the course of the rebase.

    The problem with rebasing from a known commit

    The whole problem here is that you have to know which commit you have to refer to, either by its SHA, or HEAD~x, etc. This is only a minor annoyance but it is an annoyance.

    The better way

    If you instead want to rebase all the commits in your current branch, since the most recent commit it shared with its parent branch, you can add the following alias to .gitconfig:

    rbi = !sh -c \"git rebase -i `git merge-base $1 HEAD`\" -
    

    Usage

    git rbi parentBranch
    

    How it works

    This alias is just a shell script, that is using an argument which refers to the parent branch. That argument is passed into git merge-base in order to determine the most recent shared commit between that branch, and the current branch.

    A general solution (if you don’t know the name of the upstream branch) is:

    git rebase -i @{upstream}
    

    Note that if your upstream (probably a tracking branch) has updated since you last rebased, you will pull in new commits from the upstream. If you don’t want to pull in new commits, use

    git rebase -i `git merge-base --all HEAD @{upstream}`
    

    but that is a bit of a mouthful.

    git rebase -i --onto @{u}... @{u}
    

    Interactive rebase starting from the single merge point of HEAD and its upstream including all commits in HEAD that are not in its upstream.

    In other words exactly what you want.

    Git Baby is a git and github fan, let's start git clone.