]> git.ipfire.org Git - thirdparty/git.git/blobdiff - branch.c
l10n: zh_CN v2.38.0 rounds 1 & 2
[thirdparty/git.git] / branch.c
index 4c8523c66ad07f956fc7ff8a81339d069dd586c8..d182756827fe5128292798b707a52aed25e7aa48 100644 (file)
--- a/branch.c
+++ b/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,83 @@ 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++];
+               struct string_list update_refs = STRING_LIST_INIT_DUP;
+
+               if (wt->is_bare)
+                       continue;
+
+               if (wt->head_ref) {
+                       old = strmap_put(&current_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(&current_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(&current_checked_out_branches,
+                                        ref.buf,
+                                        xstrdup(wt->path));
+                       free(old);
+                       strbuf_release(&ref);
+               }
+               wt_status_state_free_buffers(&state);
+
+               if (!sequencer_get_update_refs_state(get_worktree_git_dir(wt),
+                                                    &update_refs)) {
+                       struct string_list_item *item;
+                       for_each_string_list_item(item, &update_refs) {
+                               old = strmap_put(&current_checked_out_branches,
+                                                item->string,
+                                                xstrdup(wt->path));
+                               free(old);
+                       }
+                       string_list_clear(&update_refs, 1);
+               }
+       }
+
+       free_worktrees(worktrees);
+}
+
+const char *branch_checked_out(const char *refname)
+{
+       prepare_checked_out_branches();
+       return strmap_get(&current_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 +455,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 +463,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;
 }