prune: strategies for linked checkouts
(alias R=$GIT_COMMON_DIR/worktrees/<id>) - linked checkouts are supposed to keep its location in $R/gitdir up to date. The use case is auto fixup after a manual checkout move. - linked checkouts are supposed to update mtime of $R/gitdir. If $R/gitdir's mtime is older than a limit, and it points to nowhere, worktrees/<id> is to be pruned. - If $R/locked exists, worktrees/<id> is not supposed to be pruned. If $R/locked exists and $R/gitdir's mtime is older than a really long limit, warn about old unused repo. - "git checkout --to" is supposed to make a hard link named $R/link pointing to the .git file on supported file systems to help detect the user manually deleting the checkout. If $R/link exists and its link count is greated than 1, the repo is kept. Helped-by: Marc Branchaud <marcnarc@xiplink.com> Helped-by: Eric Sunshine <sunshine@sunshineco.com> Helped-by: Johannes Sixt <j6t@kdbg.org> Signed-off-by: Marc Branchaud <marcnarc@xiplink.com> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:

committed by
Junio C Hamano

parent
529fef20cf
commit
23af91d102
@ -826,7 +826,7 @@ static int prepare_linked_checkout(const struct checkout_opts *opts,
|
||||
const char *path = opts->new_worktree, *name;
|
||||
struct stat st;
|
||||
struct child_process cp;
|
||||
int counter = 0, len;
|
||||
int counter = 0, len, ret;
|
||||
|
||||
if (!new->commit)
|
||||
die(_("no branch specified"));
|
||||
@ -857,11 +857,21 @@ static int prepare_linked_checkout(const struct checkout_opts *opts,
|
||||
if (mkdir(sb_repo.buf, 0777))
|
||||
die_errno(_("could not create directory of '%s'"), sb_repo.buf);
|
||||
|
||||
/*
|
||||
* lock the incomplete repo so prune won't delete it, unlock
|
||||
* after the preparation is over.
|
||||
*/
|
||||
strbuf_addf(&sb, "%s/locked", sb_repo.buf);
|
||||
write_file(sb.buf, 1, "initializing\n");
|
||||
|
||||
strbuf_addf(&sb_git, "%s/.git", path);
|
||||
if (safe_create_leading_directories_const(sb_git.buf))
|
||||
die_errno(_("could not create leading directories of '%s'"),
|
||||
sb_git.buf);
|
||||
|
||||
strbuf_reset(&sb);
|
||||
strbuf_addf(&sb, "%s/gitdir", sb_repo.buf);
|
||||
write_file(sb.buf, 1, "%s\n", real_path(sb_git.buf));
|
||||
write_file(sb_git.buf, 1, "gitdir: %s/worktrees/%s\n",
|
||||
real_path(get_git_common_dir()), name);
|
||||
/*
|
||||
@ -870,6 +880,7 @@ static int prepare_linked_checkout(const struct checkout_opts *opts,
|
||||
* value would do because this value will be ignored and
|
||||
* replaced at the next (real) checkout.
|
||||
*/
|
||||
strbuf_reset(&sb);
|
||||
strbuf_addf(&sb, "%s/HEAD", sb_repo.buf);
|
||||
write_file(sb.buf, 1, "%s\n", sha1_to_hex(new->commit->object.sha1));
|
||||
strbuf_reset(&sb);
|
||||
@ -885,7 +896,11 @@ static int prepare_linked_checkout(const struct checkout_opts *opts,
|
||||
memset(&cp, 0, sizeof(cp));
|
||||
cp.git_cmd = 1;
|
||||
cp.argv = opts->saved_argv;
|
||||
return run_command(&cp);
|
||||
ret = run_command(&cp);
|
||||
strbuf_reset(&sb);
|
||||
strbuf_addf(&sb, "%s/locked", sb_repo.buf);
|
||||
unlink_or_warn(sb.buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int git_checkout_config(const char *var, const char *value, void *cb)
|
||||
|
Reference in New Issue
Block a user