git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jeff King <peff@peff.net>
To: Simon Brenner <olsner@gmail.com>
Cc: git@vger.kernel.org
Subject: Re: [RFC] deprecating and eventually removing "git relink"?
Date: Mon, 14 Nov 2011 05:34:52 -0500	[thread overview]
Message-ID: <20111114103451.GA10847@sigill.intra.peff.net> (raw)
In-Reply-To: <CAD=rjTXgH+AivmK+zLurQVC+=p1UYqFy_p=wBF-1-TOQ=Cqjtw@mail.gmail.com>

On Mon, Nov 14, 2011 at 09:48:07AM +0100, Simon Brenner wrote:

> On Mon, Nov 14, 2011 at 7:06 AM, Miles Bader <miles@gnu.org> wrote:
> > It might be nice to have a mechanism where new objects would update
> > the _alternate_ rather than the object-store in the tree where the
> > command was run... then you could easily have a bunch of trees using a
> > central object store without needing to update the central store
> > occasionally by hand (and do gc in its "clients")...
> 
> This sounds like a nice way forward: replace/extend the current
> alternates system with support for a shared object store that is
> "intelligently" shared so that it can be gc:d based on all refs from
> all referring repositories. I imagine it would be something very much
> like a bare repository - except it wouldn't have any refs of its own,
> just a list of other repositories it should search for refs when
> GC:ing.

Yes, I think that is sensible. I'm not sure there is even any core git
code to be written. I think a wrapper that does the following would
probably work:

  1. Make new repo groups. E.g.:

       $ git share init foo

     which would be implemented something like:

       ROOT=$HOME/.git-share
       git init --bare $ROOT/$1

  2. Add a repo to a group.

       $ git share add foo

     implemented as:

       echo $ROOT/$1/objects >>.git/objects/info/alternates
       git --git-dir=$ROOT/$1 config --add share.child $PWD

  3. Compact a group.

       $ git share compact foo

     implemented as:

       # delete any existing refs
       git for-each-ref --format='%(refname)' | xargs git update-ref -d

       # now make new refs for each child
       n=1
       for dir in `git config --all share.child`; do
              if ! test -d $dir; then
                      echo >&2 "warning: $dir went away"
                      continue
              fi
              git fetch $dir refs/*:refs/$1/*
              n=$(($n + 1))
       done

       # and then repack/prune
       git repack -ad

       # and then gc each child, dropping anything in the share
       for dir in `git config --all share.child`; do
              git --git-dir=$dir gc
       done

I'm sure I'm missing a corner case or two, and of course there are
quoting issues and error handling missing. But the point is, I don't
think there's a real reason that the UI can't wrap the existing
mechanism, creating a momentary list of refs and pruning based on that.

One issue with this scheme (or most similar schemes) is that child repos
are uniquely identified by their directory name. In the absence of
alternates, it's perfectly reasonable to do:

  git init; hack hack hack; commit commit commit
  cd .. ; mv project new-project-name

but here it would break the shared repo's link to the child (which is
not just inconvenient, but dangerous, as we will not respect its refs
when pruning). Probably the "warning" above should actually error out
and force the user to say "yes, I deleted this child" or "no, I moved it
here".

You could try to be clever with assigning each child a UUID, but then
you have to resort to grepping the filesystem for the UUID to detect a
move. Which is complex and still not foolproof (i.e., if you don't find
it, is it because the repo was deleted, or because it got moved
somewhere that we didn't look?).

-Peff

  reply	other threads:[~2011-11-14 10:35 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-11-14  0:38 [RFC] deprecating and eventually removing "git relink"? Junio C Hamano
2011-11-14  6:06 ` Miles Bader
2011-11-14  6:27   ` Junio C Hamano
2011-11-14  9:03     ` Chris Packham
2011-11-14  8:48   ` Simon Brenner
2011-11-14 10:34     ` Jeff King [this message]
2011-11-14 20:18       ` Junio C Hamano
2011-11-14 20:25         ` Jeff King
2011-11-14 22:08           ` Junio C Hamano
2011-11-15  4:48             ` Miles Bader
2011-11-21 22:09       ` Phillip Susi
2011-11-21 22:19         ` Jeff King
2011-11-22  1:58           ` Phillip Susi
2011-11-14 10:24   ` Junio C Hamano
2011-11-15  4:40     ` Miles Bader

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20111114103451.GA10847@sigill.intra.peff.net \
    --to=peff@peff.net \
    --cc=git@vger.kernel.org \
    --cc=olsner@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).