Re: repo.or.cz wishes?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Theodore Tso <tytso@xxxxxxx> wrote:
> On Tue, Aug 28, 2007 at 12:10:59AM -0400, Shawn O. Pearce wrote:
> > Its what happens when you use `git clone --shared A B` and the
...
> This has been discussed before, and it wouldn't be *that* hard to have
> "git clone --shared" create a backpointer from B to A, so that
> "git-prune" could also search the B's refs and not prune anything that
> is in A which is reachable from heads in A and B.

Not if I already have a pointer from B to A's refs.  repo.or.cz
also has this same pointer:

	git clone --shared A B
	ln -s A/refs B/refs/forkee

If we then do the backpointer we'll get a circular loop between these
two repositories and the output of git-ls-remote will be horrid to
look at.  It will also be confusing when you push, as we'll try to
match "refs/forkee/refs/forker/refs/forkee/heads/master"... ;-)

The reason I (and repo.or.cz) create the pointer from B to A is
so that push and fetch can see that B already has the objects in
A and clients shouldn't transfer them, because B already has them.
 
> > At day-job I have a hard rule that you cannot even push into an A,
...
> Why don't you even allow people to push into A?  That should be
> safe....

Push new things yes.  Rewind a branch or delete a branch, no.
I actually don't allow pushing into A because it just doesn't make
sense in my particular environment for this particular class of A.
 
> > So it really comes down to a rule like the following:
...
> This is morally the same, but it makes the hardlink step easier (only
> one pack to link from A to B), and by using git-gc mit makes it
> conceptually easier for people to understand what's going on.
> 
> git --git-dir=A gc
> ln A/.git/objects/pack/* B/.git/objects
> git --git-dir=B gc --prune
> git --git-dir=A prune

No, it won't work.

The problem is that during the first `git --git-dir=A gc` call
you are deleting packfiles that may contain objects that B needs.
*poof*.  They are gone.  B cannot traverse its object list to gc
itself during the third command.  That's why you have to do the
hardlinking of *everything* stored in A (even if it is not reachable)
into B before you can gc A.

The shorter and safest approach is the following, but it will cost
a lot of disk space and IO while running:

  git --git-dir=B repack -a -d    ; # yes, really no -l !
  git --git-dir=A repack -a -d
  git --git-dir=B repack -a -d -l ; # yes, now use -l

The first repack of B will copy everything from A into B, so that
if the repack of A removes the object it will reside in B and B's
own repack can keep the object.  But if A still has the object then
B won't copy it during the final repack of B.

You have to use repack here and not gc as gc defaults to including
the -l flag.

-- 
Shawn.
-
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

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux