How to git rebase -i for a range of commits?

15,767

Solution 1

You could always create a new branch with git checkout -b new_branch af39283, and then rebase that. However, if you want to include the later commits at some future point, there's no getting around rebasing them as well. The SHA1 for a commit depends on all its ancestor commits.

Solution 2

So, it's not entirely clear what you mean by "not including" the most recent commit, but when you do a rebase -i you're able to squash/re-order/reword/fixup/remove prior commits without having to do anything to the last commit. You're rewriting the history underneath it of course, so its diff will be re-applied and it will be a different commit object following the rebase, but since you haven't pushed this publicly (and you're rewriting the rest of it) that shouldn't matter much.

Share:
15,767

Related videos on Youtube

Dylan Valade
Author by

Dylan Valade

https://www.linkedin.com/in/dylan-valade/ PUMA Global E-Commerce Sungem

Updated on June 03, 2022

Comments

  • Dylan Valade
    Dylan Valade almost 2 years

    Can I squash a range of commits for a local feature/topic branch using rebase that does not include the most recent commit? This is for commits that I want to prepare before they get merged and pushed to a public repo.

    I was working quickly and made a bunch of minor changes with poor titles and descriptions that I want to squash into two or three separate logical commits with a great comments. Can I select a range of commits between 329aed9 and af39283 that could be at any point in this feature branch's short history?

    git rebase -i RANGE_START_COMMIT_ID RANGE_LAST_COMMIT_ID
    

    Thanks!

    • Cascabel
      Cascabel over 12 years
      If you're using vim (which Git does, by default), you can use visual block mode (ctrl-v) to change arbitrarily many picks to squashes at once.
    • Dylan Valade
      Dylan Valade over 12 years
      Thanks Jefromi. I finally figured out how to pick and squash using vim. For other beginners, run 'git rebase -i mybranch~5' where 5 is the number of most recent commits to handle. If you want a commit to stay as-is then leave its prefix as 'pick'. Otherwise change its line prefix from 'pick' to 'squash' and rebase will condense every 'squash' commit into the first commit labeled 'pick' above it. If you have 10 commits and you leave three as 'pick' and the rest as 'squash' then you'll get a result of three commits total after rebase. I'll post a screenshot showing how this works.
    • Cascabel
      Cascabel over 12 years
      Isn't that almost exactly what the help below the list of commits says?
    • Dylan Valade
      Dylan Valade over 12 years
      Yes but it's not readily apparent from the help that you can use pick to both leave some commits unchanged while modifying others in a single rebase. At least that was the disconnect for me and hopefully this helps others.
  • Dylan Valade
    Dylan Valade over 12 years
    Thanks for your help. "not including" meant that I wanted to make separate squashes but leave my most recent commit unchanged. The very last commit is good and I would like it to remain independent (not squashed with any others). Then there are groups of about 20 very small commits that can be condensed into a few squashed commits. In the end it's taking about 60 small commits and creating 4 reasonable ones for merging into a public repo.
  • Dylan Valade
    Dylan Valade over 12 years
    Karl, thanks for that tip. I didn't realize it was possible to generate a new branch up to a SHA but I tried it and liked it. If we are talking about creating four different squashes, then with this approach it seems that a new branch would be created for last three squashes. The original feature branch would be rebased as the first squash. Finally, each of the other three "git checkout -b new_branch SHA#" would get merged into the original feature branch to create a glorious perfect branch?
  • Karl Bielefeldt
    Karl Bielefeldt over 12 years
    Are you saying your desired end result is one branch with 3 squashed commits followed by your original commit? If that's the case, in the commit list that pops up when you do a rebase -i, you just change pick to reword for each of the first commits of your squashes, choose squash for everything else, and leave your untouched commit as pick.
  • Cascabel
    Cascabel over 12 years
    @Karl: You don't need to reword the first commits of squashes; Git automatically lets you edit them and provides the messages of all the squashed commits as a starting point.