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 teaches fast-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 as git-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 history
git filter-branch $OPTIONS HEAD~8..HEAD
If you try the same with git fast-export
, you instead get a history of
only 8 commits, with HEAD~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 cause fast-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 commit master~5
and will make master~4
no longer have master{tilde}5 as a parent (though both the old master~4
and new master~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.