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")) {
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;