Robert Hönig
Robert Hönig

Reputation: 683

How do I rebase a list of commits?

Say I have the commits

I want to do an interactive rebase for each of them. The only way I can think of doing this is typing git rebase -i 'commit_hash' for each commit and doing the rebases one by one.

Is there an easier way to rebase all at once, smt. like

git rebase -i 'commit_hash_1' 'commit_hash_2' 'commit_hash_3' ?

Upvotes: 7

Views: 27112

Answers (3)

Kasper van den Berg
Kasper van den Berg

Reputation: 9526

NOTE: This answer depends on capabilities of the text-editor opened by git rebase. I'm using vim for which it works.

Say we have a range of commits in branch my-branch on top of a revision (i.e. branch or tag) named my-branch-base.

  • a8d737b50 (my-branch)
  • bb8d6cc3c7
  • 79a2e5cc5
  • fec125378
  • 193cf566b
  • aa213lk321
  • f0j9123r9j
  • ea781de38
  • 61785bd55
  • 04428cafd (my-branch-base)

In this range there are some commits to edit:

  • bb8d6cc3c7
  • aa213lk321
  • f0j9123r9j

Perhaps they come from a file perhaps they come from a command (such as git log -G"MyFunction"). I'll show how to select them via a command.

Make a copy of your branch HEAD pre rebase
(because: you will have a backup in case your rebase does not work out as you intended; and, if you select commits to edit via git log, git needs a reference to them during the rebase):

git branch -c my-branch my-branch-prerebase

Then start the rebase:

git rebase --interactive my-branch-base

Opens your configured editor with:

pick a8d737b50 {commit msg}
pick bb8d6cc3c7 {commit msg}
pick 79a2e5cc5 {commit msg}
pick fec125378 {commit msg}
pick 193cf566b {commit msg}
pick aa213lk321 {commit msg}
pick f0j9123r9j {commit msg}
pick ea781de38 {commit msg}
pick 61785bd55 {commit msg}

Open a second buffer --in the editor started by git rebase-- with the output of the revision selection command or a the file with the hashes to edit.
In vim you can do
(note you need to specify my-branch-prerebase to git log, since HEAD now points to my-branch-base and git log would not select any applicable commit hashes.):

:vsplit
:enew
:r !git log --oneline -G"MyFunction" my-branch-prerebase

Change the (generated) list of revisions into a format that your editor can use as an expression to select lines to edit.
In vim you can do (in the right window)
(note: that \x selects hex-digits and OP's hashes contain non-hex digits suck as j and k, so OP might need \w; and, in my siuation git log --oneline produced 9 digit hash abbreviations, you might need a different length (the made-up example needs {9,10}:

:%s/\v(\x{7,9}).*\n/\1|/

The \n concatenates the lines to a single line.

In vim we copy this to a register and paste it later into the minibuffer via CTRL+r.

Return to the buffer with rebase actions. Search and replace 'pick' with 'edit' on the lines matching the selected commit hashes.
In vim:

:g/\vbb8d6cc3c7|aa213lk321|f0j9123r9j/ :s/pick/edit/

Save the list of rebase actions and discard the temporary buffer with the selected commit hashes. Close the editor. git rebase starts rebasing and stops on the marked commits.

Upvotes: 1

sensorario
sensorario

Reputation: 21698

Weel, if you have master branch and some-feature branch.

If someone updates master branch and you want to rebase you some-feature branch, ...

Just

git checkout some-feature
git rebase -i master

All the some-feature's commits are merged to master branch

Upvotes: 0

danglingpointer
danglingpointer

Reputation: 4920

This is the list of the commits you want to squash.

1. bb8d6cc3c7 <- This is the HEAD or latest commit
2. aa213lk321
3. f0j9123r9j

Command

git rebase -i HEAD~3 , if all above three commits in sequence

then you need to pick bb8d6cc3c7 and squash other two commits by entering s, it means squash.

if the commit is not in sequence then just do git rebase -i , this will open an editor and you pick one commit and squash other two commits on it.

Upvotes: 4

Related Questions