checkout: clean up half-prepared directories in --to mode
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:
parent
5883034c61
commit
3b8925c78b
@ -20,6 +20,7 @@
|
||||
#include "resolve-undo.h"
|
||||
#include "submodule.h"
|
||||
#include "argv-array.h"
|
||||
#include "sigchain.h"
|
||||
|
||||
static const char * const checkout_usage[] = {
|
||||
N_("git checkout [options] <branch>"),
|
||||
@ -823,6 +824,35 @@ static int switch_branches(const struct checkout_opts *opts,
|
||||
return ret || writeout_error;
|
||||
}
|
||||
|
||||
static char *junk_work_tree;
|
||||
static char *junk_git_dir;
|
||||
static int is_junk;
|
||||
static pid_t junk_pid;
|
||||
|
||||
static void remove_junk(void)
|
||||
{
|
||||
struct strbuf sb = STRBUF_INIT;
|
||||
if (!is_junk || getpid() != junk_pid)
|
||||
return;
|
||||
if (junk_git_dir) {
|
||||
strbuf_addstr(&sb, junk_git_dir);
|
||||
remove_dir_recursively(&sb, 0);
|
||||
strbuf_reset(&sb);
|
||||
}
|
||||
if (junk_work_tree) {
|
||||
strbuf_addstr(&sb, junk_work_tree);
|
||||
remove_dir_recursively(&sb, 0);
|
||||
}
|
||||
strbuf_release(&sb);
|
||||
}
|
||||
|
||||
static void remove_junk_on_signal(int signo)
|
||||
{
|
||||
remove_junk();
|
||||
sigchain_pop(signo);
|
||||
raise(signo);
|
||||
}
|
||||
|
||||
static int prepare_linked_checkout(const struct checkout_opts *opts,
|
||||
struct branch_info *new)
|
||||
{
|
||||
@ -859,8 +889,15 @@ static int prepare_linked_checkout(const struct checkout_opts *opts,
|
||||
strbuf_addf(&sb_repo, "%d", counter);
|
||||
}
|
||||
name = strrchr(sb_repo.buf, '/') + 1;
|
||||
|
||||
junk_pid = getpid();
|
||||
atexit(remove_junk);
|
||||
sigchain_push_common(remove_junk_on_signal);
|
||||
|
||||
if (mkdir(sb_repo.buf, 0777))
|
||||
die_errno(_("could not create directory of '%s'"), sb_repo.buf);
|
||||
junk_git_dir = xstrdup(sb_repo.buf);
|
||||
is_junk = 1;
|
||||
|
||||
/*
|
||||
* lock the incomplete repo so prune won't delete it, unlock
|
||||
@ -873,6 +910,7 @@ static int prepare_linked_checkout(const struct checkout_opts *opts,
|
||||
if (safe_create_leading_directories_const(sb_git.buf))
|
||||
die_errno(_("could not create leading directories of '%s'"),
|
||||
sb_git.buf);
|
||||
junk_work_tree = xstrdup(path);
|
||||
|
||||
strbuf_reset(&sb);
|
||||
strbuf_addf(&sb, "%s/gitdir", sb_repo.buf);
|
||||
@ -902,9 +940,19 @@ static int prepare_linked_checkout(const struct checkout_opts *opts,
|
||||
cp.git_cmd = 1;
|
||||
cp.argv = opts->saved_argv;
|
||||
ret = run_command(&cp);
|
||||
if (!ret) {
|
||||
is_junk = 0;
|
||||
free(junk_work_tree);
|
||||
free(junk_git_dir);
|
||||
junk_work_tree = NULL;
|
||||
junk_git_dir = NULL;
|
||||
}
|
||||
strbuf_reset(&sb);
|
||||
strbuf_addf(&sb, "%s/locked", sb_repo.buf);
|
||||
unlink_or_warn(sb.buf);
|
||||
strbuf_release(&sb);
|
||||
strbuf_release(&sb_repo);
|
||||
strbuf_release(&sb_git);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,12 @@ test_expect_success 'checkout --to an existing worktree' '
|
||||
test_must_fail git checkout --detach --to existing master
|
||||
'
|
||||
|
||||
test_expect_success 'checkout --to refuses to checkout locked branch' '
|
||||
test_must_fail git checkout --to zere master &&
|
||||
! test -d zere &&
|
||||
! test -d .git/worktrees/zere
|
||||
'
|
||||
|
||||
test_expect_success 'checkout --to a new worktree' '
|
||||
git rev-parse HEAD >expect &&
|
||||
git checkout --detach --to here master &&
|
||||
|
Loading…
Reference in New Issue
Block a user