v3 fixes all the things found in v2, deletes unused stuff and adds a
new patch 01/13 that renames str(n)cmp_icase to fspath(n)cmp.

Interdiff

diff --git a/branch.c b/branch.c
index 8e323d3..a5a8dcb 100644
--- a/branch.c
+++ b/branch.c
@@ -338,12 +338,12 @@ void die_if_checked_out(const char *branch, int 
ignore_current_worktree)
 {
        const struct worktree *wt;
 
-       wt = find_shared_symref("HEAD", branch, ignore_current_worktree);
-       if (wt) {
-               skip_prefix(branch, "refs/heads/", &branch);
-               die(_("'%s' is already checked out at '%s'"),
-                   branch, wt->path);
-       }
+       wt = find_shared_symref("HEAD", branch);
+       if (!wt || (ignore_current_worktree && wt->is_current))
+               return;
+       skip_prefix(branch, "refs/heads/", &branch);
+       die(_("'%s' is already checked out at '%s'"),
+           branch, wt->path);
 }
 
 int replace_each_worktree_head_symref(const char *oldref, const char *newref)
diff --git a/builtin/branch.c b/builtin/branch.c
index 3a2eceb..b488c3f 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -221,7 +221,7 @@ static int delete_branches(int argc, const char **argv, int 
force, int kinds,
 
                if (kinds == FILTER_REFS_BRANCHES) {
                        const struct worktree *wt =
-                               find_shared_symref("HEAD", name, 0);
+                               find_shared_symref("HEAD", name);
                        if (wt) {
                                error(_("Cannot delete branch '%s' "
                                        "checked out at '%s'"),
diff --git a/builtin/notes.c b/builtin/notes.c
index f154a69..c65b59a 100644
--- a/builtin/notes.c
+++ b/builtin/notes.c
@@ -852,7 +852,7 @@ static int merge(int argc, const char **argv, const char 
*prefix)
                update_ref(msg.buf, "NOTES_MERGE_PARTIAL", result_sha1, NULL,
                           0, UPDATE_REFS_DIE_ON_ERR);
                /* Store ref-to-be-updated into .git/NOTES_MERGE_REF */
-               wt = find_shared_symref("NOTES_MERGE_REF", default_notes_ref(), 
0);
+               wt = find_shared_symref("NOTES_MERGE_REF", default_notes_ref());
                if (wt)
                        die(_("A notes merge into %s is already in-progress at 
%s"),
                            default_notes_ref(), wt->path);
diff --git a/dir.c b/dir.c
index 996653b..f04bd3b 100644
--- a/dir.c
+++ b/dir.c
@@ -53,13 +53,12 @@ static enum path_treatment read_directory_recursive(struct 
dir_struct *dir,
        int check_only, const struct path_simplify *simplify);
 static int get_dtype(struct dirent *de, const char *path, int len);
 
-/* helper string functions with support for the ignore_case flag */
-int strcmp_icase(const char *a, const char *b)
+int fspathcmp(const char *a, const char *b)
 {
        return ignore_case ? strcasecmp(a, b) : strcmp(a, b);
 }
 
-int strncmp_icase(const char *a, const char *b, size_t count)
+int fspathncmp(const char *a, const char *b, size_t count)
 {
        return ignore_case ? strncasecmp(a, b, count) : strncmp(a, b, count);
 }
@@ -802,12 +801,12 @@ int match_basename(const char *basename, int basenamelen,
 {
        if (prefix == patternlen) {
                if (patternlen == basenamelen &&
-                   !strncmp_icase(pattern, basename, basenamelen))
+                   !fspathncmp(pattern, basename, basenamelen))
                        return 1;
        } else if (flags & EXC_FLAG_ENDSWITH) {
                /* "*literal" matching against "fooliteral" */
                if (patternlen - 1 <= basenamelen &&
-                   !strncmp_icase(pattern + 1,
+                   !fspathncmp(pattern + 1,
                                   basename + basenamelen - (patternlen - 1),
                                   patternlen - 1))
                        return 1;
@@ -844,7 +843,7 @@ int match_pathname(const char *pathname, int pathlen,
         */
        if (pathlen < baselen + 1 ||
            (baselen && pathname[baselen] != '/') ||
-           strncmp_icase(pathname, base, baselen))
+           fspathncmp(pathname, base, baselen))
                return 0;
 
        namelen = baselen ? pathlen - baselen - 1 : pathlen;
@@ -858,7 +857,7 @@ int match_pathname(const char *pathname, int pathlen,
                if (prefix > namelen)
                        return 0;
 
-               if (strncmp_icase(pattern, name, prefix))
+               if (fspathncmp(pattern, name, prefix))
                        return 0;
                pattern += prefix;
                patternlen -= prefix;
diff --git a/dir.h b/dir.h
index 301b737..e34d555 100644
--- a/dir.h
+++ b/dir.h
@@ -270,8 +270,8 @@ extern int remove_dir_recursively(struct strbuf *path, int 
flag);
 /* tries to remove the path with empty directories along it, ignores ENOENT */
 extern int remove_path(const char *path);
 
-extern int strcmp_icase(const char *a, const char *b);
-extern int strncmp_icase(const char *a, const char *b, size_t count);
+extern int fspathcmp(const char *a, const char *b);
+extern int fspathncmp(const char *a, const char *b, size_t count);
 extern int fnmatch_icase(const char *pattern, const char *string, int flags);
 
 /*
diff --git a/fast-import.c b/fast-import.c
index 9fc7093..339cd38 100644
--- a/fast-import.c
+++ b/fast-import.c
@@ -1512,7 +1512,7 @@ static int tree_content_set(
        t = root->tree;
        for (i = 0; i < t->entry_count; i++) {
                e = t->entries[i];
-               if (e->name->str_len == n && !strncmp_icase(p, 
e->name->str_dat, n)) {
+               if (e->name->str_len == n && !fspathncmp(p, e->name->str_dat, 
n)) {
                        if (!*slash1) {
                                if (!S_ISDIR(mode)
                                                && e->versions[1].mode == mode
@@ -1602,7 +1602,7 @@ static int tree_content_remove(
        t = root->tree;
        for (i = 0; i < t->entry_count; i++) {
                e = t->entries[i];
-               if (e->name->str_len == n && !strncmp_icase(p, 
e->name->str_dat, n)) {
+               if (e->name->str_len == n && !fspathncmp(p, e->name->str_dat, 
n)) {
                        if (*slash1 && !S_ISDIR(e->versions[1].mode))
                                /*
                                 * If p names a file in some subdirectory, and a
@@ -1669,7 +1669,7 @@ static int tree_content_get(
        t = root->tree;
        for (i = 0; i < t->entry_count; i++) {
                e = t->entries[i];
-               if (e->name->str_len == n && !strncmp_icase(p, 
e->name->str_dat, n)) {
+               if (e->name->str_len == n && !fspathncmp(p, e->name->str_dat, 
n)) {
                        if (!*slash1)
                                goto found_entry;
                        if (!S_ISDIR(e->versions[1].mode))
diff --git a/path.c b/path.c
index c421d37..8fdd187 100644
--- a/path.c
+++ b/path.c
@@ -466,16 +466,6 @@ const char *worktree_git_path(const struct worktree *wt, 
const char *fmt, ...)
        return pathname->buf;
 }
 
-char *worktree_git_pathdup(const struct worktree *wt, const char *fmt, ...)
-{
-       struct strbuf path = STRBUF_INIT;
-       va_list args;
-       va_start(args, fmt);
-       do_git_path(wt, &path, fmt, args);
-       va_end(args);
-       return strbuf_detach(&path, NULL);
-}
-
 static void do_submodule_path(struct strbuf *buf, const char *path,
                              const char *fmt, va_list args)
 {
diff --git a/sha1_file.c b/sha1_file.c
index d0f2aa0..ea6381b 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -301,7 +301,7 @@ static int link_alt_odb_entry(const char *entry, const char 
*relative_base,
                        return -1;
                }
        }
-       if (!strcmp_icase(ent->base, normalized_objdir)) {
+       if (!fspathcmp(ent->base, normalized_objdir)) {
                free(ent);
                return -1;
        }
diff --git a/worktree.c b/worktree.c
index 8a3d394..4817d60 100644
--- a/worktree.c
+++ b/worktree.c
@@ -151,14 +151,32 @@ done:
        return worktree;
 }
 
+static void mark_current_worktree(struct worktree **worktrees)
+{
+       struct strbuf git_dir = STRBUF_INIT;
+       struct strbuf path = STRBUF_INIT;
+       int i;
+
+       strbuf_addstr(&git_dir, absolute_path(get_git_dir()));
+       for (i = 0; worktrees[i]; i++) {
+               struct worktree *wt = worktrees[i];
+               strbuf_addstr(&path, absolute_path(get_worktree_git_dir(wt)));
+               wt->is_current = !fspathcmp(git_dir.buf, path.buf);
+               strbuf_reset(&path);
+               if (wt->is_current)
+                       break;
+       }
+       strbuf_release(&git_dir);
+       strbuf_release(&path);
+}
+
 struct worktree **get_worktrees(void)
 {
        struct worktree **list = NULL;
-       struct strbuf git_dir = STRBUF_INIT;
        struct strbuf path = STRBUF_INIT;
        DIR *dir;
        struct dirent *d;
-       int i, counter = 0, alloc = 2;
+       int counter = 0, alloc = 2;
 
        list = xmalloc(alloc * sizeof(struct worktree *));
 
@@ -184,17 +202,7 @@ struct worktree **get_worktrees(void)
        ALLOC_GROW(list, counter + 1, alloc);
        list[counter] = NULL;
 
-       strbuf_addstr(&git_dir, absolute_path(get_git_dir()));
-       for (i = 0; i < counter; i++) {
-               struct worktree *wt = list[i];
-               strbuf_addstr(&path, absolute_path(get_worktree_git_dir(wt)));
-               wt->is_current = !strcmp_icase(git_dir.buf, path.buf);
-               strbuf_reset(&path);
-               if (wt->is_current)
-                       break;
-       }
-       strbuf_release(&git_dir);
-       strbuf_release(&path);
+       mark_current_worktree(list);
        return list;
 }
 
@@ -241,9 +249,14 @@ int is_worktree_being_bisected(const struct worktree *wt,
        return found_rebase;
 }
 
+/*
+ * 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,
-                                         int ignore_current_worktree)
+                                         const char *target)
 {
        const struct worktree *existing = NULL;
        struct strbuf path = STRBUF_INIT;
@@ -258,9 +271,6 @@ const struct worktree *find_shared_symref(const char 
*symref,
        for (i = 0; worktrees[i]; i++) {
                struct worktree *wt = worktrees[i];
 
-               if (ignore_current_worktree && wt->is_current)
-                       continue;
-
                if (wt->is_detached && !strcmp(symref, "HEAD")) {
                        if (is_worktree_being_rebased(wt, target)) {
                                existing = wt;
diff --git a/worktree.h b/worktree.h
index d4a3534..1394909 100644
--- a/worktree.h
+++ b/worktree.h
@@ -36,26 +36,21 @@ extern void free_worktrees(struct worktree **);
 
 /*
  * Check if a per-worktree symref points to a ref in the main worktree
- * or any linked worktree, and return the path to the exising worktree
- * if it is. Returns NULL if there is no existing ref. The result
- * may be destroyed by the next call.
+ * or any linked worktree, and return the worktree that holds the ref,
+ * or NULL otherwise. The result may be destroyed by the next call.
  */
 extern const struct worktree *find_shared_symref(const char *symref,
-                                                const char *target,
-                                                int ignore_current_worktree);
+                                                const char *target);
 
 int is_worktree_being_rebased(const struct worktree *wt, const char *target);
 int is_worktree_being_bisected(const struct worktree *wt, const char *target);
 
 /*
- * Similar to git_path() and git_pathdup() but can produce paths for a
- * specified worktree instead of current one
+ * Similar to git_path() but can produce paths for a specified
+ * worktree instead of current one
  */
 extern const char *worktree_git_path(const struct worktree *wt,
                                     const char *fmt, ...)
        __attribute__((format (printf, 2, 3)));
-extern char *worktree_git_pathdup(const struct worktree *wt,
-                                 const char *fmt, ...)
-       __attribute__((format (printf, 2, 3)));
 
 #endif
diff --git a/wt-status.c b/wt-status.c
index 971e071..0032ef5 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -1410,7 +1410,7 @@ void wt_status_get_state(struct wt_status_state *state,
        if (!stat(git_path_merge_head(), &st)) {
                state->merge_in_progress = 1;
        } else if (wt_status_check_rebase(NULL, state)) {
-               ; /* all set */
+               ;               /* all set */
        } else if (!stat(git_path_cherry_pick_head(), &st) &&
                        !get_sha1("CHERRY_PICK_HEAD", sha1)) {
                state->cherry_pick_in_progress = 1;

  [01/13] dir.c: rename str(n)cmp_icase to fspath(n)cmp
  [02/13] path.c: add git_common_path() and strbuf_git_common_path()
  [03/13] worktree.c: store "id" instead of "git_dir"
  [04/13] worktree.c: make find_shared_symref() return struct worktree *
  [05/13] worktree.c: mark current worktree
  [06/13] path.c: refactor and add worktree_git_path()
  [07/13] wt-status.c: split rebase detection out of wt_status_get_state()
  [08/13] wt-status.c: make wt_status_check_rebase() work on any worktree
  [09/13] worktree.c: avoid referencing to worktrees[i] multiple times
  [10/13] worktree.c: check whether branch is rebased in another worktree
  [11/13] wt-status.c: split bisect detection out of wt_status_get_state()
  [12/13] worktree.c: check whether branch is bisected in another worktree
  [13/13] branch: do not rename a branch under bisect or rebase

Total 17 files changed, 344 insertions(+), 82 deletions(-)
--
Duy
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to