No. What documentation suggested that? Maybe it can be fixed.
The original purpose of grafts (the ideological ancestor of replacement refs) was to serve a very particular use case. Sit down by the fire, if you will, and...
Git had just came into existence and pack files did not exist yet. A full import of the Linux kernel history was possible but the result was enormous and not something ready to be imposed on all Linux contributors. So what can one do?
$ git show -s v2.6.12-rc2^0
commit 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2
Author: Linus Torvalds <torvalds@ppc970.osdl.org>
Date: Sat Apr 16 15:20:36 2005 -0700
Linux-2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it. Let it rip!
Fast forward three months, and there is discussion[1] about what to do with the historical git archive. A clever idea: teach git to _pretend_ that the historical archive is the parent to v2.6.12-rc2, so "git log --grep", "gitk", and so on work as they ought to.
So grafts were born. One of the nicest advantages of grafts is that they make it easy to do complex history surgery: make some grafts --- cut here, paste there --- and then run "git filter-branch" to make it permanent.
But grafts have a serious problem.
Transport machinery needs to ignore grafts --- otherwise, the two ends of a connection could have different ideas of the history preceding a commit, resulting in confusion and breakage. A fix to that was finally grafted on a few years later (see also [2]).
$ GIT_NOTES_REF=refs/remotes/charon/notes/full \
git log --grep=graft --grep=repack --all-match --no-merges
[...]
git repack: keep commits hidden by a graft
[...]
Archived-At: <http://thread.gmane.org/gmane.comp.version-control.git/123874>There is also the problem that grafts are too "raw": it is very easy to make a graft pointing to a nonexistent object, say. And meanwhile git has no native support for transfering grafts over the wire.
In that context there emerged the nicer (imho) refs/replace mechanism:
- reachability checking and transport machinery can treat them like
all other references --- no need for low-level tools to pay
attention to the artificial history;
- easy to script around with "git replace" and "git for-each-ref"
- can choose to fetch or not fetch with the usual
"git fetch repo refs/replace/*:refs/replace/*" syntax
Common applications:
- locally staging history changes that will later be made permanent
with "git filter-branch";
- grafting on additional (historical) history;
- replacing ancient broken commits with fixed ones, for use by "git
bisect".
Hope that helps, Jonathan
[1] http://thread.gmane.org/gmane.comp.version-control.git/6470/focus=6484 found with "git log --grep=graft --reverse" [2] http://thread.gmane.org/gmane.comp.version-control.git/37744/focus=37908