]> git.ipfire.org Git - thirdparty/git.git/commitdiff
Merge branch 'pc/lockfile-pid' into seen
authorJunio C Hamano <gitster@pobox.com>
Tue, 23 Dec 2025 03:19:57 +0000 (12:19 +0900)
committerJunio C Hamano <gitster@pobox.com>
Tue, 23 Dec 2025 03:19:57 +0000 (12:19 +0900)
Allow recording process ID of the process that holds the lock next
to a lockfile for diagnosis.

* pc/lockfile-pid:
  lockfile: add PID file for debugging stale locks

17 files changed:
1  2 
Documentation/config/core.adoc
apply.c
builtin/commit.c
builtin/credential-store.c
builtin/gc.c
cache-tree.c
commit-graph.c
compat/mingw.c
config.c
environment.c
lockfile.c
midx-write.c
odb.c
repository.c
sequencer.c
shallow.c
t/meson.build

Simple merge
diff --cc apply.c
Simple merge
Simple merge
Simple merge
diff --cc builtin/gc.c
Simple merge
diff --cc cache-tree.c
Simple merge
diff --cc commit-graph.c
Simple merge
diff --cc compat/mingw.c
Simple merge
diff --cc config.c
Simple merge
diff --cc environment.c
index b65b85a01f18cfd90a8f4d3ce6b187bf4f675826,0d1dfb525bb2ba4b5fb71b461daebf35144f4362..e7246596ddbe925d0df4684dff40c33bfdc6e286
@@@ -324,8 -325,80 +325,80 @@@ next_name
        return (current & ~negative) | positive;
  }
  
 -static int git_default_core_config(const char *var, const char *value,
 -                                 const struct config_context *ctx, void *cb)
+ static const struct lockfile_pid_component_name {
+       const char *name;
+       enum lockfile_pid_component component_bits;
+ } lockfile_pid_component_names[] = {
+       { "index", LOCKFILE_PID_INDEX },
+       { "config", LOCKFILE_PID_CONFIG },
+       { "refs", LOCKFILE_PID_REFS },
+       { "commit-graph", LOCKFILE_PID_COMMIT_GRAPH },
+       { "midx", LOCKFILE_PID_MIDX },
+       { "shallow", LOCKFILE_PID_SHALLOW },
+       { "gc", LOCKFILE_PID_GC },
+       { "other", LOCKFILE_PID_OTHER },
+       { "all", LOCKFILE_PID_ALL },
+ };
+ static enum lockfile_pid_component parse_lockfile_pid_components(const char *var,
+                                                                const char *string)
+ {
+       enum lockfile_pid_component current = LOCKFILE_PID_DEFAULT;
+       enum lockfile_pid_component positive = 0, negative = 0;
+       while (string) {
+               size_t len;
+               const char *ep;
+               int negated = 0;
+               int found = 0;
+               string = string + strspn(string, ", \t\n\r");
+               ep = strchrnul(string, ',');
+               len = ep - string;
+               if (len == 4 && !strncmp(string, "none", 4)) {
+                       current = LOCKFILE_PID_NONE;
+                       goto next_name;
+               }
+               if (*string == '-') {
+                       negated = 1;
+                       string++;
+                       len--;
+                       if (!len)
+                               warning(_("invalid value for variable %s"), var);
+               }
+               if (!len)
+                       break;
+               for (size_t i = 0; i < ARRAY_SIZE(lockfile_pid_component_names); ++i) {
+                       const struct lockfile_pid_component_name *n = &lockfile_pid_component_names[i];
+                       if (strncmp(n->name, string, len) || strlen(n->name) != len)
+                               continue;
+                       found = 1;
+                       if (negated)
+                               negative |= n->component_bits;
+                       else
+                               positive |= n->component_bits;
+               }
+               if (!found) {
+                       char *component = xstrndup(string, len);
+                       warning(_("ignoring unknown core.lockfilePid component '%s'"), component);
+                       free(component);
+               }
+ next_name:
+               string = ep;
+       }
+       return (current & ~negative) | positive;
+ }
 +int git_default_core_config(const char *var, const char *value,
 +                          const struct config_context *ctx, void *cb)
  {
        /* This needs a better name */
        if (!strcmp(var, "core.filemode")) {
diff --cc lockfile.c
Simple merge
diff --cc midx-write.c
index 66c125ccb0a189b286a7cbf7ae6e2b309044832e,8180334703883309ad4b700dbf2ceb49d40a3041..f4b419dc1a4352e7c3333d405b70e2451c83287b
@@@ -1553,8 -1308,9 +1553,9 @@@ static int write_midx_internal(struct w
        if (ctx.incremental) {
                struct strbuf lock_name = STRBUF_INIT;
  
 -              get_midx_chain_filename(source, &lock_name);
 +              get_midx_chain_filename(opts->source, &lock_name);
-               hold_lock_file_for_update(&lk, lock_name.buf, LOCK_DIE_ON_ERROR);
+               hold_lock_file_for_update(&lk, lock_name.buf, LOCK_DIE_ON_ERROR,
+                                         LOCKFILE_PID_MIDX);
                strbuf_release(&lock_name);
  
                incr = mks_tempfile_m(midx_name.buf, 0444);
diff --cc odb.c
index 838aa2e53a08d72090d721218d0db387e247247d,c98dba32e2b1405dc0161f292a5b516039770502..c2267a9a4d43cd6ab05ec688066d8f5f8a22c3a5
--- 1/odb.c
--- 2/odb.c
+++ b/odb.c
@@@ -257,37 -208,100 +257,38 @@@ static struct odb_source *odb_add_alter
        kh_value(odb->source_by_path, pos) = alternate;
  
        /* recursively add alternates */
 -      read_info_alternates(odb, alternate->path, depth + 1);
 -
 - error:
 -      strbuf_release(&tmp);
 -      strbuf_release(&pathbuf);
 -      return alternate;
 -}
 -
 -static const char *parse_alt_odb_entry(const char *string,
 -                                     int sep,
 -                                     struct strbuf *out)
 -{
 -      const char *end;
 -
 -      strbuf_reset(out);
 -
 -      if (*string == '#') {
 -              /* comment; consume up to next separator */
 -              end = strchrnul(string, sep);
 -      } else if (*string == '"' && !unquote_c_style(out, string, &end)) {
 -              /*
 -               * quoted path; unquote_c_style has copied the
 -               * data for us and set "end". Broken quoting (e.g.,
 -               * an entry that doesn't end with a quote) falls
 -               * back to the unquoted case below.
 -               */
 -      } else {
 -              /* normal, unquoted path */
 -              end = strchrnul(string, sep);
 -              strbuf_add(out, string, end - string);
 -      }
 -
 -      if (*end)
 -              end++;
 -      return end;
 -}
 -
 -static void link_alt_odb_entries(struct object_database *odb, const char *alt,
 -                               int sep, const char *relative_base, int depth)
 -{
 -      struct strbuf dir = STRBUF_INIT;
 -
 -      if (!alt || !*alt)
 -              return;
 -
 -      if (depth > 5) {
 +      odb_source_read_alternates(alternate, &sources);
 +      if (sources.nr && depth + 1 > 5) {
                error(_("%s: ignoring alternate object stores, nesting too deep"),
 -                              relative_base);
 -              return;
 -      }
 -
 -      while (*alt) {
 -              alt = parse_alt_odb_entry(alt, sep, &dir);
 -              if (!dir.len)
 -                      continue;
 -              link_alt_odb_entry(odb, dir.buf, relative_base, depth);
 -      }
 -      strbuf_release(&dir);
 -}
 -
 -static void read_info_alternates(struct object_database *odb,
 -                               const char *relative_base,
 -                               int depth)
 -{
 -      char *path;
 -      struct strbuf buf = STRBUF_INIT;
 -
 -      path = xstrfmt("%s/info/alternates", relative_base);
 -      if (strbuf_read_file(&buf, path, 1024) < 0) {
 -              warn_on_fopen_errors(path);
 -              free(path);
 -              return;
 +                    source);
 +      } else {
 +              for (size_t i = 0; i < sources.nr; i++)
 +                      odb_add_alternate_recursively(odb, sources.v[i], depth + 1);
        }
  
 -      link_alt_odb_entries(odb, buf.buf, '\n', relative_base, depth);
 -      strbuf_release(&buf);
 -      free(path);
 + error:
 +      strvec_clear(&sources);
 +      return alternate;
  }
  
 -void odb_add_to_alternates_file(struct object_database *odb,
 -                              const char *dir)
 +static int odb_source_write_alternate(struct odb_source *source,
 +                                    const char *alternate)
  {
        struct lock_file lock = LOCK_INIT;
 -      char *alts = repo_git_path(odb->repo, "objects/info/alternates");
 +      char *path = xstrfmt("%s/%s", source->path, "info/alternates");
        FILE *in, *out;
        int found = 0;
 +      int ret;
  
-       hold_lock_file_for_update(&lock, path, LOCK_DIE_ON_ERROR);
 -      hold_lock_file_for_update(&lock, alts, LOCK_DIE_ON_ERROR,
++      hold_lock_file_for_update(&lock, path, LOCK_DIE_ON_ERROR,
+                                 LOCKFILE_PID_OTHER);
        out = fdopen_lock_file(&lock, "w");
 -      if (!out)
 -              die_errno(_("unable to fdopen alternates lockfile"));
 +      if (!out) {
 +              ret = error_errno(_("unable to fdopen alternates lockfile"));
 +              goto out;
 +      }
  
 -      in = fopen(alts, "r");
 +      in = fopen(path, "r");
        if (in) {
                struct strbuf line = STRBUF_INIT;
  
diff --cc repository.c
Simple merge
diff --cc sequencer.c
Simple merge
diff --cc shallow.c
Simple merge
diff --cc t/meson.build
Simple merge