Re: [PATCH/POC 3/7] setup.c: add split-repo support to .git files

4 messages, 3 authors, 2016-06-15 · open the first message on its own page

Re: [PATCH/POC 3/7] setup.c: add split-repo support to .git files

From: Junio C Hamano <hidden>
Date: 2016-06-15 22:59:27

Nguyễn Thái Ngọc Duy  [off-list ref] writes:
If a .git file contains

gitsuper: <path>
gitdir: <id>

then we set GIT_SUPER_DIR to <path> and GIT_DIR to
$GIT_SUPER_DIR/repos/<id>.
I initially thought: "what is with that complexity? isn't it just
the matter of replacing 'gitdir: <path>' with 'gitsuper: <path>'
stored in the file .git???"

Until I realized that there is nowhere to keep per-workdir data if
we only had .git as a pointer, and that is why you have that <id>
thing.  It would have helped me avoid that confusion if the above
description was followed by:

    The latter, $GIT_SUPER_DIR/repos/<id>, is a directory,
    underneath which per-work-dir items like index, HEAD, logs/HEAD
    (what else?) reside.

or something like that.  And $GIT_SUPER_DIR/repos/*/HEAD, especially
when they are detached, plus $GIT_SUPER_DIR/repos/*/index, will work
as the starting point of object reachability scanning when running
repack, fsck, etc.

A few more random thoughts...

 - Reusing "gitdir:" for this purpose is not advisable; use a
   different name.  This <id> is used to identify a workdir, so
   perhaps "gitworkdir: <id>" might be a better name;

 - Do we want to record where the working tree directory is in
   $GIT_SUPER_DIR/repos/<id> somewhere?  Would it help to have such
   a record?

 - How would this interact with core.worktree in .git/config of that
   "super" repository?

Re: [PATCH/POC 3/7] setup.c: add split-repo support to .git files

From: Jonathan Nieder <hidden>
Date: 2016-06-15 22:59:27

Junio C Hamano wrote:
 - Do we want to record where the working tree directory is in
   $GIT_SUPER_DIR/repos/<id> somewhere?  Would it help to have such
   a record?
That could be nice for the purpose of garbage collecting them.  I fear
that for users it is too tempting to remove a worktree with "rm -rf"
without considering the relationship from the parent repo that might
be making walking through all reflogs slower or holding on to objects
no one cares about any more.

I imagine it would work like this:

 1. At worktree creation time, full path to the working tree directory
    is stored in $GIT_SUPER_DIR/repos/<id>.

 2. "git gc" notices that the worktree is missing and writes a file
    under $GIT_SUPER_DIR/repos/<id> with a timestamp, saying so.

 3. If the worktree still hasn't existed for a month, "git gc" deletes
    the corresponding $GIT_SUPER_DIR/repos/<id> directory.

Problems:

 * What if I move my worktree with "mv"?  Then I still need the
   corresponding $GIT_SUPER_DIR/repos/<id> directory, and nobody told
   the GIT_SUPER_DIR about it.

 * What if my worktree is on removable media (think "network
   filesystem") and has just been temporarily unmounted instead of
   deleted?

So maybe it would be nicer to:

  i. When the worktree is on the same filesystem, keep a *hard link* to
     some file in the worktree (e.g., the .git file).  If the link count
     goes down, it is safe to remove the $GIT_SUPER_DIR/repos/<id>
     directory.

 ii. When the worktree is on another filesystem, always keep
     $GIT_SUPER_DIR/repos/<id> unless the user decides to manually
     remove it.  Provide documentation or a command to list basic
     information about $GIT_SUPER_DIR/repos directories (path to
     worktree, what branch they're on, etc).

(i) doesn't require any futureproofing.  As soon as someone wants it,
they can implement the check and fall back to (ii) for worktrees
without the magic hard link.

(ii) would benefit from recording the working tree directory as a
possibly unreliable, human-friendly reminder.
 - How would this interact with core.worktree in .git/config of that
   "super" repository?
Eek.

Thanks,
Jonathan

Re: [PATCH/POC 3/7] setup.c: add split-repo support to .git files

From: Duy Nguyen <hidden>
Date: 2016-06-15 22:59:27

On Sat, Dec 14, 2013 at 3:43 AM, Jonathan Nieder [off-list ref] wrote:
Junio C Hamano wrote:
quoted
 - Do we want to record where the working tree directory is in
   $GIT_SUPER_DIR/repos/<id> somewhere?  Would it help to have such
   a record?
That could be nice for the purpose of garbage collecting them.  I fear
that for users it is too tempting to remove a worktree with "rm -rf"
without considering the relationship from the parent repo that might
be making walking through all reflogs slower or holding on to objects
no one cares about any more.

I imagine it would work like this:

 1. At worktree creation time, full path to the working tree directory
    is stored in $GIT_SUPER_DIR/repos/<id>.

 2. "git gc" notices that the worktree is missing and writes a file
    under $GIT_SUPER_DIR/repos/<id> with a timestamp, saying so.

 3. If the worktree still hasn't existed for a month, "git gc" deletes
    the corresponding $GIT_SUPER_DIR/repos/<id> directory.
I was thinking about doing something like this in "git prune" but
manually. Your idea sounds nicer.
Problems:

 * What if I move my worktree with "mv"?  Then I still need the
   corresponding $GIT_SUPER_DIR/repos/<id> directory, and nobody told
   the GIT_SUPER_DIR about it.
We could store $GIT_SUPER_DIR as relative path. That way if you move
it, you break it. When you fix it, hopefully you remember to fix the
link in repos/<id> too

Alternatively, the setup up code could be taught to verify that
$GIT_SUPER_DIR/repos/id/<backlink> actually points to the current
worktree. If not warn the user or something
 * What if my worktree is on removable media (think "network
   filesystem") and has just been temporarily unmounted instead of
   deleted?
Or we keep update a timestamp in repos/<id> to note the last used time
of this worktree. "gc" or "prune" would warn about unused repos after
a certain amount of time, do not remove them automatically. This could
be iii. to your list below.
So maybe it would be nicer to:

  i. When the worktree is on the same filesystem, keep a *hard link* to
     some file in the worktree (e.g., the .git file).  If the link count
     goes down, it is safe to remove the $GIT_SUPER_DIR/repos/<id>
     directory.
This can still break with updating by creating a new version, then
renaming it. Although I can't think why anybody (or anything) would
want to do that on .git file. This does not work on Windows though.
 ii. When the worktree is on another filesystem, always keep
     $GIT_SUPER_DIR/repos/<id> unless the user decides to manually
     remove it.  Provide documentation or a command to list basic
     information about $GIT_SUPER_DIR/repos directories (path to
     worktree, what branch they're on, etc).
And on Windows, a new partition means a new drive, so it works there too.
(i) doesn't require any futureproofing.  As soon as someone wants it,
they can implement the check and fall back to (ii) for worktrees
without the magic hard link.

(ii) would benefit from recording the working tree directory as a
possibly unreliable, human-friendly reminder.
quoted
 - How would this interact with core.worktree in .git/config of that
   "super" repository?
Eek.
I'll see if I can ignore core.worktree when $GIT_SUPER_DIR is set. If
not, ban this use case :)
-- 
Duy

Re: [PATCH/POC 3/7] setup.c: add split-repo support to .git files

From: Duy Nguyen <hidden>
Date: 2016-06-15 22:59:30

On Sat, Dec 14, 2013 at 3:43 AM, Jonathan Nieder [off-list ref] wrote:
Problems:

 * What if I move my worktree with "mv"?  Then I still need the
   corresponding $GIT_SUPER_DIR/repos/<id> directory, and nobody told
   the GIT_SUPER_DIR about it.

 * What if my worktree is on removable media (think "network
   filesystem") and has just been temporarily unmounted instead of
   deleted?

So maybe it would be nicer to:

  i. When the worktree is on the same filesystem, keep a *hard link* to
     some file in the worktree (e.g., the .git file).  If the link count
     goes down, it is safe to remove the $GIT_SUPER_DIR/repos/<id>
     directory.
Link count goes down to 1 if I move the worktree to a different
filesystem and it's not safe to remove $GIT_SUPER_DIR/repos/<id> in
this case, I think.
 ii. When the worktree is on another filesystem, always keep
     $GIT_SUPER_DIR/repos/<id> unless the user decides to manually
     remove it.  Provide documentation or a command to list basic
     information about $GIT_SUPER_DIR/repos directories (path to
     worktree, what branch they're on, etc).

(i) doesn't require any futureproofing.  As soon as someone wants it,
they can implement the check and fall back to (ii) for worktrees
without the magic hard link.

(ii) would benefit from recording the working tree directory as a
possibly unreliable, human-friendly reminder.
-- 
Duy
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help