Merge branch 'ds/branch-checked-out' into ds/rebase-update-ref
* ds/branch-checked-out: branch: drop unused worktrees variable fetch: stop passing around unused worktrees variable branch: fix branch_checked_out() leaks branch: use branch_checked_out() when deleting refs fetch: use new branch_checked_out() and add tests branch: check for bisects and rebases branch: add branch_checked_out() helper
This commit is contained in:
76
branch.c
76
branch.c
@ -10,6 +10,7 @@
|
||||
#include "worktree.h"
|
||||
#include "submodule-config.h"
|
||||
#include "run-command.h"
|
||||
#include "strmap.h"
|
||||
|
||||
struct tracking {
|
||||
struct refspec_item spec;
|
||||
@ -369,6 +370,70 @@ int validate_branchname(const char *name, struct strbuf *ref)
|
||||
return ref_exists(ref->buf);
|
||||
}
|
||||
|
||||
static int initialized_checked_out_branches;
|
||||
static struct strmap current_checked_out_branches = STRMAP_INIT;
|
||||
|
||||
static void prepare_checked_out_branches(void)
|
||||
{
|
||||
int i = 0;
|
||||
struct worktree **worktrees;
|
||||
|
||||
if (initialized_checked_out_branches)
|
||||
return;
|
||||
initialized_checked_out_branches = 1;
|
||||
|
||||
worktrees = get_worktrees();
|
||||
|
||||
while (worktrees[i]) {
|
||||
char *old;
|
||||
struct wt_status_state state = { 0 };
|
||||
struct worktree *wt = worktrees[i++];
|
||||
|
||||
if (wt->is_bare)
|
||||
continue;
|
||||
|
||||
if (wt->head_ref) {
|
||||
old = strmap_put(¤t_checked_out_branches,
|
||||
wt->head_ref,
|
||||
xstrdup(wt->path));
|
||||
free(old);
|
||||
}
|
||||
|
||||
if (wt_status_check_rebase(wt, &state) &&
|
||||
(state.rebase_in_progress || state.rebase_interactive_in_progress) &&
|
||||
state.branch) {
|
||||
struct strbuf ref = STRBUF_INIT;
|
||||
strbuf_addf(&ref, "refs/heads/%s", state.branch);
|
||||
old = strmap_put(¤t_checked_out_branches,
|
||||
ref.buf,
|
||||
xstrdup(wt->path));
|
||||
free(old);
|
||||
strbuf_release(&ref);
|
||||
}
|
||||
wt_status_state_free_buffers(&state);
|
||||
|
||||
if (wt_status_check_bisect(wt, &state) &&
|
||||
state.branch) {
|
||||
struct strbuf ref = STRBUF_INIT;
|
||||
strbuf_addf(&ref, "refs/heads/%s", state.branch);
|
||||
old = strmap_put(¤t_checked_out_branches,
|
||||
ref.buf,
|
||||
xstrdup(wt->path));
|
||||
free(old);
|
||||
strbuf_release(&ref);
|
||||
}
|
||||
wt_status_state_free_buffers(&state);
|
||||
}
|
||||
|
||||
free_worktrees(worktrees);
|
||||
}
|
||||
|
||||
const char *branch_checked_out(const char *refname)
|
||||
{
|
||||
prepare_checked_out_branches();
|
||||
return strmap_get(¤t_checked_out_branches, refname);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if a branch 'name' can be created as a new branch; die otherwise.
|
||||
* 'force' can be used when it is OK for the named branch already exists.
|
||||
@ -377,9 +442,7 @@ int validate_branchname(const char *name, struct strbuf *ref)
|
||||
*/
|
||||
int validate_new_branchname(const char *name, struct strbuf *ref, int force)
|
||||
{
|
||||
struct worktree **worktrees;
|
||||
const struct worktree *wt;
|
||||
|
||||
const char *path;
|
||||
if (!validate_branchname(name, ref))
|
||||
return 0;
|
||||
|
||||
@ -387,13 +450,10 @@ int validate_new_branchname(const char *name, struct strbuf *ref, int force)
|
||||
die(_("a branch named '%s' already exists"),
|
||||
ref->buf + strlen("refs/heads/"));
|
||||
|
||||
worktrees = get_worktrees();
|
||||
wt = find_shared_symref(worktrees, "HEAD", ref->buf);
|
||||
if (wt && !wt->is_bare)
|
||||
if ((path = branch_checked_out(ref->buf)))
|
||||
die(_("cannot force update the branch '%s' "
|
||||
"checked out at '%s'"),
|
||||
ref->buf + strlen("refs/heads/"), wt->path);
|
||||
free_worktrees(worktrees);
|
||||
ref->buf + strlen("refs/heads/"), path);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
Reference in New Issue
Block a user