Re: CAREFUL! No more delta object support!
From: Linus Torvalds <torvalds@osdl.org>
Date: 2016-06-15 22:42:01
On Mon, 27 Jun 2005, Linus Torvalds wrote:
On Mon, 27 Jun 2005, Junio C Hamano wrote:quoted
Shouldn't feeding "git-rev-list --object" output plus handcrafted list of objects in 2.6.11 tree object to git-pack-objects just work???You could do that. And yes, we can add support for "tag" objects too (which the packing doesn't do at all right now. So this is not a "fundamental" problem, it's just a practical one right now.
Ok, I've added the logic to "git-rev-list --object" to handle arbitrary
object dependencies.
So you can do things like this, if you want to:
git-rev-list --object HEAD ^v2.6.11-tree
which basically generates the complete list of every object reachable from
HEAD, but not reachable from the v2.6.11 tree. It also understands about
tags, so if you do
git-rev-list --object v2.6.12 ^v2.6.11-tree
the end result will have the "v2.6.12" tag in it (along with all the
objects reachable from it, but not reachable from v2.6.11-tree).
What does this mean? It means that you can do a "push" from repository "a"
to repository "b" by doing
- in "b", do
refs_in_b=($(find .git/refs -type f | xargs cat))
- in "a" do
refs_in_a=($(find .git/refs -type f | xargs cat))
- then, in "a", do
git-rev-list "${refs_in_a[@]}" --not "${refs_in_b[@]}" |
git-pack-objects --stdout > push.pack
to generate the objects pack in "push.pack"
- then, in "b", do
git-unpack-objects < push.pack
and you now have moved over _all_ the objects that were referenced in "a",
but not in "b". Including tags etc. So after that last stage, when you've
unpacked the objects, the only thing left to do is to make the refs in "b"
point to the new references from "a" (which basically boils down to a
"cp", except it would be good to verify that the refs in "b" still have
the same values as they did before we did the object push).
Daniel (or anybody else), interested? Please?
Of course, you can do this one branch at a time, too, if you want to, but
the above was meant as an example of how you can actually do all the
branches in one single pack-file, which is a lot more efficient (if you do
it one branch at a time, you'll quite possible end up transferring objects
that are reachable in other branches multiple times, while the "all in one
go" thing will pack each object just once).
Now, have I actually _tested_ the above? Hell no. But all the heavy
lifting should now be done for doing an efficient "git push" that pushes
all branches in one go (or one at a time, it's your choice on how you end
up using git-rev-list).
Linus