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-id
without 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-ids
option to fast-export which will make it add a 'original-oid <hash>
' line to blob, commits, and tags.
It also teachesfast-import
to 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-parents
option
git filter-branch
has a nifty feature allowing you to rewrite, e.g. just the last 8 commits of a linear historygit filter-branch $OPTIONS HEAD~8..HEAD
If you try the same with
git fast-export
, you instead get a history of only 8 commits, withHEAD~7
being 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-parents
option which will causefast-export
to 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..master
will not include the commitmaster~5
and will makemaster~4
no longer have master{tilde}5 as a parent (though both the oldmaster~4
and newmaster~4
will have all the same files).Use
--reference-excluded-parents
to 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.