Phillip Susi wrote: > Isn't the whole purpose of using replace to avoid having to use > filter-branch, which throws out all of the existing commit records, and > creates an entirely new commit chain that is slightly modified? 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@xxxxxxxxxxxxxxx> 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 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html