static void do_git_path(const struct worktree *wt, struct strbuf *buf, const char *fmt, va_list args) { int gitdir_len; strbuf_addstr(buf, get_worktree_git_dir(wt)); if (buf->len && !is_dir_sep(buf->buf[buf->len - 1])) strbuf_addch(buf, '/'); gitdir_len = buf->len; strbuf_vaddf(buf, fmt, args); adjust_git_path(buf, gitdir_len); strbuf_cleanup_path(buf); }
/* * note: this function should be able to detect shared symref even if * HEAD is temporarily detached (e.g. in the middle of rebase or * bisect). New commands that do similar things should update this * function as well. */ const struct worktree *find_shared_symref(const char *symref, const char *target) { const struct worktree *existing = NULL; struct strbuf path = STRBUF_INIT; struct strbuf sb = STRBUF_INIT; static struct worktree **worktrees; int i = 0; if (worktrees) free_worktrees(worktrees); worktrees = get_worktrees(); for (i = 0; worktrees[i]; i++) { struct worktree *wt = worktrees[i]; if (wt->is_bare) continue; if (wt->is_detached && !strcmp(symref, "HEAD")) { if (is_worktree_being_rebased(wt, target)) { existing = wt; break; } if (is_worktree_being_bisected(wt, target)) { existing = wt; break; } } strbuf_reset(&path); strbuf_reset(&sb); strbuf_addf(&path, "%s/%s", get_worktree_git_dir(wt), symref); if (parse_ref(path.buf, &sb, NULL)) { continue; } if (!strcmp(sb.buf, target)) { existing = wt; break; } } strbuf_release(&path); strbuf_release(&sb); return existing; }
static void mark_current_worktree(struct worktree **worktrees) { char *git_dir = absolute_pathdup(get_git_dir()); int i; for (i = 0; worktrees[i]; i++) { struct worktree *wt = worktrees[i]; const char *wt_git_dir = get_worktree_git_dir(wt); if (!fspathcmp(git_dir, absolute_path(wt_git_dir))) { wt->is_current = 1; break; } } free(git_dir); }
static void validate_no_submodules(const struct worktree *wt) { struct index_state istate = { NULL }; int i, found_submodules = 0; if (read_index_from(&istate, worktree_git_path(wt, "index"), get_worktree_git_dir(wt)) > 0) { for (i = 0; i < istate.cache_nr; i++) { struct cache_entry *ce = istate.cache[i]; if (S_ISGITLINK(ce->ce_mode)) { found_submodules = 1; break; } } } discard_index(&istate); if (found_submodules) die(_("working trees containing submodules cannot be moved or removed")); }
int replace_each_worktree_head_symref(const char *oldref, const char *newref) { int ret = 0; struct worktree **worktrees = get_worktrees(0); int i; for (i = 0; worktrees[i]; i++) { if (worktrees[i]->is_detached) continue; if (strcmp(oldref, worktrees[i]->head_ref)) continue; if (set_worktree_head_symref(get_worktree_git_dir(worktrees[i]), newref)) { ret = -1; error(_("HEAD of working tree %s is not updated"), worktrees[i]->path); } } free_worktrees(worktrees); return ret; }