From: Junio C Hamano Date: Tue, 23 Dec 2025 03:19:57 +0000 (+0900) Subject: Merge branch 'pc/lockfile-pid' into seen X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7e37fab8c052b36244bdb52efcbc2a3ac504447d;p=thirdparty%2Fgit.git Merge branch 'pc/lockfile-pid' into seen 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 --- 7e37fab8c052b36244bdb52efcbc2a3ac504447d diff --cc environment.c index b65b85a01f,0d1dfb525b..e7246596dd --- a/environment.c +++ b/environment.c @@@ -324,8 -325,80 +325,80 @@@ next_name return (current & ~negative) | positive; } + 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; + } + -static int git_default_core_config(const char *var, const char *value, - const struct config_context *ctx, void *cb) +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 midx-write.c index 66c125ccb0,8180334703..f4b419dc1a --- a/midx-write.c +++ b/midx-write.c @@@ -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 838aa2e53a,c98dba32e2..c2267a9a4d --- a/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;