I.e., I have:
root -- c1 -- c2 -- .. - c1000 -- c1001 -- c1002 -- .. -- c2000 -- top
and I want to have:
root = c1000 -- c1
I have found the below useful for creating new repos with a different root ( which is what I think you are asking when you say remove history before a commit):
git fast-export master~5..master | (cd ../newrepo.git && git init . && git fast-import && git checkout)
(you can do the above in the same repo too)
Easiest way is with a git graft. If you edit the file .git/info/grafts, you can put lines in the file of the format
[ref] [parent1] [parent2] ...
Any commits referenced on the left side are then treated as if the parents listed on the right are the parents of that commit. So you can insert a line like
c1000
and it will be treated as though it has no parents. This can then be "baked in stone" by running git-filter-branch.
Note that with Git 2.21 (Q1 2019, 7+ years later), git fast-export is more complete.
That means the solution based on git fast-export/import can now do more.
git fast-export master~5..master | \
(cd ../newrepo.git && git init . && git fast-import && git checkout)
See commit a965bb3, commit 25dd3e4, commit 530ca19, commit fdf31b6, commit cd13762, commit f129c42, commit 1f30c90, commit b93b81e, commit 4532be7, commit f55c979, commit 843b9e6 (16 Nov 2018) by Elijah Newren (newren).
(Merged by Junio C Hamano -- gitster -- in commit 4d59753, 04 Jan 2019)
fast-export: add a --show-original-ids option to show original names
Knowing the original names (hashes) of commits can sometimes enable post-filtering that would otherwise be difficult or impossible.
In particular, the desire to rewrite commit messages which refer to other prior commits (on top of whatever other filtering is being done) is very difficult without knowing the original names of each commit.In addition, knowing the original names (hashes) of blobs can allow filtering by
blob-idwithout requiring re-hashing the content of the blob, and is thus useful as a small optimization.Once we add original ids for both commits and blobs, we may as well add them for tags too for completeness.
Perhaps someone will have a use for them.This commit teaches a new
--show-original-idsoption to fast-export which will make it add a 'original-oid <hash>' line to blob, commits, and tags.
It also teachesfast-importto parse (and ignore) such lines.
The man page now shows:
--show-original-ids:
Add an extra directive to the output for commits and blobs,
original-oid <SHA1SUM>.
While such directives will likely be ignored by importers such asgit-fast-import, it may be useful for intermediary filters (e.g. for rewriting commit messages which refer to older commits, or for stripping blobs by id).
And:
fast-export: add--reference-excluded-parentsoption
git filter-branchhas a nifty feature allowing you to rewrite, e.g. just the last 8 commits of a linear historygit filter-branch $OPTIONS HEAD~8..HEADIf you try the same with
git fast-export, you instead get a history of only 8 commits, withHEAD~7being rewritten into a root commit.There are two alternatives:
- Don't use the negative revision specification, and when you're filtering the output to make modifications to the last 8 commits, just be careful to not modify any earlier commits somehow.
- First run '
git fast-export --export-marks=somefile HEAD~8', then run 'git fast-export --import-marks=somefile HEAD~8..HEAD'.Both are more error prone than I'd like (the first for obvious reasons; with the second option I have sometimes accidentally included too many revisions in the first command and then found that the corresponding extra revisions were not exported by the second command and thus were not modified as I expected).
Also, both are poor from a performance perspective.Add a new
--reference-excluded-parentsoption which will causefast-exportto refer to commits outside the specified rev-list-args range by their sha1sum.
Such a stream will only be useful in a repository which already contains the necessary commits (much like the restriction imposed when using--no-data).
The documentation now includes:
--reference-excluded-parents:By default, running a command such as
git fast-export master~5..masterwill not include the commitmaster~5and will makemaster~4no longer have master{tilde}5 as a parent (though both the oldmaster~4and newmaster~4will have all the same files).Use
--reference-excluded-parentsto instead have the the stream refer to commits in the excluded range of history by their sha1sum.
Note that the resulting stream can only be used by a repository which already contains the necessary parent commits.