]> git.ipfire.org Git - thirdparty/git.git/commitdiff
Merge branch 'ma/worktree-cleanups'
authorJunio C Hamano <gitster@pobox.com>
Mon, 5 Oct 2020 21:01:52 +0000 (14:01 -0700)
committerJunio C Hamano <gitster@pobox.com>
Mon, 5 Oct 2020 21:01:52 +0000 (14:01 -0700)
Code clean-up.

* ma/worktree-cleanups:
  worktree: use skip_prefix to parse target
  worktree: rename copy-pasted variable
  worktree: update renamed variable in comment
  worktree: inline `worktree_ref()` into its only caller
  wt-status: introduce wt_status_state_free_buffers()
  wt-status: print to s->fp, not stdout
  wt-status: replace sha1 mentions with oid

1  2 
ref-filter.c
worktree.c
worktree.h
wt-status.c

diff --cc ref-filter.c
Simple merge
diff --cc worktree.c
index 46a5fb844766a74afee9223354801f26b7e3a908,0b1252569775556337a29ccc579caec2ad942c43..f84ceae87d3847019c45c335f1015ff15b8bfe0e
@@@ -569,140 -562,6 +562,141 @@@ int other_head_refs(each_ref_fn fn, voi
                        break;
        }
        free_worktrees(worktrees);
+       strbuf_release(&refname);
        return ret;
  }
 +
 +/*
 + * Repair worktree's /path/to/worktree/.git file if missing, corrupt, or not
 + * pointing at <repo>/worktrees/<id>.
 + */
 +static void repair_gitfile(struct worktree *wt,
 +                         worktree_repair_fn fn, void *cb_data)
 +{
 +      struct strbuf dotgit = STRBUF_INIT;
 +      struct strbuf repo = STRBUF_INIT;
 +      char *backlink;
 +      const char *repair = NULL;
 +      int err;
 +
 +      /* missing worktree can't be repaired */
 +      if (!file_exists(wt->path))
 +              return;
 +
 +      if (!is_directory(wt->path)) {
 +              fn(1, wt->path, _("not a directory"), cb_data);
 +              return;
 +      }
 +
 +      strbuf_realpath(&repo, git_common_path("worktrees/%s", wt->id), 1);
 +      strbuf_addf(&dotgit, "%s/.git", wt->path);
 +      backlink = xstrdup_or_null(read_gitfile_gently(dotgit.buf, &err));
 +
 +      if (err == READ_GITFILE_ERR_NOT_A_FILE)
 +              fn(1, wt->path, _(".git is not a file"), cb_data);
 +      else if (err)
 +              repair = _(".git file broken");
 +      else if (fspathcmp(backlink, repo.buf))
 +              repair = _(".git file incorrect");
 +
 +      if (repair) {
 +              fn(0, wt->path, repair, cb_data);
 +              write_file(dotgit.buf, "gitdir: %s", repo.buf);
 +      }
 +
 +      free(backlink);
 +      strbuf_release(&repo);
 +      strbuf_release(&dotgit);
 +}
 +
 +static void repair_noop(int iserr, const char *path, const char *msg,
 +                      void *cb_data)
 +{
 +      /* nothing */
 +}
 +
 +void repair_worktrees(worktree_repair_fn fn, void *cb_data)
 +{
 +      struct worktree **worktrees = get_worktrees();
 +      struct worktree **wt = worktrees + 1; /* +1 skips main worktree */
 +
 +      if (!fn)
 +              fn = repair_noop;
 +      for (; *wt; wt++)
 +              repair_gitfile(*wt, fn, cb_data);
 +      free_worktrees(worktrees);
 +}
 +
 +static int is_main_worktree_path(const char *path)
 +{
 +      struct strbuf target = STRBUF_INIT;
 +      struct strbuf maindir = STRBUF_INIT;
 +      int cmp;
 +
 +      strbuf_add_real_path(&target, path);
 +      strbuf_strip_suffix(&target, "/.git");
 +      strbuf_add_real_path(&maindir, get_git_common_dir());
 +      strbuf_strip_suffix(&maindir, "/.git");
 +      cmp = fspathcmp(maindir.buf, target.buf);
 +
 +      strbuf_release(&maindir);
 +      strbuf_release(&target);
 +      return !cmp;
 +}
 +
 +/*
 + * Repair <repo>/worktrees/<id>/gitdir if missing, corrupt, or not pointing at
 + * the worktree's path.
 + */
 +void repair_worktree_at_path(const char *path,
 +                           worktree_repair_fn fn, void *cb_data)
 +{
 +      struct strbuf dotgit = STRBUF_INIT;
 +      struct strbuf realdotgit = STRBUF_INIT;
 +      struct strbuf gitdir = STRBUF_INIT;
 +      struct strbuf olddotgit = STRBUF_INIT;
 +      char *backlink = NULL;
 +      const char *repair = NULL;
 +      int err;
 +
 +      if (!fn)
 +              fn = repair_noop;
 +
 +      if (is_main_worktree_path(path))
 +              goto done;
 +
 +      strbuf_addf(&dotgit, "%s/.git", path);
 +      if (!strbuf_realpath(&realdotgit, dotgit.buf, 0)) {
 +              fn(1, path, _("not a valid path"), cb_data);
 +              goto done;
 +      }
 +
 +      backlink = xstrdup_or_null(read_gitfile_gently(realdotgit.buf, &err));
 +      if (err == READ_GITFILE_ERR_NOT_A_FILE) {
 +              fn(1, realdotgit.buf, _("unable to locate repository; .git is not a file"), cb_data);
 +              goto done;
 +      } else if (err) {
 +              fn(1, realdotgit.buf, _("unable to locate repository; .git file broken"), cb_data);
 +              goto done;
 +      }
 +
 +      strbuf_addf(&gitdir, "%s/gitdir", backlink);
 +      if (strbuf_read_file(&olddotgit, gitdir.buf, 0) < 0)
 +              repair = _("gitdir unreadable");
 +      else {
 +              strbuf_rtrim(&olddotgit);
 +              if (fspathcmp(olddotgit.buf, realdotgit.buf))
 +                      repair = _("gitdir incorrect");
 +      }
 +
 +      if (repair) {
 +              fn(0, gitdir.buf, repair, cb_data);
 +              write_file(gitdir.buf, "%s", realdotgit.buf);
 +      }
 +done:
 +      free(backlink);
 +      strbuf_release(&olddotgit);
 +      strbuf_release(&gitdir);
 +      strbuf_release(&realdotgit);
 +      strbuf_release(&dotgit);
 +}
diff --cc worktree.h
Simple merge
diff --cc wt-status.c
index 160d14970abed09ee14267307b537002ff8a5dec,4345eb1749794f62861137b3d438d2e7e9779919..7074bbdd53cc1141c75546ad6e009b5ac74a63c2
@@@ -1567,10 -1574,10 +1572,10 @@@ static void wt_status_get_detached_from
                return;
        }
  
 -      if (dwim_ref(cb.buf.buf, cb.buf.len, &oid, &ref) == 1 &&
 +      if (dwim_ref(cb.buf.buf, cb.buf.len, &oid, &ref, 1) == 1 &&
-           /* sha1 is a commit? match without further lookup */
+           /* oid is a commit? match without further lookup */
            (oideq(&cb.noid, &oid) ||
-            /* perhaps sha1 is a tag, try to dereference to a commit */
+            /* perhaps oid is a tag, try to dereference to a commit */
             ((commit = lookup_commit_reference_gently(r, &oid, 1)) != NULL &&
              oideq(&cb.noid, &commit->object.oid)))) {
                const char *from = ref;
@@@ -1848,8 -1862,8 +1860,8 @@@ static void wt_shortstatus_unmerged(str
        } else {
                struct strbuf onebuf = STRBUF_INIT;
                const char *one;
 -              one = quote_path(it->string, s->prefix, &onebuf);
 +              one = quote_path(it->string, s->prefix, &onebuf, QUOTE_PATH_QUOTE_SP);
-               printf(" %s\n", one);
+               fprintf(s->fp, " %s\n", one);
                strbuf_release(&onebuf);
        }
  }
@@@ -1877,13 -1891,22 +1889,13 @@@ static void wt_shortstatus_status(struc
                const char *one;
  
                if (d->rename_source) {
 -                      one = quote_path(d->rename_source, s->prefix, &onebuf);
 -                      if (*one != '"' && strchr(one, ' ') != NULL) {
 -                              fputc('"', s->fp);
 -                              strbuf_addch(&onebuf, '"');
 -                              one = onebuf.buf;
 -                      }
 +                      one = quote_path(d->rename_source, s->prefix, &onebuf,
 +                                       QUOTE_PATH_QUOTE_SP);
-                       printf("%s -> ", one);
+                       fprintf(s->fp, "%s -> ", one);
                        strbuf_release(&onebuf);
                }
 -              one = quote_path(it->string, s->prefix, &onebuf);
 -              if (*one != '"' && strchr(one, ' ') != NULL) {
 -                      fputc('"', s->fp);
 -                      strbuf_addch(&onebuf, '"');
 -                      one = onebuf.buf;
 -              }
 +              one = quote_path(it->string, s->prefix, &onebuf, QUOTE_PATH_QUOTE_SP);
-               printf("%s\n", one);
+               fprintf(s->fp, "%s\n", one);
                strbuf_release(&onebuf);
        }
  }
@@@ -1896,9 -1919,9 +1908,9 @@@ static void wt_shortstatus_other(struc
        } else {
                struct strbuf onebuf = STRBUF_INIT;
                const char *one;
 -              one = quote_path(it->string, s->prefix, &onebuf);
 +              one = quote_path(it->string, s->prefix, &onebuf, QUOTE_PATH_QUOTE_SP);
                color_fprintf(s->fp, color(WT_STATUS_UNTRACKED, s), "%s", sign);
-               printf(" %s\n", one);
+               fprintf(s->fp, " %s\n", one);
                strbuf_release(&onebuf);
        }
  }