aboutsummaryrefslogtreecommitdiff
path: root/builtin/checkout.c
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2015-08-12 14:09:56 -0700
committerJunio C Hamano <gitster@pobox.com>2015-08-12 14:09:56 -0700
commit53860f03927fea9c46d64b556a06fffe4b46e41f (patch)
tree356d50e67d39bc96390d50a81c3976fb831c012f /builtin/checkout.c
parent7aa2da616208a51ec51ce3639fe6abd9631b74db (diff)
parent65f9b75dfe34a67cf4c6a8507f999c5710d36ba9 (diff)
downloadgit-53860f03927fea9c46d64b556a06fffe4b46e41f.tar.gz
git-53860f03927fea9c46d64b556a06fffe4b46e41f.tar.xz
Merge branch 'es/worktree-add-cleanup'
The "new-worktree-mode" hack in "checkout" that was added in nd/multiple-work-trees topic has been removed by updating the implementation of new "worktree add". * es/worktree-add-cleanup: (25 commits) Documentation/git-worktree: fix duplicated 'from' Documentation/config: mention "now" and "never" for 'expire' settings Documentation/git-worktree: fix broken 'linkgit' invocation checkout: drop intimate knowledge of newly created worktree worktree: populate via "git reset --hard" rather than "git checkout" worktree: avoid resolving HEAD unnecessarily worktree: make setup of new HEAD distinct from worktree population worktree: detect branch-name/detached and error conditions locally worktree: add_worktree: construct worktree-population command locally worktree: elucidate environment variables intended for child processes worktree: make branch creation distinct from worktree population worktree: add: suppress auto-vivication with --detach and no <branch> worktree: make --detach mutually exclusive with -b/-B worktree: introduce options container worktree: simplify new branch (-b/-B) option checking worktree: improve worktree setup message branch: publish die_if_checked_out() checkout: teach check_linked_checkout() about symbolic link HEAD checkout: check_linked_checkout: simplify symref parsing checkout: check_linked_checkout: improve "already checked out" aesthetic ...
Diffstat (limited to 'builtin/checkout.c')
-rw-r--r--builtin/checkout.c82
1 files changed, 6 insertions, 76 deletions
diff --git a/builtin/checkout.c b/builtin/checkout.c
index 9ff5ca4cb..e1403bec2 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -48,8 +48,6 @@ struct checkout_opts {
const char *prefix;
struct pathspec pathspec;
struct tree *source_tree;
-
- int new_worktree_mode;
};
static int post_checkout_hook(struct commit *old, struct commit *new,
@@ -509,7 +507,7 @@ static int merge_working_tree(const struct checkout_opts *opts,
topts.dir->flags |= DIR_SHOW_IGNORED;
setup_standard_excludes(topts.dir);
}
- tree = parse_tree_indirect(old->commit && !opts->new_worktree_mode ?
+ tree = parse_tree_indirect(old->commit ?
old->commit->object.sha1 :
EMPTY_TREE_SHA1_BIN);
init_tree_desc(&trees[0], tree->buffer, tree->size);
@@ -830,8 +828,7 @@ static int switch_branches(const struct checkout_opts *opts,
return ret;
}
- if (!opts->quiet && !old.path && old.commit &&
- new->commit != old.commit && !opts->new_worktree_mode)
+ if (!opts->quiet && !old.path && old.commit && new->commit != old.commit)
orphaned_commit_warning(old.commit, new->commit);
update_refs_for_switch(opts, &old, new);
@@ -896,71 +893,6 @@ static const char *unique_tracking_name(const char *name, unsigned char *sha1)
return NULL;
}
-static void check_linked_checkout(struct branch_info *new, const char *id)
-{
- struct strbuf sb = STRBUF_INIT;
- struct strbuf path = STRBUF_INIT;
- struct strbuf gitdir = STRBUF_INIT;
- const char *start, *end;
-
- if (id)
- strbuf_addf(&path, "%s/worktrees/%s/HEAD", get_git_common_dir(), id);
- else
- strbuf_addf(&path, "%s/HEAD", get_git_common_dir());
-
- if (strbuf_read_file(&sb, path.buf, 0) < 0 ||
- !skip_prefix(sb.buf, "ref:", &start))
- goto done;
- while (isspace(*start))
- start++;
- end = start;
- while (*end && !isspace(*end))
- end++;
- if (strncmp(start, new->path, end - start) || new->path[end - start] != '\0')
- goto done;
- if (id) {
- strbuf_reset(&path);
- strbuf_addf(&path, "%s/worktrees/%s/gitdir", get_git_common_dir(), id);
- if (strbuf_read_file(&gitdir, path.buf, 0) <= 0)
- goto done;
- strbuf_rtrim(&gitdir);
- } else
- strbuf_addstr(&gitdir, get_git_common_dir());
- die(_("'%s' is already checked out at '%s'"), new->name, gitdir.buf);
-done:
- strbuf_release(&path);
- strbuf_release(&sb);
- strbuf_release(&gitdir);
-}
-
-static void check_linked_checkouts(struct branch_info *new)
-{
- struct strbuf path = STRBUF_INIT;
- DIR *dir;
- struct dirent *d;
-
- strbuf_addf(&path, "%s/worktrees", get_git_common_dir());
- if ((dir = opendir(path.buf)) == NULL) {
- strbuf_release(&path);
- return;
- }
-
- /*
- * $GIT_COMMON_DIR/HEAD is practically outside
- * $GIT_DIR so resolve_ref_unsafe() won't work (it
- * uses git_path). Parse the ref ourselves.
- */
- check_linked_checkout(new, NULL);
-
- while ((d = readdir(dir)) != NULL) {
- if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
- continue;
- check_linked_checkout(new, d->d_name);
- }
- strbuf_release(&path);
- closedir(dir);
-}
-
static int parse_branchname_arg(int argc, const char **argv,
int dwim_new_local_branch_ok,
struct branch_info *new,
@@ -1168,14 +1100,14 @@ static int checkout_branch(struct checkout_opts *opts,
die(_("Cannot switch branch to a non-commit '%s'"),
new->name);
- if (new->path && !opts->force_detach && !opts->new_branch) {
+ if (new->path && !opts->force_detach && !opts->new_branch &&
+ !opts->ignore_other_worktrees) {
unsigned char sha1[20];
int flag;
char *head_ref = resolve_refdup("HEAD", 0, sha1, &flag);
if (head_ref &&
- (!(flag & REF_ISSYMREF) || strcmp(head_ref, new->path)) &&
- !opts->ignore_other_worktrees)
- check_linked_checkouts(new);
+ (!(flag & REF_ISSYMREF) || strcmp(head_ref, new->path)))
+ die_if_checked_out(new->path);
free(head_ref);
}
@@ -1239,8 +1171,6 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
argc = parse_options(argc, argv, prefix, options, checkout_usage,
PARSE_OPT_KEEP_DASHDASH);
- opts.new_worktree_mode = getenv("GIT_CHECKOUT_NEW_WORKTREE") != NULL;
-
if (conflict_style) {
opts.merge = 1; /* implied */
git_xmerge_config("merge.conflictstyle", conflict_style, NULL);