4

I have a commit history over of 40 commits. Some of this commits are not necessary and are only there for no reason.

I would like to remove a range of unnecessary commits and at first I tried this one:

git rebase --onto <branch name>~<first commit number to remove> <branch name>~<first commit to be kept> <branch name>

Unfortunately this won't work. What I really want is to delete the very last commit in the log (the first one committed) until another one like the 10th from the last so in general to delete the last 10 commits.

I am not looking to rollback to that version, as these commits are not something useful and will lead to empty source folder.

Phrixus
  • 1,209
  • 2
  • 19
  • 36
  • Do the commits that you want to delete introduce *any* changes? – Shaun Luttin Feb 17 '15 at 17:00
  • Nothing at all! Is a new branch with old commits from other branch that has no reason to be in this branch. But this branch now contains some with changes.. – Phrixus Feb 17 '15 at 17:01
  • You can do a interactive rebase `git rebase -i HEAD~40' and then just remove the lines (commits) you don't whant. – Mathias Feb 17 '15 at 17:03
  • this will delete the last one? or will change the head to the last one? – Phrixus Feb 17 '15 at 17:05
  • possible duplicate of [Delete commits from a branch in Git](http://stackoverflow.com/questions/1338728/delete-commits-from-a-branch-in-git) – Andrew C Feb 17 '15 at 17:43

2 Answers2

3

You can use git rebase -i --root to rebase everything starting with the initial commit.

Let's say you had 11 commits that looked something like this:

* cf0bc41 - (HEAD, master) Faun: Eleven (2 seconds ago)
* b32d8cc - Faun: Ten (2 seconds ago)
* f789e49 - Faun: Nine (2 seconds ago)
* 780435e - Faun: Eight (2 seconds ago)
* 3c6b084 - Faun: Seven (2 seconds ago)
* fecce89 - Faun: Six (2 seconds ago)
* 0433dbe - Faun: Five (2 seconds ago)
* 8002cb7 - Faun: Four (2 seconds ago)
* 3439445 - Faun: Three (2 seconds ago)
* 38181f1 - Faun: Two (2 seconds ago)
* 9373809 - Faun: One (2 seconds ago)

If you want to remove the first 10 commits, just run git rebase -i --root, which will open something like the following in your editor:

pick 9373809 One
pick 38181f1 Two
pick 3439445 Three
pick 8002cb7 Four
pick 0433dbe Five
pick fecce89 Six
pick 3c6b084 Seven
pick 780435e Eight
pick f789e49 Nine
pick b32d8cc Ten
pick cf0bc41 Eleven

# Rebase cf0bc41 onto 0bd34c4

You can simply delete the lines of the commits that you want to delete. However, that will probably result in a conflict, as later commits most likely modified files you introduced with one of your earlier commits.

Also be aware that running this command will rewrite the SHAs for all commits, which might also cause you problems.

It's probably better to squash or fixup those initial commits. Leave the first one alone and change the word pick to squash or fixup. See the comments at the bottom of the interactive rebase for more information.

For example if you edit the interactive rebase look like this:

pick 9373809 One
fixup 38181f1 Two
fixup 3439445 Three
fixup 8002cb7 Four
fixup 0433dbe Five
fixup fecce89 Six
fixup 3c6b084 Seven
fixup 780435e Eight
fixup f789e49 Nine
fixup b32d8cc Ten
pick cf0bc41 Eleven

You'll end up with this git history:

* f8980bc - (HEAD, master) Faun: Eleven (0 seconds ago)
* 3d300e9 - Faun: One (0 seconds ago)
Faun
  • 614
  • 6
  • 17
  • 1
    Hmm I don't want to gain new problems just to delete some commits. So may is not good idea to delete the commits – Phrixus Feb 17 '15 at 17:17
  • 1
    Probably true, especially if you've pushed the repository to somewhere public. – Faun Feb 17 '15 at 17:20
  • 1
    I'd recommend reading a [tutorial](https://www.atlassian.com/git/tutorials/rewriting-history/git-rebase) on git rebase, because it's a very powerful tool, but also a very sharp one. – Faun Feb 17 '15 at 17:23
1

What you can do is to squash the first 10 commits into one commit. Here is an example that squashes five initial commits into one while preserving the rest of your history.

Warning: rewriting history will change SHA1s. It is not possible to prevent this. Don't rewrite the SHAs of public commits unless you've talked to your team first.

Original Log

> git log --online --decorate

f85179d (HEAD, master) ten
7de4071 nine
5c7a482 eight
9585035 seven
b41bffc six
d102f05 five
5a28cb9 four
6fc27c9 three
524b0c7 two
bb7e6ae one

Rebase everthing, which opens Notepad (or whatever commit editor you use.) Choose the commits that you want to squash together by the s option.

> git rebase -i --root

# this is notepad

pick bb7e6ae one
s 524b0c7 two
s 6fc27c9 three
s 5a28cb9 four
s d102f05 five
pick b41bffc six
pick 9585035 seven
pick 5c7a482 eight
pick 7de4071 nine
pick f85179d ten

After you save, this is the result of your log. Note that you have changed all the SHA1s.

> git log --oneline --decorate

6c63e02 (HEAD, master) ten
276cc7c nine
5248b0b eight
251f87a seven
a70d035 six
3529f1a Squash the five initial commits into one.
Community
  • 1
  • 1
Shaun Luttin
  • 133,272
  • 81
  • 405
  • 467