diff options
author | Nguyễn Thái Ngọc Duy <pclouds@gmail.com> | 2014-11-30 15:24:48 +0700 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2014-12-01 11:00:17 -0800 |
commit | 23af91d102e1efaff33b77ab7746356835a3d600 (patch) | |
tree | 0746595338cd8933f368287199b26f8216ed2340 /builtin/checkout.c | |
parent | checkout: support checking out into a new working directory (diff) | |
download | tgif-23af91d102e1efaff33b77ab7746356835a3d600.tar.xz |
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>
Diffstat (limited to 'builtin/checkout.c')
-rw-r--r-- | builtin/checkout.c | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/builtin/checkout.c b/builtin/checkout.c index 797e14df41..645135a812 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -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) |