Merge branch 'nd/rewritten-ref-is-per-worktree'
authorJunio C Hamano <gitster@pobox.com>
Tue, 9 Apr 2019 17:14:23 +0000 (02:14 +0900)
committerJunio C Hamano <gitster@pobox.com>
Tue, 9 Apr 2019 17:14:23 +0000 (02:14 +0900)
"git rebase" uses the refs/rewritten/ hierarchy to store its
intermediate states, which inherently makes the hierarchy per
worktree, but it didn't quite work well.

* nd/rewritten-ref-is-per-worktree:
Make sure refs/rewritten/ is per-worktree
files-backend.c: reduce duplication in add_per_worktree_entries_to_dir()
files-backend.c: factor out per-worktree code in loose_fill_ref_dir()

1  2 
path.c
refs/files-backend.c
diff --combined path.c
index 03ab712839a7878e3d3b5d79c698f4e2bb29c8b1,a29f131c449214c341767de249fa985ca0af1577..25e97b8c3f76ce9246d8d985adba9777acd5f43c
--- 1/path.c
--- 2/path.c
+++ b/path.c
@@@ -115,10 -115,13 +115,13 @@@ static struct common_dir common_list[] 
        { 1, 1, 0, "logs" },
        { 1, 1, 1, "logs/HEAD" },
        { 0, 1, 1, "logs/refs/bisect" },
+       { 0, 1, 1, "logs/refs/rewritten" },
+       { 0, 1, 1, "logs/refs/worktree" },
        { 0, 1, 0, "lost-found" },
        { 0, 1, 0, "objects" },
        { 0, 1, 0, "refs" },
        { 0, 1, 1, "refs/bisect" },
+       { 0, 1, 1, "refs/rewritten" },
        { 0, 1, 1, "refs/worktree" },
        { 0, 1, 0, "remotes" },
        { 0, 1, 0, "worktrees" },
@@@ -385,7 -388,7 +388,7 @@@ static void adjust_git_path(const struc
                strbuf_splice(buf, 0, buf->len,
                              repo->index_file, strlen(repo->index_file));
        else if (dir_prefix(base, "objects"))
 -              replace_dir(buf, git_dir_len + 7, repo->objects->objectdir);
 +              replace_dir(buf, git_dir_len + 7, repo->objects->odb->path);
        else if (git_hooks_path && dir_prefix(base, "hooks"))
                replace_dir(buf, git_dir_len + 5, git_hooks_path);
        else if (repo->different_commondir)
diff --combined refs/files-backend.c
index ef053f716c300ec13a06a63119bc7e3a289d2494,3daf8e6dd0223258d7ef37f8003bfea17b11e39a..5848f32ef8f206f489416cd3cfe52d12cc54ad36
@@@ -180,8 -180,7 +180,8 @@@ static void files_reflog_path(struct fi
                break;
        case REF_TYPE_OTHER_PSEUDOREF:
        case REF_TYPE_MAIN_PSEUDOREF:
 -              return files_reflog_path_other_worktrees(refs, sb, refname);
 +              files_reflog_path_other_worktrees(refs, sb, refname);
 +              break;
        case REF_TYPE_NORMAL:
                strbuf_addf(sb, "%s/logs/%s", refs->gitcommondir, refname);
                break;
@@@ -214,6 -213,33 +214,33 @@@ static void files_ref_path(struct files
        }
  }
  
+ /*
+  * Manually add refs/bisect, refs/rewritten and refs/worktree, which, being
+  * per-worktree, might not appear in the directory listing for
+  * refs/ in the main repo.
+  */
+ static void add_per_worktree_entries_to_dir(struct ref_dir *dir, const char *dirname)
+ {
+       const char *prefixes[] = { "refs/bisect/", "refs/worktree/", "refs/rewritten/" };
+       int ip;
+       if (strcmp(dirname, "refs/"))
+               return;
+       for (ip = 0; ip < ARRAY_SIZE(prefixes); ip++) {
+               const char *prefix = prefixes[ip];
+               int prefix_len = strlen(prefix);
+               struct ref_entry *child_entry;
+               int pos;
+               pos = search_ref_dir(dir, prefix, prefix_len);
+               if (pos >= 0)
+                       continue;
+               child_entry = create_dir_entry(dir->cache, prefix, prefix_len, 1);
+               add_entry_to_dir(dir, child_entry);
+       }
+ }
  /*
   * Read the loose references from the namespace dirname into dir
   * (without recursing).  dirname must end with '/'.  dir must be the
@@@ -297,28 -323,7 +324,7 @@@ static void loose_fill_ref_dir(struct r
        strbuf_release(&path);
        closedir(d);
  
-       /*
-        * Manually add refs/bisect and refs/worktree, which, being
-        * per-worktree, might not appear in the directory listing for
-        * refs/ in the main repo.
-        */
-       if (!strcmp(dirname, "refs/")) {
-               int pos = search_ref_dir(dir, "refs/bisect/", 12);
-               if (pos < 0) {
-                       struct ref_entry *child_entry = create_dir_entry(
-                                       dir->cache, "refs/bisect/", 12, 1);
-                       add_entry_to_dir(dir, child_entry);
-               }
-               pos = search_ref_dir(dir, "refs/worktree/", 11);
-               if (pos < 0) {
-                       struct ref_entry *child_entry = create_dir_entry(
-                                       dir->cache, "refs/worktree/", 11, 1);
-                       add_entry_to_dir(dir, child_entry);
-               }
-       }
+       add_per_worktree_entries_to_dir(dir, dirname);
  }
  
  static struct ref_cache *get_loose_ref_cache(struct files_ref_store *refs)
@@@ -2254,7 -2259,8 +2260,7 @@@ static int split_head_update(struct ref
   * Note that the new update will itself be subject to splitting when
   * the iteration gets to it.
   */
 -static int split_symref_update(struct files_ref_store *refs,
 -                             struct ref_update *update,
 +static int split_symref_update(struct ref_update *update,
                               const char *referent,
                               struct ref_transaction *transaction,
                               struct string_list *affected_refnames,
@@@ -2448,7 -2454,7 +2454,7 @@@ static int lock_ref_for_update(struct f
                         * of processing the split-off update, so we
                         * don't have to do it here.
                         */
 -                      ret = split_symref_update(refs, update,
 +                      ret = split_symref_update(update,
                                                  referent.buf, transaction,
                                                  affected_refnames, err);
                        if (ret)