1

Say I have the following history :

commit A
[... list of commits]
commit R
[... list of commits]
commit Z

I would like to set R as the first commit and delete all those are before it but keep commit history from R to A. The result would be :

commit A
[... list of commits]
commit R

Is this possible ?

Komo
  • 2,043
  • 1
  • 22
  • 35
  • The contents of commit `R` include its `parent` line(s) that connect it to prior commits, so making an otherwise-equivalent commit that *is* a root commit (has no `parent` lines) will result in a new, different hash ID. As a consequence, every subsequent commit (down to `A`) will *also* need to be copied to a new, different commit (with different `parent` line(s)). Is that acceptable / desirable? – torek Jan 08 '17 at 09:49
  • Yes, new hashes are totally acceptable – Komo Jan 08 '17 at 09:51
  • 1
    In that case, you can use `git filter-branch` to delete all the earlier commits. There are several ways to set this up, but the easiest general method is to use `git replace` to make a copy of `R` that has no parents (read the man pages for `git replace`), then run `git filter-branch` with `--all`, and if there are annotated tags, `--tag-name-filter cat`. – torek Jan 08 '17 at 09:54
  • Note that filter-branch actually *copies* all the filtered commits (while obeying grafts/replacements), so the filtered repository has both old and new, but *cloning* the filtered repository will get you a clean "new only" copy. – torek Jan 08 '17 at 09:55
  • @torek thanks that worked. I did `git replace --graft hashOfR` then `git filter-branch -- --all` – Komo Jan 08 '17 at 17:03

1 Answers1

0

You can user git rebase:

git rebase -i HEAD~3

should give you something like:

pick somehash A
pick somehash R
pick somehash Z

# Commands:
#  p, pick = use commit
#  e, edit = use commit, but stop for amending
#  s, 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.
#

You can now simply move the commits in the order you want them to be.

The documentation includes examples and explanation on various things you can apply on your commits, read it for more details.

Maroun
  • 94,125
  • 30
  • 188
  • 241
  • I should have been clearer but there's actually many commits between A and R and between R and Z, I wanted to know if there is a way of doing that without `rebase -i` – Komo Jan 08 '17 at 09:36
  • Note that you might need to use the --root option. http://stackoverflow.com/questions/2246208/change-first-commit-of-project-with-git – Kev Jan 08 '17 at 09:42