diff options
276 files changed, 2889 insertions, 1621 deletions
diff --git a/.cirrus.yml b/.cirrus.yml index 77346a4929..1fbdc2652b 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -9,7 +9,7 @@ freebsd_task: DEFAULT_TEST_TARGET: prove DEVELOPER: 1 freebsd_instance: - image_family: freebsd-13-2 + image_family: freebsd-13-4 memory: 2G install_script: pkg install -y gettext gmake perl5 diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 80b1668ebe..4abfbc3e20 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -9,6 +9,8 @@ workflow: test:linux: image: $image + tags: + - saas-linux-medium-amd64 variables: CUSTOM_PATH: "/custom" before_script: diff --git a/Documentation/RelNotes/2.46.2.txt b/Documentation/RelNotes/2.46.2.txt index 51471e5400..613386878d 100644 --- a/Documentation/RelNotes/2.46.2.txt +++ b/Documentation/RelNotes/2.46.2.txt @@ -9,3 +9,15 @@ It also reverts the "git patch-id" change that went into 2.46.1, as it seems to have got a regression reported (I haven't verified, but it is better to keep a known breakage than adding an unintended regression). + +Other than that, a handful of minor bugfixes are included. + + * In a few corner cases "git diff --exit-code" failed to report + "changes" (e.g., renamed without any content change), which has + been corrected. + + * Cygwin does have /dev/tty support that is needed by things like + single-key input mode. + + * The interpret-trailers command failed to recognise the end of the + message when the commit log ends in an incomplete line. diff --git a/Documentation/RelNotes/2.47.0.txt b/Documentation/RelNotes/2.47.0.txt index cae537422b..6100871ec5 100644 --- a/Documentation/RelNotes/2.47.0.txt +++ b/Documentation/RelNotes/2.47.0.txt @@ -145,6 +145,20 @@ Performance, Internal Implementation, Development Support etc. * The error messages from the test script checker have been improved. + * The convention to calling into built-in command implementation has + been updated to pass the repository, if known, together with the + prefix value. + + * "git apply" had custom buffer management code that predated before + use of strbuf got widespread, which has been updated to use strbuf, + which also plugged some memory leaks. + + * The reftable backend learned to more efficiently handle exclude + patterns while enumerating the refs. + + * CI updates. FreeBSD image has been updated to 13.4. + (merge 2eeb29702e cb/ci-freebsd-13-4 later to maint). + Fixes since v2.46 ----------------- @@ -240,17 +254,49 @@ Fixes since v2.46 * In a few corner cases "git diff --exit-code" failed to report "changes" (e.g., renamed without any content change), which has been corrected. - (merge 11591850dd rs/diff-exit-code-fix later to maint). * Cygwin does have /dev/tty support that is needed by things like single-key input mode. - (merge 39ba986b0e rj/cygwin-has-dev-tty later to maint). * The interpret-trailers command failed to recognise the end of the message when the commit log ends in an incomplete line. - (merge c02414a997 bl/trailers-and-incomplete-last-line-fix later to maint). + + * "git rebase --autostash" failed to resurrect the autostashed + changes when the command gets aborted after giving back control + asking for hlep in conflict resolution. + (merge bf6ab087d1 pw/rebase-autostash-fix later to maint). + + * The "imap-send" now allows to be compiled with NO_OPENSSL and + OPENSSL_SHA1 defined together. + (merge 997950a750 jk/no-openssl-with-openssl-sha1 later to maint). + + * The support to customize build options to adjust for older versions + and/or older systems for the interop tests has been improved. + (merge 22ef5f02a8 jk/interop-test-build-options later to maint). + + * Update the character width table for Unicode 16. + (merge 44dc651132 bb/unicode-width-table-16 later to maint). + + * In Git 2.39, Git.pm stopped working in a bare repository, which has + been corrected. + (merge d3edb0bdde jk/git-pm-bare-repo-fix later to maint). + + * When a remote-helper dies before Git writes to it, SIGPIPE killed + Git silently. We now explain the situation a bit better to the end + user in our error message. + (merge 6e7fac9bca jk/diag-unexpected-remote-helper-death later to maint). + + * A few usability fixes to "git jump" (in contrib/). + (merge 083b82544d jk/jump-quickfix-fixes later to maint). + + * "git diff --exit-code" ignored modified binary files, which has + been corrected. + (merge 9a41735af6 rs/diff-exit-code-binary later to maint). * Other code cleanup, docfix, build fix, etc. (merge be10ac7037 jc/mailinfo-header-cleanup later to maint). - (merge 9a36ea37ae jc/doc-skip-fetch-all-and-prefetch later to maint). (merge 4460e052e0 jc/range-diff-lazy-setup later to maint). + (merge 0627c58e7a ak/typofixes later to maint). + (merge 83799f1500 jk/t9001-deflake later to maint). + (merge e02cc08a88 ak/typofix-2.46-maint later to maint). + (merge 5c5d29e1c4 ps/ci-gitlab-upgrade later to maint). diff --git a/Documentation/config/sendemail.txt b/Documentation/config/sendemail.txt index 6a869d67eb..5ffcfc9f2a 100644 --- a/Documentation/config/sendemail.txt +++ b/Documentation/config/sendemail.txt @@ -30,6 +30,21 @@ sendemail.confirm:: in the linkgit:git-send-email[1] documentation for the meaning of these values. +sendemail.mailmap:: + If true, makes linkgit:git-send-email[1] assume `--mailmap`, + otherwise assume `--no-mailmap`. False by default. + +sendemail.mailmap.file:: + The location of a linkgit:git-send-email[1] specific augmenting + mailmap file. The default mailmap and `mailmap.file` are loaded + first. Thus, entries in this file take precedence over entries in + the default mailmap locations. See linkgit:gitmailmap[5]. + +sendemail.mailmap.blob:: + Like `sendemail.mailmap.file`, but consider the value as a reference + to a blob in the repository. Entries in `sendemail.mailmap.file` + take precedence over entries here. See linkgit:gitmailmap[5]. + sendemail.aliasesFile:: To avoid typing long email addresses, point this to one or more email aliases files. You must also supply `sendemail.aliasFileType`. diff --git a/Documentation/git-send-email.txt b/Documentation/git-send-email.txt index 2e6f1d63ae..bc3ef45acb 100644 --- a/Documentation/git-send-email.txt +++ b/Documentation/git-send-email.txt @@ -414,6 +414,12 @@ exists when 'git send-email' is asked to add it (especially note that Failure to do so may not produce the expected result in the recipient's MUA. +--[no-]mailmap:: + Use the mailmap file (see linkgit:gitmailmap[5]) to map all + addresses to their canonical real name and email address. Additional + mailmap data specific to git-send-email may be provided using the + `sendemail.mailmap.file` or `sendemail.mailmap.blob` configuration + values. Defaults to `sendemail.mailmap`. Administering ~~~~~~~~~~~~~ diff --git a/Documentation/technical/sparse-checkout.txt b/Documentation/technical/sparse-checkout.txt index fa0d01cbda..d968659354 100644 --- a/Documentation/technical/sparse-checkout.txt +++ b/Documentation/technical/sparse-checkout.txt @@ -287,7 +287,7 @@ everything behaves like a dense checkout with a few exceptions (e.g. branch checkouts and switches write fewer things, knowing the VFS will lazily write the rest on an as-needed basis). -Since there is no publically available VFS-related code for folks to try, +Since there is no publicly available VFS-related code for folks to try, the number of folks who can test such a usecase is limited. The primary reason to note the Behavior C usecase is that as we fix things diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN index ee71e9d8aa..38e920725c 100755 --- a/GIT-VERSION-GEN +++ b/GIT-VERSION-GEN @@ -1,7 +1,7 @@ #!/bin/sh GVF=GIT-VERSION-FILE -DEF_VER=v2.46.GIT +DEF_VER=v2.47.0-rc0 LF=' ' @@ -1356,6 +1356,7 @@ UNIT_TEST_PROGRAMS += t-reftable-basics UNIT_TEST_PROGRAMS += t-reftable-block UNIT_TEST_PROGRAMS += t-reftable-merged UNIT_TEST_PROGRAMS += t-reftable-pq +UNIT_TEST_PROGRAMS += t-reftable-reader UNIT_TEST_PROGRAMS += t-reftable-readwrite UNIT_TEST_PROGRAMS += t-reftable-record UNIT_TEST_PROGRAMS += t-reftable-stack @@ -1365,9 +1366,9 @@ UNIT_TEST_PROGRAMS += t-strcmp-offset UNIT_TEST_PROGRAMS += t-trailer UNIT_TEST_PROGRAMS += t-urlmatch-normalization UNIT_TEST_PROGS = $(patsubst %,$(UNIT_TEST_BIN)/%$X,$(UNIT_TEST_PROGRAMS)) -UNIT_TEST_OBJS = $(patsubst %,$(UNIT_TEST_DIR)/%.o,$(UNIT_TEST_PROGRAMS)) UNIT_TEST_OBJS += $(UNIT_TEST_DIR)/test-lib.o UNIT_TEST_OBJS += $(UNIT_TEST_DIR)/lib-oid.o +UNIT_TEST_OBJS += $(UNIT_TEST_DIR)/lib-reftable.o # xdiff and reftable libs may in turn depend on what is in libgit.a GITLIBS = common-main.o $(LIB_FILE) $(XDIFF_LIB) $(REFTABLE_LIB) $(LIB_FILE) @@ -2725,6 +2726,7 @@ OBJECTS += $(FUZZ_OBJS) OBJECTS += $(REFTABLE_OBJS) $(REFTABLE_TEST_OBJS) OBJECTS += $(UNIT_TEST_OBJS) OBJECTS += $(CLAR_TEST_OBJS) +OBJECTS += $(patsubst %,$(UNIT_TEST_DIR)/%.o,$(UNIT_TEST_PROGRAMS)) ifndef NO_CURL OBJECTS += http.o http-walker.o remote-curl.o @@ -3864,9 +3866,7 @@ $(FUZZ_PROGRAMS): %: %.o oss-fuzz/dummy-cmd-main.o $(GITLIBS) GIT-LDFLAGS -Wl,--allow-multiple-definition \ $(filter %.o,$^) $(filter %.a,$^) $(LIBS) $(LIB_FUZZING_ENGINE) -$(UNIT_TEST_PROGS): $(UNIT_TEST_BIN)/%$X: $(UNIT_TEST_DIR)/%.o \ - $(UNIT_TEST_DIR)/test-lib.o \ - $(UNIT_TEST_DIR)/lib-oid.o \ +$(UNIT_TEST_PROGS): $(UNIT_TEST_BIN)/%$X: $(UNIT_TEST_DIR)/%.o $(UNIT_TEST_OBJS) \ $(GITLIBS) GIT-LDFLAGS $(call mkdir_p_parent_template) $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) \ @@ -1,3 +1,5 @@ +#define USE_THE_REPOSITORY_VARIABLE + #include "git-compat-util.h" #include "alias.h" #include "config.h" @@ -37,7 +39,7 @@ char *alias_lookup(const char *alias) { struct config_alias_data data = { alias, NULL }; - read_early_config(config_alias_cb, &data); + read_early_config(the_repository, config_alias_cb, &data); return data.v; } @@ -46,7 +48,7 @@ void list_aliases(struct string_list *list) { struct config_alias_data data = { NULL, NULL, list }; - read_early_config(config_alias_cb, &data); + read_early_config(the_repository, config_alias_cb, &data); } void quote_cmdline(struct strbuf *buf, const char **argv) @@ -30,6 +30,7 @@ #include "path.h" #include "quote.h" #include "read-cache.h" +#include "repository.h" #include "rerere.h" #include "apply.h" #include "entry.h" @@ -277,13 +278,26 @@ struct line { * This represents a "file", which is an array of "lines". */ struct image { - char *buf; - size_t len; - size_t nr; - size_t alloc; - struct line *line_allocated; + struct strbuf buf; struct line *line; + size_t line_nr, line_alloc; }; +#define IMAGE_INIT { \ + .buf = STRBUF_INIT, \ +} + +static void image_init(struct image *image) +{ + struct image empty = IMAGE_INIT; + memcpy(image, &empty, sizeof(*image)); +} + +static void image_clear(struct image *image) +{ + strbuf_release(&image->buf); + free(image->line); + image_init(image); +} static uint32_t hash_line(const char *cp, size_t len) { @@ -297,49 +311,13 @@ static uint32_t hash_line(const char *cp, size_t len) return h; } -/* - * Compare lines s1 of length n1 and s2 of length n2, ignoring - * whitespace difference. Returns 1 if they match, 0 otherwise - */ -static int fuzzy_matchlines(const char *s1, size_t n1, - const char *s2, size_t n2) +static void image_add_line(struct image *img, const char *bol, size_t len, unsigned flag) { - const char *end1 = s1 + n1; - const char *end2 = s2 + n2; - - /* ignore line endings */ - while (s1 < end1 && (end1[-1] == '\r' || end1[-1] == '\n')) - end1--; - while (s2 < end2 && (end2[-1] == '\r' || end2[-1] == '\n')) - end2--; - - while (s1 < end1 && s2 < end2) { - if (isspace(*s1)) { - /* - * Skip whitespace. We check on both buffers - * because we don't want "a b" to match "ab". - */ - if (!isspace(*s2)) - return 0; - while (s1 < end1 && isspace(*s1)) - s1++; - while (s2 < end2 && isspace(*s2)) - s2++; - } else if (*s1++ != *s2++) - return 0; - } - - /* If we reached the end on one side only, lines don't match. */ - return s1 == end1 && s2 == end2; -} - -static void add_line_info(struct image *img, const char *bol, size_t len, unsigned flag) -{ - ALLOC_GROW(img->line_allocated, img->nr + 1, img->alloc); - img->line_allocated[img->nr].len = len; - img->line_allocated[img->nr].hash = hash_line(bol, len); - img->line_allocated[img->nr].flag = flag; - img->nr++; + ALLOC_GROW(img->line, img->line_nr + 1, img->line_alloc); + img->line[img->line_nr].len = len; + img->line[img->line_nr].hash = hash_line(bol, len); + img->line[img->line_nr].flag = flag; + img->line_nr++; } /* @@ -347,37 +325,43 @@ static void add_line_info(struct image *img, const char *bol, size_t len, unsign * attach it to "image" and add line-based index to it. * "image" now owns the "buf". */ -static void prepare_image(struct image *image, char *buf, size_t len, +static void image_prepare(struct image *image, char *buf, size_t len, int prepare_linetable) { const char *cp, *ep; - memset(image, 0, sizeof(*image)); - image->buf = buf; - image->len = len; + image_clear(image); + strbuf_attach(&image->buf, buf, len, len + 1); if (!prepare_linetable) return; - ep = image->buf + image->len; - cp = image->buf; + ep = image->buf.buf + image->buf.len; + cp = image->buf.buf; while (cp < ep) { const char *next; for (next = cp; next < ep && *next != '\n'; next++) ; if (next < ep) next++; - add_line_info(image, cp, next - cp, 0); + image_add_line(image, cp, next - cp, 0); cp = next; } - image->line = image->line_allocated; } -static void clear_image(struct image *image) +static void image_remove_first_line(struct image *img) { - free(image->buf); - free(image->line_allocated); - memset(image, 0, sizeof(*image)); + strbuf_remove(&img->buf, 0, img->line[0].len); + img->line_nr--; + if (img->line_nr) + MOVE_ARRAY(img->line, img->line + 1, img->line_nr); +} + +static void image_remove_last_line(struct image *img) +{ + size_t last_line_len = img->line[img->line_nr - 1].len; + strbuf_setlen(&img->buf, img->buf.len - last_line_len); + img->line_nr--; } /* fmt must contain _one_ %s and no other substitution */ @@ -2326,65 +2310,43 @@ static int read_old_data(struct stat *st, struct patch *patch, /* * Update the preimage, and the common lines in postimage, - * from buffer buf of length len. If postlen is 0 the postimage - * is updated in place, otherwise it's updated on a new buffer - * of length postlen + * from buffer buf of length len. */ - static void update_pre_post_images(struct image *preimage, struct image *postimage, - char *buf, - size_t len, size_t postlen) + char *buf, size_t len) { + struct image fixed_preimage = IMAGE_INIT; + size_t insert_pos = 0; int i, ctx, reduced; - char *new_buf, *old_buf, *fixed; - struct image fixed_preimage; + const char *fixed; /* * Update the preimage with whitespace fixes. Note that we * are not losing preimage->buf -- apply_one_fragment() will * free "oldlines". */ - prepare_image(&fixed_preimage, buf, len, 1); - assert(postlen - ? fixed_preimage.nr == preimage->nr - : fixed_preimage.nr <= preimage->nr); - for (i = 0; i < fixed_preimage.nr; i++) + image_prepare(&fixed_preimage, buf, len, 1); + for (i = 0; i < fixed_preimage.line_nr; i++) fixed_preimage.line[i].flag = preimage->line[i].flag; - free(preimage->line_allocated); + image_clear(preimage); *preimage = fixed_preimage; + fixed = preimage->buf.buf; /* - * Adjust the common context lines in postimage. This can be - * done in-place when we are shrinking it with whitespace - * fixing, but needs a new buffer when ignoring whitespace or - * expanding leading tabs to spaces. - * - * We trust the caller to tell us if the update can be done - * in place (postlen==0) or not. + * Adjust the common context lines in postimage. */ - old_buf = postimage->buf; - if (postlen) - new_buf = postimage->buf = xmalloc(postlen); - else - new_buf = old_buf; - fixed = preimage->buf; - - for (i = reduced = ctx = 0; i < postimage->nr; i++) { + for (i = reduced = ctx = 0; i < postimage->line_nr; i++) { size_t l_len = postimage->line[i].len; + if (!(postimage->line[i].flag & LINE_COMMON)) { /* an added line -- no counterparts in preimage */ - memmove(new_buf, old_buf, l_len); - old_buf += l_len; - new_buf += l_len; + insert_pos += l_len; continue; } - /* a common context -- skip it in the original postimage */ - old_buf += l_len; - /* and find the corresponding one in the fixed preimage */ - while (ctx < preimage->nr && + while (ctx < preimage->line_nr && !(preimage->line[ctx].flag & LINE_COMMON)) { fixed += preimage->line[ctx].len; ctx++; @@ -2394,29 +2356,59 @@ static void update_pre_post_images(struct image *preimage, * preimage is expected to run out, if the caller * fixed addition of trailing blank lines. */ - if (preimage->nr <= ctx) { + if (preimage->line_nr <= ctx) { reduced++; continue; } /* and copy it in, while fixing the line length */ l_len = preimage->line[ctx].len; - memcpy(new_buf, fixed, l_len); - new_buf += l_len; + strbuf_splice(&postimage->buf, insert_pos, postimage->line[i].len, + fixed, l_len); + insert_pos += l_len; fixed += l_len; postimage->line[i].len = l_len; ctx++; } - if (postlen - ? postlen < new_buf - postimage->buf - : postimage->len < new_buf - postimage->buf) - BUG("caller miscounted postlen: asked %d, orig = %d, used = %d", - (int)postlen, (int) postimage->len, (int)(new_buf - postimage->buf)); - /* Fix the length of the whole thing */ - postimage->len = new_buf - postimage->buf; - postimage->nr -= reduced; + postimage->line_nr -= reduced; +} + +/* + * Compare lines s1 of length n1 and s2 of length n2, ignoring + * whitespace difference. Returns 1 if they match, 0 otherwise + */ +static int fuzzy_matchlines(const char *s1, size_t n1, + const char *s2, size_t n2) +{ + const char *end1 = s1 + n1; + const char *end2 = s2 + n2; + + /* ignore line endings */ + while (s1 < end1 && (end1[-1] == '\r' || end1[-1] == '\n')) + end1--; + while (s2 < end2 && (end2[-1] == '\r' || end2[-1] == '\n')) + end2--; + + while (s1 < end1 && s2 < end2) { + if (isspace(*s1)) { + /* + * Skip whitespace. We check on both buffers + * because we don't want "a b" to match "ab". + */ + if (!isspace(*s2)) + return 0; + while (s1 < end1 && isspace(*s1)) + s1++; + while (s2 < end2 && isspace(*s2)) + s2++; + } else if (*s1++ != *s2++) + return 0; + } + + /* If we reached the end on one side only, lines don't match. */ + return s1 == end1 && s2 == end2; } static int line_by_line_fuzzy_match(struct image *img, @@ -2429,7 +2421,6 @@ static int line_by_line_fuzzy_match(struct image *img, int i; size_t imgoff = 0; size_t preoff = 0; - size_t postlen = postimage->len; size_t extra_chars; char *buf; char *preimage_eof; @@ -2442,11 +2433,9 @@ static int line_by_line_fuzzy_match(struct image *img, size_t prelen = preimage->line[i].len; size_t imglen = img->line[current_lno+i].len; - if (!fuzzy_matchlines(img->buf + current + imgoff, imglen, - preimage->buf + preoff, prelen)) + if (!fuzzy_matchlines(img->buf.buf + current + imgoff, imglen, + preimage->buf.buf + preoff, prelen)) return 0; - if (preimage->line[i].flag & LINE_COMMON) - postlen += imglen - prelen; imgoff += imglen; preoff += prelen; } @@ -2462,10 +2451,10 @@ static int line_by_line_fuzzy_match(struct image *img, * are whitespace characters. (This can only happen if * we are removing blank lines at the end of the file.) */ - buf = preimage_eof = preimage->buf + preoff; - for ( ; i < preimage->nr; i++) + buf = preimage_eof = preimage->buf.buf + preoff; + for ( ; i < preimage->line_nr; i++) preoff += preimage->line[i].len; - preimage_end = preimage->buf + preoff; + preimage_end = preimage->buf.buf + preoff; for ( ; buf < preimage_end; buf++) if (!isspace(*buf)) return 0; @@ -2479,11 +2468,11 @@ static int line_by_line_fuzzy_match(struct image *img, */ extra_chars = preimage_end - preimage_eof; strbuf_init(&fixed, imgoff + extra_chars); - strbuf_add(&fixed, img->buf + current, imgoff); + strbuf_add(&fixed, img->buf.buf + current, imgoff); strbuf_add(&fixed, preimage_eof, extra_chars); fixed_buf = strbuf_detach(&fixed, &fixed_len); update_pre_post_images(preimage, postimage, - fixed_buf, fixed_len, postlen); + fixed_buf, fixed_len); return 1; } @@ -2499,16 +2488,17 @@ static int match_fragment(struct apply_state *state, int i; const char *orig, *target; struct strbuf fixed = STRBUF_INIT; - size_t postlen; + char *fixed_buf; + size_t fixed_len; int preimage_limit; int ret; - if (preimage->nr + current_lno <= img->nr) { + if (preimage->line_nr + current_lno <= img->line_nr) { /* * The hunk falls within the boundaries of img. */ - preimage_limit = preimage->nr; - if (match_end && (preimage->nr + current_lno != img->nr)) { + preimage_limit = preimage->line_nr; + if (match_end && (preimage->line_nr + current_lno != img->line_nr)) { ret = 0; goto out; } @@ -2521,7 +2511,7 @@ static int match_fragment(struct apply_state *state, * match with img, and the remainder of the preimage * must be blank. */ - preimage_limit = img->nr - current_lno; + preimage_limit = img->line_nr - current_lno; } else { /* * The hunk extends beyond the end of the img and @@ -2546,7 +2536,7 @@ static int match_fragment(struct apply_state *state, } } - if (preimage_limit == preimage->nr) { + if (preimage_limit == preimage->line_nr) { /* * Do we have an exact match? If we were told to match * at the end, size must be exactly at current+fragsize, @@ -2555,9 +2545,9 @@ static int match_fragment(struct apply_state *state, * exactly. */ if ((match_end - ? (current + preimage->len == img->len) - : (current + preimage->len <= img->len)) && - !memcmp(img->buf + current, preimage->buf, preimage->len)) { + ? (current + preimage->buf.len == img->buf.len) + : (current + preimage->buf.len <= img->buf.len)) && + !memcmp(img->buf.buf + current, preimage->buf.buf, preimage->buf.len)) { ret = 1; goto out; } @@ -2571,7 +2561,7 @@ static int match_fragment(struct apply_state *state, */ const char *buf, *buf_end; - buf = preimage->buf; + buf = preimage->buf.buf; buf_end = buf; for (i = 0; i < preimage_limit; i++) buf_end += preimage->line[i].len; @@ -2616,21 +2606,14 @@ static int match_fragment(struct apply_state *state, * fixed. */ - /* First count added lines in postimage */ - postlen = 0; - for (i = 0; i < postimage->nr; i++) { - if (!(postimage->line[i].flag & LINE_COMMON)) - postlen += postimage->line[i].len; - } - /* * The preimage may extend beyond the end of the file, * but in this loop we will only handle the part of the * preimage that falls within the file. */ - strbuf_grow(&fixed, preimage->len + 1); - orig = preimage->buf; - target = img->buf + current; + strbuf_grow(&fixed, preimage->buf.len + 1); + orig = preimage->buf.buf; + target = img->buf.buf + current; for (i = 0; i < preimage_limit; i++) { size_t oldlen = preimage->line[i].len; size_t tgtlen = img->line[current_lno + i].len; @@ -2659,10 +2642,6 @@ static int match_fragment(struct apply_state *state, !memcmp(tgtfix.buf, fixed.buf + fixstart, fixed.len - fixstart)); - /* Add the length if this is common with the postimage */ - if (preimage->line[i].flag & LINE_COMMON) - postlen += tgtfix.len; - strbuf_release(&tgtfix); if (!match) { ret = 0; @@ -2680,7 +2659,7 @@ static int match_fragment(struct apply_state *state, * empty or only contain whitespace (if WS_BLANK_AT_EOL is * false). */ - for ( ; i < preimage->nr; i++) { + for ( ; i < preimage->line_nr; i++) { size_t fixstart = fixed.len; /* start of the fixed preimage */ size_t oldlen = preimage->line[i].len; int j; @@ -2704,10 +2683,9 @@ static int match_fragment(struct apply_state *state, * has whitespace breakages unfixed, and fixing them makes the * hunk match. Update the context lines in the postimage. */ - if (postlen < postimage->len) - postlen = 0; + fixed_buf = strbuf_detach(&fixed, &fixed_len); update_pre_post_images(preimage, postimage, - fixed.buf, fixed.len, postlen); + fixed_buf, fixed_len); ret = 1; @@ -2735,7 +2713,7 @@ static int find_pos(struct apply_state *state, * than `match_beginning`. */ if (state->allow_overlap && match_beginning && match_end && - img->nr - preimage->nr != 0) + img->line_nr - preimage->line_nr != 0) match_beginning = 0; /* @@ -2746,15 +2724,15 @@ static int find_pos(struct apply_state *state, if (match_beginning) line = 0; else if (match_end) - line = img->nr - preimage->nr; + line = img->line_nr - preimage->line_nr; /* * Because the comparison is unsigned, the following test * will also take care of a negative line number that can * result when match_end and preimage is larger than the target. */ - if ((size_t) line > img->nr) - line = img->nr; + if ((size_t) line > img->line_nr) + line = img->line_nr; current = 0; for (i = 0; i < line; i++) @@ -2777,7 +2755,7 @@ static int find_pos(struct apply_state *state, return current_lno; again: - if (backwards_lno == 0 && forwards_lno == img->nr) + if (backwards_lno == 0 && forwards_lno == img->line_nr) break; if (i & 1) { @@ -2790,7 +2768,7 @@ static int find_pos(struct apply_state *state, current = backwards; current_lno = backwards_lno; } else { - if (forwards_lno == img->nr) { + if (forwards_lno == img->line_nr) { i++; goto again; } @@ -2804,19 +2782,6 @@ static int find_pos(struct apply_state *state, return -1; } -static void remove_first_line(struct image *img) -{ - img->buf += img->line[0].len; - img->len -= img->line[0].len; - img->line++; - img->nr--; -} - -static void remove_last_line(struct image *img) -{ - img->len -= img->line[--img->nr].len; -} - /* * The change from "preimage" and "postimage" has been found to * apply at applied_pos (counts in line numbers) in "img". @@ -2834,6 +2799,7 @@ static void update_image(struct apply_state *state, */ int i, nr; size_t remove_count, insert_count, applied_at = 0; + size_t result_alloc; char *result; int preimage_limit; @@ -2846,9 +2812,9 @@ static void update_image(struct apply_state *state, * to the number of lines in the preimage that falls * within the boundaries. */ - preimage_limit = preimage->nr; - if (preimage_limit > img->nr - applied_pos) - preimage_limit = img->nr - applied_pos; + preimage_limit = preimage->line_nr; + if (preimage_limit > img->line_nr - applied_pos) + preimage_limit = img->line_nr - applied_pos; for (i = 0; i < applied_pos; i++) applied_at += img->line[i].len; @@ -2856,39 +2822,36 @@ static void update_image(struct apply_state *state, remove_count = 0; for (i = 0; i < preimage_limit; i++) remove_count += img->line[applied_pos + i].len; - insert_count = postimage->len; + insert_count = postimage->buf.len; /* Adjust the contents */ - result = xmalloc(st_add3(st_sub(img->len, remove_count), insert_count, 1)); - memcpy(result, img->buf, applied_at); - memcpy(result + applied_at, postimage->buf, postimage->len); - memcpy(result + applied_at + postimage->len, - img->buf + (applied_at + remove_count), - img->len - (applied_at + remove_count)); - free(img->buf); - img->buf = result; - img->len += insert_count - remove_count; - result[img->len] = '\0'; + result_alloc = st_add3(st_sub(img->buf.len, remove_count), insert_count, 1); + result = xmalloc(result_alloc); + memcpy(result, img->buf.buf, applied_at); + memcpy(result + applied_at, postimage->buf.buf, postimage->buf.len); + memcpy(result + applied_at + postimage->buf.len, + img->buf.buf + (applied_at + remove_count), + img->buf.len - (applied_at + remove_count)); + strbuf_attach(&img->buf, result, postimage->buf.len + img->buf.len - remove_count, + result_alloc); /* Adjust the line table */ - nr = img->nr + postimage->nr - preimage_limit; - if (preimage_limit < postimage->nr) { + nr = img->line_nr + postimage->line_nr - preimage_limit; + if (preimage_limit < postimage->line_nr) /* - * NOTE: this knows that we never call remove_first_line() + * NOTE: this knows that we never call image_remove_first_line() * on anything other than pre/post image. */ REALLOC_ARRAY(img->line, nr); - img->line_allocated = img->line; - } - if (preimage_limit != postimage->nr) - MOVE_ARRAY(img->line + applied_pos + postimage->nr, + if (preimage_limit != postimage->line_nr) + MOVE_ARRAY(img->line + applied_pos + postimage->line_nr, img->line + applied_pos + preimage_limit, - img->nr - (applied_pos + preimage_limit)); - COPY_ARRAY(img->line + applied_pos, postimage->line, postimage->nr); + img->line_nr - (applied_pos + preimage_limit)); + COPY_ARRAY(img->line + applied_pos, postimage->line, postimage->line_nr); if (!state->allow_overlap) - for (i = 0; i < postimage->nr; i++) + for (i = 0; i < postimage->line_nr; i++) img->line[applied_pos + i].flag |= LINE_PATCHED; - img->nr = nr; + img->line_nr = nr; } /* @@ -2911,11 +2874,9 @@ static int apply_one_fragment(struct apply_state *state, int hunk_linenr = frag->linenr; unsigned long leading, trailing; int pos, applied_pos; - struct image preimage; - struct image postimage; + struct image preimage = IMAGE_INIT; + struct image postimage = IMAGE_INIT; - memset(&preimage, 0, sizeof(preimage)); - memset(&postimage, 0, sizeof(postimage)); oldlines = xmalloc(size); strbuf_init(&newlines, size); @@ -2957,8 +2918,8 @@ static int apply_one_fragment(struct apply_state *state, break; *old++ = '\n'; strbuf_addch(&newlines, '\n'); - add_line_info(&preimage, "\n", 1, LINE_COMMON); - add_line_info(&postimage, "\n", 1, LINE_COMMON); + image_add_line(&preimage, "\n", 1, LINE_COMMON); + image_add_line(&postimage, "\n", 1, LINE_COMMON); is_blank_context = 1; break; case ' ': @@ -2968,7 +2929,7 @@ static int apply_one_fragment(struct apply_state *state, /* fallthrough */ case '-': memcpy(old, patch + 1, plen); - add_line_info(&preimage, old, plen, + image_add_line(&preimage, old, plen, (first == ' ' ? LINE_COMMON : 0)); old += plen; if (first == '-') @@ -2988,7 +2949,7 @@ static int apply_one_fragment(struct apply_state *state, else { ws_fix_copy(&newlines, patch + 1, plen, ws_rule, &state->applied_after_fixing_ws); } - add_line_info(&postimage, newlines.buf + start, newlines.len - start, + image_add_line(&postimage, newlines.buf + start, newlines.len - start, (first == '+' ? 0 : LINE_COMMON)); if (first == '+' && (ws_rule & WS_BLANK_AT_EOF) && @@ -3022,8 +2983,8 @@ static int apply_one_fragment(struct apply_state *state, newlines.len > 0 && newlines.buf[newlines.len - 1] == '\n') { old--; strbuf_setlen(&newlines, newlines.len - 1); - preimage.line_allocated[preimage.nr - 1].len--; - postimage.line_allocated[postimage.nr - 1].len--; + preimage.line[preimage.line_nr - 1].len--; + postimage.line[postimage.line_nr - 1].len--; } leading = frag->leading; @@ -3053,12 +3014,8 @@ static int apply_one_fragment(struct apply_state *state, match_end = !state->unidiff_zero && !trailing; pos = frag->newpos ? (frag->newpos - 1) : 0; - preimage.buf = oldlines; - preimage.len = old - oldlines; - postimage.buf = newlines.buf; - postimage.len = newlines.len; - preimage.line = preimage.line_allocated; - postimage.line = postimage.line_allocated; + strbuf_add(&preimage.buf, oldlines, old - oldlines); + strbuf_swap(&postimage.buf, &newlines); for (;;) { @@ -3082,28 +3039,28 @@ static int apply_one_fragment(struct apply_state *state, * just reduce the larger context. */ if (leading >= trailing) { - remove_first_line(&preimage); - remove_first_line(&postimage); + image_remove_first_line(&preimage); + image_remove_first_line(&postimage); pos--; leading--; } if (trailing > leading) { - remove_last_line(&preimage); - remove_last_line(&postimage); + image_remove_last_line(&preimage); + image_remove_last_line(&postimage); trailing--; } } if (applied_pos >= 0) { if (new_blank_lines_at_end && - preimage.nr + applied_pos >= img->nr && + preimage.line_nr + applied_pos >= img->line_nr && (ws_rule & WS_BLANK_AT_EOF) && state->ws_error_action != nowarn_ws_error) { record_ws_error(state, WS_BLANK_AT_EOF, "+", 1, found_new_blank_lines_at_end); if (state->ws_error_action == correct_ws_error) { while (new_blank_lines_at_end--) - remove_last_line(&postimage); + image_remove_last_line(&postimage); } /* * We would want to prevent write_out_results() @@ -3146,8 +3103,8 @@ static int apply_one_fragment(struct apply_state *state, out: free(oldlines); strbuf_release(&newlines); - free(preimage.line_allocated); - free(postimage.line_allocated); + image_clear(&preimage); + image_clear(&postimage); return (applied_pos < 0); } @@ -3177,18 +3134,16 @@ static int apply_binary_fragment(struct apply_state *state, } switch (fragment->binary_patch_method) { case BINARY_DELTA_DEFLATED: - dst = patch_delta(img->buf, img->len, fragment->patch, + dst = patch_delta(img->buf.buf, img->buf.len, fragment->patch, fragment->size, &len); if (!dst) return -1; - clear_image(img); - img->buf = dst; - img->len = len; + image_clear(img); + strbuf_attach(&img->buf, dst, len, len + 1); return 0; case BINARY_LITERAL_DEFLATED: - clear_image(img); - img->len = fragment->size; - img->buf = xmemdupz(fragment->patch, img->len); + image_clear(img); + strbuf_add(&img->buf, fragment->patch, fragment->size); return 0; } return -1; @@ -3224,8 +3179,8 @@ static int apply_binary(struct apply_state *state, * See if the old one matches what the patch * applies to. */ - hash_object_file(the_hash_algo, img->buf, img->len, OBJ_BLOB, - &oid); + hash_object_file(the_hash_algo, img->buf.buf, img->buf.len, + OBJ_BLOB, &oid); if (strcmp(oid_to_hex(&oid), patch->old_oid_prefix)) return error(_("the patch applies to '%s' (%s), " "which does not match the " @@ -3234,14 +3189,14 @@ static int apply_binary(struct apply_state *state, } else { /* Otherwise, the old one must be empty. */ - if (img->len) + if (img->buf.len) return error(_("the patch applies to an empty " "'%s' but it is not empty"), name); } get_oid_hex(patch->new_oid_prefix, &oid); if (is_null_oid(&oid)) { - clear_image(img); + image_clear(img); return 0; /* deletion patch */ } @@ -3257,9 +3212,8 @@ static int apply_binary(struct apply_state *state, return error(_("the necessary postimage %s for " "'%s' cannot be read"), patch->new_oid_prefix, name); - clear_image(img); - img->buf = result; - img->len = size; + image_clear(img); + strbuf_attach(&img->buf, result, size, size + 1); } else { /* * We have verified buf matches the preimage; @@ -3271,7 +3225,7 @@ static int apply_binary(struct apply_state *state, name); /* verify that the result matches */ - hash_object_file(the_hash_algo, img->buf, img->len, OBJ_BLOB, + hash_object_file(the_hash_algo, img->buf.buf, img->buf.len, OBJ_BLOB, &oid); if (strcmp(oid_to_hex(&oid), patch->new_oid_prefix)) return error(_("binary patch to '%s' creates incorrect result (expecting %s, got %s)"), @@ -3533,7 +3487,7 @@ static int load_preimage(struct apply_state *state, } img = strbuf_detach(&buf, &len); - prepare_image(image, img, len, !patch->is_binary); + image_prepare(image, img, len, !patch->is_binary); return 0; } @@ -3541,14 +3495,14 @@ static int resolve_to(struct image *image, const struct object_id *result_id) { unsigned long size; enum object_type type; + char *data; - clear_image(image); + image_clear(image); - image->buf = repo_read_object_file(the_repository, result_id, &type, - &size); - if (!image->buf || type != OBJ_BLOB) + data = repo_read_object_file(the_repository, result_id, &type, &size); + if (!data || type != OBJ_BLOB) die("unable to read blob object %s", oid_to_hex(result_id)); - image->len = size; + strbuf_attach(&image->buf, data, size, size + 1); return 0; } @@ -3591,9 +3545,8 @@ static int three_way_merge(struct apply_state *state, free(result.ptr); return -1; } - clear_image(image); - image->buf = result.ptr; - image->len = result.size; + image_clear(image); + strbuf_attach(&image->buf, result.ptr, result.size, result.size); return status; } @@ -3638,7 +3591,7 @@ static int load_current(struct apply_state *state, else if (status) return -1; img = strbuf_detach(&buf, &len); - prepare_image(image, img, len, !patch->is_binary); + image_prepare(image, img, len, !patch->is_binary); return 0; } @@ -3653,7 +3606,7 @@ static int try_threeway(struct apply_state *state, size_t len; int status; char *img; - struct image tmp_image; + struct image tmp_image = IMAGE_INIT; /* No point falling back to 3-way merge in these cases */ if (patch->is_delete || @@ -3673,15 +3626,15 @@ static int try_threeway(struct apply_state *state, fprintf(stderr, _("Performing three-way merge...\n")); img = strbuf_detach(&buf, &len); - prepare_image(&tmp_image, img, len, 1); + image_prepare(&tmp_image, img, len, 1); /* Apply the patch to get the post image */ if (apply_fragments(state, &tmp_image, patch) < 0) { - clear_image(&tmp_image); + image_clear(&tmp_image); return -1; } /* post_oid is theirs */ - write_object_file(tmp_image.buf, tmp_image.len, OBJ_BLOB, &post_oid); - clear_image(&tmp_image); + write_object_file(tmp_image.buf.buf, tmp_image.buf.len, OBJ_BLOB, &post_oid); + image_clear(&tmp_image); /* our_oid is ours */ if (patch->is_new) { @@ -3693,8 +3646,8 @@ static int try_threeway(struct apply_state *state, return error(_("cannot read the current contents of '%s'"), patch->old_name); } - write_object_file(tmp_image.buf, tmp_image.len, OBJ_BLOB, &our_oid); - clear_image(&tmp_image); + write_object_file(tmp_image.buf.buf, tmp_image.buf.len, OBJ_BLOB, &our_oid); + image_clear(&tmp_image); /* in-core three-way merge between post and our using pre as base */ status = three_way_merge(state, image, patch->new_name, @@ -3730,7 +3683,7 @@ static int try_threeway(struct apply_state *state, static int apply_data(struct apply_state *state, struct patch *patch, struct stat *st, const struct cache_entry *ce) { - struct image image; + struct image image = IMAGE_INIT; if (load_preimage(state, &image, patch, st, ce) < 0) return -1; @@ -3742,14 +3695,13 @@ static int apply_data(struct apply_state *state, struct patch *patch, /* Note: with --reject, apply_fragments() returns 0 */ if (patch->direct_to_threeway || apply_fragments(state, &image, patch) < 0) { - clear_image(&image); + image_clear(&image); return -1; } } - patch->result = image.buf; - patch->resultsize = image.len; + patch->result = strbuf_detach(&image.buf, &patch->resultsize); add_to_fn_table(state, patch); - free(image.line_allocated); + free(image.line); if (0 < patch->is_delete && patch->resultsize) return error(_("removal patch leaves file contents")); @@ -4113,7 +4065,7 @@ static int read_apply_cache(struct apply_state *state) { if (state->index_file) return read_index_from(state->repo->index, state->index_file, - get_git_dir()); + repo_get_git_dir(the_repository)); else return repo_read_index(state->repo); } @@ -187,7 +187,7 @@ static void all_attrs_init(struct attr_hashmap *map, struct attr_check *check) } /* - * Atribute name cannot begin with "builtin_" which + * Attribute name cannot begin with "builtin_" which * is a reserved namespace for built in attributes values. */ static int attr_name_reserved(const char *name) @@ -18,7 +18,7 @@ struct bloom_filter_settings { /* * The number of times a path is hashed, i.e. the - * number of bit positions tht cumulatively + * number of bit positions that cumulatively * determine whether a path is present in the * Bloom filter. */ @@ -601,6 +601,7 @@ void create_branch(struct repository *r, int forcing = 0; struct ref_transaction *transaction; struct strbuf err = STRBUF_INIT; + int flags = 0; char *msg; if (track == BRANCH_TRACK_OVERRIDE) @@ -619,7 +620,7 @@ void create_branch(struct repository *r, goto cleanup; if (reflog) - log_all_ref_updates = LOG_REFS_NORMAL; + flags |= REF_FORCE_CREATE_REFLOG; if (forcing) msg = xstrfmt("branch: Reset to %s", start_name); @@ -630,7 +631,7 @@ void create_branch(struct repository *r, if (!transaction || ref_transaction_update(transaction, ref.buf, &oid, forcing ? NULL : null_oid(), - NULL, NULL, 0, msg, &err) || + NULL, NULL, flags, msg, &err) || ref_transaction_commit(transaction, &err)) die("%s", err.buf); ref_transaction_free(transaction); @@ -1,15 +1,8 @@ #ifndef BUILTIN_H #define BUILTIN_H -/* - * TODO: Almost all of our builtins access `the_repository` by necessity - * because they do not get passed a pointer to it. We should adapt the function - * signature of those main functions to accept a `struct repository *` and then - * remove the macro here. - */ -#define USE_THE_REPOSITORY_VARIABLE - #include "git-compat-util.h" +#include "repository.h" /* * builtin API @@ -122,143 +115,143 @@ int is_builtin(const char *s); BUG("unexpected prefix in builtin: %s", (prefix)); \ } while (0) -int cmd_add(int argc, const char **argv, const char *prefix); -int cmd_am(int argc, const char **argv, const char *prefix); -int cmd_annotate(int argc, const char **argv, const char *prefix); -int cmd_apply(int argc, const char **argv, const char *prefix); -int cmd_archive(int argc, const char **argv, const char *prefix); -int cmd_bisect(int argc, const char **argv, const char *prefix); -int cmd_blame(int argc, const char **argv, const char *prefix); -int cmd_branch(int argc, const char **argv, const char *prefix); -int cmd_bugreport(int argc, const char **argv, const char *prefix); -int cmd_bundle(int argc, const char **argv, const char *prefix); -int cmd_cat_file(int argc, const char **argv, const char *prefix); -int cmd_checkout(int argc, const char **argv, const char *prefix); -int cmd_checkout__worker(int argc, const char **argv, const char *prefix); -int cmd_checkout_index(int argc, const char **argv, const char *prefix); -int cmd_check_attr(int argc, const char **argv, const char *prefix); -int cmd_check_ignore(int argc, const char **argv, const char *prefix); -int cmd_check_mailmap(int argc, const char **argv, const char *prefix); -int cmd_check_ref_format(int argc, const char **argv, const char *prefix); -int cmd_cherry(int argc, const char **argv, const char *prefix); -int cmd_cherry_pick(int argc, const char **argv, const char *prefix); -int cmd_clone(int argc, const char **argv, const char *prefix); -int cmd_clean(int argc, const char **argv, const char *prefix); -int cmd_column(int argc, const char **argv, const char *prefix); -int cmd_commit(int argc, const char **argv, const char *prefix); -int cmd_commit_graph(int argc, const char **argv, const char *prefix); -int cmd_commit_tree(int argc, const char **argv, const char *prefix); -int cmd_config(int argc, const char **argv, const char *prefix); -int cmd_count_objects(int argc, const char **argv, const char *prefix); -int cmd_credential(int argc, const char **argv, const char *prefix); -int cmd_credential_cache(int argc, const char **argv, const char *prefix); -int cmd_credential_cache_daemon(int argc, const char **argv, const char *prefix); -int cmd_credential_store(int argc, const char **argv, const char *prefix); -int cmd_describe(int argc, const char **argv, const char *prefix); -int cmd_diagnose(int argc, const char **argv, const char *prefix); -int cmd_diff_files(int argc, const char **argv, const char *prefix); -int cmd_diff_index(int argc, const char **argv, const char *prefix); -int cmd_diff(int argc, const char **argv, const char *prefix); -int cmd_diff_tree(int argc, const char **argv, const char *prefix); -int cmd_difftool(int argc, const char **argv, const char *prefix); -int cmd_env__helper(int argc, const char **argv, const char *prefix); -int cmd_fast_export(int argc, const char **argv, const char *prefix); -int cmd_fast_import(int argc, const char **argv, const char *prefix); -int cmd_fetch(int argc, const char **argv, const char *prefix); -int cmd_fetch_pack(int argc, const char **argv, const char *prefix); -int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix); -int cmd_for_each_ref(int argc, const char **argv, const char *prefix); -int cmd_for_each_repo(int argc, const char **argv, const char *prefix); -int cmd_format_patch(int argc, const char **argv, const char *prefix); -int cmd_fsck(int argc, const char **argv, const char *prefix); -int cmd_fsmonitor__daemon(int argc, const char **argv, const char *prefix); -int cmd_gc(int argc, const char **argv, const char *prefix); -int cmd_get_tar_commit_id(int argc, const char **argv, const char *prefix); -int cmd_grep(int argc, const char **argv, const char *prefix); -int cmd_hash_object(int argc, const char **argv, const char *prefix); -int cmd_help(int argc, const char **argv, const char *prefix); -int cmd_hook(int argc, const char **argv, const char *prefix); -int cmd_index_pack(int argc, const char **argv, const char *prefix); -int cmd_init_db(int argc, const char **argv, const char *prefix); -int cmd_interpret_trailers(int argc, const char **argv, const char *prefix); -int cmd_log(int argc, const char **argv, const char *prefix); -int cmd_log_reflog(int argc, const char **argv, const char *prefix); -int cmd_ls_files(int argc, const char **argv, const char *prefix); -int cmd_ls_tree(int argc, const char **argv, const char *prefix); -int cmd_ls_remote(int argc, const char **argv, const char *prefix); -int cmd_mailinfo(int argc, const char **argv, const char *prefix); -int cmd_mailsplit(int argc, const char **argv, const char *prefix); -int cmd_maintenance(int argc, const char **argv, const char *prefix); -int cmd_merge(int argc, const char **argv, const char *prefix); -int cmd_merge_base(int argc, const char **argv, const char *prefix); -int cmd_merge_index(int argc, const char **argv, const char *prefix); -int cmd_merge_ours(int argc, const char **argv, const char *prefix); -int cmd_merge_file(int argc, const char **argv, const char *prefix); -int cmd_merge_recursive(int argc, const char **argv, const char *prefix); -int cmd_merge_tree(int argc, const char **argv, const char *prefix); -int cmd_mktag(int argc, const char **argv, const char *prefix); -int cmd_mktree(int argc, const char **argv, const char *prefix); -int cmd_multi_pack_index(int argc, const char **argv, const char *prefix); -int cmd_mv(int argc, const char **argv, const char *prefix); -int cmd_name_rev(int argc, const char **argv, const char *prefix); -int cmd_notes(int argc, const char **argv, const char *prefix); -int cmd_pack_objects(int argc, const char **argv, const char *prefix); -int cmd_pack_redundant(int argc, const char **argv, const char *prefix); -int cmd_patch_id(int argc, const char **argv, const char *prefix); -int cmd_prune(int argc, const char **argv, const char *prefix); -int cmd_prune_packed(int argc, const char **argv, const char *prefix); -int cmd_pull(int argc, const char **argv, const char *prefix); -int cmd_push(int argc, const char **argv, const char *prefix); -int cmd_range_diff(int argc, const char **argv, const char *prefix); -int cmd_read_tree(int argc, const char **argv, const char *prefix); -int cmd_rebase(int argc, const char **argv, const char *prefix); -int cmd_rebase__interactive(int argc, const char **argv, const char *prefix); -int cmd_receive_pack(int argc, const char **argv, const char *prefix); -int cmd_reflog(int argc, const char **argv, const char *prefix); -int cmd_refs(int argc, const char **argv, const char *prefix); -int cmd_remote(int argc, const char **argv, const char *prefix); -int cmd_remote_ext(int argc, const char **argv, const char *prefix); -int cmd_remote_fd(int argc, const char **argv, const char *prefix); -int cmd_repack(int argc, const char **argv, const char *prefix); -int cmd_replay(int argc, const char **argv, const char *prefix); -int cmd_rerere(int argc, const char **argv, const char *prefix); -int cmd_reset(int argc, const char **argv, const char *prefix); -int cmd_restore(int argc, const char **argv, const char *prefix); -int cmd_rev_list(int argc, const char **argv, const char *prefix); -int cmd_rev_parse(int argc, const char **argv, const char *prefix); -int cmd_revert(int argc, const char **argv, const char *prefix); -int cmd_rm(int argc, const char **argv, const char *prefix); -int cmd_send_pack(int argc, const char **argv, const char *prefix); -int cmd_shortlog(int argc, const char **argv, const char *prefix); -int cmd_show(int argc, const char **argv, const char *prefix); -int cmd_show_branch(int argc, const char **argv, const char *prefix); -int cmd_show_index(int argc, const char **argv, const char *prefix); -int cmd_sparse_checkout(int argc, const char **argv, const char *prefix); -int cmd_status(int argc, const char **argv, const char *prefix); -int cmd_stash(int argc, const char **argv, const char *prefix); -int cmd_stripspace(int argc, const char **argv, const char *prefix); -int cmd_submodule__helper(int argc, const char **argv, const char *prefix); -int cmd_switch(int argc, const char **argv, const char *prefix); -int cmd_symbolic_ref(int argc, const char **argv, const char *prefix); -int cmd_tag(int argc, const char **argv, const char *prefix); -int cmd_unpack_file(int argc, const char **argv, const char *prefix); -int cmd_unpack_objects(int argc, const char **argv, const char *prefix); -int cmd_update_index(int argc, const char **argv, const char *prefix); -int cmd_update_ref(int argc, const char **argv, const char *prefix); -int cmd_update_server_info(int argc, const char **argv, const char *prefix); -int cmd_upload_archive(int argc, const char **argv, const char *prefix); -int cmd_upload_archive_writer(int argc, const char **argv, const char *prefix); -int cmd_upload_pack(int argc, const char **argv, const char *prefix); -int cmd_var(int argc, const char **argv, const char *prefix); -int cmd_verify_commit(int argc, const char **argv, const char *prefix); -int cmd_verify_tag(int argc, const char **argv, const char *prefix); -int cmd_version(int argc, const char **argv, const char *prefix); -int cmd_whatchanged(int argc, const char **argv, const char *prefix); -int cmd_worktree(int argc, const char **argv, const char *prefix); -int cmd_write_tree(int argc, const char **argv, const char *prefix); -int cmd_verify_pack(int argc, const char **argv, const char *prefix); -int cmd_show_ref(int argc, const char **argv, const char *prefix); -int cmd_pack_refs(int argc, const char **argv, const char *prefix); -int cmd_replace(int argc, const char **argv, const char *prefix); +int cmd_add(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_am(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_annotate(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_apply(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_archive(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_bisect(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_blame(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_branch(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_bugreport(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_bundle(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_cat_file(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_checkout(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_checkout__worker(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_checkout_index(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_check_attr(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_check_ignore(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_check_mailmap(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_check_ref_format(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_cherry(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_cherry_pick(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_clone(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_clean(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_column(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_commit(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_commit_graph(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_commit_tree(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_config(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_count_objects(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_credential(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_credential_cache(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_credential_cache_daemon(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_credential_store(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_describe(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_diagnose(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_diff_files(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_diff_index(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_diff(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_diff_tree(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_difftool(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_env__helper(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_fast_export(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_fast_import(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_fetch(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_fetch_pack(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_for_each_ref(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_for_each_repo(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_format_patch(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_fsck(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_fsmonitor__daemon(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_gc(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_get_tar_commit_id(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_grep(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_hash_object(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_help(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_hook(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_index_pack(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_init_db(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_interpret_trailers(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_log_reflog(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_log(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_ls_files(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_ls_tree(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_ls_remote(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_mailinfo(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_mailsplit(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_maintenance(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_merge(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_merge_base(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_merge_index(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_merge_ours(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_merge_file(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_merge_recursive(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_merge_tree(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_mktag(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_mktree(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_multi_pack_index(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_mv(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_name_rev(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_notes(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_pack_objects(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_pack_redundant(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_patch_id(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_prune(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_prune_packed(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_pull(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_push(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_range_diff(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_read_tree(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_rebase(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_rebase__interactive(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_receive_pack(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_reflog(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_refs(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_remote(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_remote_ext(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_remote_fd(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_repack(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_replay(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_rerere(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_reset(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_restore(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_rev_list(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_rev_parse(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_revert(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_rm(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_send_pack(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_shortlog(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_show(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_show_branch(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_show_index(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_sparse_checkout(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_status(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_stash(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_stripspace(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_submodule__helper(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_switch(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_symbolic_ref(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_tag(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_unpack_file(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_unpack_objects(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_update_index(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_update_ref(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_update_server_info(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_upload_archive(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_upload_archive_writer(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_upload_pack(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_var(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_verify_commit(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_verify_tag(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_version(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_whatchanged(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_worktree(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_write_tree(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_verify_pack(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_show_ref(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_pack_refs(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_replace(int argc, const char **argv, const char *prefix, struct repository *repo); #endif diff --git a/builtin/add.c b/builtin/add.c index 40b61ef90d..773b7224a4 100644 --- a/builtin/add.c +++ b/builtin/add.c @@ -3,7 +3,6 @@ * * Copyright (C) 2006 Linus Torvalds */ - #include "builtin.h" #include "advice.h" #include "config.h" @@ -18,7 +17,6 @@ #include "preload-index.h" #include "diff.h" #include "read-cache.h" -#include "repository.h" #include "revision.h" #include "bulk-checkin.h" #include "strvec.h" @@ -36,24 +34,27 @@ static int pathspec_file_nul; static int include_sparse; static const char *pathspec_from_file; -static int chmod_pathspec(struct pathspec *pathspec, char flip, int show_only) +static int chmod_pathspec(struct repository *repo, + struct pathspec *pathspec, + char flip, + int show_only) { int i, ret = 0; - for (i = 0; i < the_repository->index->cache_nr; i++) { - struct cache_entry *ce = the_repository->index->cache[i]; + for (i = 0; i < repo->index->cache_nr; i++) { + struct cache_entry *ce = repo->index->cache[i]; int err; if (!include_sparse && (ce_skip_worktree(ce) || - !path_in_sparse_checkout(ce->name, the_repository->index))) + !path_in_sparse_checkout(ce->name, repo->index))) continue; - if (pathspec && !ce_path_match(the_repository->index, ce, pathspec, NULL)) + if (pathspec && !ce_path_match(repo->index, ce, pathspec, NULL)) continue; if (!show_only) - err = chmod_index_entry(the_repository->index, ce, flip); + err = chmod_index_entry(repo->index, ce, flip); else err = S_ISREG(ce->ce_mode) ? 0 : -1; @@ -64,31 +65,36 @@ static int chmod_pathspec(struct pathspec *pathspec, char flip, int show_only) return ret; } -static int renormalize_tracked_files(const struct pathspec *pathspec, int flags) +static int renormalize_tracked_files(struct repository *repo, + const struct pathspec *pathspec, + int flags) { int i, retval = 0; - for (i = 0; i < the_repository->index->cache_nr; i++) { - struct cache_entry *ce = the_repository->index->cache[i]; + for (i = 0; i < repo->index->cache_nr; i++) { + struct cache_entry *ce = repo->index->cache[i]; if (!include_sparse && (ce_skip_worktree(ce) || - !path_in_sparse_checkout(ce->name, the_repository->index))) + !path_in_sparse_checkout(ce->name, repo->index))) continue; if (ce_stage(ce)) continue; /* do not touch unmerged paths */ if (!S_ISREG(ce->ce_mode) && !S_ISLNK(ce->ce_mode)) continue; /* do not touch non blobs */ - if (pathspec && !ce_path_match(the_repository->index, ce, pathspec, NULL)) + if (pathspec && !ce_path_match(repo->index, ce, pathspec, NULL)) continue; - retval |= add_file_to_index(the_repository->index, ce->name, + retval |= add_file_to_index(repo->index, ce->name, flags | ADD_CACHE_RENORMALIZE); } return retval; } -static char *prune_directory(struct dir_struct *dir, struct pathspec *pathspec, int prefix) +static char *prune_directory(struct repository *repo, + struct dir_struct *dir, + struct pathspec *pathspec, + int prefix) { char *seen; int i; @@ -100,16 +106,16 @@ static char *prune_directory(struct dir_struct *dir, struct pathspec *pathspec, i = dir->nr; while (--i >= 0) { struct dir_entry *entry = *src++; - if (dir_path_match(the_repository->index, entry, pathspec, prefix, seen)) + if (dir_path_match(repo->index, entry, pathspec, prefix, seen)) *dst++ = entry; } dir->nr = dst - dir->entries; - add_pathspec_matches_against_index(pathspec, the_repository->index, seen, + add_pathspec_matches_against_index(pathspec, repo->index, seen, PS_IGNORE_SKIP_WORKTREE); return seen; } -static int refresh(int verbose, const struct pathspec *pathspec) +static int refresh(struct repository *repo, int verbose, const struct pathspec *pathspec) { char *seen; int i, ret = 0; @@ -119,14 +125,14 @@ static int refresh(int verbose, const struct pathspec *pathspec) (verbose ? REFRESH_IN_PORCELAIN : REFRESH_QUIET); seen = xcalloc(pathspec->nr, 1); - refresh_index(the_repository->index, flags, pathspec, seen, + refresh_index(repo->index, flags, pathspec, seen, _("Unstaged changes after refreshing the index:")); for (i = 0; i < pathspec->nr; i++) { if (!seen[i]) { const char *path = pathspec->items[i].original; if (matches_skip_worktree(pathspec, i, &skip_worktree_seen) || - !path_in_sparse_checkout(path, the_repository->index)) { + !path_in_sparse_checkout(path, repo->index)) { string_list_append(&only_match_skip_worktree, pathspec->items[i].original); } else { @@ -147,7 +153,10 @@ static int refresh(int verbose, const struct pathspec *pathspec) return ret; } -int interactive_add(const char **argv, const char *prefix, int patch) +int interactive_add(struct repository *repo, + const char **argv, + const char *prefix, + int patch) { struct pathspec pathspec; int ret; @@ -159,28 +168,31 @@ int interactive_add(const char **argv, const char *prefix, int patch) prefix, argv); if (patch) - ret = !!run_add_p(the_repository, ADD_P_ADD, NULL, &pathspec); + ret = !!run_add_p(repo, ADD_P_ADD, NULL, &pathspec); else - ret = !!run_add_i(the_repository, &pathspec); + ret = !!run_add_i(repo, &pathspec); clear_pathspec(&pathspec); return ret; } -static int edit_patch(int argc, const char **argv, const char *prefix) +static int edit_patch(struct repository *repo, + int argc, + const char **argv, + const char *prefix) { - char *file = git_pathdup("ADD_EDIT.patch"); + char *file = repo_git_path(repo, "ADD_EDIT.patch"); struct child_process child = CHILD_PROCESS_INIT; struct rev_info rev; int out; struct stat st; - git_config(git_diff_basic_config, NULL); /* no "diff" UI options */ + repo_config(repo, git_diff_basic_config, NULL); - if (repo_read_index(the_repository) < 0) + if (repo_read_index(repo) < 0) die(_("could not read the index")); - repo_init_revisions(the_repository, &rev, prefix); + repo_init_revisions(repo, &rev, prefix); rev.diffopt.context = 7; argc = setup_revisions(argc, argv, &rev, NULL); @@ -318,7 +330,7 @@ static void check_embedded_repo(const char *path) strbuf_release(&name); } -static int add_files(struct dir_struct *dir, int flags) +static int add_files(struct repository *repo, struct dir_struct *dir, int flags) { int i, exit_status = 0; struct string_list matched_sparse_paths = STRING_LIST_INIT_NODUP; @@ -334,12 +346,12 @@ static int add_files(struct dir_struct *dir, int flags) for (i = 0; i < dir->nr; i++) { if (!include_sparse && - !path_in_sparse_checkout(dir->entries[i]->name, the_repository->index)) { + !path_in_sparse_checkout(dir->entries[i]->name, repo->index)) { string_list_append(&matched_sparse_paths, dir->entries[i]->name); continue; } - if (add_file_to_index(the_repository->index, dir->entries[i]->name, flags)) { + if (add_file_to_index(repo->index, dir->entries[i]->name, flags)) { if (!ignore_add_errors) die(_("adding files failed")); exit_status = 1; @@ -358,7 +370,10 @@ static int add_files(struct dir_struct *dir, int flags) return exit_status; } -int cmd_add(int argc, const char **argv, const char *prefix) +int cmd_add(int argc, + const char **argv, + const char *prefix, + struct repository *repo) { int exit_status = 0; struct pathspec pathspec; @@ -370,7 +385,7 @@ int cmd_add(int argc, const char **argv, const char *prefix) char *ps_matched = NULL; struct lock_file lock_file = LOCK_INIT; - git_config(add_config, NULL); + repo_config(repo, add_config, NULL); argc = parse_options(argc, argv, prefix, builtin_add_options, builtin_add_usage, PARSE_OPT_KEEP_ARGV0); @@ -381,13 +396,13 @@ int cmd_add(int argc, const char **argv, const char *prefix) die(_("options '%s' and '%s' cannot be used together"), "--dry-run", "--interactive/--patch"); if (pathspec_from_file) die(_("options '%s' and '%s' cannot be used together"), "--pathspec-from-file", "--interactive/--patch"); - exit(interactive_add(argv + 1, prefix, patch_interactive)); + exit(interactive_add(repo, argv + 1, prefix, patch_interactive)); } if (edit_interactive) { if (pathspec_from_file) die(_("options '%s' and '%s' cannot be used together"), "--pathspec-from-file", "--edit"); - return(edit_patch(argc, argv, prefix)); + return(edit_patch(repo, argc, argv, prefix)); } argc--; argv++; @@ -410,10 +425,10 @@ int cmd_add(int argc, const char **argv, const char *prefix) add_new_files = !take_worktree_changes && !refresh_only && !add_renormalize; require_pathspec = !(take_worktree_changes || (0 < addremove_explicit)); - prepare_repo_settings(the_repository); - the_repository->settings.command_requires_full_index = 0; + prepare_repo_settings(repo); + repo->settings.command_requires_full_index = 0; - repo_hold_locked_index(the_repository, &lock_file, LOCK_DIE_ON_ERROR); + repo_hold_locked_index(repo, &lock_file, LOCK_DIE_ON_ERROR); /* * Check the "pathspec '%s' did not match any files" block @@ -454,11 +469,11 @@ int cmd_add(int argc, const char **argv, const char *prefix) (!(addremove || take_worktree_changes) ? ADD_CACHE_IGNORE_REMOVAL : 0)); - if (repo_read_index_preload(the_repository, &pathspec, 0) < 0) + if (repo_read_index_preload(repo, &pathspec, 0) < 0) die(_("index file corrupt")); - die_in_unpopulated_submodule(the_repository->index, prefix); - die_path_inside_submodule(the_repository->index, &pathspec); + die_in_unpopulated_submodule(repo->index, prefix); + die_path_inside_submodule(repo->index, &pathspec); if (add_new_files) { int baselen; @@ -470,13 +485,13 @@ int cmd_add(int argc, const char **argv, const char *prefix) } /* This picks up the paths that are not tracked */ - baselen = fill_directory(&dir, the_repository->index, &pathspec); + baselen = fill_directory(&dir, repo->index, &pathspec); if (pathspec.nr) - seen = prune_directory(&dir, &pathspec, baselen); + seen = prune_directory(repo, &dir, &pathspec, baselen); } if (refresh_only) { - exit_status |= refresh(verbose, &pathspec); + exit_status |= refresh(repo, verbose, &pathspec); goto finish; } @@ -487,7 +502,7 @@ int cmd_add(int argc, const char **argv, const char *prefix) if (!seen) seen = find_pathspecs_matching_against_index(&pathspec, - the_repository->index, PS_IGNORE_SKIP_WORKTREE); + repo->index, PS_IGNORE_SKIP_WORKTREE); /* * file_exists() assumes exact match @@ -523,8 +538,8 @@ int cmd_add(int argc, const char **argv, const char *prefix) !file_exists(path)) { if (ignore_missing) { int dtype = DT_UNKNOWN; - if (is_excluded(&dir, the_repository->index, path, &dtype)) - dir_add_ignored(&dir, the_repository->index, + if (is_excluded(&dir, repo->index, path, &dtype)) + dir_add_ignored(&dir, repo->index, path, pathspec.items[i].len); } else die(_("pathspec '%s' did not match any files"), @@ -547,9 +562,9 @@ int cmd_add(int argc, const char **argv, const char *prefix) ps_matched = xcalloc(pathspec.nr, 1); if (add_renormalize) - exit_status |= renormalize_tracked_files(&pathspec, flags); + exit_status |= renormalize_tracked_files(repo, &pathspec, flags); else - exit_status |= add_files_to_cache(the_repository, prefix, + exit_status |= add_files_to_cache(repo, prefix, &pathspec, ps_matched, include_sparse, flags); @@ -558,14 +573,14 @@ int cmd_add(int argc, const char **argv, const char *prefix) exit(128); if (add_new_files) - exit_status |= add_files(&dir, flags); + exit_status |= add_files(repo, &dir, flags); if (chmod_arg && pathspec.nr) - exit_status |= chmod_pathspec(&pathspec, chmod_arg[0], show_only); + exit_status |= chmod_pathspec(repo, &pathspec, chmod_arg[0], show_only); end_odb_transaction(); finish: - if (write_locked_index(the_repository->index, &lock_file, + if (write_locked_index(repo->index, &lock_file, COMMIT_LOCK | SKIP_IF_UNCHANGED)) die(_("unable to write new index file")); diff --git a/builtin/am.c b/builtin/am.c index d8875ad402..bfa95147cf 100644 --- a/builtin/am.c +++ b/builtin/am.c @@ -4,6 +4,7 @@ * Based on git-am.sh by Junio C Hamano. */ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "abspath.h" #include "advice.h" @@ -38,7 +39,6 @@ #include "string-list.h" #include "pager.h" #include "path.h" -#include "repository.h" #include "pretty.h" /** @@ -1544,7 +1544,8 @@ static int run_apply(const struct am_state *state, const char *index_file) if (index_file) { /* Reload index as apply_all_patches() will have modified it. */ discard_index(the_repository->index); - read_index_from(the_repository->index, index_file, get_git_dir()); + read_index_from(the_repository->index, index_file, + repo_get_git_dir(the_repository)); } return 0; @@ -1587,7 +1588,7 @@ static int fall_back_threeway(const struct am_state *state, const char *index_pa return error("could not build fake ancestor"); discard_index(the_repository->index); - read_index_from(the_repository->index, index_path, get_git_dir()); + read_index_from(the_repository->index, index_path, repo_get_git_dir(the_repository)); if (write_index_as_tree(&bases[0], the_repository->index, index_path, 0, NULL)) return error(_("Repository lacks necessary blobs to fall back on 3-way merge.")); @@ -1667,7 +1668,9 @@ static void do_commit(const struct am_state *state) if (!state->no_verify && run_hooks(the_repository, "pre-applypatch")) exit(1); - if (write_index_as_tree(&tree, the_repository->index, get_index_file(), 0, NULL)) + if (write_index_as_tree(&tree, the_repository->index, + repo_get_index_file(the_repository), + 0, NULL)) die(_("git write-tree failed to write a tree")); if (!repo_get_oid_commit(the_repository, "HEAD", &parent)) { @@ -2077,7 +2080,9 @@ static int clean_index(const struct object_id *head, const struct object_id *rem if (fast_forward_to(head_tree, head_tree, 1)) return -1; - if (write_index_as_tree(&index, the_repository->index, get_index_file(), 0, NULL)) + if (write_index_as_tree(&index, the_repository->index, + repo_get_index_file(the_repository), + 0, NULL)) return -1; index_tree = parse_tree_indirect(&index); @@ -2298,7 +2303,10 @@ static int parse_opt_show_current_patch(const struct option *opt, const char *ar return 0; } -int cmd_am(int argc, const char **argv, const char *prefix) +int cmd_am(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct am_state state; int binary = -1; diff --git a/builtin/annotate.c b/builtin/annotate.c index 58ff977a23..a99179fe4d 100644 --- a/builtin/annotate.c +++ b/builtin/annotate.c @@ -3,11 +3,16 @@ * * Copyright (C) 2006 Ryan Anderson */ + +#define USE_THE_REPOSITORY_VARIABLE #include "git-compat-util.h" #include "builtin.h" #include "strvec.h" -int cmd_annotate(int argc, const char **argv, const char *prefix) +int cmd_annotate(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct strvec args = STRVEC_INIT; int i; @@ -18,5 +23,5 @@ int cmd_annotate(int argc, const char **argv, const char *prefix) strvec_push(&args, argv[i]); } - return cmd_blame(args.nr, args.v, prefix); + return cmd_blame(args.nr, args.v, prefix, the_repository); } diff --git a/builtin/apply.c b/builtin/apply.c index d623c52f78..84f1863d3a 100644 --- a/builtin/apply.c +++ b/builtin/apply.c @@ -1,6 +1,6 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "gettext.h" -#include "repository.h" #include "hash.h" #include "apply.h" @@ -9,7 +9,10 @@ static const char * const apply_usage[] = { NULL }; -int cmd_apply(int argc, const char **argv, const char *prefix) +int cmd_apply(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { int force_apply = 0; int options = 0; diff --git a/builtin/archive.c b/builtin/archive.c index 63f02990d1..dc926d1a3d 100644 --- a/builtin/archive.c +++ b/builtin/archive.c @@ -2,13 +2,13 @@ * Copyright (c) 2006 Franck Bui-Huu * Copyright (c) 2006 Rene Scharfe */ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "archive.h" #include "gettext.h" #include "transport.h" #include "parse-options.h" #include "pkt-line.h" -#include "repository.h" static void create_output_file(const char *output_file) { @@ -76,7 +76,10 @@ static int run_remote_archiver(int argc, const char **argv, PARSE_OPT_KEEP_UNKNOWN_OPT | \ PARSE_OPT_NO_INTERNAL_HELP ) -int cmd_archive(int argc, const char **argv, const char *prefix) +int cmd_archive(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { const char *exec = "git-upload-archive"; char *output = NULL; diff --git a/builtin/bisect.c b/builtin/bisect.c index c8aa92b19d..21d17a6c1a 100644 --- a/builtin/bisect.c +++ b/builtin/bisect.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "copy.h" #include "environment.h" @@ -1411,7 +1412,10 @@ static int cmd_bisect__run(int argc, const char **argv, const char *prefix UNUSE return res; } -int cmd_bisect(int argc, const char **argv, const char *prefix) +int cmd_bisect(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { int res = 0; parse_opt_subcommand_fn *fn = NULL; diff --git a/builtin/blame.c b/builtin/blame.c index 35e975fb13..e407a22da3 100644 --- a/builtin/blame.c +++ b/builtin/blame.c @@ -4,7 +4,7 @@ * Copyright (c) 2006, 2014 by its authors * See COPYING for licensing conditions */ - +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "color.h" @@ -12,7 +12,6 @@ #include "environment.h" #include "gettext.h" #include "hex.h" -#include "repository.h" #include "commit.h" #include "diff.h" #include "revision.h" @@ -864,7 +863,10 @@ static void build_ignorelist(struct blame_scoreboard *sb, } } -int cmd_blame(int argc, const char **argv, const char *prefix) +int cmd_blame(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct rev_info revs; char *path = NULL; @@ -1081,7 +1083,7 @@ parse_done: path = add_prefix(prefix, argv[1]); argv[1] = argv[2]; } else { /* (2a) */ - if (argc == 2 && is_a_rev(argv[1]) && !get_git_work_tree()) + if (argc == 2 && is_a_rev(argv[1]) && !repo_get_work_tree(the_repository)) die("missing <path> to blame"); path = add_prefix(prefix, argv[argc - 1]); } diff --git a/builtin/branch.c b/builtin/branch.c index c98601c6fe..fd1611ebf5 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -4,7 +4,7 @@ * Copyright (c) 2006 Kristian Høgsberg <krh@redhat.com> * Based on git-branch.sh by Junio C Hamano. */ - +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "color.h" @@ -704,7 +704,10 @@ static int edit_branch_description(const char *branch_name) return 0; } -int cmd_branch(int argc, const char **argv, const char *prefix) +int cmd_branch(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { /* possible actions */ int delete = 0, rename = 0, copy = 0, list = 0, diff --git a/builtin/bugreport.c b/builtin/bugreport.c index bdfed3d8f1..7c2df035c9 100644 --- a/builtin/bugreport.c +++ b/builtin/bugreport.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "abspath.h" #include "editor.h" @@ -98,7 +99,10 @@ static void get_header(struct strbuf *buf, const char *title) strbuf_addf(buf, "\n\n[%s]\n", title); } -int cmd_bugreport(int argc, const char **argv, const char *prefix) +int cmd_bugreport(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct strbuf buffer = STRBUF_INIT; struct strbuf report_path = STRBUF_INIT; diff --git a/builtin/bundle.c b/builtin/bundle.c index b858552ee6..127518c2a8 100644 --- a/builtin/bundle.c +++ b/builtin/bundle.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "abspath.h" #include "gettext.h" @@ -5,7 +6,6 @@ #include "strvec.h" #include "parse-options.h" #include "pkt-line.h" -#include "repository.h" #include "bundle.h" /* @@ -228,7 +228,10 @@ cleanup: return ret; } -int cmd_bundle(int argc, const char **argv, const char *prefix) +int cmd_bundle(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { parse_opt_subcommand_fn *fn = NULL; struct option options[] = { diff --git a/builtin/cat-file.c b/builtin/cat-file.c index 1afdfb5cba..bfdfb51c7c 100644 --- a/builtin/cat-file.c +++ b/builtin/cat-file.c @@ -3,7 +3,7 @@ * * Copyright (C) Linus Torvalds, 2005 */ - +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "convert.h" @@ -191,7 +191,7 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name, const char *ls_args[3] = { NULL }; ls_args[0] = "ls-tree"; ls_args[1] = obj_name; - ret = cmd_ls_tree(2, ls_args, NULL); + ret = cmd_ls_tree(2, ls_args, NULL, the_repository); goto cleanup; } @@ -923,7 +923,10 @@ static int batch_option_callback(const struct option *opt, return 0; } -int cmd_cat_file(int argc, const char **argv, const char *prefix) +int cmd_cat_file(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { int opt = 0; int opt_cw = 0; diff --git a/builtin/check-attr.c b/builtin/check-attr.c index 9376810710..7cf275b893 100644 --- a/builtin/check-attr.c +++ b/builtin/check-attr.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "attr.h" @@ -5,7 +6,6 @@ #include "gettext.h" #include "object-name.h" #include "quote.h" -#include "repository.h" #include "setup.h" #include "parse-options.h" #include "write-or-die.h" @@ -107,7 +107,10 @@ static NORETURN void error_with_usage(const char *msg) usage_with_options(check_attr_usage, check_attr_options); } -int cmd_check_attr(int argc, const char **argv, const char *prefix) +int cmd_check_attr(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct attr_check *check; struct object_id initialized_oid; diff --git a/builtin/check-ignore.c b/builtin/check-ignore.c index 2bda6a1d46..7b7831d13a 100644 --- a/builtin/check-ignore.c +++ b/builtin/check-ignore.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "dir.h" @@ -5,7 +6,6 @@ #include "quote.h" #include "pathspec.h" #include "parse-options.h" -#include "repository.h" #include "submodule.h" #include "write-or-die.h" @@ -151,7 +151,10 @@ static int check_ignore_stdin_paths(struct dir_struct *dir, const char *prefix) return num_ignored; } -int cmd_check_ignore(int argc, const char **argv, const char *prefix) +int cmd_check_ignore(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { int num_ignored; struct dir_struct dir = DIR_INIT; diff --git a/builtin/check-mailmap.c b/builtin/check-mailmap.c index 2334b57222..df00b5ee13 100644 --- a/builtin/check-mailmap.c +++ b/builtin/check-mailmap.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "gettext.h" @@ -47,7 +48,10 @@ static void check_mailmap(struct string_list *mailmap, const char *contact) printf("<%.*s>\n", (int)maillen, mail); } -int cmd_check_mailmap(int argc, const char **argv, const char *prefix) +int cmd_check_mailmap(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { int i; struct string_list mailmap = STRING_LIST_INIT_NODUP; diff --git a/builtin/check-ref-format.c b/builtin/check-ref-format.c index 5eb6bdc3f6..e86d8ef980 100644 --- a/builtin/check-ref-format.c +++ b/builtin/check-ref-format.c @@ -1,7 +1,6 @@ /* * GIT - The information manager from hell */ - #include "builtin.h" #include "refs.h" #include "setup.h" @@ -51,7 +50,10 @@ static int check_ref_format_branch(const char *arg) return 0; } -int cmd_check_ref_format(int argc, const char **argv, const char *prefix) +int cmd_check_ref_format(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { int i; int normalize = 0; diff --git a/builtin/checkout--worker.c b/builtin/checkout--worker.c index 6b62b5375b..ff6cdccc21 100644 --- a/builtin/checkout--worker.c +++ b/builtin/checkout--worker.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "entry.h" @@ -113,7 +114,10 @@ static const char * const checkout_worker_usage[] = { NULL }; -int cmd_checkout__worker(int argc, const char **argv, const char *prefix) +int cmd_checkout__worker(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct checkout state = CHECKOUT_INIT; struct option checkout_worker_options[] = { diff --git a/builtin/checkout-index.c b/builtin/checkout-index.c index 29e744d11b..6dd38eb05d 100644 --- a/builtin/checkout-index.c +++ b/builtin/checkout-index.c @@ -4,13 +4,12 @@ * Copyright (C) 2005 Linus Torvalds * */ - +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "gettext.h" #include "lockfile.h" #include "quote.h" -#include "repository.h" #include "cache-tree.h" #include "parse-options.h" #include "entry.h" @@ -208,7 +207,10 @@ static int option_parse_stage(const struct option *opt, return 0; } -int cmd_checkout_index(int argc, const char **argv, const char *prefix) +int cmd_checkout_index(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { int i; struct lock_file lock_file = LOCK_INIT; diff --git a/builtin/checkout.c b/builtin/checkout.c index 4cfe6fab50..9c30000d3a 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "advice.h" #include "branch.h" @@ -23,6 +24,7 @@ #include "read-cache.h" #include "refs.h" #include "remote.h" +#include "repo-settings.h" #include "resolve-undo.h" #include "revision.h" #include "setup.h" @@ -950,11 +952,13 @@ static void update_refs_for_switch(const struct checkout_opts *opts, const char *old_desc, *reflog_msg; if (opts->new_branch) { if (opts->new_orphan_branch) { + enum log_refs_config log_all_ref_updates = + repo_settings_get_log_all_ref_updates(the_repository); char *refname; refname = mkpathdup("refs/heads/%s", opts->new_orphan_branch); if (opts->new_branch_log && - !should_autocreate_reflog(refname)) { + !should_autocreate_reflog(log_all_ref_updates, refname)) { int ret; struct strbuf err = STRBUF_INIT; @@ -1953,7 +1957,10 @@ static int checkout_main(int argc, const char **argv, const char *prefix, return ret; } -int cmd_checkout(int argc, const char **argv, const char *prefix) +int cmd_checkout(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct checkout_opts opts = CHECKOUT_OPTS_INIT; struct option *options; @@ -2000,7 +2007,10 @@ int cmd_checkout(int argc, const char **argv, const char *prefix) checkout_usage); } -int cmd_switch(int argc, const char **argv, const char *prefix) +int cmd_switch(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct checkout_opts opts = CHECKOUT_OPTS_INIT; struct option *options = NULL; @@ -2036,7 +2046,10 @@ int cmd_switch(int argc, const char **argv, const char *prefix) switch_branch_usage); } -int cmd_restore(int argc, const char **argv, const char *prefix) +int cmd_restore(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct checkout_opts opts = CHECKOUT_OPTS_INIT; struct option *options; diff --git a/builtin/clean.c b/builtin/clean.c index ded5a91534..9c48dd0271 100644 --- a/builtin/clean.c +++ b/builtin/clean.c @@ -5,7 +5,7 @@ * * Based on git-clean.sh by Pavel Roskin */ - +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "abspath.h" #include "config.h" @@ -14,7 +14,6 @@ #include "parse-options.h" #include "path.h" #include "read-cache-ll.h" -#include "repository.h" #include "setup.h" #include "string-list.h" #include "quote.h" @@ -915,7 +914,10 @@ static void correct_untracked_entries(struct dir_struct *dir) dir->nr = dst; } -int cmd_clean(int argc, const char **argv, const char *prefix) +int cmd_clean(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { int i, res; int dry_run = 0, remove_directories = 0, quiet = 0, ignored = 0; diff --git a/builtin/clone.c b/builtin/clone.c index 269b6e18a4..e77339c847 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -7,8 +7,9 @@ * * Clone a repository into a different directory that does not yet exist. */ - +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" + #include "abspath.h" #include "advice.h" #include "config.h" @@ -956,7 +957,10 @@ static int path_exists(const char *path) return !stat(path, &sb); } -int cmd_clone(int argc, const char **argv, const char *prefix) +int cmd_clone(int argc, + const char **argv, + const char *prefix, + struct repository *repository UNUSED) { int is_bundle = 0, is_local; int reject_shallow = 0; diff --git a/builtin/column.c b/builtin/column.c index 10ff7e0166..50314cc255 100644 --- a/builtin/column.c +++ b/builtin/column.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "gettext.h" @@ -18,7 +19,10 @@ static int column_config(const char *var, const char *value, return git_column_config(var, value, cb, &colopts); } -int cmd_column(int argc, const char **argv, const char *prefix) +int cmd_column(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct string_list list = STRING_LIST_INIT_DUP; struct strbuf sb = STRBUF_INIT; diff --git a/builtin/commit-graph.c b/builtin/commit-graph.c index 7102ee90a0..7c991db6eb 100644 --- a/builtin/commit-graph.c +++ b/builtin/commit-graph.c @@ -1,11 +1,10 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "commit.h" #include "config.h" -#include "environment.h" #include "gettext.h" #include "hex.h" #include "parse-options.h" -#include "repository.h" #include "commit-graph.h" #include "object-store-ll.h" #include "progress.h" @@ -95,7 +94,7 @@ static int graph_verify(int argc, const char **argv, const char *prefix) usage_with_options(builtin_commit_graph_verify_usage, options); if (!opts.obj_dir) - opts.obj_dir = get_object_directory(); + opts.obj_dir = repo_get_object_directory(the_repository); if (opts.shallow) flags |= COMMIT_GRAPH_VERIFY_SHALLOW; if (opts.progress) @@ -275,7 +274,7 @@ static int graph_write(int argc, const char **argv, const char *prefix) if (opts.reachable + opts.stdin_packs + opts.stdin_commits > 1) die(_("use at most one of --reachable, --stdin-commits, or --stdin-packs")); if (!opts.obj_dir) - opts.obj_dir = get_object_directory(); + opts.obj_dir = repo_get_object_directory(the_repository); if (opts.append) flags |= COMMIT_GRAPH_WRITE_APPEND; if (opts.split) @@ -331,7 +330,10 @@ cleanup: return result; } -int cmd_commit_graph(int argc, const char **argv, const char *prefix) +int cmd_commit_graph(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { parse_opt_subcommand_fn *fn = NULL; struct option builtin_commit_graph_options[] = { diff --git a/builtin/commit-tree.c b/builtin/commit-tree.c index 84bb450222..2ca1a57ebb 100644 --- a/builtin/commit-tree.c +++ b/builtin/commit-tree.c @@ -3,13 +3,14 @@ * * Copyright (C) Linus Torvalds, 2005 */ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "gettext.h" #include "hex.h" #include "object-name.h" #include "object-store-ll.h" -#include "repository.h" + #include "commit.h" #include "parse-options.h" @@ -90,7 +91,10 @@ static int parse_file_arg_callback(const struct option *opt, return 0; } -int cmd_commit_tree(int argc, const char **argv, const char *prefix) +int cmd_commit_tree(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { static struct strbuf buffer = STRBUF_INIT; struct commit_list *parents = NULL; diff --git a/builtin/commit.c b/builtin/commit.c index b2033c4887..8db4e9df0c 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -4,7 +4,7 @@ * Copyright (c) 2007 Kristian Høgsberg <krh@redhat.com> * Based on git-commit.sh by Junio C Hamano and Linus Torvalds */ - +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "advice.h" #include "config.h" @@ -26,6 +26,7 @@ #include "path.h" #include "preload-index.h" #include "read-cache.h" +#include "repository.h" #include "string-list.h" #include "rerere.h" #include "unpack-trees.h" @@ -395,7 +396,7 @@ static const char *prepare_index(const char **argv, const char *prefix, old_index_env = xstrdup_or_null(getenv(INDEX_ENVIRONMENT)); setenv(INDEX_ENVIRONMENT, the_repository->index_file, 1); - if (interactive_add(argv, prefix, patch_interactive) != 0) + if (interactive_add(the_repository, argv, prefix, patch_interactive) != 0) die(_("interactive add failed")); the_repository->index_file = old_repo_index_file; @@ -407,7 +408,7 @@ static const char *prepare_index(const char **argv, const char *prefix, discard_index(the_repository->index); read_index_from(the_repository->index, get_lock_file_path(&index_lock), - get_git_dir()); + repo_get_git_dir(the_repository)); if (cache_tree_update(the_repository->index, WRITE_TREE_SILENT) == 0) { if (reopen_lock_file(&index_lock) < 0) die(_("unable to write index file")); @@ -472,7 +473,7 @@ static const char *prepare_index(const char **argv, const char *prefix, COMMIT_LOCK | SKIP_IF_UNCHANGED)) die(_("unable to write new index file")); commit_style = COMMIT_AS_IS; - ret = get_index_file(); + ret = repo_get_index_file(the_repository); goto out; } @@ -534,7 +535,7 @@ static const char *prepare_index(const char **argv, const char *prefix, discard_index(the_repository->index); ret = get_lock_file_path(&false_lock); - read_index_from(the_repository->index, ret, get_git_dir()); + read_index_from(the_repository->index, ret, repo_get_git_dir(the_repository)); out: string_list_clear(&partial, 0); clear_pathspec(&pathspec); @@ -1072,7 +1073,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix, */ discard_index(the_repository->index); } - read_index_from(the_repository->index, index_file, get_git_dir()); + read_index_from(the_repository->index, index_file, repo_get_git_dir(the_repository)); if (cache_tree_update(the_repository->index, 0)) { error(_("Error building trees")); @@ -1502,7 +1503,10 @@ static int git_status_config(const char *k, const char *v, return git_diff_ui_config(k, v, ctx, NULL); } -int cmd_status(int argc, const char **argv, const char *prefix) +int cmd_status(int argc, +const char **argv, +const char *prefix, +struct repository *repo UNUSED) { static int no_renames = -1; static const char *rename_score_arg = (const char *)-1; @@ -1641,7 +1645,10 @@ static int git_commit_config(const char *k, const char *v, return git_status_config(k, v, ctx, s); } -int cmd_commit(int argc, const char **argv, const char *prefix) +int cmd_commit(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { static struct wt_status s; static struct option builtin_commit_options[] = { @@ -1873,8 +1880,8 @@ int cmd_commit(int argc, const char **argv, const char *prefix) repo_rerere(the_repository, 0); run_auto_maintenance(quiet); - run_commit_hook(use_editor, get_index_file(), NULL, "post-commit", - NULL); + run_commit_hook(use_editor, repo_get_index_file(the_repository), + NULL, "post-commit", NULL); if (amend && !no_post_rewrite) { commit_post_rewrite(the_repository, current_head, &oid); } diff --git a/builtin/config.c b/builtin/config.c index 95c8a00915..d8fd3def0e 100644 --- a/builtin/config.c +++ b/builtin/config.c @@ -1,10 +1,10 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "abspath.h" #include "config.h" #include "color.h" #include "editor.h" #include "environment.h" -#include "repository.h" #include "gettext.h" #include "ident.h" #include "parse-options.h" @@ -807,8 +807,8 @@ static void location_options_init(struct config_location_options *opts, else opts->options.respect_includes = opts->respect_includes_opt; if (startup_info->have_repository) { - opts->options.commondir = get_git_common_dir(); - opts->options.git_dir = get_git_dir(); + opts->options.commondir = repo_get_common_dir(the_repository); + opts->options.git_dir = repo_get_git_dir(the_repository); } } @@ -1392,7 +1392,10 @@ out: return ret; } -int cmd_config(int argc, const char **argv, const char *prefix) +int cmd_config(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { parse_opt_subcommand_fn *subcommand = NULL; struct option subcommand_opts[] = { diff --git a/builtin/count-objects.c b/builtin/count-objects.c index ec6098a149..04d80887e0 100644 --- a/builtin/count-objects.c +++ b/builtin/count-objects.c @@ -3,14 +3,12 @@ * * Copyright (c) 2006 Junio C Hamano */ - +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "dir.h" -#include "environment.h" #include "gettext.h" #include "path.h" -#include "repository.h" #include "parse-options.h" #include "quote.h" #include "packfile.h" @@ -95,7 +93,10 @@ static char const * const count_objects_usage[] = { NULL }; -int cmd_count_objects(int argc, const char **argv, const char *prefix) +int cmd_count_objects(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { int human_readable = 0; struct option opts[] = { @@ -116,7 +117,7 @@ int cmd_count_objects(int argc, const char **argv, const char *prefix) report_linked_checkout_garbage(the_repository); } - for_each_loose_file_in_objdir(get_object_directory(), + for_each_loose_file_in_objdir(repo_get_object_directory(the_repository), count_loose, count_cruft, NULL, NULL); if (verbose) { diff --git a/builtin/credential-cache--daemon.c b/builtin/credential-cache--daemon.c index 4952b22547..bc22f5c6d2 100644 --- a/builtin/credential-cache--daemon.c +++ b/builtin/credential-cache--daemon.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "abspath.h" #include "gettext.h" @@ -287,7 +288,10 @@ static void init_socket_directory(const char *path) free(path_copy); } -int cmd_credential_cache_daemon(int argc, const char **argv, const char *prefix) +int cmd_credential_cache_daemon(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct tempfile *socket_file; const char *socket_path; @@ -330,7 +334,10 @@ int cmd_credential_cache_daemon(int argc, const char **argv, const char *prefix) #else -int cmd_credential_cache_daemon(int argc, const char **argv, const char *prefix) +int cmd_credential_cache_daemon(int argc, +const char **argv, +const char *prefix, +struct repository *repo UNUSED) { const char * const usage[] = { "git credential-cache--daemon [--debug] <socket-path>", diff --git a/builtin/credential-cache.c b/builtin/credential-cache.c index aaf2f8438b..5de8b9123b 100644 --- a/builtin/credential-cache.c +++ b/builtin/credential-cache.c @@ -137,7 +137,10 @@ static void announce_capabilities(void) credential_announce_capabilities(&c, stdout); } -int cmd_credential_cache(int argc, const char **argv, const char *prefix) +int cmd_credential_cache(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { const char *socket_path_arg = NULL; char *socket_path; diff --git a/builtin/credential-store.c b/builtin/credential-store.c index 97968bfa1c..e669e99dbf 100644 --- a/builtin/credential-store.c +++ b/builtin/credential-store.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "gettext.h" @@ -170,7 +171,10 @@ static void lookup_credential(const struct string_list *fns, struct credential * return; /* Found credential */ } -int cmd_credential_store(int argc, const char **argv, const char *prefix) +int cmd_credential_store(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { const char * const usage[] = { "git credential-store [<options>] <action>", diff --git a/builtin/credential.c b/builtin/credential.c index b72e76dd9a..14c8c6608b 100644 --- a/builtin/credential.c +++ b/builtin/credential.c @@ -1,3 +1,5 @@ +#define USE_THE_REPOSITORY_VARIABLE + #include "git-compat-util.h" #include "credential.h" #include "builtin.h" @@ -6,7 +8,10 @@ static const char usage_msg[] = "git credential (fill|approve|reject)"; -int cmd_credential(int argc, const char **argv, const char *prefix UNUSED) +int cmd_credential(int argc, + const char **argv, + const char *prefix UNUSED, + struct repository *repo UNUSED) { const char *op; struct credential c = CREDENTIAL_INIT; diff --git a/builtin/describe.c b/builtin/describe.c index 9a49a2c9b5..7330a77b38 100644 --- a/builtin/describe.c +++ b/builtin/describe.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "environment.h" @@ -571,7 +572,10 @@ static int option_parse_exact_match(const struct option *opt, const char *arg, return 0; } -int cmd_describe(int argc, const char **argv, const char *prefix) +int cmd_describe(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED ) { int contains = 0; struct option options[] = { @@ -650,7 +654,7 @@ int cmd_describe(int argc, const char **argv, const char *prefix) argv_copy[i] = args.v[i]; argv_copy[args.nr] = NULL; - ret = cmd_name_rev(args.nr, argv_copy, prefix); + ret = cmd_name_rev(args.nr, argv_copy, prefix, the_repository); strvec_clear(&args); free(argv_copy); diff --git a/builtin/diagnose.c b/builtin/diagnose.c index 4857a4395b..66a22d918e 100644 --- a/builtin/diagnose.c +++ b/builtin/diagnose.c @@ -11,7 +11,10 @@ static const char * const diagnose_usage[] = { NULL }; -int cmd_diagnose(int argc, const char **argv, const char *prefix) +int cmd_diagnose(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct strbuf zip_path = STRBUF_INIT; time_t now = time(NULL); diff --git a/builtin/diff-files.c b/builtin/diff-files.c index dd0b76e7d5..e0e0ccec23 100644 --- a/builtin/diff-files.c +++ b/builtin/diff-files.c @@ -3,13 +3,13 @@ * * Copyright (C) Linus Torvalds, 2005 */ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "diff.h" #include "diff-merges.h" #include "commit.h" #include "preload-index.h" -#include "repository.h" #include "revision.h" static const char diff_files_usage[] = @@ -17,7 +17,10 @@ static const char diff_files_usage[] = "\n" COMMON_DIFF_OPTIONS_HELP; -int cmd_diff_files(int argc, const char **argv, const char *prefix) +int cmd_diff_files(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct rev_info rev; int result; diff --git a/builtin/diff-index.c b/builtin/diff-index.c index 8bd5aa464b..ad503624c0 100644 --- a/builtin/diff-index.c +++ b/builtin/diff-index.c @@ -1,10 +1,10 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "diff.h" #include "diff-merges.h" #include "commit.h" #include "preload-index.h" -#include "repository.h" #include "revision.h" #include "setup.h" @@ -14,7 +14,10 @@ static const char diff_cache_usage[] = "\n" COMMON_DIFF_OPTIONS_HELP; -int cmd_diff_index(int argc, const char **argv, const char *prefix) +int cmd_diff_index(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct rev_info rev; unsigned int option = 0; diff --git a/builtin/diff-tree.c b/builtin/diff-tree.c index dcaad56712..4b6656bb9f 100644 --- a/builtin/diff-tree.c +++ b/builtin/diff-tree.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "diff.h" @@ -6,7 +7,6 @@ #include "hex.h" #include "log-tree.h" #include "read-cache-ll.h" -#include "repository.h" #include "revision.h" #include "tmp-objdir.h" #include "tree.h" @@ -108,7 +108,10 @@ static void diff_tree_tweak_rev(struct rev_info *rev) } } -int cmd_diff_tree(int argc, const char **argv, const char *prefix) +int cmd_diff_tree(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { char line[1000]; struct object *tree1, *tree2; diff --git a/builtin/diff.c b/builtin/diff.c index 5fb8a5545e..dca52d4221 100644 --- a/builtin/diff.c +++ b/builtin/diff.c @@ -3,7 +3,7 @@ * * Copyright (c) 2006 Junio C Hamano */ - +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "ewah/ewok.h" @@ -393,7 +393,10 @@ static void symdiff_release(struct symdiff *sdiff) bitmap_free(sdiff->skip); } -int cmd_diff(int argc, const char **argv, const char *prefix) +int cmd_diff(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { int i; struct rev_info rev; diff --git a/builtin/difftool.c b/builtin/difftool.c index dcc68e190c..4b416743ff 100644 --- a/builtin/difftool.c +++ b/builtin/difftool.c @@ -11,8 +11,9 @@ * * Copyright (C) 2016 Johannes Schindelin */ - +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" + #include "abspath.h" #include "config.h" #include "copy.h" @@ -22,6 +23,7 @@ #include "hex.h" #include "parse-options.h" #include "read-cache-ll.h" +#include "repository.h" #include "sparse-index.h" #include "strvec.h" #include "strbuf.h" @@ -214,7 +216,7 @@ static void changed_files(struct hashmap *result, const char *index_path, struct child_process update_index = CHILD_PROCESS_INIT; struct child_process diff_files = CHILD_PROCESS_INIT; struct strbuf buf = STRBUF_INIT; - const char *git_dir = absolute_path(get_git_dir()); + const char *git_dir = absolute_path(repo_get_git_dir(the_repository)); FILE *fp; strvec_pushl(&update_index.args, @@ -377,7 +379,7 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix, struct hashmap wt_modified, tmp_modified; int indices_loaded = 0; - workdir = get_git_work_tree(); + workdir = repo_get_work_tree(the_repository); /* Setup temp directories */ tmp = getenv("TMPDIR"); @@ -690,7 +692,10 @@ static int run_file_diff(int prompt, const char *prefix, return run_command(child); } -int cmd_difftool(int argc, const char **argv, const char *prefix) +int cmd_difftool(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { int use_gui_tool = -1, dir_diff = 0, prompt = -1, symlinks = 0, tool_help = 0, no_index = 0; @@ -737,8 +742,8 @@ int cmd_difftool(int argc, const char **argv, const char *prefix) if (!no_index){ setup_work_tree(); - setenv(GIT_DIR_ENVIRONMENT, absolute_path(get_git_dir()), 1); - setenv(GIT_WORK_TREE_ENVIRONMENT, absolute_path(get_git_work_tree()), 1); + setenv(GIT_DIR_ENVIRONMENT, absolute_path(repo_get_git_dir(the_repository)), 1); + setenv(GIT_WORK_TREE_ENVIRONMENT, absolute_path(repo_get_work_tree(the_repository)), 1); } else if (dir_diff) die(_("options '%s' and '%s' cannot be used together"), "--dir-diff", "--no-index"); diff --git a/builtin/fast-export.c b/builtin/fast-export.c index f253b79322..e17f262e8e 100644 --- a/builtin/fast-export.c +++ b/builtin/fast-export.c @@ -3,6 +3,7 @@ * * Copyright (C) 2007 Johannes E. Schindelin */ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "gettext.h" @@ -1180,7 +1181,10 @@ static int parse_opt_anonymize_map(const struct option *opt, return 0; } -int cmd_fast_export(int argc, const char **argv, const char *prefix) +int cmd_fast_export(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct rev_info revs; struct commit *commit; diff --git a/builtin/fast-import.c b/builtin/fast-import.c index 2214c105f1..1e7ab67f6e 100644 --- a/builtin/fast-import.c +++ b/builtin/fast-import.c @@ -1,9 +1,9 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "abspath.h" #include "environment.h" #include "gettext.h" #include "hex.h" -#include "repository.h" #include "config.h" #include "lockfile.h" #include "object.h" @@ -3537,7 +3537,10 @@ static void parse_argv(void) build_mark_map(&sub_marks_from, &sub_marks_to); } -int cmd_fast_import(int argc, const char **argv, const char *prefix) +int cmd_fast_import(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { unsigned int i; diff --git a/builtin/fetch-pack.c b/builtin/fetch-pack.c index fe404d1305..49222a36fa 100644 --- a/builtin/fetch-pack.c +++ b/builtin/fetch-pack.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "gettext.h" #include "hex.h" @@ -43,7 +44,10 @@ static void add_sought_entry(struct ref ***sought, int *nr, int *alloc, (*sought)[*nr - 1] = ref; } -int cmd_fetch_pack(int argc, const char **argv, const char *prefix UNUSED) +int cmd_fetch_pack(int argc, + const char **argv, + const char *prefix UNUSED, + struct repository *repo UNUSED) { int i, ret; struct ref *fetched_refs = NULL, *remote_refs = NULL; diff --git a/builtin/fetch.c b/builtin/fetch.c index 55f97134aa..c900f57721 100644 --- a/builtin/fetch.c +++ b/builtin/fetch.c @@ -1,13 +1,13 @@ /* * "git fetch" */ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "advice.h" #include "config.h" #include "gettext.h" #include "environment.h" #include "hex.h" -#include "repository.h" #include "refs.h" #include "refspec.h" #include "object-name.h" @@ -2138,7 +2138,10 @@ static int fetch_one(struct remote *remote, int argc, const char **argv, return exit_code; } -int cmd_fetch(int argc, const char **argv, const char *prefix) +int cmd_fetch(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct fetch_config config = { .display_format = DISPLAY_FORMAT_FULL, diff --git a/builtin/fmt-merge-msg.c b/builtin/fmt-merge-msg.c index 957786d1b3..189cd1096a 100644 --- a/builtin/fmt-merge-msg.c +++ b/builtin/fmt-merge-msg.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "fmt-merge-msg.h" @@ -9,7 +10,10 @@ static const char * const fmt_merge_msg_usage[] = { NULL }; -int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix) +int cmd_fmt_merge_msg(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { char *inpath = NULL; const char *message = NULL; @@ -67,6 +71,8 @@ int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix) return ret; write_in_full(STDOUT_FILENO, output.buf, output.len); + strbuf_release(&input); + strbuf_release(&output); free(inpath); return 0; } diff --git a/builtin/for-each-ref.c b/builtin/for-each-ref.c index c72fa05bcb..715745a262 100644 --- a/builtin/for-each-ref.c +++ b/builtin/for-each-ref.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "commit.h" #include "config.h" @@ -16,7 +17,10 @@ static char const * const for_each_ref_usage[] = { NULL }; -int cmd_for_each_ref(int argc, const char **argv, const char *prefix) +int cmd_for_each_ref(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct ref_sorting *sorting; struct string_list sorting_options = STRING_LIST_INIT_DUP; diff --git a/builtin/for-each-repo.c b/builtin/for-each-repo.c index c4fa41fda9..fae7f91cf1 100644 --- a/builtin/for-each-repo.c +++ b/builtin/for-each-repo.c @@ -1,9 +1,9 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "gettext.h" #include "parse-options.h" #include "path.h" -#include "repository.h" #include "run-command.h" #include "string-list.h" @@ -29,7 +29,10 @@ static int run_command_on_repo(const char *path, int argc, const char ** argv) return run_command(&child); } -int cmd_for_each_repo(int argc, const char **argv, const char *prefix) +int cmd_for_each_repo(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { static const char *config_key = NULL; int keep_going = 0; diff --git a/builtin/fsck.c b/builtin/fsck.c index 60f4e6fad9..7f4e2f0414 100644 --- a/builtin/fsck.c +++ b/builtin/fsck.c @@ -1,7 +1,7 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "gettext.h" #include "hex.h" -#include "repository.h" #include "config.h" #include "commit.h" #include "tree.h" @@ -925,7 +925,10 @@ static struct option fsck_opts[] = { OPT_END(), }; -int cmd_fsck(int argc, const char **argv, const char *prefix) +int cmd_fsck(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { int i; struct object_directory *odb; diff --git a/builtin/fsmonitor--daemon.c b/builtin/fsmonitor--daemon.c index 1593713f4c..dce8a3b248 100644 --- a/builtin/fsmonitor--daemon.c +++ b/builtin/fsmonitor--daemon.c @@ -1,8 +1,8 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "abspath.h" #include "config.h" #include "dir.h" -#include "environment.h" #include "gettext.h" #include "parse-options.h" #include "fsmonitor-ll.h" @@ -11,7 +11,7 @@ #include "compat/fsmonitor/fsm-health.h" #include "compat/fsmonitor/fsm-listen.h" #include "fsmonitor--daemon.h" -#include "repository.h" + #include "simple-ipc.h" #include "khash.h" #include "run-command.h" @@ -1291,7 +1291,8 @@ static int fsmonitor_run_daemon(void) /* Prepare to (recursively) watch the <worktree-root> directory. */ strbuf_init(&state.path_worktree_watch, 0); - strbuf_addstr(&state.path_worktree_watch, absolute_path(get_git_work_tree())); + strbuf_addstr(&state.path_worktree_watch, + absolute_path(repo_get_work_tree(the_repository))); state.nr_paths_watching = 1; strbuf_init(&state.alias.alias, 0); @@ -1311,7 +1312,8 @@ static int fsmonitor_run_daemon(void) strbuf_addstr(&state.path_gitdir_watch, "/.git"); if (!is_directory(state.path_gitdir_watch.buf)) { strbuf_reset(&state.path_gitdir_watch); - strbuf_addstr(&state.path_gitdir_watch, absolute_path(get_git_dir())); + strbuf_addstr(&state.path_gitdir_watch, + absolute_path(repo_get_git_dir(the_repository))); state.nr_paths_watching = 2; } @@ -1521,7 +1523,10 @@ static int try_to_start_background_daemon(void) } } -int cmd_fsmonitor__daemon(int argc, const char **argv, const char *prefix) +int cmd_fsmonitor__daemon(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { const char *subcmd; enum fsmonitor_reason reason; @@ -1584,7 +1589,7 @@ int cmd_fsmonitor__daemon(int argc, const char **argv, const char *prefix) } #else -int cmd_fsmonitor__daemon(int argc, const char **argv, const char *prefix UNUSED) +int cmd_fsmonitor__daemon(int argc, const char **argv, const char *prefix UNUSED, struct repository *repo UNUSED) { struct option options[] = { OPT_END() diff --git a/builtin/gc.c b/builtin/gc.c index 7dac971405..c3894fb6bd 100644 --- a/builtin/gc.c +++ b/builtin/gc.c @@ -9,13 +9,12 @@ * * Copyright (c) 2006 Shawn O. Pearce */ - +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "abspath.h" #include "date.h" #include "environment.h" #include "hex.h" -#include "repository.h" #include "config.h" #include "tempfile.h" #include "lockfile.h" @@ -657,7 +656,10 @@ static void gc_before_repack(struct maintenance_run_opts *opts, } } -int cmd_gc(int argc, const char **argv, const char *prefix) +int cmd_gc(int argc, +const char **argv, +const char *prefix, +struct repository *repo UNUSED) { int aggressive = 0; int quiet = 0; @@ -2132,7 +2134,7 @@ static int schtasks_schedule_task(const char *exec_path, enum schedule_priority get_schedule_cmd(&cmd, NULL); strbuf_addf(&tfilename, "%s/schedule_%s_XXXXXX", - get_git_common_dir(), frequency); + repo_get_common_dir(the_repository), frequency); tfile = xmks_tempfile(tfilename.buf); strbuf_release(&tfilename); @@ -2890,7 +2892,10 @@ static const char * const builtin_maintenance_usage[] = { NULL, }; -int cmd_maintenance(int argc, const char **argv, const char *prefix) +int cmd_maintenance(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { parse_opt_subcommand_fn *fn = NULL; struct option builtin_maintenance_options[] = { diff --git a/builtin/get-tar-commit-id.c b/builtin/get-tar-commit-id.c index 7195a072ed..6bec0d1854 100644 --- a/builtin/get-tar-commit-id.c +++ b/builtin/get-tar-commit-id.c @@ -12,7 +12,10 @@ static const char builtin_get_tar_commit_id_usage[] = #define RECORDSIZE (512) #define HEADERSIZE (2 * RECORDSIZE) -int cmd_get_tar_commit_id(int argc, const char **argv UNUSED, const char *prefix) +int cmd_get_tar_commit_id(int argc, + const char **argv UNUSED, + const char *prefix, + struct repository *repo UNUSED) { char buffer[HEADERSIZE]; struct ustar_header *header = (struct ustar_header *)buffer; diff --git a/builtin/grep.c b/builtin/grep.c index dfc3c3e8bd..f17d46a06e 100644 --- a/builtin/grep.c +++ b/builtin/grep.c @@ -3,11 +3,11 @@ * * Copyright (c) 2006 Junio C Hamano */ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "abspath.h" #include "gettext.h" #include "hex.h" -#include "repository.h" #include "config.h" #include "tag.h" #include "tree-walk.h" @@ -888,7 +888,10 @@ static int pattern_callback(const struct option *opt, const char *arg, return 0; } -int cmd_grep(int argc, const char **argv, const char *prefix) +int cmd_grep(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { int hit = 0; int cached = 0, untracked = 0, opt_exclude = -1; @@ -1133,6 +1136,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix) &oid, &oc)) { if (seen_dashdash) die(_("unable to resolve revision: %s"), arg); + object_context_release(&oc); break; } diff --git a/builtin/hash-object.c b/builtin/hash-object.c index c767414a0c..a25f0403f4 100644 --- a/builtin/hash-object.c +++ b/builtin/hash-object.c @@ -4,6 +4,7 @@ * Copyright (C) Linus Torvalds, 2005 * Copyright (C) Junio C Hamano, 2005 */ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "abspath.h" #include "config.h" @@ -84,7 +85,10 @@ static void hash_stdin_paths(const char *type, int no_filters, unsigned flags, strbuf_release(&unquoted); } -int cmd_hash_object(int argc, const char **argv, const char *prefix) +int cmd_hash_object(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { static const char * const hash_object_usage[] = { N_("git hash-object [-t <type>] [-w] [--path=<file> | --no-filters]\n" diff --git a/builtin/help.c b/builtin/help.c index dc1fbe2b98..a509241a80 100644 --- a/builtin/help.c +++ b/builtin/help.c @@ -1,6 +1,8 @@ + /* * Builtin help command */ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "exec-cmd.h" @@ -540,7 +542,7 @@ static void open_html(const char *path) static void show_html_page(const char *page) { - struct strbuf page_path; /* it leaks but we exec bellow */ + struct strbuf page_path; /* it leaks but we exec below */ get_html_page_path(&page_path, page); @@ -631,7 +633,10 @@ static void opt_mode_usage(int argc, const char *opt_mode, no_help_format(opt_mode, fmt); } -int cmd_help(int argc, const char **argv, const char *prefix) +int cmd_help(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { int nongit; enum help_format parsed_help_format; diff --git a/builtin/hook.c b/builtin/hook.c index cc37438fde..367ef3e0b8 100644 --- a/builtin/hook.c +++ b/builtin/hook.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "gettext.h" @@ -66,7 +67,10 @@ usage: usage_with_options(builtin_hook_run_usage, run_options); } -int cmd_hook(int argc, const char **argv, const char *prefix) +int cmd_hook(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { parse_opt_subcommand_fn *fn = NULL; struct option builtin_hook_options[] = { diff --git a/builtin/index-pack.c b/builtin/index-pack.c index 763b01372a..e228c56ff2 100644 --- a/builtin/index-pack.c +++ b/builtin/index-pack.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "delta.h" @@ -1718,7 +1719,10 @@ static void show_pack_info(int stat_only) free(chain_histogram); } -int cmd_index_pack(int argc, const char **argv, const char *prefix) +int cmd_index_pack(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { int i, fix_thin_pack = 0, verify = 0, stat_only = 0, rev_index; const char *curr_index; diff --git a/builtin/init-db.c b/builtin/init-db.c index 582dcf20f8..7e00d57d65 100644 --- a/builtin/init-db.c +++ b/builtin/init-db.c @@ -3,6 +3,7 @@ * * Copyright (C) Linus Torvalds, 2005 */ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "abspath.h" #include "environment.h" @@ -11,7 +12,6 @@ #include "parse-options.h" #include "path.h" #include "refs.h" -#include "repository.h" #include "setup.h" #include "strbuf.h" @@ -70,7 +70,10 @@ static const char *const init_db_usage[] = { * On the other hand, it might just make lookup slower and messier. You * be the judge. The default case is to have one DB per managed directory. */ -int cmd_init_db(int argc, const char **argv, const char *prefix) +int cmd_init_db(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { const char *git_dir; const char *real_git_dir = NULL; @@ -231,9 +234,9 @@ int cmd_init_db(int argc, const char **argv, const char *prefix) set_git_work_tree(work_tree); else set_git_work_tree(git_work_tree_cfg); - if (access(get_git_work_tree(), X_OK)) + if (access(repo_get_work_tree(the_repository), X_OK)) die_errno (_("Cannot access work tree '%s'"), - get_git_work_tree()); + repo_get_work_tree(the_repository)); } else { if (real_git_dir) diff --git a/builtin/interpret-trailers.c b/builtin/interpret-trailers.c index e6f22459f1..c5e56e2cd3 100644 --- a/builtin/interpret-trailers.c +++ b/builtin/interpret-trailers.c @@ -4,7 +4,7 @@ * Copyright (c) 2013, 2014 Christian Couder <chriscool@tuxfamily.org> * */ - +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "gettext.h" #include "parse-options.h" @@ -189,7 +189,10 @@ static void interpret_trailers(const struct process_trailer_options *opts, strbuf_release(&sb); } -int cmd_interpret_trailers(int argc, const char **argv, const char *prefix) +int cmd_interpret_trailers(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct process_trailer_options opts = PROCESS_TRAILER_OPTIONS_INIT; LIST_HEAD(trailers); diff --git a/builtin/log.c b/builtin/log.c index b49b59621f..368f6580a6 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -4,6 +4,7 @@ * (C) Copyright 2006 Linus Torvalds * 2006 Junio Hamano */ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "abspath.h" #include "config.h" @@ -37,7 +38,7 @@ #include "mailmap.h" #include "progress.h" #include "commit-slab.h" -#include "repository.h" + #include "commit-reach.h" #include "range-diff.h" #include "tmp-objdir.h" @@ -627,7 +628,10 @@ static int git_log_config(const char *var, const char *value, return git_diff_ui_config(var, value, ctx, cb); } -int cmd_whatchanged(int argc, const char **argv, const char *prefix) +int cmd_whatchanged(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct log_config cfg; struct rev_info rev; @@ -748,7 +752,10 @@ static void show_setup_revisions_tweak(struct rev_info *rev) rev->diffopt.output_format = DIFF_FORMAT_PATCH; } -int cmd_show(int argc, const char **argv, const char *prefix) +int cmd_show(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct log_config cfg; struct rev_info rev; @@ -864,7 +871,10 @@ int cmd_show(int argc, const char **argv, const char *prefix) /* * This is equivalent to "git log -g --abbrev-commit --pretty=oneline" */ -int cmd_log_reflog(int argc, const char **argv, const char *prefix) +int cmd_log_reflog(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct log_config cfg; struct rev_info rev; @@ -906,7 +916,10 @@ static void log_setup_revisions_tweak(struct rev_info *rev) diff_merges_default_to_first_parent(rev); } -int cmd_log(int argc, const char **argv, const char *prefix) +int cmd_log(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct log_config cfg; struct rev_info rev; @@ -1976,7 +1989,10 @@ static void infer_range_diff_ranges(struct strbuf *r1, } } -int cmd_format_patch(int argc, const char **argv, const char *prefix) +int cmd_format_patch(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct format_config cfg; struct commit *commit; @@ -2609,7 +2625,10 @@ static void print_commit(char sign, struct commit *commit, int verbose, } } -int cmd_cherry(int argc, const char **argv, const char *prefix) +int cmd_cherry(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct rev_info revs; struct patch_ids ids; diff --git a/builtin/ls-files.c b/builtin/ls-files.c index 6eeb5cba78..e016b0415d 100644 --- a/builtin/ls-files.c +++ b/builtin/ls-files.c @@ -5,8 +5,8 @@ * * Copyright (C) Linus Torvalds, 2005 */ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" -#include "repository.h" #include "config.h" #include "convert.h" #include "quote.h" @@ -507,7 +507,7 @@ static int get_common_prefix_len(const char *common_prefix) common_prefix_len = strlen(common_prefix); /* - * If the prefix has a trailing slash, strip it so that submodules wont + * If the prefix has a trailing slash, strip it so that submodules won't * be pruned from the index. */ if (common_prefix[common_prefix_len - 1] == '/') @@ -561,7 +561,10 @@ static int option_parse_exclude_standard(const struct option *opt, return 0; } -int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix) +int cmd_ls_files(int argc, + const char **argv, + const char *cmd_prefix, + struct repository *repo UNUSED) { int require_work_tree = 0, show_tag = 0, i; char *max_prefix; diff --git a/builtin/ls-remote.c b/builtin/ls-remote.c index 0a491595ca..f723b3bf3b 100644 --- a/builtin/ls-remote.c +++ b/builtin/ls-remote.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "gettext.h" #include "hex.h" @@ -37,7 +38,10 @@ static int tail_match(const struct strvec *pattern, const char *path) return 0; } -int cmd_ls_remote(int argc, const char **argv, const char *prefix) +int cmd_ls_remote(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { const char *dest = NULL; unsigned flags = 0; diff --git a/builtin/ls-tree.c b/builtin/ls-tree.c index bf372c67d7..8542b5d53e 100644 --- a/builtin/ls-tree.c +++ b/builtin/ls-tree.c @@ -3,7 +3,9 @@ * * Copyright (C) Linus Torvalds, 2005 */ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" + #include "config.h" #include "gettext.h" #include "hex.h" @@ -329,7 +331,10 @@ static struct ls_tree_cmdmode_to_fmt ls_tree_cmdmode_format[] = { }, }; -int cmd_ls_tree(int argc, const char **argv, const char *prefix) +int cmd_ls_tree(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct object_id oid; struct tree *tree; diff --git a/builtin/mailinfo.c b/builtin/mailinfo.c index 53a22645da..e17dec27b1 100644 --- a/builtin/mailinfo.c +++ b/builtin/mailinfo.c @@ -2,6 +2,7 @@ * Another stupid program, this one parsing the headers of an * email to figure out authorship and subject */ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "abspath.h" #include "environment.h" @@ -48,7 +49,10 @@ static int parse_opt_quoted_cr(const struct option *opt, const char *arg, int un return 0; } -int cmd_mailinfo(int argc, const char **argv, const char *prefix) +int cmd_mailinfo(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct metainfo_charset meta_charset; struct mailinfo mi; diff --git a/builtin/mailsplit.c b/builtin/mailsplit.c index fe6dbc5d05..b8f7150ce9 100644 --- a/builtin/mailsplit.c +++ b/builtin/mailsplit.c @@ -269,7 +269,10 @@ out: return ret; } -int cmd_mailsplit(int argc, const char **argv, const char *prefix) +int cmd_mailsplit(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { int nr = 0, nr_prec = 4, num = 0; int allow_bare = 0; diff --git a/builtin/merge-base.c b/builtin/merge-base.c index 5a8e729502..a20c93b11a 100644 --- a/builtin/merge-base.c +++ b/builtin/merge-base.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "commit.h" @@ -5,7 +6,6 @@ #include "hex.h" #include "object-name.h" #include "parse-options.h" -#include "repository.h" #include "commit-reach.h" static int show_merge_base(struct commit **rev, int rev_nr, int show_all) @@ -143,7 +143,10 @@ static int handle_fork_point(int argc, const char **argv) return 0; } -int cmd_merge_base(int argc, const char **argv, const char *prefix) +int cmd_merge_base(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct commit **rev; int rev_nr = 0; diff --git a/builtin/merge-file.c b/builtin/merge-file.c index 1f987334a3..cb42865eb5 100644 --- a/builtin/merge-file.c +++ b/builtin/merge-file.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "abspath.h" #include "diff.h" @@ -53,7 +54,10 @@ static int diff_algorithm_cb(const struct option *opt, return 0; } -int cmd_merge_file(int argc, const char **argv, const char *prefix) +int cmd_merge_file(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { const char *names[3] = { 0 }; mmfile_t mmfs[3] = { 0 }; diff --git a/builtin/merge-index.c b/builtin/merge-index.c index 0fabe3f6bb..a5b87ee3c5 100644 --- a/builtin/merge-index.c +++ b/builtin/merge-index.c @@ -1,7 +1,7 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "hex.h" #include "read-cache-ll.h" -#include "repository.h" #include "run-command.h" #include "sparse-index.h" @@ -73,7 +73,10 @@ static void merge_all(void) } } -int cmd_merge_index(int argc, const char **argv, const char *prefix UNUSED) +int cmd_merge_index(int argc, + const char **argv, + const char *prefix UNUSED, + struct repository *repo UNUSED) { int i, force_file = 0; diff --git a/builtin/merge-ours.c b/builtin/merge-ours.c index 932924e5d0..1fcf53f005 100644 --- a/builtin/merge-ours.c +++ b/builtin/merge-ours.c @@ -7,15 +7,19 @@ * * Pretend we resolved the heads, but declare our tree trumps everybody else. */ +#define USE_THE_REPOSITORY_VARIABLE #include "git-compat-util.h" #include "builtin.h" #include "diff.h" -#include "repository.h" + static const char builtin_merge_ours_usage[] = "git merge-ours <base>... -- HEAD <remote>..."; -int cmd_merge_ours(int argc, const char **argv, const char *prefix UNUSED) +int cmd_merge_ours(int argc, + const char **argv, + const char *prefix UNUSED, + struct repository *repo UNUSED) { if (argc == 2 && !strcmp(argv[1], "-h")) usage(builtin_merge_ours_usage); diff --git a/builtin/merge-recursive.c b/builtin/merge-recursive.c index e951b09805..1dd295558b 100644 --- a/builtin/merge-recursive.c +++ b/builtin/merge-recursive.c @@ -1,10 +1,10 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "advice.h" #include "gettext.h" #include "hash.h" #include "merge-recursive.h" #include "object-name.h" -#include "repository.h" static const char builtin_merge_recursive_usage[] = "git %s <base>... -- <head> <remote> ..."; @@ -21,7 +21,10 @@ static char *better_branch_name(const char *branch) return xstrdup(name ? name : branch); } -int cmd_merge_recursive(int argc, const char **argv, const char *prefix UNUSED) +int cmd_merge_recursive(int argc, + const char **argv, + const char *prefix UNUSED, + struct repository *repo UNUSED) { struct object_id bases[21]; unsigned bases_count = 0; diff --git a/builtin/merge-tree.c b/builtin/merge-tree.c index c00469ed3d..c5ed472967 100644 --- a/builtin/merge-tree.c +++ b/builtin/merge-tree.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "tree-walk.h" #include "xdiff-interface.h" @@ -10,7 +11,6 @@ #include "object-name.h" #include "object-store-ll.h" #include "parse-options.h" -#include "repository.h" #include "blob.h" #include "merge-blobs.h" #include "quote.h" @@ -526,7 +526,10 @@ static int real_merge(struct merge_tree_options *o, return !result.clean; /* result.clean < 0 handled above */ } -int cmd_merge_tree(int argc, const char **argv, const char *prefix) +int cmd_merge_tree(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct merge_tree_options o = { .show_messages = -1 }; struct strvec xopts = STRVEC_INIT; diff --git a/builtin/merge.c b/builtin/merge.c index 662a49a0e8..84d0f3604b 100644 --- a/builtin/merge.c +++ b/builtin/merge.c @@ -5,8 +5,9 @@ * * Based on git-merge.sh by Junio C Hamano. */ - +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" + #include "abspath.h" #include "advice.h" #include "config.h" @@ -17,6 +18,7 @@ #include "object-name.h" #include "parse-options.h" #include "lockfile.h" +#include "repository.h" #include "run-command.h" #include "hook.h" #include "diff.h" @@ -695,7 +697,9 @@ static int read_tree_trivial(struct object_id *common, struct object_id *head, static void write_tree_trivial(struct object_id *oid) { - if (write_index_as_tree(oid, the_repository->index, get_index_file(), 0, NULL)) + if (write_index_as_tree(oid, the_repository->index, + repo_get_index_file(the_repository), + 0, NULL)) die(_("git write-tree failed to write a tree")); } @@ -757,7 +761,7 @@ static int try_merge_strategy(const char *strategy, struct commit_list *common, } if (write_locked_index(the_repository->index, &lock, COMMIT_LOCK | SKIP_IF_UNCHANGED)) - die(_("unable to write %s"), get_index_file()); + die(_("unable to write %s"), repo_get_index_file(the_repository)); return clean ? 0 : 1; } else { return try_merge_command(the_repository, @@ -839,7 +843,7 @@ static void write_merge_heads(struct commit_list *); static void prepare_to_commit(struct commit_list *remoteheads) { struct strbuf msg = STRBUF_INIT; - const char *index_file = get_index_file(); + const char *index_file = repo_get_index_file(the_repository); if (!no_verify) { int invoked_hook; @@ -855,7 +859,8 @@ static void prepare_to_commit(struct commit_list *remoteheads) if (invoked_hook) discard_index(the_repository->index); } - read_index_from(the_repository->index, index_file, get_git_dir()); + read_index_from(the_repository->index, index_file, + repo_get_git_dir(the_repository)); strbuf_addbuf(&msg, &merge_msg); if (squash) BUG("the control must not reach here under --squash"); @@ -878,8 +883,8 @@ static void prepare_to_commit(struct commit_list *remoteheads) append_signoff(&msg, ignored_log_message_bytes(msg.buf, msg.len), 0); write_merge_heads(remoteheads); write_file_buf(git_path_merge_msg(the_repository), msg.buf, msg.len); - if (run_commit_hook(0 < option_edit, get_index_file(), NULL, - "prepare-commit-msg", + if (run_commit_hook(0 < option_edit, repo_get_index_file(the_repository), + NULL, "prepare-commit-msg", git_path_merge_msg(the_repository), "merge", NULL)) abort_commit(remoteheads, NULL); if (0 < option_edit) { @@ -887,7 +892,7 @@ static void prepare_to_commit(struct commit_list *remoteheads) abort_commit(remoteheads, NULL); } - if (!no_verify && run_commit_hook(0 < option_edit, get_index_file(), + if (!no_verify && run_commit_hook(0 < option_edit, repo_get_index_file(the_repository), NULL, "commit-msg", git_path_merge_msg(the_repository), NULL)) abort_commit(remoteheads, NULL); @@ -1275,7 +1280,10 @@ static int merging_a_throwaway_tag(struct commit *commit) return is_throwaway_tag; } -int cmd_merge(int argc, const char **argv, const char *prefix) +int cmd_merge(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct object_id result_tree, stash, head_oid; struct commit *head_commit; @@ -1347,7 +1355,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix) REF_NO_DEREF); /* Invoke 'git reset --merge' */ - ret = cmd_reset(nargc, nargv, prefix); + ret = cmd_reset(nargc, nargv, prefix, the_repository); if (!is_null_oid(&stash_oid)) { oid_to_hex_r(stash_oid_hex, &stash_oid); @@ -1379,7 +1387,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix) die(_("There is no merge in progress (MERGE_HEAD missing).")); /* Invoke 'git commit' */ - ret = cmd_commit(nargc, nargv, prefix); + ret = cmd_commit(nargc, nargv, prefix, the_repository); goto done; } diff --git a/builtin/mktag.c b/builtin/mktag.c index c6b644219f..6e188dce50 100644 --- a/builtin/mktag.c +++ b/builtin/mktag.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "gettext.h" #include "hex.h" @@ -71,7 +72,10 @@ static int verify_object_in_tag(struct object_id *tagged_oid, int *tagged_type) return ret; } -int cmd_mktag(int argc, const char **argv, const char *prefix) +int cmd_mktag(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { static struct option builtin_mktag_options[] = { OPT_BOOL(0, "strict", &option_strict, diff --git a/builtin/mktree.c b/builtin/mktree.c index 9a22d4e277..3c16faa40e 100644 --- a/builtin/mktree.c +++ b/builtin/mktree.c @@ -3,6 +3,7 @@ * * Copyright (c) Junio C Hamano, 2006, 2009 */ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "gettext.h" #include "hex.h" @@ -150,7 +151,10 @@ static void mktree_line(char *buf, int nul_term_line, int allow_missing) free(to_free); } -int cmd_mktree(int ac, const char **av, const char *prefix) +int cmd_mktree(int ac, + const char **av, + const char *prefix, + struct repository *repo UNUSED) { struct strbuf sb = STRBUF_INIT; struct object_id oid; @@ -199,5 +203,6 @@ int cmd_mktree(int ac, const char **av, const char *prefix) used=0; /* reset tree entry buffer for re-use in batch mode */ } strbuf_release(&sb); + return 0; } diff --git a/builtin/multi-pack-index.c b/builtin/multi-pack-index.c index 8805cbbeb3..d159ed1314 100644 --- a/builtin/multi-pack-index.c +++ b/builtin/multi-pack-index.c @@ -1,7 +1,7 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "abspath.h" #include "config.h" -#include "environment.h" #include "gettext.h" #include "parse-options.h" #include "midx.h" @@ -9,6 +9,7 @@ #include "trace2.h" #include "object-store-ll.h" #include "replace-object.h" +#include "repository.h" #define BUILTIN_MIDX_WRITE_USAGE \ N_("git multi-pack-index [<options>] write [--preferred-pack=<pack>]" \ @@ -63,7 +64,7 @@ static int parse_object_dir(const struct option *opt, const char *arg, char **value = opt->value; free(*value); if (unset) - *value = xstrdup(get_object_directory()); + *value = xstrdup(repo_get_object_directory(the_repository)); else *value = real_pathdup(arg, 1); return 0; @@ -267,8 +268,10 @@ static int cmd_multi_pack_index_repack(int argc, const char **argv, (size_t)opts.batch_size, opts.flags); } -int cmd_multi_pack_index(int argc, const char **argv, - const char *prefix) +int cmd_multi_pack_index(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { int res; parse_opt_subcommand_fn *fn = NULL; diff --git a/builtin/mv.c b/builtin/mv.c index 6c69033c5f..472a278737 100644 --- a/builtin/mv.c +++ b/builtin/mv.c @@ -3,6 +3,7 @@ * * Copyright (C) 2006 Johannes Schindelin */ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "abspath.h" @@ -18,7 +19,7 @@ #include "string-list.h" #include "parse-options.h" #include "read-cache-ll.h" -#include "repository.h" + #include "setup.h" #include "strvec.h" #include "submodule.h" @@ -178,7 +179,10 @@ static void remove_empty_src_dirs(const char **src_dir, size_t src_dir_nr) strbuf_release(&a_src_dir); } -int cmd_mv(int argc, const char **argv, const char *prefix) +int cmd_mv(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { int i, flags, gitmodules_modified = 0; int verbose = 0, show_only = 0, force = 0, ignore_errors = 0, ignore_sparse = 0; diff --git a/builtin/name-rev.c b/builtin/name-rev.c index a468ef84c3..765eb20a93 100644 --- a/builtin/name-rev.c +++ b/builtin/name-rev.c @@ -1,8 +1,8 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "environment.h" #include "gettext.h" #include "hex.h" -#include "repository.h" #include "config.h" #include "commit.h" #include "tag.h" @@ -65,7 +65,7 @@ static void set_commit_cutoff(struct commit *commit) static void adjust_cutoff_timestamp_for_slop(void) { if (cutoff) { - /* check for undeflow */ + /* check for underflow */ if (cutoff > TIME_MIN + CUTOFF_DATE_SLOP) cutoff = cutoff - CUTOFF_DATE_SLOP; else @@ -558,7 +558,10 @@ static void name_rev_line(char *p, struct name_ref_data *data) strbuf_release(&buf); } -int cmd_name_rev(int argc, const char **argv, const char *prefix) +int cmd_name_rev(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct mem_pool string_pool; struct object_array revs = OBJECT_ARRAY_INIT; diff --git a/builtin/notes.c b/builtin/notes.c index 04f9dfb7fb..8c26e45526 100644 --- a/builtin/notes.c +++ b/builtin/notes.c @@ -6,7 +6,7 @@ * Based on git-notes.sh by Johannes Schindelin, * and builtin/tag.c by Kristian Høgsberg and Carlos Rica. */ - +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "editor.h" @@ -17,7 +17,7 @@ #include "object-name.h" #include "object-store-ll.h" #include "path.h" -#include "repository.h" + #include "pretty.h" #include "refs.h" #include "exec-cmd.h" @@ -897,6 +897,7 @@ static int merge(int argc, const char **argv, const char *prefix) 1, PARSE_OPT_NONEG), OPT_END() }; + char *notes_ref; argc = parse_options(argc, argv, prefix, options, git_notes_merge_usage, 0); @@ -924,7 +925,8 @@ static int merge(int argc, const char **argv, const char *prefix) if (do_commit) return merge_commit(&o); - o.local_ref = default_notes_ref(); + notes_ref = default_notes_ref(the_repository); + o.local_ref = notes_ref; strbuf_addstr(&remote_ref, argv[0]); expand_loose_notes_ref(&remote_ref); o.remote_ref = remote_ref.buf; @@ -953,7 +955,7 @@ static int merge(int argc, const char **argv, const char *prefix) } strbuf_addf(&msg, "notes: Merged notes from %s into %s", - remote_ref.buf, default_notes_ref()); + remote_ref.buf, notes_ref); strbuf_add(&(o.commit_msg), msg.buf + 7, msg.len - 7); /* skip "notes: " */ result = notes_merge(&o, t, &result_oid); @@ -961,7 +963,7 @@ static int merge(int argc, const char **argv, const char *prefix) if (result >= 0) /* Merge resulted (trivially) in result_oid */ /* Update default notes ref with new commit */ refs_update_ref(get_main_ref_store(the_repository), msg.buf, - default_notes_ref(), &result_oid, NULL, 0, + notes_ref, &result_oid, NULL, 0, UPDATE_REFS_DIE_ON_ERR); else { /* Merge has unresolved conflicts */ struct worktree **worktrees; @@ -973,14 +975,14 @@ static int merge(int argc, const char **argv, const char *prefix) /* Store ref-to-be-updated into .git/NOTES_MERGE_REF */ worktrees = get_worktrees(); wt = find_shared_symref(worktrees, "NOTES_MERGE_REF", - default_notes_ref()); + notes_ref); if (wt) die(_("a notes merge into %s is already in-progress at %s"), - default_notes_ref(), wt->path); + notes_ref, wt->path); free_worktrees(worktrees); - if (refs_update_symref(get_main_ref_store(the_repository), "NOTES_MERGE_REF", default_notes_ref(), NULL)) + if (refs_update_symref(get_main_ref_store(the_repository), "NOTES_MERGE_REF", notes_ref, NULL)) die(_("failed to store link to current notes ref (%s)"), - default_notes_ref()); + notes_ref); fprintf(stderr, _("Automatic notes merge failed. Fix conflicts in %s " "and commit the result with 'git notes merge --commit', " "or abort the merge with 'git notes merge --abort'.\n"), @@ -988,6 +990,7 @@ static int merge(int argc, const char **argv, const char *prefix) } free_notes(t); + free(notes_ref); strbuf_release(&remote_ref); strbuf_release(&msg); return result < 0; /* return non-zero on conflicts */ @@ -1084,6 +1087,7 @@ static int prune(int argc, const char **argv, const char *prefix) static int get_ref(int argc, const char **argv, const char *prefix) { struct option options[] = { OPT_END() }; + char *notes_ref; argc = parse_options(argc, argv, prefix, options, git_notes_get_ref_usage, 0); @@ -1092,11 +1096,16 @@ static int get_ref(int argc, const char **argv, const char *prefix) usage_with_options(git_notes_get_ref_usage, options); } - puts(default_notes_ref()); + notes_ref = default_notes_ref(the_repository); + puts(notes_ref); + free(notes_ref); return 0; } -int cmd_notes(int argc, const char **argv, const char *prefix) +int cmd_notes(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { const char *override_notes_ref = NULL; parse_opt_subcommand_fn *fn = NULL; diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c index c6e2852d3c..0fc0680b40 100644 --- a/builtin/pack-objects.c +++ b/builtin/pack-objects.c @@ -1,8 +1,8 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "environment.h" #include "gettext.h" #include "hex.h" -#include "repository.h" #include "config.h" #include "attr.h" #include "object.h" @@ -3968,7 +3968,7 @@ static int add_loose_object(const struct object_id *oid, const char *path, */ static void add_unreachable_loose_objects(void) { - for_each_loose_file_in_objdir(get_object_directory(), + for_each_loose_file_in_objdir(repo_get_object_directory(the_repository), add_loose_object, NULL, NULL, NULL); } @@ -4312,7 +4312,10 @@ static int option_parse_cruft_expiration(const struct option *opt UNUSED, return 0; } -int cmd_pack_objects(int argc, const char **argv, const char *prefix) +int cmd_pack_objects(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { int use_internal_rev_list = 0; int shallow = 0; @@ -4669,6 +4672,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix) cleanup: clear_packing_data(&to_pack); list_objects_filter_release(&filter_options); + string_list_clear(&keep_pack_list, 0); strvec_clear(&rp); return 0; diff --git a/builtin/pack-redundant.c b/builtin/pack-redundant.c index dd9bf35f5b..81f4494d46 100644 --- a/builtin/pack-redundant.c +++ b/builtin/pack-redundant.c @@ -5,11 +5,12 @@ * This file is licensed under the GPL v2. * */ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "gettext.h" #include "hex.h" -#include "repository.h" + #include "packfile.h" #include "object-store-ll.h" @@ -561,11 +562,8 @@ static void load_all(void) } } -int cmd_pack_redundant(int argc, const char **argv, const char *prefix UNUSED) -{ - int i; - int i_still_use_this = 0; - struct pack_list *min = NULL, *red, *pl; +int cmd_pack_redundant(int argc, const char **argv, const char *prefix UNUSED, struct repository *repo UNUSED) { + int i; int i_still_use_this = 0; struct pack_list *min = NULL, *red, *pl; struct llist *ignore; struct object_id *oid; char buf[GIT_MAX_HEXSZ + 2]; /* hex hash + \n + \0 */ diff --git a/builtin/pack-refs.c b/builtin/pack-refs.c index db40825666..2d83c1ed2a 100644 --- a/builtin/pack-refs.c +++ b/builtin/pack-refs.c @@ -1,9 +1,9 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "gettext.h" #include "parse-options.h" #include "refs.h" -#include "repository.h" #include "revision.h" static char const * const pack_refs_usage[] = { @@ -11,7 +11,10 @@ static char const * const pack_refs_usage[] = { NULL }; -int cmd_pack_refs(int argc, const char **argv, const char *prefix) +int cmd_pack_refs(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct ref_exclusions excludes = REF_EXCLUSIONS_INIT; struct string_list included_refs = STRING_LIST_INIT_NODUP; diff --git a/builtin/patch-id.c b/builtin/patch-id.c index d790ae6354..93b398e391 100644 --- a/builtin/patch-id.c +++ b/builtin/patch-id.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "diff.h" @@ -214,7 +215,10 @@ static int git_patch_id_config(const char *var, const char *value, return git_default_config(var, value, ctx, cb); } -int cmd_patch_id(int argc, const char **argv, const char *prefix) +int cmd_patch_id(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { /* if nothing is set, default to unstable */ struct patch_id_opts config = {0, 0}; diff --git a/builtin/prune-packed.c b/builtin/prune-packed.c index ca3578e158..4d63f26b0a 100644 --- a/builtin/prune-packed.c +++ b/builtin/prune-packed.c @@ -8,7 +8,10 @@ static const char * const prune_packed_usage[] = { NULL }; -int cmd_prune_packed(int argc, const char **argv, const char *prefix) +int cmd_prune_packed(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { int opts = isatty(2) ? PRUNE_PACKED_VERBOSE : 0; const struct option prune_packed_options[] = { diff --git a/builtin/prune.c b/builtin/prune.c index 57fe31467f..2b1de01339 100644 --- a/builtin/prune.c +++ b/builtin/prune.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "commit.h" #include "diff.h" @@ -147,7 +148,10 @@ static void remove_temporary_files(const char *path) closedir(dir); } -int cmd_prune(int argc, const char **argv, const char *prefix) +int cmd_prune(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct rev_info revs; int exclude_promisor_objects = 0; @@ -193,12 +197,12 @@ int cmd_prune(int argc, const char **argv, const char *prefix) revs.exclude_promisor_objects = 1; } - for_each_loose_file_in_objdir(get_object_directory(), prune_object, - prune_cruft, prune_subdir, &revs); + for_each_loose_file_in_objdir(repo_get_object_directory(the_repository), + prune_object, prune_cruft, prune_subdir, &revs); prune_packed_objects(show_only ? PRUNE_PACKED_DRY_RUN : 0); - remove_temporary_files(get_object_directory()); - s = mkpathdup("%s/pack", get_object_directory()); + remove_temporary_files(repo_get_object_directory(the_repository)); + s = mkpathdup("%s/pack", repo_get_object_directory(the_repository)); remove_temporary_files(s); free(s); diff --git a/builtin/pull.c b/builtin/pull.c index 4c54d8196f..149f201320 100644 --- a/builtin/pull.c +++ b/builtin/pull.c @@ -6,6 +6,7 @@ * Fetch one or more remote refs and merge it/them into the current HEAD. */ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "advice.h" #include "config.h" @@ -977,7 +978,10 @@ static void show_advice_pull_non_ff(void) "invocation.\n")); } -int cmd_pull(int argc, const char **argv, const char *prefix) +int cmd_pull(int argc, + const char **argv, + const char *prefix, + struct repository *repository UNUSED) { const char *repo, **refspecs; struct oid_array merge_heads = OID_ARRAY_INIT; diff --git a/builtin/push.c b/builtin/push.c index 7a67398124..e6f48969b8 100644 --- a/builtin/push.c +++ b/builtin/push.c @@ -1,6 +1,7 @@ /* * "git push" */ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "advice.h" #include "branch.h" @@ -13,7 +14,6 @@ #include "transport.h" #include "parse-options.h" #include "pkt-line.h" -#include "repository.h" #include "submodule.h" #include "submodule-config.h" #include "send-pack.h" @@ -72,13 +72,15 @@ static void refspec_append_mapped(struct refspec *refspec, const char *ref, const char *branch_name; if (remote->push.nr) { - struct refspec_item query; - memset(&query, 0, sizeof(struct refspec_item)); - query.src = matched->name; + struct refspec_item query = { + .src = matched->name, + }; + if (!query_refspecs(&remote->push, &query) && query.dst) { refspec_appendf(refspec, "%s%s:%s", query.force ? "+" : "", query.src, query.dst); + free(query.dst); return; } } @@ -546,7 +548,10 @@ static int git_push_config(const char *k, const char *v, return git_default_config(k, v, ctx, NULL); } -int cmd_push(int argc, const char **argv, const char *prefix) +int cmd_push(int argc, + const char **argv, + const char *prefix, + struct repository *repository UNUSED) { int flags = 0; int tags = 0; diff --git a/builtin/range-diff.c b/builtin/range-diff.c index f02cbac087..1b33ab66a7 100644 --- a/builtin/range-diff.c +++ b/builtin/range-diff.c @@ -1,10 +1,11 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "gettext.h" #include "object-name.h" #include "parse-options.h" #include "range-diff.h" #include "config.h" -#include "repository.h" + static const char * const builtin_range_diff_usage[] = { N_("git range-diff [<options>] <old-base>..<old-tip> <new-base>..<new-tip>"), @@ -13,7 +14,10 @@ N_("git range-diff [<options>] <base> <old-tip> <new-tip>"), NULL }; -int cmd_range_diff(int argc, const char **argv, const char *prefix) +int cmd_range_diff(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct diff_options diffopt = { NULL }; struct strvec other_arg = STRVEC_INIT; diff --git a/builtin/read-tree.c b/builtin/read-tree.c index a8cf8504b8..d2a807a828 100644 --- a/builtin/read-tree.c +++ b/builtin/read-tree.c @@ -3,7 +3,7 @@ * * Copyright (C) Linus Torvalds, 2005 */ - +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "gettext.h" @@ -16,7 +16,6 @@ #include "cache-tree.h" #include "unpack-trees.h" #include "parse-options.h" -#include "repository.h" #include "resolve-undo.h" #include "setup.h" #include "sparse-index.h" @@ -108,7 +107,10 @@ static int git_read_tree_config(const char *var, const char *value, return git_default_config(var, value, ctx, cb); } -int cmd_read_tree(int argc, const char **argv, const char *cmd_prefix) +int cmd_read_tree(int argc, + const char **argv, + const char *cmd_prefix, + struct repository *repo UNUSED) { int i, stage = 0; struct object_id oid; diff --git a/builtin/rebase.c b/builtin/rebase.c index a2c96c080e..bbaca3c5d5 100644 --- a/builtin/rebase.c +++ b/builtin/rebase.c @@ -3,8 +3,9 @@ * * Copyright (c) 2018 Pratik Karki */ - +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" + #include "abspath.h" #include "environment.h" #include "gettext.h" @@ -527,6 +528,23 @@ static int rebase_write_basic_state(struct rebase_options *opts) return 0; } +static int cleanup_autostash(struct rebase_options *opts) +{ + int ret; + struct strbuf dir = STRBUF_INIT; + const char *path = state_dir_path("autostash", opts); + + if (!file_exists(path)) + return 0; + ret = apply_autostash(path); + strbuf_addstr(&dir, opts->state_dir); + if (remove_dir_recursively(&dir, 0)) + ret = error_errno(_("could not remove '%s'"), opts->state_dir); + strbuf_release(&dir); + + return ret; +} + static int finish_rebase(struct rebase_options *opts) { struct strbuf dir = STRBUF_INIT; @@ -1063,7 +1081,10 @@ static int check_exec_cmd(const char *cmd) return 0; } -int cmd_rebase(int argc, const char **argv, const char *prefix) +int cmd_rebase(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct rebase_options options = REBASE_OPTIONS_INIT; const char *branch_name; @@ -1727,7 +1748,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) if (require_clean_work_tree(the_repository, "rebase", _("Please commit or stash them."), 1, 1)) { ret = -1; - goto cleanup; + goto cleanup_autostash; } /* @@ -1750,7 +1771,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) if (options.switch_to) { ret = checkout_up_to_date(&options); if (ret) - goto cleanup; + goto cleanup_autostash; } if (!(options.flags & REBASE_NO_QUIET)) @@ -1776,8 +1797,10 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) /* If a hook exists, give it a chance to interrupt*/ if (!ok_to_skip_pre_rebase && run_hooks_l(the_repository, "pre-rebase", options.upstream_arg, - argc ? argv[0] : NULL, NULL)) - die(_("The pre-rebase hook refused to rebase.")); + argc ? argv[0] : NULL, NULL)) { + ret = error(_("The pre-rebase hook refused to rebase.")); + goto cleanup_autostash; + } if (options.flags & REBASE_DIFFSTAT) { struct diff_options opts; @@ -1822,9 +1845,10 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) RESET_HEAD_RUN_POST_CHECKOUT_HOOK; ropts.head_msg = msg.buf; ropts.default_reflog_action = options.reflog_action; - if (reset_head(the_repository, &ropts)) - die(_("Could not detach HEAD")); - strbuf_release(&msg); + if (reset_head(the_repository, &ropts)) { + ret = error(_("Could not detach HEAD")); + goto cleanup_autostash; + } /* * If the onto is a proper descendant of the tip of the branch, then @@ -1852,9 +1876,14 @@ run_rebase: cleanup: strbuf_release(&buf); + strbuf_release(&msg); strbuf_release(&revisions); rebase_options_release(&options); free(squash_onto_name); free(keep_base_onto_name); return !!ret; + +cleanup_autostash: + ret |= !!cleanup_autostash(&options); + goto cleanup; } diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c index 3f35140e48..536d22761d 100644 --- a/builtin/receive-pack.c +++ b/builtin/receive-pack.c @@ -1,6 +1,7 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "abspath.h" -#include "repository.h" + #include "config.h" #include "environment.h" #include "gettext.h" @@ -339,12 +340,26 @@ static void show_one_alternate_ref(const struct object_id *oid, static void write_head_info(void) { static struct oidset seen = OIDSET_INIT; + struct strvec excludes_vector = STRVEC_INIT; + const char **exclude_patterns; + + /* + * We need access to the reference names both with and without their + * namespace and thus cannot use `refs_for_each_namespaced_ref()`. We + * thus have to adapt exclude patterns to carry the namespace prefix + * ourselves. + */ + exclude_patterns = get_namespaced_exclude_patterns( + hidden_refs_to_excludes(&hidden_refs), + get_git_namespace(), &excludes_vector); refs_for_each_fullref_in(get_main_ref_store(the_repository), "", - hidden_refs_to_excludes(&hidden_refs), - show_ref_cb, &seen); + exclude_patterns, show_ref_cb, &seen); for_each_alternate_ref(show_one_alternate_ref, &seen); + oidset_clear(&seen); + strvec_clear(&excludes_vector); + if (!sent_capabilities) show_ref("capabilities^{}", null_oid()); @@ -1324,7 +1339,7 @@ static int update_shallow_ref(struct command *cmd, struct shallow_info *si) } /* - * NEEDSWORK: we should consolidate various implementions of "are we + * NEEDSWORK: we should consolidate various implementations of "are we * on an unborn branch?" test into one, and make the unified one more * robust. !get_sha1() based check used here and elsewhere would not * allow us to tell an unborn branch from corrupt ref, for example. @@ -2480,7 +2495,10 @@ static int delete_only(struct command *commands) return 1; } -int cmd_receive_pack(int argc, const char **argv, const char *prefix) +int cmd_receive_pack(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { int advertise_refs = 0; struct command *commands; diff --git a/builtin/reflog.c b/builtin/reflog.c index 0d2ff95c6e..22df6834f7 100644 --- a/builtin/reflog.c +++ b/builtin/reflog.c @@ -1,7 +1,7 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "gettext.h" -#include "repository.h" #include "revision.h" #include "reachable.h" #include "wildmatch.h" @@ -244,7 +244,7 @@ static int cmd_reflog_show(int argc, const char **argv, const char *prefix) PARSE_OPT_KEEP_DASHDASH | PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN_OPT); - return cmd_log_reflog(argc, argv, prefix); + return cmd_log_reflog(argc, argv, prefix, the_repository); } static int show_reflog(const char *refname, void *cb_data UNUSED) @@ -447,7 +447,10 @@ static int cmd_reflog_exists(int argc, const char **argv, const char *prefix) * main "reflog" */ -int cmd_reflog(int argc, const char **argv, const char *prefix) +int cmd_reflog(int argc, + const char **argv, + const char *prefix, + struct repository *repository) { parse_opt_subcommand_fn *fn = NULL; struct option options[] = { @@ -466,5 +469,5 @@ int cmd_reflog(int argc, const char **argv, const char *prefix) if (fn) return fn(argc - 1, argv + 1, prefix); else - return cmd_log_reflog(argc, argv, prefix); + return cmd_log_reflog(argc, argv, prefix, repository); } diff --git a/builtin/refs.c b/builtin/refs.c index 131f98be98..24978a7b7b 100644 --- a/builtin/refs.c +++ b/builtin/refs.c @@ -1,9 +1,9 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "fsck.h" #include "parse-options.h" #include "refs.h" -#include "repository.h" #include "strbuf.h" #define REFS_MIGRATE_USAGE \ @@ -90,7 +90,10 @@ static int cmd_refs_verify(int argc, const char **argv, const char *prefix) return ret; } -int cmd_refs(int argc, const char **argv, const char *prefix) +int cmd_refs(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { const char * const refs_usage[] = { REFS_MIGRATE_USAGE, diff --git a/builtin/remote-ext.c b/builtin/remote-ext.c index 282782eccd..33c8ae0fc7 100644 --- a/builtin/remote-ext.c +++ b/builtin/remote-ext.c @@ -195,7 +195,10 @@ static int command_loop(const char *child) } } -int cmd_remote_ext(int argc, const char **argv, const char *prefix) +int cmd_remote_ext(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { BUG_ON_NON_EMPTY_PREFIX(prefix); diff --git a/builtin/remote-fd.c b/builtin/remote-fd.c index 9020fab9c5..ae896eda57 100644 --- a/builtin/remote-fd.c +++ b/builtin/remote-fd.c @@ -53,7 +53,10 @@ static void command_loop(int input_fd, int output_fd) } } -int cmd_remote_fd(int argc, const char **argv, const char *prefix) +int cmd_remote_fd(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { int input_fd = -1; int output_fd = -1; diff --git a/builtin/remote.c b/builtin/remote.c index 0acc547d69..76670ddd8b 100644 --- a/builtin/remote.c +++ b/builtin/remote.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "gettext.h" @@ -1761,7 +1762,10 @@ out: return 0; } -int cmd_remote(int argc, const char **argv, const char *prefix) +int cmd_remote(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { parse_opt_subcommand_fn *fn = NULL; struct option options[] = { diff --git a/builtin/repack.c b/builtin/repack.c index 8bb875532b..cb4420f085 100644 --- a/builtin/repack.c +++ b/builtin/repack.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "dir.h" @@ -425,9 +426,11 @@ static void repack_promisor_objects(const struct pack_objects_args *args, free(promisor_name); } + fclose(out); if (finish_command(&cmd)) die(_("could not finish pack-objects to repack promisor objects")); + strbuf_release(&line); } struct pack_geometry { @@ -1134,7 +1137,10 @@ static const char *find_pack_prefix(const char *packdir, const char *packtmp) return pack_prefix; } -int cmd_repack(int argc, const char **argv, const char *prefix) +int cmd_repack(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct child_process cmd = CHILD_PROCESS_INIT; struct string_list_item *item; @@ -1258,7 +1264,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix) if (write_midx && write_bitmaps) { struct strbuf path = STRBUF_INIT; - strbuf_addf(&path, "%s/%s_XXXXXX", get_object_directory(), + strbuf_addf(&path, "%s/%s_XXXXXX", repo_get_object_directory(the_repository), "bitmap-ref-tips"); refs_snapshot = xmks_tempfile(path.buf); @@ -1267,7 +1273,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix) strbuf_release(&path); } - packdir = mkpathdup("%s/pack", get_object_directory()); + packdir = mkpathdup("%s/pack", repo_get_object_directory(the_repository)); packtmp_name = xstrfmt(".tmp-%d-pack", (int)getpid()); packtmp = mkpathdup("%s/%s", packdir, packtmp_name); @@ -1537,10 +1543,12 @@ int cmd_repack(int argc, const char **argv, const char *prefix) unsigned flags = 0; if (git_env_bool(GIT_TEST_MULTI_PACK_INDEX_WRITE_INCREMENTAL, 0)) flags |= MIDX_WRITE_INCREMENTAL; - write_midx_file(get_object_directory(), NULL, NULL, flags); + write_midx_file(repo_get_object_directory(the_repository), + NULL, NULL, flags); } cleanup: + string_list_clear(&keep_pack_list, 0); string_list_clear(&names, 1); existing_packs_release(&existing); free_pack_geometry(&geometry); diff --git a/builtin/replace.c b/builtin/replace.c index 34cc4672bc..a44f4e7ea9 100644 --- a/builtin/replace.c +++ b/builtin/replace.c @@ -7,11 +7,10 @@ * and Carlos Rica <jasampler@gmail.com> that was itself based on * git-tag.sh and mktag.c by Linus Torvalds. */ - +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "editor.h" -#include "environment.h" #include "gettext.h" #include "hex.h" #include "refs.h" @@ -22,7 +21,6 @@ #include "object-name.h" #include "object-store-ll.h" #include "replace-object.h" -#include "repository.h" #include "tag.h" #include "wildmatch.h" @@ -514,7 +512,7 @@ static int create_graft(int argc, const char **argv, int force, int gentle) static int convert_graft_file(int force) { - const char *graft_file = get_graft_file(the_repository); + const char *graft_file = repo_get_graft_file(the_repository); FILE *fp = fopen_or_warn(graft_file, "r"); struct strbuf buf = STRBUF_INIT, err = STRBUF_INIT; struct strvec args = STRVEC_INIT; @@ -545,7 +543,10 @@ static int convert_graft_file(int force) return -1; } -int cmd_replace(int argc, const char **argv, const char *prefix) +int cmd_replace(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { int force = 0; int raw = 0; diff --git a/builtin/replay.c b/builtin/replay.c index 138198ce9c..2d12a4e403 100644 --- a/builtin/replay.c +++ b/builtin/replay.c @@ -4,6 +4,7 @@ #include "git-compat-util.h" +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "environment.h" #include "hex.h" @@ -274,7 +275,10 @@ static struct commit *pick_regular_commit(struct commit *pickme, return create_commit(result->tree, pickme, replayed_base); } -int cmd_replay(int argc, const char **argv, const char *prefix) +int cmd_replay(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { const char *advance_name_opt = NULL; char *advance_name = NULL; diff --git a/builtin/rerere.c b/builtin/rerere.c index 81b65ffa39..f7143c3f5d 100644 --- a/builtin/rerere.c +++ b/builtin/rerere.c @@ -1,8 +1,9 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "gettext.h" #include "parse-options.h" -#include "repository.h" + #include "string-list.h" #include "rerere.h" #include "xdiff/xdiff.h" @@ -48,7 +49,10 @@ static int diff_two(const char *file1, const char *label1, return ret; } -int cmd_rerere(int argc, const char **argv, const char *prefix) +int cmd_rerere(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct string_list merge_rr = STRING_LIST_INIT_DUP; int i, autoupdate = -1, flags = 0; diff --git a/builtin/reset.c b/builtin/reset.c index 5f941fb3a2..7154f88826 100644 --- a/builtin/reset.c +++ b/builtin/reset.c @@ -7,7 +7,7 @@ * * Copyright (c) 2005, 2006 Linus Torvalds and Junio C Hamano */ - +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "advice.h" #include "config.h" @@ -26,6 +26,7 @@ #include "object-name.h" #include "parse-options.h" #include "path.h" +#include "repository.h" #include "unpack-trees.h" #include "cache-tree.h" #include "setup.h" @@ -330,7 +331,10 @@ static int git_reset_config(const char *var, const char *value, return git_default_config(var, value, ctx, cb); } -int cmd_reset(int argc, const char **argv, const char *prefix) +int cmd_reset(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { int reset_type = NONE, update_ref_status = 0, quiet = 0; int no_refresh = 0; @@ -441,7 +445,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix) else trace2_cmd_mode(reset_type_names[reset_type]); - if (reset_type != SOFT && (reset_type != MIXED || get_git_work_tree())) + if (reset_type != SOFT && (reset_type != MIXED || repo_get_work_tree(the_repository))) setup_work_tree(); if (reset_type == MIXED && is_bare_repository()) @@ -474,7 +478,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix) goto cleanup; } the_repository->index->updated_skipworktree = 1; - if (!no_refresh && get_git_work_tree()) { + if (!no_refresh && repo_get_work_tree(the_repository)) { uint64_t t_begin, t_delta_in_ms; t_begin = getnanotime(); diff --git a/builtin/rev-list.c b/builtin/rev-list.c index 97d077a994..f62bcbf2b1 100644 --- a/builtin/rev-list.c +++ b/builtin/rev-list.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "commit.h" @@ -513,7 +514,10 @@ static int try_bitmap_disk_usage(struct rev_info *revs, return 0; } -int cmd_rev_list(int argc, const char **argv, const char *prefix) +int cmd_rev_list(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct rev_info revs; struct rev_list_info info; diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c index 4285dc34a7..8401b4d7ab 100644 --- a/builtin/rev-parse.c +++ b/builtin/rev-parse.c @@ -3,8 +3,9 @@ * * Copyright (C) Linus Torvalds, 2005 */ - +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" + #include "abspath.h" #include "config.h" #include "commit.h" @@ -19,6 +20,8 @@ #include "path.h" #include "diff.h" #include "read-cache-ll.h" +#include "repo-settings.h" +#include "repository.h" #include "revision.h" #include "setup.h" #include "split-index.h" @@ -688,7 +691,10 @@ static void print_path(const char *path, const char *prefix, enum format_type fo free(cwd); } -int cmd_rev_parse(int argc, const char **argv, const char *prefix) +int cmd_rev_parse(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { int i, as_is = 0, verify = 0, quiet = 0, revs_count = 0, type = 0; const struct git_hash_algo *output_algo = NULL; @@ -898,7 +904,8 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix) } if (opt_with_value(arg, "--abbrev-ref", &arg)) { abbrev_ref = 1; - abbrev_ref_strict = warn_ambiguous_refs; + abbrev_ref_strict = + repo_settings_get_warn_ambiguous_refs(the_repository); if (arg) { if (!strcmp(arg, "strict")) abbrev_ref_strict = 1; @@ -966,7 +973,7 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix) continue; } if (!strcmp(arg, "--show-toplevel")) { - const char *work_tree = get_git_work_tree(); + const char *work_tree = repo_get_work_tree(the_repository); if (work_tree) print_path(work_tree, prefix, format, DEFAULT_UNMODIFIED); else @@ -991,7 +998,7 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix) const char *pfx = prefix; if (!is_inside_work_tree()) { const char *work_tree = - get_git_work_tree(); + repo_get_work_tree(the_repository); if (work_tree) printf("%s\n", work_tree); continue; @@ -1042,7 +1049,7 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix) continue; } if (!strcmp(arg, "--git-common-dir")) { - print_path(get_git_common_dir(), prefix, format, DEFAULT_RELATIVE_IF_SHARED); + print_path(repo_get_common_dir(the_repository), prefix, format, DEFAULT_RELATIVE_IF_SHARED); continue; } if (!strcmp(arg, "--is-inside-git-dir")) { diff --git a/builtin/revert.c b/builtin/revert.c index 7bf2b4e11d..55ba1092c5 100644 --- a/builtin/revert.c +++ b/builtin/revert.c @@ -1,9 +1,9 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "git-compat-util.h" #include "builtin.h" #include "parse-options.h" #include "diff.h" #include "gettext.h" -#include "repository.h" #include "revision.h" #include "rerere.h" #include "sequencer.h" @@ -261,7 +261,10 @@ static int run_sequencer(int argc, const char **argv, const char *prefix, return sequencer_pick_revisions(the_repository, opts); } -int cmd_revert(int argc, const char **argv, const char *prefix) +int cmd_revert(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct replay_opts opts = REPLAY_OPTS_INIT; int res; @@ -275,7 +278,10 @@ int cmd_revert(int argc, const char **argv, const char *prefix) return res; } -int cmd_cherry_pick(int argc, const char **argv, const char *prefix) +int cmd_cherry_pick(int argc, +const char **argv, +const char *prefix, +struct repository *repo UNUSED) { struct replay_opts opts = REPLAY_OPTS_INIT; int res; diff --git a/builtin/rm.c b/builtin/rm.c index 0e79cbab62..eaff027258 100644 --- a/builtin/rm.c +++ b/builtin/rm.c @@ -3,7 +3,7 @@ * * Copyright (C) Linus Torvalds 2006 */ - +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "advice.h" #include "config.h" @@ -15,7 +15,7 @@ #include "object-name.h" #include "parse-options.h" #include "read-cache.h" -#include "repository.h" + #include "string-list.h" #include "setup.h" #include "sparse-index.h" @@ -261,7 +261,10 @@ static struct option builtin_rm_options[] = { OPT_END(), }; -int cmd_rm(int argc, const char **argv, const char *prefix) +int cmd_rm(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct lock_file lock_file = LOCK_INIT; int i, ret = 0; diff --git a/builtin/send-pack.c b/builtin/send-pack.c index ef0df80824..81fc96d423 100644 --- a/builtin/send-pack.c +++ b/builtin/send-pack.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "hex.h" @@ -147,7 +148,10 @@ static int send_pack_config(const char *k, const char *v, return git_default_config(k, v, ctx, cb); } -int cmd_send_pack(int argc, const char **argv, const char *prefix) +int cmd_send_pack(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct refspec rs = REFSPEC_INIT_PUSH; const char *remote_name = NULL; diff --git a/builtin/shortlog.c b/builtin/shortlog.c index b529608c92..3ed5c46078 100644 --- a/builtin/shortlog.c +++ b/builtin/shortlog.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "commit.h" @@ -5,7 +6,6 @@ #include "environment.h" #include "gettext.h" #include "string-list.h" -#include "repository.h" #include "revision.h" #include "utf8.h" #include "mailmap.h" @@ -378,7 +378,10 @@ void shortlog_finish_setup(struct shortlog *log) string_list_sort(&log->trailers); } -int cmd_shortlog(int argc, const char **argv, const char *prefix) +int cmd_shortlog(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct shortlog log = { STRING_LIST_INIT_NODUP }; struct rev_info rev; diff --git a/builtin/show-branch.c b/builtin/show-branch.c index 29237f653d..cd6bdf63bc 100644 --- a/builtin/show-branch.c +++ b/builtin/show-branch.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "environment.h" @@ -10,7 +11,7 @@ #include "strvec.h" #include "object-name.h" #include "parse-options.h" -#include "repository.h" + #include "dir.h" #include "commit-slab.h" #include "date.h" @@ -632,7 +633,10 @@ static int parse_reflog_param(const struct option *opt, const char *arg, return 0; } -int cmd_show_branch(int ac, const char **av, const char *prefix) +int cmd_show_branch(int ac, + const char **av, + const char *prefix, + struct repository *repo UNUSED) { struct commit *rev[MAX_REVS], *commit; char *reflog_msg[MAX_REVS] = {0}; diff --git a/builtin/show-index.c b/builtin/show-index.c index 540dc3dad1..f164c01bbe 100644 --- a/builtin/show-index.c +++ b/builtin/show-index.c @@ -1,17 +1,20 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "gettext.h" #include "hash.h" #include "hex.h" #include "pack.h" #include "parse-options.h" -#include "repository.h" static const char *const show_index_usage[] = { "git show-index [--object-format=<hash-algorithm>]", NULL }; -int cmd_show_index(int argc, const char **argv, const char *prefix) +int cmd_show_index(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { int i; unsigned nr; diff --git a/builtin/show-ref.c b/builtin/show-ref.c index f5899ce9ff..285cd3e433 100644 --- a/builtin/show-ref.c +++ b/builtin/show-ref.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "gettext.h" @@ -287,7 +288,10 @@ static int exclude_existing_callback(const struct option *opt, const char *arg, return 0; } -int cmd_show_ref(int argc, const char **argv, const char *prefix) +int cmd_show_ref(int argc, +const char **argv, +const char *prefix, +struct repository *repo UNUSED) { struct exclude_existing_options exclude_existing_opts = {0}; struct patterns_options patterns_opts = {0}; diff --git a/builtin/sparse-checkout.c b/builtin/sparse-checkout.c index 5ccf696862..e4e791a4c9 100644 --- a/builtin/sparse-checkout.c +++ b/builtin/sparse-checkout.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "dir.h" @@ -7,7 +8,6 @@ #include "object-name.h" #include "parse-options.h" #include "pathspec.h" -#include "repository.h" #include "strbuf.h" #include "string-list.h" #include "lockfile.h" @@ -1029,7 +1029,10 @@ static int sparse_checkout_check_rules(int argc, const char **argv, const char * return ret; } -int cmd_sparse_checkout(int argc, const char **argv, const char *prefix) +int cmd_sparse_checkout(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { parse_opt_subcommand_fn *fn = NULL; struct option builtin_sparse_checkout_options[] = { diff --git a/builtin/stash.c b/builtin/stash.c index 4a2a633ce3..f1acc918d0 100644 --- a/builtin/stash.c +++ b/builtin/stash.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "abspath.h" #include "config.h" @@ -19,6 +20,7 @@ #include "entry.h" #include "preload-index.h" #include "read-cache.h" +#include "repository.h" #include "rerere.h" #include "revision.h" #include "setup.h" @@ -539,8 +541,8 @@ static int do_apply_stash(const char *prefix, struct stash_info *info, NULL, NULL, NULL)) return error(_("could not write index")); - if (write_index_as_tree(&c_tree, the_repository->index, get_index_file(), 0, - NULL)) + if (write_index_as_tree(&c_tree, the_repository->index, + repo_get_index_file(the_repository), 0, NULL)) return error(_("cannot apply a stash in the middle of a merge")); if (index) { @@ -565,7 +567,7 @@ static int do_apply_stash(const char *prefix, struct stash_info *info, discard_index(the_repository->index); repo_read_index(the_repository); if (write_index_as_tree(&index_tree, the_repository->index, - get_index_file(), 0, NULL)) + repo_get_index_file(the_repository), 0, NULL)) return error(_("could not save index tree")); reset_head(); @@ -640,9 +642,9 @@ restore_untracked: cp.git_cmd = 1; cp.dir = prefix; strvec_pushf(&cp.env, GIT_WORK_TREE_ENVIRONMENT"=%s", - absolute_path(get_git_work_tree())); + absolute_path(repo_get_work_tree(the_repository))); strvec_pushf(&cp.env, GIT_DIR_ENVIRONMENT"=%s", - absolute_path(get_git_dir())); + absolute_path(repo_get_git_dir(the_repository))); strvec_push(&cp.args, "status"); run_command(&cp); } @@ -1405,8 +1407,8 @@ static int do_create_stash(const struct pathspec *ps, struct strbuf *stash_msg_b strbuf_addf(&commit_tree_label, "index on %s\n", msg.buf); commit_list_insert(head_commit, &parents); - if (write_index_as_tree(&info->i_tree, the_repository->index, get_index_file(), 0, - NULL) || + if (write_index_as_tree(&info->i_tree, the_repository->index, + repo_get_index_file(the_repository), 0, NULL) || commit_tree(commit_tree_label.buf, commit_tree_label.len, &info->i_tree, parents, &info->i_commit, NULL, NULL)) { if (!quiet) @@ -1871,7 +1873,10 @@ static int save_stash(int argc, const char **argv, const char *prefix) return ret; } -int cmd_stash(int argc, const char **argv, const char *prefix) +int cmd_stash(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { pid_t pid = getpid(); const char *index_file; @@ -1904,7 +1909,7 @@ int cmd_stash(int argc, const char **argv, const char *prefix) prepare_repo_settings(the_repository); the_repository->settings.command_requires_full_index = 0; - index_file = get_index_file(); + index_file = repo_get_index_file(the_repository); strbuf_addf(&stash_index_path, "%s.stash.%" PRIuMAX, index_file, (uintmax_t)pid); diff --git a/builtin/stripspace.c b/builtin/stripspace.c index e5626e5126..e147f3ff92 100644 --- a/builtin/stripspace.c +++ b/builtin/stripspace.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "environment.h" @@ -29,7 +30,10 @@ enum stripspace_mode { COMMENT_LINES }; -int cmd_stripspace(int argc, const char **argv, const char *prefix) +int cmd_stripspace(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct strbuf buf = STRBUF_INIT; enum stripspace_mode mode = STRIP_DEFAULT; diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 3e0b6c45c0..a1ada86952 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -1,9 +1,10 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "abspath.h" #include "environment.h" #include "gettext.h" #include "hex.h" -#include "repository.h" + #include "config.h" #include "parse-options.h" #include "quote.h" @@ -1709,7 +1710,7 @@ static int clone_submodule(const struct module_clone_data *clone_data, exit(128); if (!is_absolute_path(clone_data->path)) - clone_data_path = to_free = xstrfmt("%s/%s", get_git_work_tree(), + clone_data_path = to_free = xstrfmt("%s/%s", repo_get_work_tree(the_repository), clone_data->path); if (validate_submodule_git_dir(sm_gitdir, clone_data->name) < 0) @@ -2958,7 +2959,9 @@ static int push_check(int argc, const char **argv, const char *prefix UNUSED) rs->src); } } + refspec_clear(&refspec); + free_refs(local_refs); } free(head); @@ -3528,7 +3531,10 @@ cleanup: return ret; } -int cmd_submodule__helper(int argc, const char **argv, const char *prefix) +int cmd_submodule__helper(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { parse_opt_subcommand_fn *fn = NULL; const char *const usage[] = { diff --git a/builtin/symbolic-ref.c b/builtin/symbolic-ref.c index 81abdd170f..299d23d76a 100644 --- a/builtin/symbolic-ref.c +++ b/builtin/symbolic-ref.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "gettext.h" @@ -41,7 +42,10 @@ static int check_symref(const char *HEAD, int quiet, int shorten, int recurse, i return 0; } -int cmd_symbolic_ref(int argc, const char **argv, const char *prefix) +int cmd_symbolic_ref(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { int quiet = 0, delete = 0, shorten = 0, recurse = 1, ret = 0; const char *msg = NULL; diff --git a/builtin/tag.c b/builtin/tag.c index 607e48e311..93d10d5915 100644 --- a/builtin/tag.c +++ b/builtin/tag.c @@ -5,7 +5,7 @@ * Carlos Rica <jasampler@gmail.com> * Based on git-tag.sh and mktag.c by Linus Torvalds. */ - +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "advice.h" #include "config.h" @@ -160,7 +160,7 @@ static int do_sign(struct strbuf *buffer, struct object_id **compat_oid, const struct git_hash_algo *compat = the_repository->compat_hash_algo; struct strbuf sig = STRBUF_INIT, compat_sig = STRBUF_INIT; struct strbuf compat_buf = STRBUF_INIT; - const char *keyid = get_signing_key(); + char *keyid = get_signing_key(); int ret = -1; if (sign_buffer(buffer, &sig, keyid)) @@ -190,6 +190,7 @@ out: strbuf_release(&sig); strbuf_release(&compat_sig); strbuf_release(&compat_buf); + free(keyid); return ret; } @@ -457,7 +458,10 @@ static int strbuf_check_tag_ref(struct strbuf *sb, const char *name) return check_refname_format(sb->buf, 0); } -int cmd_tag(int argc, const char **argv, const char *prefix) +int cmd_tag(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct strbuf buf = STRBUF_INIT; struct strbuf ref = STRBUF_INIT; diff --git a/builtin/unpack-file.c b/builtin/unpack-file.c index c129e2bb6c..6da2825753 100644 --- a/builtin/unpack-file.c +++ b/builtin/unpack-file.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "hex.h" @@ -25,7 +26,10 @@ static char *create_temp_file(struct object_id *oid) return path; } -int cmd_unpack_file(int argc, const char **argv, const char *prefix UNUSED) +int cmd_unpack_file(int argc, + const char **argv, + const char *prefix UNUSED, + struct repository *repo UNUSED) { struct object_id oid; diff --git a/builtin/unpack-objects.c b/builtin/unpack-objects.c index 08fa2a7a74..02b8d02f63 100644 --- a/builtin/unpack-objects.c +++ b/builtin/unpack-objects.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "bulk-checkin.h" #include "config.h" @@ -601,7 +602,10 @@ static void unpack_all(void) die("unresolved deltas left after unpacking"); } -int cmd_unpack_objects(int argc, const char **argv, const char *prefix UNUSED) +int cmd_unpack_objects(int argc, + const char **argv, + const char *prefix UNUSED, + struct repository *repo UNUSED) { int i; struct object_id oid; diff --git a/builtin/update-index.c b/builtin/update-index.c index 35a1f957ad..45b4a8b555 100644 --- a/builtin/update-index.c +++ b/builtin/update-index.c @@ -3,7 +3,7 @@ * * Copyright (C) Linus Torvalds, 2005 */ - +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "bulk-checkin.h" #include "config.h" @@ -22,7 +22,6 @@ #include "pathspec.h" #include "dir.h" #include "read-cache.h" -#include "repository.h" #include "setup.h" #include "sparse-index.h" #include "split-index.h" @@ -917,7 +916,10 @@ static enum parse_opt_result reupdate_callback( return 0; } -int cmd_update_index(int argc, const char **argv, const char *prefix) +int cmd_update_index(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { int newfd, entries, has_errors = 0, nul_term_line = 0; enum uc_mode untracked_cache = UC_UNSPECIFIED; @@ -1194,7 +1196,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix) "remove or change it, if you really want to " "enable the untracked cache")); add_untracked_cache(the_repository->index); - report(_("Untracked cache enabled for '%s'"), get_git_work_tree()); + report(_("Untracked cache enabled for '%s'"), repo_get_work_tree(the_repository)); break; default: BUG("bad untracked_cache value: %d", untracked_cache); @@ -1239,7 +1241,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix) if (newfd < 0) { if (refresh_args.flags & REFRESH_QUIET) exit(128); - unable_to_lock_die(get_index_file(), lock_error); + unable_to_lock_die(repo_get_index_file(the_repository), lock_error); } if (write_locked_index(the_repository->index, &lock_file, COMMIT_LOCK)) die("Unable to write new index file"); diff --git a/builtin/update-ref.c b/builtin/update-ref.c index 8f31da9a4b..8a98615dc8 100644 --- a/builtin/update-ref.c +++ b/builtin/update-ref.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "gettext.h" @@ -6,7 +7,6 @@ #include "object-name.h" #include "parse-options.h" #include "quote.h" -#include "repository.h" static const char * const git_update_ref_usage[] = { N_("git update-ref [<options>] -d <refname> [<old-oid>]"), @@ -713,7 +713,10 @@ static void update_refs_stdin(void) strbuf_release(&input); } -int cmd_update_ref(int argc, const char **argv, const char *prefix) +int cmd_update_ref(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { const char *refname, *oldval; struct object_id oid, oldoid; diff --git a/builtin/update-server-info.c b/builtin/update-server-info.c index 1dc3971ede..6769611a02 100644 --- a/builtin/update-server-info.c +++ b/builtin/update-server-info.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "gettext.h" @@ -9,7 +10,10 @@ static const char * const update_server_info_usage[] = { NULL }; -int cmd_update_server_info(int argc, const char **argv, const char *prefix) +int cmd_update_server_info(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { int force = 0; struct option options[] = { diff --git a/builtin/upload-archive.c b/builtin/upload-archive.c index 313a8dfa81..9e9343f121 100644 --- a/builtin/upload-archive.c +++ b/builtin/upload-archive.c @@ -1,12 +1,12 @@ /* * Copyright (c) 2006 Franck Bui-Huu */ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "archive.h" #include "path.h" #include "pkt-line.h" #include "sideband.h" -#include "repository.h" #include "run-command.h" #include "strvec.h" @@ -18,7 +18,10 @@ static const char deadchild[] = #define MAX_ARGS (64) -int cmd_upload_archive_writer(int argc, const char **argv, const char *prefix) +int cmd_upload_archive_writer(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct strvec sent_argv = STRVEC_INIT; const char *arg_cmd = "argument "; @@ -80,7 +83,10 @@ static ssize_t process_input(int child_fd, int band) return sz; } -int cmd_upload_archive(int argc, const char **argv, const char *prefix) +int cmd_upload_archive(int argc, +const char **argv, +const char *prefix, +struct repository *repo UNUSED) { struct child_process writer = CHILD_PROCESS_INIT; diff --git a/builtin/upload-pack.c b/builtin/upload-pack.c index 46d93278d9..3b6c83fbce 100644 --- a/builtin/upload-pack.c +++ b/builtin/upload-pack.c @@ -17,7 +17,10 @@ static const char * const upload_pack_usage[] = { NULL }; -int cmd_upload_pack(int argc, const char **argv, const char *prefix) +int cmd_upload_pack(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { const char *dir; int strict = 0; diff --git a/builtin/var.c b/builtin/var.c index e30ff45be1..2ecaed51b4 100644 --- a/builtin/var.c +++ b/builtin/var.c @@ -3,7 +3,9 @@ * * Copyright (C) Eric Biederman, 2005 */ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" + #include "attr.h" #include "config.h" #include "editor.h" @@ -210,7 +212,10 @@ static int show_config(const char *var, const char *value, return git_default_config(var, value, ctx, cb); } -int cmd_var(int argc, const char **argv, const char *prefix UNUSED) +int cmd_var(int argc, + const char **argv, + const char *prefix UNUSED, + struct repository *repo UNUSED) { const struct git_var *git_var; char *val; diff --git a/builtin/verify-commit.c b/builtin/verify-commit.c index 0d2b9aea2a..779b7988ca 100644 --- a/builtin/verify-commit.c +++ b/builtin/verify-commit.c @@ -5,11 +5,11 @@ * * Based on git-verify-tag */ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "gettext.h" #include "object-name.h" -#include "repository.h" #include "commit.h" #include "parse-options.h" #include "gpg-interface.h" @@ -51,7 +51,10 @@ static int verify_commit(const char *name, unsigned flags) return run_gpg_verify((struct commit *)obj, flags); } -int cmd_verify_commit(int argc, const char **argv, const char *prefix) +int cmd_verify_commit(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { int i = 1, verbose = 0, had_error = 0; unsigned flags = 0; diff --git a/builtin/verify-pack.c b/builtin/verify-pack.c index 011dddd2dc..34e4ed715f 100644 --- a/builtin/verify-pack.c +++ b/builtin/verify-pack.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "gettext.h" @@ -61,7 +62,10 @@ static const char * const verify_pack_usage[] = { NULL }; -int cmd_verify_pack(int argc, const char **argv, const char *prefix) +int cmd_verify_pack(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { int err = 0; unsigned int flags = 0; diff --git a/builtin/verify-tag.c b/builtin/verify-tag.c index 77becf7e75..a7f20618ff 100644 --- a/builtin/verify-tag.c +++ b/builtin/verify-tag.c @@ -5,6 +5,7 @@ * * Based on git-verify-tag.sh */ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "gettext.h" @@ -19,7 +20,10 @@ static const char * const verify_tag_usage[] = { NULL }; -int cmd_verify_tag(int argc, const char **argv, const char *prefix) +int cmd_verify_tag(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { int i = 1, verbose = 0, had_error = 0; unsigned flags = 0; diff --git a/builtin/worktree.c b/builtin/worktree.c index 41e7f6a327..fc31d072a6 100644 --- a/builtin/worktree.c +++ b/builtin/worktree.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "abspath.h" #include "advice.h" @@ -17,7 +18,6 @@ #include "read-cache-ll.h" #include "refs.h" #include "remote.h" -#include "repository.h" #include "run-command.h" #include "hook.h" #include "sigchain.h" @@ -219,7 +219,7 @@ static void prune_worktrees(void) } closedir(dir); - strbuf_add_absolute_path(&main_path, get_git_common_dir()); + strbuf_add_absolute_path(&main_path, repo_get_common_dir(the_repository)); /* massage main worktree absolute path to match 'gitdir' content */ strbuf_strip_suffix(&main_path, "/."); string_list_append_nodup(&kept, strbuf_detach(&main_path, NULL)); @@ -492,7 +492,7 @@ static int add_worktree(const char *path, const char *refname, strbuf_addf(&sb, "%s/gitdir", sb_repo.buf); strbuf_realpath(&realpath, sb_git.buf, 1); write_file(sb.buf, "%s", realpath.buf); - strbuf_realpath(&realpath, get_git_common_dir(), 1); + strbuf_realpath(&realpath, repo_get_common_dir(the_repository), 1); write_file(sb_git.buf, "gitdir: %s/worktrees/%s", realpath.buf, name); strbuf_reset(&sb); @@ -1392,7 +1392,10 @@ static int repair(int ac, const char **av, const char *prefix) return rc; } -int cmd_worktree(int ac, const char **av, const char *prefix) +int cmd_worktree(int ac, + const char **av, + const char *prefix, + struct repository *repo UNUSED) { parse_opt_subcommand_fn *fn = NULL; struct option options[] = { diff --git a/builtin/write-tree.c b/builtin/write-tree.c index 8c75b4609b..43f233e69b 100644 --- a/builtin/write-tree.c +++ b/builtin/write-tree.c @@ -3,23 +3,24 @@ * * Copyright (C) Linus Torvalds, 2005 */ - +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" -#include "environment.h" #include "gettext.h" #include "hex.h" #include "tree.h" #include "cache-tree.h" #include "parse-options.h" -#include "repository.h" static const char * const write_tree_usage[] = { N_("git write-tree [--missing-ok] [--prefix=<prefix>/]"), NULL }; -int cmd_write_tree(int argc, const char **argv, const char *cmd_prefix) +int cmd_write_tree(int argc, + const char **argv, + const char *cmd_prefix, + struct repository *repo UNUSED) { int flags = 0, ret; const char *tree_prefix = NULL; @@ -44,7 +45,8 @@ int cmd_write_tree(int argc, const char **argv, const char *cmd_prefix) prepare_repo_settings(the_repository); the_repository->settings.command_requires_full_index = 0; - ret = write_index_as_tree(&oid, the_repository->index, get_index_file(), + ret = write_index_as_tree(&oid, the_repository->index, + repo_get_index_file(the_repository), flags, tree_prefix); switch (ret) { case 0: diff --git a/bulk-checkin.c b/bulk-checkin.c index 9089c214fa..2753d5bbe4 100644 --- a/bulk-checkin.c +++ b/bulk-checkin.c @@ -75,7 +75,7 @@ static void flush_bulk_checkin_packfile(struct bulk_checkin_packfile *state) close(fd); } - strbuf_addf(&packname, "%s/pack/pack-%s.", get_object_directory(), + strbuf_addf(&packname, "%s/pack/pack-%s.", repo_get_object_directory(the_repository), hash_to_hex(hash)); finish_tmp_packfile(&packname, state->pack_tmp_name, state->written, state->nr_written, @@ -113,7 +113,7 @@ static void flush_batch_fsync(void) * to ensure that the data in each new object file is durable before * the final name is visible. */ - strbuf_addf(&temp_path, "%s/bulk_fsync_XXXXXX", get_object_directory()); + strbuf_addf(&temp_path, "%s/bulk_fsync_XXXXXX", repo_get_object_directory(the_repository)); temp = xmks_tempfile(temp_path.buf); fsync_or_die(get_tempfile_fd(temp), get_tempfile_path(temp)); delete_tempfile(&temp); diff --git a/bundle-uri.c b/bundle-uri.c index dc0c96955b..4b1a2e2937 100644 --- a/bundle-uri.c +++ b/bundle-uri.c @@ -4,7 +4,6 @@ #include "bundle-uri.h" #include "bundle.h" #include "copy.h" -#include "environment.h" #include "gettext.h" #include "refs.h" #include "run-command.h" @@ -14,6 +13,7 @@ #include "fetch-pack.h" #include "remote.h" #include "trace2.h" +#include "object-store-ll.h" static struct { enum bundle_list_heuristic heuristic; diff --git a/cache-tree.c b/cache-tree.c index 50610c3f3c..b482167a69 100644 --- a/cache-tree.c +++ b/cache-tree.c @@ -1,7 +1,6 @@ #define USE_THE_REPOSITORY_VARIABLE #include "git-compat-util.h" -#include "environment.h" #include "hex.h" #include "lockfile.h" #include "tree.h" @@ -12,6 +11,7 @@ #include "object-store-ll.h" #include "read-cache-ll.h" #include "replace-object.h" +#include "repository.h" #include "promisor-remote.h" #include "trace.h" #include "trace2.h" @@ -725,7 +725,8 @@ int write_index_as_tree(struct object_id *oid, struct index_state *index_state, hold_lock_file_for_update(&lock_file, index_path, LOCK_DIE_ON_ERROR); - entries = read_index_from(index_state, index_path, get_git_dir()); + entries = read_index_from(index_state, index_path, + repo_get_git_dir(the_repository)); if (entries < 0) { ret = WRITE_TREE_UNREADABLE_INDEX; goto out; @@ -12,7 +12,7 @@ static struct cb_node *cb_node_of(const void *p) return (struct cb_node *)((uintptr_t)p - 1); } -/* locate the best match, does not do a final comparision */ +/* locate the best match, does not do a final comparison */ static struct cb_node *cb_internal_best_match(struct cb_node *p, const uint8_t *k, size_t klen) { @@ -183,7 +183,7 @@ int commit_graft_pos(struct repository *r, const struct object_id *oid) commit_graft_oid_access); } -static void unparse_commit(struct repository *r, const struct object_id *oid) +void unparse_commit(struct repository *r, const struct object_id *oid) { struct commit *c = lookup_commit(r, oid); @@ -292,14 +292,14 @@ static int read_graft_file(struct repository *r, const char *graft_file) void prepare_commit_graft(struct repository *r) { - char *graft_file; + const char *graft_file; if (r->parsed_objects->commit_graft_prepared) return; if (!startup_info->have_repository) return; - graft_file = get_graft_file(r); + graft_file = repo_get_graft_file(r); read_graft_file(r, graft_file); /* make sure shallows are read */ is_repository_shallow(r); @@ -324,18 +324,6 @@ int for_each_commit_graft(each_commit_graft_fn fn, void *cb_data) return ret; } -void reset_commit_grafts(struct repository *r) -{ - int i; - - for (i = 0; i < r->parsed_objects->grafts_nr; i++) { - unparse_commit(r, &r->parsed_objects->grafts[i]->oid); - free(r->parsed_objects->grafts[i]); - } - r->parsed_objects->grafts_nr = 0; - r->parsed_objects->commit_graft_prepared = 0; -} - struct commit_buffer { void *buffer; unsigned long size; @@ -1156,11 +1144,14 @@ int add_header_signature(struct strbuf *buf, struct strbuf *sig, const struct gi static int sign_commit_to_strbuf(struct strbuf *sig, struct strbuf *buf, const char *keyid) { + char *keyid_to_free = NULL; + int ret = 0; if (!keyid || !*keyid) - keyid = get_signing_key(); + keyid = keyid_to_free = get_signing_key(); if (sign_buffer(buf, sig, keyid)) - return -1; - return 0; + ret = -1; + free(keyid_to_free); + return ret; } int parse_signed_commit(const struct commit *commit, @@ -110,6 +110,8 @@ static inline int repo_parse_commit_no_graph(struct repository *r, void parse_commit_or_die(struct commit *item); +void unparse_commit(struct repository *r, const struct object_id *oid); + struct buffer_slab; struct buffer_slab *allocate_commit_buffer_slab(void); void free_commit_buffer_slab(struct buffer_slab *bs); @@ -242,7 +244,6 @@ int commit_graft_pos(struct repository *r, const struct object_id *oid); int register_commit_graft(struct repository *r, struct commit_graft *, int); void prepare_commit_graft(struct repository *r); struct commit_graft *lookup_commit_graft(struct repository *r, const struct object_id *oid); -void reset_commit_grafts(struct repository *r); struct commit *get_fork_point(const char *refname, struct commit *commit); @@ -253,7 +254,10 @@ struct oid_array; struct ref; int for_each_commit_graft(each_commit_graft_fn, void *); -int interactive_add(const char **argv, const char *prefix, int patch); +int interactive_add(struct repository *repo, + const char **argv, + const char *prefix, + int patch); struct commit_extra_header { struct commit_extra_header *next; diff --git a/compat/mingw.c b/compat/mingw.c index eb13c02a76..0e851ecae2 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -1,3 +1,5 @@ +#define USE_THE_REPOSITORY_VARIABLE + #include "../git-compat-util.h" #include "win32.h" #include <aclapi.h> diff --git a/compat/win32/path-utils.c b/compat/win32/path-utils.c index b658ca3f81..966ef779b9 100644 --- a/compat/win32/path-utils.c +++ b/compat/win32/path-utils.c @@ -1,3 +1,5 @@ +#define USE_THE_REPOSITORY_VARIABLE + #include "../../git-compat-util.h" #include "../../environment.h" @@ -6,6 +6,8 @@ * */ +#define USE_THE_REPOSITORY_VARIABLE + #include "git-compat-util.h" #include "abspath.h" #include "advice.h" @@ -1445,26 +1447,6 @@ static int git_default_core_config(const char *var, const char *value, return 0; } - if (!strcmp(var, "core.prefersymlinkrefs")) { - prefer_symlink_refs = git_config_bool(var, value); - return 0; - } - - if (!strcmp(var, "core.logallrefupdates")) { - if (value && !strcasecmp(value, "always")) - log_all_ref_updates = LOG_REFS_ALWAYS; - else if (git_config_bool(var, value)) - log_all_ref_updates = LOG_REFS_NORMAL; - else - log_all_ref_updates = LOG_REFS_NONE; - return 0; - } - - if (!strcmp(var, "core.warnambiguousrefs")) { - warn_ambiguous_refs = git_config_bool(var, value); - return 0; - } - if (!strcmp(var, "core.abbrev")) { if (!value) return config_error_nonbool(var); @@ -1573,14 +1555,6 @@ static int git_default_core_config(const char *var, const char *value, return git_config_string(&check_roundtrip_encoding, var, value); } - if (!strcmp(var, "core.notesref")) { - if (!value) - return config_error_nonbool(var); - free(notes_ref_name); - notes_ref_name = xstrdup(value); - return 0; - } - if (!strcmp(var, "core.editor")) { FREE_AND_NULL(editor_program); return git_config_string(&editor_program, var, value); @@ -2202,7 +2176,7 @@ static void configset_iter(struct config_set *set, config_fn_t fn, void *data) } } -void read_early_config(config_fn_t cb, void *data) +void read_early_config(struct repository *repo, config_fn_t cb, void *data) { struct config_options opts = {0}; struct strbuf commondir = STRBUF_INIT; @@ -2210,9 +2184,9 @@ void read_early_config(config_fn_t cb, void *data) opts.respect_includes = 1; - if (have_git_dir()) { - opts.commondir = get_git_common_dir(); - opts.git_dir = get_git_dir(); + if (repo && repo->gitdir) { + opts.commondir = repo_get_common_dir(repo); + opts.git_dir = repo_get_git_dir(repo); /* * When setup_git_directory() was not yet asked to discover the * GIT_DIR, we ask discover_git_directory() to figure out whether there @@ -2232,10 +2206,6 @@ void read_early_config(config_fn_t cb, void *data) strbuf_release(&gitdir); } -/* - * Read config but only enumerate system and global settings. - * Omit any repo-local, worktree-local, or command-line settings. - */ void read_very_early_config(config_fn_t cb, void *data) { struct config_options opts = { 0 }; @@ -192,7 +192,18 @@ int git_config_from_blob_oid(config_fn_t fn, const char *name, void git_config_push_parameter(const char *text); void git_config_push_env(const char *spec); int git_config_from_parameters(config_fn_t fn, void *data); -void read_early_config(config_fn_t cb, void *data); + +/* + * Read config when the Git directory has not yet been set up. In case + * `the_repository` has not yet been set up, try to discover the Git + * directory to read the configuration from. + */ +void read_early_config(struct repository *repo, config_fn_t cb, void *data); + +/* + * Read config but only enumerate system and global settings. + * Omit any repo-local, worktree-local, or command-line settings. + */ void read_very_early_config(config_fn_t cb, void *data); /** diff --git a/config.mak.dev b/config.mak.dev index 50026d1e0e..8eca7fa228 100644 --- a/config.mak.dev +++ b/config.mak.dev @@ -69,7 +69,7 @@ DEVELOPER_CFLAGS += -Wno-missing-braces endif endif -# Old versions of clang complain about initializaing a +# Old versions of clang complain about initializing a # struct-within-a-struct using just "{0}" rather than "{{0}}". This # error is considered a false-positive and not worth fixing, because # new clang versions do not, so just disable it. diff --git a/contrib/buildsystems/CMakeLists.txt b/contrib/buildsystems/CMakeLists.txt index 608fd3fe70..62af7b33d2 100644 --- a/contrib/buildsystems/CMakeLists.txt +++ b/contrib/buildsystems/CMakeLists.txt @@ -970,18 +970,15 @@ if(BUILD_TESTING) add_executable(test-fake-ssh ${CMAKE_SOURCE_DIR}/t/helper/test-fake-ssh.c) target_link_libraries(test-fake-ssh common-main) -#reftable-tests -parse_makefile_for_sources(test-reftable_SOURCES "REFTABLE_TEST_OBJS") -list(TRANSFORM test-reftable_SOURCES PREPEND "${CMAKE_SOURCE_DIR}/") - #unit-tests -add_library(unit-test-lib OBJECT ${CMAKE_SOURCE_DIR}/t/unit-tests/test-lib.c) -add_library(unit-test-lib-oid OBJECT ${CMAKE_SOURCE_DIR}/t/unit-tests/lib-oid.c) +parse_makefile_for_sources(unit-test_SOURCES "UNIT_TEST_OBJS") +list(TRANSFORM unit-test_SOURCES REPLACE "\\$\\(UNIT_TEST_DIR\\)/" "${CMAKE_SOURCE_DIR}/t/unit-tests/") +add_library(unit-test-lib STATIC ${unit-test_SOURCES}) parse_makefile_for_scripts(unit_test_PROGRAMS "UNIT_TEST_PROGRAMS" "") foreach(unit_test ${unit_test_PROGRAMS}) add_executable("${unit_test}" "${CMAKE_SOURCE_DIR}/t/unit-tests/${unit_test}.c") - target_link_libraries("${unit_test}" unit-test-lib unit-test-lib-oid common-main) + target_link_libraries("${unit_test}" unit-test-lib common-main) set_target_properties("${unit_test}" PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/t/unit-tests/bin) if(MSVC) @@ -1004,14 +1001,14 @@ foreach(unit_test ${unit_test_PROGRAMS}) endif() endforeach() -parse_makefile_for_scripts(unit_tests_SUITES "UNIT_TESTS_SUITES" "") +parse_makefile_for_scripts(clar_test_SUITES "CLAR_TEST_SUITES" "") set(clar_decls "") set(clar_cbs "") set(clar_cbs_count 0) set(clar_suites "static struct clar_suite _clar_suites[] = {\n") -list(LENGTH unit_tests_SUITES clar_suites_count) -foreach(suite ${unit_tests_SUITES}) +list(LENGTH clar_test_SUITES clar_suites_count) +foreach(suite ${clar_test_SUITES}) file(STRINGS "${CMAKE_SOURCE_DIR}/t/unit-tests/${suite}.c" decls REGEX "^void test_${suite}__[a-zA-Z_0-9][a-zA-Z_0-9]*\\(void\\)$") @@ -1042,9 +1039,9 @@ string(APPEND clar_suites file(WRITE "${CMAKE_BINARY_DIR}/t/unit-tests/clar-decls.h" "${clar_decls}") file(WRITE "${CMAKE_BINARY_DIR}/t/unit-tests/clar.suite" "${clar_decls}" "${clar_cbs}" "${clar_suites}") -list(TRANSFORM unit_tests_SUITES PREPEND "${CMAKE_SOURCE_DIR}/t/unit-tests/") -list(TRANSFORM unit_tests_SUITES APPEND ".c") -add_library(unit-tests-lib ${unit_tests_SUITES} "${CMAKE_SOURCE_DIR}/t/unit-tests/clar/clar.c") +list(TRANSFORM clar_test_SUITES PREPEND "${CMAKE_SOURCE_DIR}/t/unit-tests/") +list(TRANSFORM clar_test_SUITES APPEND ".c") +add_library(unit-tests-lib ${clar_test_SUITES} "${CMAKE_SOURCE_DIR}/t/unit-tests/clar/clar.c") target_include_directories(unit-tests-lib PRIVATE "${CMAKE_SOURCE_DIR}/t/unit-tests") add_executable(unit-tests "${CMAKE_SOURCE_DIR}/t/unit-tests/unit-test.c") target_link_libraries(unit-tests unit-tests-lib common-main) @@ -1062,7 +1059,7 @@ parse_makefile_for_sources(test-tool_SOURCES "TEST_BUILTINS_OBJS") add_library(test-lib OBJECT ${CMAKE_SOURCE_DIR}/t/unit-tests/test-lib.c) list(TRANSFORM test-tool_SOURCES PREPEND "${CMAKE_SOURCE_DIR}/t/helper/") -add_executable(test-tool ${CMAKE_SOURCE_DIR}/t/helper/test-tool.c ${test-tool_SOURCES} ${test-reftable_SOURCES}) +add_executable(test-tool ${CMAKE_SOURCE_DIR}/t/helper/test-tool.c ${test-tool_SOURCES}) target_link_libraries(test-tool test-lib common-main) set_target_properties(test-fake-ssh test-tool diff --git a/contrib/git-jump/git-jump b/contrib/git-jump/git-jump index 47e0c557e6..3f69675961 100755 --- a/contrib/git-jump/git-jump +++ b/contrib/git-jump/git-jump @@ -44,13 +44,13 @@ open_editor() { mode_diff() { git diff --no-prefix --relative "$@" | perl -ne ' - if (m{^\+\+\+ (.*)}) { $file = $1; next } + if (m{^\+\+\+ (.*)}) { $file = $1 eq "/dev/null" ? undef : $1; next } defined($file) or next; if (m/^@@ .*?\+(\d+)/) { $line = $1; next } defined($line) or next; if (/^ /) { $line++; next } if (/^[-+]\s*(.*)/) { - print "$file:$line: $1\n"; + print "$file:$line:1: $1\n"; $line = undef; } ' @@ -3675,6 +3675,7 @@ static void builtin_diff(const char *name_a, emit_diff_symbol(o, DIFF_SYMBOL_BINARY_FILES, sb.buf, sb.len, 0); strbuf_release(&sb); + o->found_changes = 1; goto free_ab_and_return; } if (fill_mmfile(o->repo, &mf1, one) < 0 || diff --git a/diffcore-rename.c b/diffcore-rename.c index fab45b10d7..3d6826baa3 100644 --- a/diffcore-rename.c +++ b/diffcore-rename.c @@ -933,7 +933,7 @@ static int find_basename_matches(struct diff_options *options, * spend more cycles to find similarities between files, so it may * be less likely that this heuristic is wanted. If someone is * doing break detection, that means they do not want filename - * similarity to imply any form of content similiarity, and thus + * similarity to imply any form of content similarity, and thus * this heuristic would definitely be incompatible. */ @@ -1534,7 +1534,7 @@ void diffcore_rename_extended(struct diff_options *options, * - remove ones not found in relevant_sources * and * - remove ones in relevant_sources which are needed only - * for directory renames IF no ancestory directory + * for directory renames IF no ancestry directory * actually needs to know any more individual path * renames under them */ @@ -20,6 +20,7 @@ #include "object-store-ll.h" #include "path.h" #include "refs.h" +#include "repository.h" #include "wildmatch.h" #include "pathspec.h" #include "utf8.h" @@ -2838,7 +2839,7 @@ static const char *get_ident_string(void) return sb.buf; if (uname(&uts) < 0) die_errno(_("failed to get kernel name and information")); - strbuf_addf(&sb, "Location %s, system %s", get_git_work_tree(), + strbuf_addf(&sb, "Location %s, system %s", repo_get_work_tree(the_repository), uts.sysname); return sb.buf; } diff --git a/environment.c b/environment.c index 1d6c48b52d..a2ce998081 100644 --- a/environment.c +++ b/environment.c @@ -22,15 +22,9 @@ #include "fmt-merge-msg.h" #include "commit.h" #include "strvec.h" -#include "object-file.h" -#include "object-store-ll.h" #include "path.h" -#include "replace-object.h" -#include "tmp-objdir.h" #include "chdir-notify.h" #include "setup.h" -#include "shallow.h" -#include "trace.h" #include "write-or-die.h" int trust_executable_bit = 1; @@ -40,9 +34,7 @@ int has_symlinks = 1; int minimum_abbrev = 4, default_abbrev = -1; int ignore_case; int assume_unchanged; -int prefer_symlink_refs; int is_bare_repository_cfg = -1; /* unspecified */ -int warn_ambiguous_refs = 1; int warn_on_object_refname_ambiguity = 1; int repository_format_precious_objects; char *git_commit_encoding; @@ -75,7 +67,6 @@ enum push_default_type push_default = PUSH_DEFAULT_UNSPECIFIED; #define OBJECT_CREATION_MODE OBJECT_CREATION_USES_HARDLINKS #endif enum object_creation_mode object_creation_mode = OBJECT_CREATION_MODE; -char *notes_ref_name; int grafts_keep_true_parents; int core_apply_sparse_checkout; int core_sparse_checkout_cone; @@ -83,7 +74,6 @@ int sparse_expect_files_outside_of_patterns; int merge_log_config = -1; int precomposed_unicode = -1; /* see probe_utf8_pathname_composition() */ unsigned long pack_size_limit_cfg; -enum log_refs_config log_all_ref_updates = LOG_REFS_UNSET; int max_allowed_tree_depth = #ifdef _MSC_VER /* @@ -123,8 +113,6 @@ int core_preload_index = 1; /* This is set by setup_git_dir_gently() and/or git_default_config() */ char *git_work_tree_cfg; -static char *git_namespace; - /* * Repository-local GIT_* environment variables; see environment.h for details. */ @@ -147,27 +135,6 @@ const char * const local_repo_env[] = { NULL }; -static char *expand_namespace(const char *raw_namespace) -{ - struct strbuf buf = STRBUF_INIT; - struct strbuf **components, **c; - - if (!raw_namespace || !*raw_namespace) - return xstrdup(""); - - strbuf_addstr(&buf, raw_namespace); - components = strbuf_split(&buf, '/'); - strbuf_reset(&buf); - for (c = components; *c; c++) - if (strcmp((*c)->buf, "/") != 0) - strbuf_addf(&buf, "refs/namespaces/%s", (*c)->buf); - strbuf_list_free(components); - if (check_refname_format(buf.buf, 0)) - die(_("bad git namespace path \"%s\""), raw_namespace); - strbuf_addch(&buf, '/'); - return strbuf_detach(&buf, NULL); -} - const char *getenv_safe(struct strvec *argv, const char *name) { const char *value = getenv(name); @@ -179,47 +146,10 @@ const char *getenv_safe(struct strvec *argv, const char *name) return argv->v[argv->nr - 1]; } -void setup_git_env(const char *git_dir) -{ - char *git_replace_ref_base; - const char *shallow_file; - const char *replace_ref_base; - struct set_gitdir_args args = { NULL }; - struct strvec to_free = STRVEC_INIT; - - args.commondir = getenv_safe(&to_free, GIT_COMMON_DIR_ENVIRONMENT); - args.object_dir = getenv_safe(&to_free, DB_ENVIRONMENT); - args.graft_file = getenv_safe(&to_free, GRAFT_ENVIRONMENT); - args.index_file = getenv_safe(&to_free, INDEX_ENVIRONMENT); - args.alternate_db = getenv_safe(&to_free, ALTERNATE_DB_ENVIRONMENT); - if (getenv(GIT_QUARANTINE_ENVIRONMENT)) { - args.disable_ref_updates = 1; - } - - repo_set_gitdir(the_repository, git_dir, &args); - strvec_clear(&to_free); - - if (getenv(NO_REPLACE_OBJECTS_ENVIRONMENT)) - disable_replace_refs(); - replace_ref_base = getenv(GIT_REPLACE_REF_BASE_ENVIRONMENT); - git_replace_ref_base = xstrdup(replace_ref_base ? replace_ref_base - : "refs/replace/"); - update_ref_namespace(NAMESPACE_REPLACE, git_replace_ref_base); - - free(git_namespace); - git_namespace = expand_namespace(getenv(GIT_NAMESPACE_ENVIRONMENT)); - shallow_file = getenv(GIT_SHALLOW_FILE_ENVIRONMENT); - if (shallow_file) - set_alternate_shallow_file(the_repository, shallow_file, 0); - - if (git_env_bool(NO_LAZY_FETCH_ENVIRONMENT, 0)) - fetch_if_missing = 0; -} - int is_bare_repository(void) { /* if core.bare is not 'false', let's see if there is a work tree */ - return is_bare_repository_cfg && !get_git_work_tree(); + return is_bare_repository_cfg && !repo_get_work_tree(the_repository); } int have_git_dir(void) @@ -228,156 +158,45 @@ int have_git_dir(void) || the_repository->gitdir; } -const char *get_git_dir(void) -{ - if (!the_repository->gitdir) - BUG("git environment hasn't been setup"); - return the_repository->gitdir; -} - -const char *get_git_common_dir(void) -{ - if (!the_repository->commondir) - BUG("git environment hasn't been setup"); - return the_repository->commondir; -} - const char *get_git_namespace(void) { - if (!git_namespace) - BUG("git environment hasn't been setup"); - return git_namespace; -} + static const char *namespace; -const char *strip_namespace(const char *namespaced_ref) -{ - const char *out; - if (skip_prefix(namespaced_ref, get_git_namespace(), &out)) - return out; - return NULL; -} - -static int git_work_tree_initialized; + struct strbuf buf = STRBUF_INIT; + struct strbuf **components, **c; + const char *raw_namespace; -/* - * Note. This works only before you used a work tree. This was added - * primarily to support git-clone to work in a new repository it just - * created, and is not meant to flip between different work trees. - */ -void set_git_work_tree(const char *new_work_tree) -{ - if (git_work_tree_initialized) { - struct strbuf realpath = STRBUF_INIT; + if (namespace) + return namespace; - strbuf_realpath(&realpath, new_work_tree, 1); - new_work_tree = realpath.buf; - if (strcmp(new_work_tree, the_repository->worktree)) - die("internal error: work tree has already been set\n" - "Current worktree: %s\nNew worktree: %s", - the_repository->worktree, new_work_tree); - strbuf_release(&realpath); - return; + raw_namespace = getenv(GIT_NAMESPACE_ENVIRONMENT); + if (!raw_namespace || !*raw_namespace) { + namespace = ""; + return namespace; } - git_work_tree_initialized = 1; - repo_set_worktree(the_repository, new_work_tree); -} - -const char *get_git_work_tree(void) -{ - return the_repository->worktree; -} - -const char *get_object_directory(void) -{ - if (!the_repository->objects->odb) - BUG("git environment hasn't been setup"); - return the_repository->objects->odb->path; -} - -int odb_mkstemp(struct strbuf *temp_filename, const char *pattern) -{ - int fd; - /* - * we let the umask do its job, don't try to be more - * restrictive except to remove write permission. - */ - int mode = 0444; - git_path_buf(temp_filename, "objects/%s", pattern); - fd = git_mkstemp_mode(temp_filename->buf, mode); - if (0 <= fd) - return fd; - - /* slow path */ - /* some mkstemp implementations erase temp_filename on failure */ - git_path_buf(temp_filename, "objects/%s", pattern); - safe_create_leading_directories(temp_filename->buf); - return xmkstemp_mode(temp_filename->buf, mode); -} - -int odb_pack_keep(const char *name) -{ - int fd; - - fd = open(name, O_RDWR|O_CREAT|O_EXCL, 0600); - if (0 <= fd) - return fd; - - /* slow path */ - safe_create_leading_directories_const(name); - return open(name, O_RDWR|O_CREAT|O_EXCL, 0600); -} - -char *get_index_file(void) -{ - if (!the_repository->index_file) - BUG("git environment hasn't been setup"); - return the_repository->index_file; -} - -char *get_graft_file(struct repository *r) -{ - if (!r->graft_file) - BUG("git environment hasn't been setup"); - return r->graft_file; -} -static void set_git_dir_1(const char *path) -{ - xsetenv(GIT_DIR_ENVIRONMENT, path, 1); - setup_git_env(path); -} + strbuf_addstr(&buf, raw_namespace); + components = strbuf_split(&buf, '/'); + strbuf_reset(&buf); + for (c = components; *c; c++) + if (strcmp((*c)->buf, "/") != 0) + strbuf_addf(&buf, "refs/namespaces/%s", (*c)->buf); + strbuf_list_free(components); + if (check_refname_format(buf.buf, 0)) + die(_("bad git namespace path \"%s\""), raw_namespace); + strbuf_addch(&buf, '/'); -static void update_relative_gitdir(const char *name UNUSED, - const char *old_cwd, - const char *new_cwd, - void *data UNUSED) -{ - char *path = reparent_relative_path(old_cwd, new_cwd, get_git_dir()); - struct tmp_objdir *tmp_objdir = tmp_objdir_unapply_primary_odb(); + namespace = strbuf_detach(&buf, NULL); - trace_printf_key(&trace_setup_key, - "setup: move $GIT_DIR to '%s'", - path); - set_git_dir_1(path); - if (tmp_objdir) - tmp_objdir_reapply_primary_odb(tmp_objdir, old_cwd, new_cwd); - free(path); + return namespace; } -void set_git_dir(const char *path, int make_realpath) +const char *strip_namespace(const char *namespaced_ref) { - struct strbuf realpath = STRBUF_INIT; - - if (make_realpath) { - strbuf_realpath(&realpath, path, 1); - path = realpath.buf; - } - - set_git_dir_1(path); - if (!is_absolute_path(path)) - chdir_notify_register(NULL, update_relative_gitdir, NULL); - - strbuf_release(&realpath); + const char *out; + if (skip_prefix(namespaced_ref, get_git_namespace(), &out)) + return out; + return NULL; } const char *get_log_output_encoding(void) diff --git a/environment.h b/environment.h index 0148738ed6..923e12661e 100644 --- a/environment.h +++ b/environment.h @@ -1,22 +1,7 @@ #ifndef ENVIRONMENT_H #define ENVIRONMENT_H -struct repository; -struct strvec; - -/* - * The character that begins a commented line in user-editable file - * that is subject to stripspace. - */ -extern const char *comment_line_str; -extern char *comment_line_str_to_free; -extern int auto_comment_line_char; - -/* - * Wrapper of getenv() that returns a strdup value. This value is kept - * in argv to be freed later. - */ -const char *getenv_safe(struct strvec *argv, const char *name); +#include "repo-settings.h" /* Double-check local_repo_env below if you add to this list. */ #define GIT_DIR_ENVIRONMENT "GIT_DIR" @@ -87,6 +72,8 @@ const char *getenv_safe(struct strvec *argv, const char *name); */ #define GIT_IMPLICIT_WORK_TREE_ENVIRONMENT "GIT_IMPLICIT_WORK_TREE" +#define ALTERNATE_DB_ENVIRONMENT "GIT_ALTERNATE_OBJECT_DIRECTORIES" + /* * Repository-local GIT_* environment variables; these will be cleared * when git spawns a sub-process that runs inside another repository. @@ -95,6 +82,50 @@ const char *getenv_safe(struct strvec *argv, const char *name); */ extern const char * const local_repo_env[]; +struct strvec; + +/* + * Wrapper of getenv() that returns a strdup value. This value is kept + * in argv to be freed later. + */ +const char *getenv_safe(struct strvec *argv, const char *name); + +/* + * Should we print an ellipsis after an abbreviated SHA-1 value + * when doing diff-raw output or indicating a detached HEAD? + */ +int print_sha1_ellipsis(void); + +/* + * Returns the boolean value of $GIT_OPTIONAL_LOCKS (or the default value). + */ +int use_optional_locks(void); + +const char *get_git_namespace(void); +const char *strip_namespace(const char *namespaced_ref); + +/* + * TODO: All the below state either explicitly or implicitly relies on + * `the_repository`. We should eventually get rid of these and make the + * dependency on a repository explicit: + * + * - `setup_git_env()` ideally shouldn't exist as it modifies global state, + * namely the environment. The current process shouldn't ever access that + * state via envvars though, but should instead consult a `struct + * repository`. When spawning new processes, we would ideally also pass a + * `struct repository` and then set up the environment variables for the + * child process, only. + * + * - `have_git_dir()` should not have to exist at all. Instead, we should + * decide on whether or not we have a `struct repository`. + * + * - All the global config variables should become tied to a repository. Like + * this, we'd correctly honor repository-local configuration and be able to + * distinguish configuration values from different repositories. + * + * Please do not add new global config variables here. + */ +# ifdef USE_THE_REPOSITORY_VARIABLE void setup_git_env(const char *git_dir); /* @@ -103,21 +134,19 @@ void setup_git_env(const char *git_dir); */ int have_git_dir(void); +/* + * Accessors for the core.sharedrepository config which lazy-load the value + * from the config (if not already set). The "reset" function can be + * used to unset "set" or cached value, meaning that the value will be loaded + * fresh from the config file on the next call to get_shared_repository(). + */ +void set_shared_repository(int value); +int get_shared_repository(void); +void reset_shared_repository(void); + extern int is_bare_repository_cfg; int is_bare_repository(void); extern char *git_work_tree_cfg; -const char *get_git_dir(void); -const char *get_git_common_dir(void); -const char *get_object_directory(void); -char *get_index_file(void); -char *get_graft_file(struct repository *r); -void set_git_dir(const char *path, int make_realpath); -const char *get_git_namespace(void); -const char *strip_namespace(const char *namespaced_ref); -const char *get_git_work_tree(void); -void set_git_work_tree(const char *tree); - -#define ALTERNATE_DB_ENVIRONMENT "GIT_ALTERNATE_OBJECT_DIRECTORIES" /* Environment bits from configuration mechanism */ extern int trust_executable_bit; @@ -127,8 +156,6 @@ extern int has_symlinks; extern int minimum_abbrev, default_abbrev; extern int ignore_case; extern int assume_unchanged; -extern int prefer_symlink_refs; -extern int warn_ambiguous_refs; extern int warn_on_object_refname_ambiguity; extern char *apply_default_whitespace; extern char *apply_default_ignorewhitespace; @@ -143,16 +170,6 @@ extern unsigned long big_file_threshold; extern unsigned long pack_size_limit_cfg; extern int max_allowed_tree_depth; -/* - * Accessors for the core.sharedrepository config which lazy-load the value - * from the config (if not already set). The "reset" function can be - * used to unset "set" or cached value, meaning that the value will be loaded - * fresh from the config file on the next call to get_shared_repository(). - */ -void set_shared_repository(int value); -int get_shared_repository(void); -void reset_shared_repository(void); - extern int core_preload_index; extern int precomposed_unicode; extern int protect_hfs; @@ -162,25 +179,13 @@ extern int core_apply_sparse_checkout; extern int core_sparse_checkout_cone; extern int sparse_expect_files_outside_of_patterns; -/* - * Returns the boolean value of $GIT_OPTIONAL_LOCKS (or the default value). - */ -int use_optional_locks(void); - -enum log_refs_config { - LOG_REFS_UNSET = -1, - LOG_REFS_NONE = 0, - LOG_REFS_NORMAL, - LOG_REFS_ALWAYS -}; -extern enum log_refs_config log_all_ref_updates; - enum rebase_setup_type { AUTOREBASE_NEVER = 0, AUTOREBASE_LOCAL, AUTOREBASE_REMOTE, AUTOREBASE_ALWAYS }; +extern enum rebase_setup_type autorebase; enum push_default_type { PUSH_DEFAULT_NOTHING = 0, @@ -190,38 +195,18 @@ enum push_default_type { PUSH_DEFAULT_CURRENT, PUSH_DEFAULT_UNSPECIFIED }; - -extern enum rebase_setup_type autorebase; extern enum push_default_type push_default; enum object_creation_mode { OBJECT_CREATION_USES_HARDLINKS = 0, OBJECT_CREATION_USES_RENAMES = 1 }; - extern enum object_creation_mode object_creation_mode; -extern char *notes_ref_name; - extern int grafts_keep_true_parents; extern int repository_format_precious_objects; -/* - * Create a temporary file rooted in the object database directory, or - * die on failure. The filename is taken from "pattern", which should have the - * usual "XXXXXX" trailer, and the resulting filename is written into the - * "template" buffer. Returns the open descriptor. - */ -int odb_mkstemp(struct strbuf *temp_filename, const char *pattern); - -/* - * Create a pack .keep file named "name" (which should generally be the output - * of odb_pack_name). Returns a file descriptor opened for writing, or -1 on - * error. - */ -int odb_pack_keep(const char *name); - const char *get_log_output_encoding(void); const char *get_commit_output_encoding(void); @@ -233,9 +218,12 @@ extern char *askpass_program; extern char *excludes_file; /* - * Should we print an ellipsis after an abbreviated SHA-1 value - * when doing diff-raw output or indicating a detached HEAD? + * The character that begins a commented line in user-editable file + * that is subject to stripspace. */ -int print_sha1_ellipsis(void); +extern const char *comment_line_str; +extern char *comment_line_str_to_free; +extern int auto_comment_line_char; -#endif +# endif /* USE_THE_REPOSITORY_VARIABLE */ +#endif /* ENVIRONMENT_H */ diff --git a/fetch-pack.c b/fetch-pack.c index 983c560785..f752da93a8 100644 --- a/fetch-pack.c +++ b/fetch-pack.c @@ -1839,7 +1839,7 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args, string_list_append_nodup(pack_lockfiles, xstrfmt("%s/pack/pack-%s.keep", - get_object_directory(), + repo_get_object_directory(the_repository), packname)); } string_list_clear(&packfile_uris, 0); @@ -2227,7 +2227,10 @@ void negotiate_using_fetch(const struct oid_array *negotiation_tips, trace2_region_leave("fetch-pack", "negotiate_using_fetch", the_repository); trace2_data_intmax("negotiate_using_fetch", the_repository, "total_rounds", negotiation_round); + clear_common_flag(acked_commits); + object_array_clear(&nt_object_array); + negotiator.release(&negotiator); strbuf_release(&req_buf); } diff --git a/fsmonitor-settings.c b/fsmonitor-settings.c index e818583420..a6587a8972 100644 --- a/fsmonitor-settings.c +++ b/fsmonitor-settings.c @@ -7,7 +7,7 @@ #include "fsmonitor-path-utils.h" /* - * We keep this structure defintion private and have getters + * We keep this structure definition private and have getters * for all fields so that we can lazy load it as needed. */ struct fsmonitor_settings { diff --git a/fsmonitor.c b/fsmonitor.c index 28130f748f..237ca59d00 100644 --- a/fsmonitor.c +++ b/fsmonitor.c @@ -8,6 +8,7 @@ #include "fsmonitor.h" #include "fsmonitor-ipc.h" #include "name-hash.h" +#include "repository.h" #include "run-command.h" #include "strbuf.h" #include "trace2.h" @@ -169,7 +170,7 @@ static int query_fsmonitor_hook(struct repository *r, strvec_pushf(&cp.args, "%d", version); strvec_pushf(&cp.args, "%s", last_update); cp.use_shell = 1; - cp.dir = get_git_work_tree(); + cp.dir = repo_get_work_tree(the_repository); trace2_region_enter("fsm_hook", "query", NULL); diff --git a/git-instaweb.sh b/git-instaweb.sh index 994431c887..8dbe21d588 100755 --- a/git-instaweb.sh +++ b/git-instaweb.sh @@ -612,7 +612,7 @@ python_conf() { ln -sf "$root/static" "$fqgitdir/gitweb/$httpd_only/" # generate a standalone 'python http.server' script in $fqgitdir/gitweb - # This asumes that python is in user's $PATH + # This assumes that python is in user's $PATH # This script is Python 2 and 3 compatible cat > "$fqgitdir/gitweb/gitweb.py" <<EOF #!/usr/bin/env python @@ -54,7 +54,7 @@ import time import zipfile import zlib -# On python2.7 where raw_input() and input() are both availble, +# On python2.7 where raw_input() and input() are both available, # we want raw_input's semantics, but aliased to input for python3 # compatibility # support basestring in python3 @@ -1804,7 +1804,7 @@ class P4Submit(Command, P4UserMap): status from the script will abort the process. The purpose of the hook is to edit the message file in place, and it is not - supressed by the `--no-verify` option. This hook is called even if + suppressed by the `--no-verify` option. This hook is called even if `--prepare-p4-only` is set. The `p4-changelist` hook is executed after the changelist message has been @@ -31,7 +31,7 @@ struct cmd_struct { const char *cmd; - int (*fn)(int, const char **, const char *); + int (*fn)(int, const char **, const char *, struct repository *); unsigned int option; }; @@ -441,7 +441,7 @@ static int handle_alias(int *argcp, const char ***argv) return ret; } -static int run_builtin(struct cmd_struct *p, int argc, const char **argv) +static int run_builtin(struct cmd_struct *p, int argc, const char **argv, struct repository *repo) { int status, help; struct stat st; @@ -479,9 +479,9 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv) trace_argv_printf(argv, "trace: built-in: git"); trace2_cmd_name(p->cmd); - validate_cache_entries(the_repository->index); - status = p->fn(argc, argv, prefix); - validate_cache_entries(the_repository->index); + validate_cache_entries(repo->index); + status = p->fn(argc, argv, prefix, (p->option & RUN_SETUP)? repo : NULL); + validate_cache_entries(repo->index); if (status) return status; @@ -736,7 +736,7 @@ static void handle_builtin(int argc, const char **argv) builtin = get_builtin(cmd); if (builtin) - exit(run_builtin(builtin, argc, argv)); + exit(run_builtin(builtin, argc, argv, the_repository)); strvec_clear(&args); } diff --git a/gpg-interface.c b/gpg-interface.c index 6587085cd1..07335987a6 100644 --- a/gpg-interface.c +++ b/gpg-interface.c @@ -45,8 +45,8 @@ struct gpg_format { size_t signature_size); int (*sign_buffer)(struct strbuf *buffer, struct strbuf *signature, const char *signing_key); - const char *(*get_default_key)(void); - const char *(*get_key_id)(void); + char *(*get_default_key)(void); + char *(*get_key_id)(void); }; static const char *openpgp_verify_args[] = { @@ -86,9 +86,9 @@ static int sign_buffer_gpg(struct strbuf *buffer, struct strbuf *signature, static int sign_buffer_ssh(struct strbuf *buffer, struct strbuf *signature, const char *signing_key); -static const char *get_default_ssh_signing_key(void); +static char *get_default_ssh_signing_key(void); -static const char *get_ssh_key_id(void); +static char *get_ssh_key_id(void); static struct gpg_format gpg_format[] = { { @@ -400,7 +400,7 @@ static void parse_ssh_output(struct signature_check *sigc) * Note that "PRINCIPAL" can contain whitespace, "RSA" and * "SHA256" part could be a different token that names of * the algorithms used, and "FINGERPRINT" is a hexadecimal - * string. By finding the last occurence of " with ", we can + * string. By finding the last occurrence of " with ", we can * reliably parse out the PRINCIPAL. */ sigc->result = 'B'; @@ -847,7 +847,7 @@ static char *get_ssh_key_fingerprint(const char *signing_key) } /* Returns the first public key from an ssh-agent to use for signing */ -static const char *get_default_ssh_signing_key(void) +static char *get_default_ssh_signing_key(void) { struct child_process ssh_default_key = CHILD_PROCESS_INIT; int ret = -1; @@ -899,12 +899,16 @@ static const char *get_default_ssh_signing_key(void) return default_key; } -static const char *get_ssh_key_id(void) { - return get_ssh_key_fingerprint(get_signing_key()); +static char *get_ssh_key_id(void) +{ + char *signing_key = get_signing_key(); + char *key_id = get_ssh_key_fingerprint(signing_key); + free(signing_key); + return key_id; } /* Returns a textual but unique representation of the signing key */ -const char *get_signing_key_id(void) +char *get_signing_key_id(void) { gpg_interface_lazy_init(); @@ -916,17 +920,17 @@ const char *get_signing_key_id(void) return get_signing_key(); } -const char *get_signing_key(void) +char *get_signing_key(void) { gpg_interface_lazy_init(); if (configured_signing_key) - return configured_signing_key; + return xstrdup(configured_signing_key); if (use_format->get_default_key) { return use_format->get_default_key(); } - return git_committer_info(IDENT_STRICT | IDENT_NO_DATE); + return xstrdup(git_committer_info(IDENT_STRICT | IDENT_NO_DATE)); } const char *gpg_trust_level_to_str(enum signature_trust_level level) diff --git a/gpg-interface.h b/gpg-interface.h index 7cd98161f7..e09f12e8d0 100644 --- a/gpg-interface.h +++ b/gpg-interface.h @@ -80,13 +80,13 @@ int sign_buffer(struct strbuf *buffer, struct strbuf *signature, const char *gpg_trust_level_to_str(enum signature_trust_level level); void set_signing_key(const char *); -const char *get_signing_key(void); +char *get_signing_key(void); /* * Returns a textual unique representation of the signing key in use * Either a GPG KeyID or a SSH Key Fingerprint */ -const char *get_signing_key_id(void); +char *get_signing_key_id(void); int check_signature(struct signature_check *sigc, const char *signature, size_t slen); void print_signature_buffer(const struct signature_check *sigc, @@ -16,6 +16,7 @@ #include "parse-options.h" #include "prompt.h" #include "fsmonitor-ipc.h" +#include "repository.h" #ifndef NO_CURL #include "git-curl-compat.h" /* For LIBCURL_VERSION only */ @@ -618,7 +619,7 @@ const char *help_unknown_cmd(const char *cmd) memset(&other_cmds, 0, sizeof(other_cmds)); memset(&aliases, 0, sizeof(aliases)); - read_early_config(git_unknown_cmd_config, NULL); + read_early_config(the_repository, git_unknown_cmd_config, NULL); /* * Disable autocorrection prompt in a non-interactive session @@ -775,7 +776,7 @@ void get_version_info(struct strbuf *buf, int show_build_options) } } -int cmd_version(int argc, const char **argv, const char *prefix) +int cmd_version(int argc, const char **argv, const char *prefix, struct repository *repository UNUSED) { struct strbuf buf = STRBUF_INIT; int build_options = 0; diff --git a/http-backend.c b/http-backend.c index 79ce097359..73eec4ea3d 100644 --- a/http-backend.c +++ b/http-backend.c @@ -601,7 +601,7 @@ static void get_head(struct strbuf *hdr, char *arg UNUSED) static void get_info_packs(struct strbuf *hdr, char *arg UNUSED) { - size_t objdirlen = strlen(get_object_directory()); + size_t objdirlen = strlen(repo_get_object_directory(the_repository)); struct strbuf buf = STRBUF_INIT; struct packed_git *p; size_t cnt = 0; @@ -1707,7 +1707,7 @@ void run_active_slot(struct active_request_slot *slot) * The value of slot->finished we set before the loop was used * to set our "finished" variable when our request completed. * - * 1. The slot may not have been reused for another requst + * 1. The slot may not have been reused for another request * yet, in which case it still has &finished. * * 2. The slot may already be in-use to serve another request, diff --git a/imap-send.c b/imap-send.c index 2dd42807cd..ec68a06687 100644 --- a/imap-send.c +++ b/imap-send.c @@ -31,9 +31,6 @@ #include "parse-options.h" #include "setup.h" #include "strbuf.h" -#if defined(NO_OPENSSL) && !defined(HAVE_OPENSSL_CSPRNG) -typedef void *SSL; -#endif #ifdef USE_CURL_FOR_IMAP_SEND #include "http.h" #endif @@ -85,7 +82,11 @@ struct imap_server_conf { struct imap_socket { int fd[2]; +#if defined(NO_OPENSSL) && !defined(HAVE_OPENSSL_CSPRNG) + void *ssl; +#else SSL *ssl; +#endif }; struct imap_buffer { diff --git a/match-trees.c b/match-trees.c index f17c74d483..147b03abf1 100644 --- a/match-trees.c +++ b/match-trees.c @@ -294,18 +294,22 @@ void shift_tree(struct repository *r, unsigned short mode; if (!*del_prefix) - return; + goto out; if (get_tree_entry(r, hash2, del_prefix, shifted, &mode)) die("cannot find path %s in tree %s", del_prefix, oid_to_hex(hash2)); - return; + goto out; } if (!*add_prefix) - return; + goto out; splice_tree(hash1, add_prefix, hash2, shifted); + +out: + free(add_prefix); + free(del_prefix); } /* diff --git a/merge-ll.c b/merge-ll.c index badb6dea57..8e63071922 100644 --- a/merge-ll.c +++ b/merge-ll.c @@ -334,7 +334,7 @@ static int read_merge_config(const char *var, const char *value, * %X - the revision for our version * %Y - the revision for their version * - * If the file is not named indentically in all versions, then each + * If the file is not named identically in all versions, then each * revision is joined with the corresponding path, separated by a colon. * The external merge driver should write the results in the * file named by %A, and signal that it has done with zero exit diff --git a/merge-ort.c b/merge-ort.c index 3752c7e595..8b81153e8f 100644 --- a/merge-ort.c +++ b/merge-ort.c @@ -1147,7 +1147,7 @@ static void collect_rename_info(struct merge_options *opt, * Update dir_rename_mask (determines ignore-rename-source validity) * * dir_rename_mask helps us keep track of when directory rename - * detection may be relevant. Basically, whenver a directory is + * detection may be relevant. Basically, whenever a directory is * removed on one side of history, and a file is added to that * directory on the other side of history, directory rename * detection is relevant (meaning we have to detect renames for all @@ -2710,7 +2710,7 @@ static void apply_directory_rename_modifications(struct merge_options *opt, struct conflict_info *dir_ci; char *cur_dir = dirs_to_insert.items[i].string; - CALLOC_ARRAY(dir_ci, 1); + dir_ci = mem_pool_calloc(&opt->priv->pool, 1, sizeof(*dir_ci)); dir_ci->merged.directory_name = parent_name; len = strlen(parent_name); @@ -2838,6 +2838,8 @@ static void apply_directory_rename_modifications(struct merge_options *opt, * Finally, record the new location. */ pair->two->path = new_path; + + string_list_clear(&dirs_to_insert, 0); } /*** Function Grouping: functions related to regular rename detection ***/ @@ -3835,7 +3837,7 @@ static int write_completed_directory(struct merge_options *opt, * src/moduleB 2 * * which is used to know that xtract.c & token.txt are from the - * toplevel dirctory, while umm.c & stuff.h & baz.c are from the + * toplevel directory, while umm.c & stuff.h & baz.c are from the * src/moduleB directory. Again, following the example above, * once we need to process src/moduleB, then info->offsets is * updated to diff --git a/name-hash.c b/name-hash.c index 3a58ce03d9..95528e3bcd 100644 --- a/name-hash.c +++ b/name-hash.c @@ -5,6 +5,9 @@ * * Copyright (C) 2008 Linus Torvalds */ + +#define USE_THE_REPOSITORY_VARIABLE + #include "git-compat-util.h" #include "environment.h" #include "gettext.h" diff --git a/negotiator/skipping.c b/negotiator/skipping.c index 6e61b3c5f1..abedb70a48 100644 --- a/negotiator/skipping.c +++ b/negotiator/skipping.c @@ -247,8 +247,11 @@ static int ack(struct fetch_negotiator *n, struct commit *c) static void release(struct fetch_negotiator *n) { - clear_prio_queue(&((struct data *)n->data)->rev_list); - FREE_AND_NULL(n->data); + struct data *data = n->data; + for (int i = 0; i < data->rev_list.nr; i++) + free(data->rev_list.array[i].data); + clear_prio_queue(&data->rev_list); + FREE_AND_NULL(data); } void skipping_negotiator_init(struct fetch_negotiator *negotiator) @@ -992,15 +992,16 @@ static int notes_display_config(const char *k, const char *v, return 0; } -const char *default_notes_ref(void) +char *default_notes_ref(struct repository *repo) { - const char *notes_ref = NULL; + char *notes_ref = NULL; + if (!notes_ref) - notes_ref = getenv(GIT_NOTES_REF_ENVIRONMENT); + notes_ref = xstrdup_or_null(getenv(GIT_NOTES_REF_ENVIRONMENT)); if (!notes_ref) - notes_ref = notes_ref_name; /* value of core.notesRef config */ + repo_config_get_string(repo, "core.notesref", ¬es_ref); if (!notes_ref) - notes_ref = GIT_NOTES_DEFAULT_REF; + notes_ref = xstrdup(GIT_NOTES_DEFAULT_REF); return notes_ref; } @@ -1010,13 +1011,14 @@ void init_notes(struct notes_tree *t, const char *notes_ref, struct object_id oid, object_oid; unsigned short mode; struct leaf_node root_tree; + char *to_free = NULL; if (!t) t = &default_notes_tree; assert(!t->initialized); if (!notes_ref) - notes_ref = default_notes_ref(); + notes_ref = to_free = default_notes_ref(the_repository); update_ref_namespace(NAMESPACE_NOTES, xstrdup(notes_ref)); if (!combine_notes) @@ -1033,7 +1035,7 @@ void init_notes(struct notes_tree *t, const char *notes_ref, if (flags & NOTES_INIT_EMPTY || repo_get_oid_treeish(the_repository, notes_ref, &object_oid)) - return; + goto out; if (flags & NOTES_INIT_WRITABLE && refs_read_ref(get_main_ref_store(the_repository), notes_ref, &object_oid)) die("Cannot use notes ref %s", notes_ref); if (get_tree_entry(the_repository, &object_oid, "", &oid, &mode)) @@ -1043,6 +1045,9 @@ void init_notes(struct notes_tree *t, const char *notes_ref, oidclr(&root_tree.key_oid, the_repository->hash_algo); oidcpy(&root_tree.val_oid, &oid); load_subtree(t, &root_tree, t->root, 0); + +out: + free(to_free); } struct notes_tree **load_notes_trees(struct string_list *refs, int flags) @@ -1105,7 +1110,7 @@ void load_display_notes(struct display_notes_opt *opt) if (!opt || opt->use_default_notes > 0 || (opt->use_default_notes == -1 && !opt->extra_notes_refs.nr)) { - string_list_append(&display_notes_refs, default_notes_ref()); + string_list_append_nodup(&display_notes_refs, default_notes_ref(the_repository)); display_ref_env = getenv(GIT_NOTES_DISPLAY_REF_ENVIRONMENT); if (display_ref_env) { string_list_add_refs_from_colon_sep(&display_notes_refs, @@ -4,6 +4,7 @@ #include "string-list.h" struct object_id; +struct repository; struct strbuf; /* @@ -70,7 +71,7 @@ extern struct notes_tree { * 3. The value of the core.notesRef config variable, if set * 4. GIT_NOTES_DEFAULT_REF (i.e. "refs/notes/commits") */ -const char *default_notes_ref(void); +char *default_notes_ref(struct repository *repo); /* * Flags controlling behaviour of notes tree initialization diff --git a/object-file.c b/object-file.c index c5994202ba..7ac9533ab1 100644 --- a/object-file.c +++ b/object-file.c @@ -419,6 +419,39 @@ enum scld_error safe_create_leading_directories_const(const char *path) return result; } +int odb_mkstemp(struct strbuf *temp_filename, const char *pattern) +{ + int fd; + /* + * we let the umask do its job, don't try to be more + * restrictive except to remove write permission. + */ + int mode = 0444; + git_path_buf(temp_filename, "objects/%s", pattern); + fd = git_mkstemp_mode(temp_filename->buf, mode); + if (0 <= fd) + return fd; + + /* slow path */ + /* some mkstemp implementations erase temp_filename on failure */ + git_path_buf(temp_filename, "objects/%s", pattern); + safe_create_leading_directories(temp_filename->buf); + return xmkstemp_mode(temp_filename->buf, mode); +} + +int odb_pack_keep(const char *name) +{ + int fd; + + fd = open(name, O_RDWR|O_CREAT|O_EXCL, 0600); + if (0 <= fd) + return fd; + + /* slow path */ + safe_create_leading_directories_const(name); + return open(name, O_RDWR|O_CREAT|O_EXCL, 0600); +} + static void fill_loose_path(struct strbuf *buf, const struct object_id *oid) { int i; @@ -2053,7 +2086,7 @@ static int start_loose_object_common(struct strbuf *tmp_file, else if (errno == EACCES) return error(_("insufficient permission for adding " "an object to repository database %s"), - get_object_directory()); + repo_get_object_directory(the_repository)); else return error_errno( _("unable to create temporary file")); @@ -2228,7 +2261,7 @@ int stream_loose_object(struct input_stream *in_stream, size_t len, prepare_loose_object_bulk_checkin(); /* Since oid is not determined, save tmp file to odb path. */ - strbuf_addf(&filename, "%s/", get_object_directory()); + strbuf_addf(&filename, "%s/", repo_get_object_directory(the_repository)); hdrlen = format_object_header(hdr, sizeof(hdr), OBJ_BLOB, len); /* @@ -2275,7 +2308,7 @@ int stream_loose_object(struct input_stream *in_stream, size_t len, /* * Common steps for write_loose_object and stream_loose_object to - * end writing loose oject: + * end writing loose object: * * - End the compression of zlib stream. * - Get the calculated oid. diff --git a/object-name.c b/object-name.c index 09c1bd93a3..c892fbe80a 100644 --- a/object-name.c +++ b/object-name.c @@ -20,6 +20,7 @@ #include "pretty.h" #include "object-store-ll.h" #include "read-cache-ll.h" +#include "repo-settings.h" #include "repository.h" #include "setup.h" #include "midx.h" @@ -959,7 +960,7 @@ static int get_oid_basic(struct repository *r, const char *str, int len, int fatal = !(flags & GET_OID_QUIETLY); if (len == r->hash_algo->hexsz && !get_oid_hex(str, oid)) { - if (warn_ambiguous_refs && warn_on_object_refname_ambiguity) { + if (repo_settings_get_warn_ambiguous_refs(r) && warn_on_object_refname_ambiguity) { refs_found = repo_dwim_ref(r, str, len, &tmp_oid, &real_ref, 0); if (refs_found > 0) { warning(warn_msg, len, str); @@ -1020,7 +1021,7 @@ static int get_oid_basic(struct repository *r, const char *str, int len, if (!refs_found) return -1; - if (warn_ambiguous_refs && !(flags & GET_OID_QUIETLY) && + if (repo_settings_get_warn_ambiguous_refs(r) && !(flags & GET_OID_QUIETLY) && (refs_found > 1 || !get_short_oid(r, str, len, &tmp_oid, GET_OID_QUIETLY))) warning(warn_msg, len, str); diff --git a/object-store-ll.h b/object-store-ll.h index c5f2bb2fc2..53b8e693b1 100644 --- a/object-store-ll.h +++ b/object-store-ll.h @@ -232,6 +232,21 @@ struct raw_object_store *raw_object_store_new(void); void raw_object_store_clear(struct raw_object_store *o); /* + * Create a temporary file rooted in the object database directory, or + * die on failure. The filename is taken from "pattern", which should have the + * usual "XXXXXX" trailer, and the resulting filename is written into the + * "template" buffer. Returns the open descriptor. + */ +int odb_mkstemp(struct strbuf *temp_filename, const char *pattern); + +/* + * Create a pack .keep file named "name" (which should generally be the output + * of odb_pack_name). Returns a file descriptor opened for writing, or -1 on + * error. + */ +int odb_pack_keep(const char *name); + +/* * Put in `buf` the name of the file in the local object database that * would be used to store a loose object with the specified oid. */ @@ -545,11 +545,12 @@ void repo_clear_commit_marks(struct repository *r, unsigned int flags) } } -struct parsed_object_pool *parsed_object_pool_new(void) +struct parsed_object_pool *parsed_object_pool_new(struct repository *repo) { struct parsed_object_pool *o = xmalloc(sizeof(*o)); memset(o, 0, sizeof(*o)); + o->repo = repo; o->blob_state = allocate_alloc_state(); o->tree_state = allocate_alloc_state(); o->commit_state = allocate_alloc_state(); @@ -628,6 +629,16 @@ void raw_object_store_clear(struct raw_object_store *o) hashmap_clear(&o->pack_map); } +void parsed_object_pool_reset_commit_grafts(struct parsed_object_pool *o) +{ + for (int i = 0; i < o->grafts_nr; i++) { + unparse_commit(o->repo, &o->grafts[i]->oid); + free(o->grafts[i]); + } + o->grafts_nr = 0; + o->commit_graft_prepared = 0; +} + void parsed_object_pool_clear(struct parsed_object_pool *o) { /* @@ -659,6 +670,7 @@ void parsed_object_pool_clear(struct parsed_object_pool *o) free_commit_buffer_slab(o->buffer_slab); o->buffer_slab = NULL; + parsed_object_pool_reset_commit_grafts(o); clear_alloc_state(o->blob_state); clear_alloc_state(o->tree_state); clear_alloc_state(o->commit_state); @@ -7,6 +7,7 @@ struct buffer_slab; struct repository; struct parsed_object_pool { + struct repository *repo; struct object **obj_hash; int nr_objs, obj_hash_size; @@ -31,8 +32,9 @@ struct parsed_object_pool { struct buffer_slab *buffer_slab; }; -struct parsed_object_pool *parsed_object_pool_new(void); +struct parsed_object_pool *parsed_object_pool_new(struct repository *repo); void parsed_object_pool_clear(struct parsed_object_pool *o); +void parsed_object_pool_reset_commit_grafts(struct parsed_object_pool *o); struct object_list { struct object *item; diff --git a/pack-write.c b/pack-write.c index d07f03d0ab..27965672f1 100644 --- a/pack-write.c +++ b/pack-write.c @@ -12,6 +12,7 @@ #include "pack-objects.h" #include "pack-revindex.h" #include "path.h" +#include "repository.h" #include "strbuf.h" void reset_pack_idx_option(struct pack_idx_option *opts) @@ -473,7 +474,7 @@ char *index_pack_lockfile(int ip_out, int *is_well_formed) packname[len-1] = 0; if (skip_prefix(packname, "keep\t", &name)) return xstrfmt("%s/pack/pack-%s.keep", - get_object_directory(), name); + repo_get_object_directory(the_repository), name); return NULL; } if (is_well_formed) diff --git a/packfile.c b/packfile.c index cf12a539ea..df4ba67719 100644 --- a/packfile.c +++ b/packfile.c @@ -30,7 +30,7 @@ char *odb_pack_name(struct strbuf *buf, const char *ext) { strbuf_reset(buf); - strbuf_addf(buf, "%s/pack/pack-%s.%s", get_object_directory(), + strbuf_addf(buf, "%s/pack/pack-%s.%s", repo_get_object_directory(the_repository), hash_to_hex(hash), ext); return buf->buf; } @@ -1,3 +1,5 @@ +#define USE_THE_REPOSITORY_VARIABLE + #include "git-compat-util.h" #include "config.h" #include "editor.h" @@ -92,7 +94,8 @@ const char *git_pager(int stdout_is_tty) pager = getenv("GIT_PAGER"); if (!pager) { if (!pager_program) - read_early_config(core_pager_config, NULL); + read_early_config(the_repository, + core_pager_config, NULL); pager = pager_program; } if (!pager) @@ -298,7 +301,7 @@ int check_pager_config(const char *cmd) data.want = -1; data.value = NULL; - read_early_config(pager_command_config, &data); + read_early_config(the_repository, pager_command_config, &data); if (data.value) pager_program = data.value; @@ -2,6 +2,8 @@ * Utilities for paths and pathnames */ +#define USE_THE_REPOSITORY_VARIABLE + #include "git-compat-util.h" #include "abspath.h" #include "environment.h" diff --git a/pathspec.c b/pathspec.c index fe1f0f41af..0fc6f84a6e 100644 --- a/pathspec.c +++ b/pathspec.c @@ -495,9 +495,9 @@ static void init_pathspec_item(struct pathspec_item *item, unsigned flags, if (!have_git_dir()) die(_("'%s' is outside the directory tree"), copyfrom); - hint_path = get_git_work_tree(); + hint_path = repo_get_work_tree(the_repository); if (!hint_path) - hint_path = get_git_dir(); + hint_path = repo_get_git_dir(the_repository); die(_("%s: '%s' is outside repository at '%s'"), elt, copyfrom, absolute_path(hint_path)); } diff --git a/perl/Git.pm b/perl/Git.pm index aebfe0c6e0..667152c6c6 100644 --- a/perl/Git.pm +++ b/perl/Git.pm @@ -187,7 +187,7 @@ sub repository { try { # Note that "--is-bare-repository" must come first, as # --git-dir output could contain newlines. - $out = $search->command([qw(rev-parse --is-bare-repository --git-dir)], + $out = $search->command([qw(rev-parse --is-bare-repository --absolute-git-dir)], STDERR => 0); } catch Git::Error::Command with { throw Error::Simple("fatal: not a git repository: $opts{Directory}"); @@ -196,12 +196,12 @@ sub repository { chomp $out; my ($bare, $dir) = split /\n/, $out, 2; - require Cwd; - if ($bare ne 'true') { - require File::Spec; - File::Spec->file_name_is_absolute($dir) or $dir = $opts{Directory} . '/' . $dir; - $opts{Repository} = Cwd::abs_path($dir); + # We know this is an absolute path, because we used + # --absolute-git-dir above. + $opts{Repository} = $dir; + if ($bare ne 'true') { + require Cwd; # If --git-dir went ok, this shouldn't die either. my $prefix = $search->command_oneline('rev-parse', '--show-prefix'); $dir = Cwd::abs_path($opts{Directory}) . '/'; @@ -214,8 +214,6 @@ sub repository { $opts{WorkingCopy} = $dir; $opts{WorkingSubdir} = $prefix; - } else { - $opts{Repository} = Cwd::abs_path($dir); } delete $opts{Directory}; diff --git a/preload-index.c b/preload-index.c index 63fd35d64b..7926eb09a6 100644 --- a/preload-index.c +++ b/preload-index.c @@ -1,6 +1,9 @@ /* * Copyright (C) 2008 Linus Torvalds */ + +#define USE_THE_REPOSITORY_VARIABLE + #include "git-compat-util.h" #include "pathspec.h" #include "dir.h" @@ -2205,7 +2205,7 @@ static void strbuf_add_tabexpand(struct strbuf *sb, struct grep_opt *opt, } /* - * pp_handle_indent() prints out the intendation, and + * pp_handle_indent() prints out the indentation, and * the whole line (without the final newline), after * de-tabifying. */ @@ -1,3 +1,5 @@ +#define USE_THE_REPOSITORY_VARIABLE + #include "git-compat-util.h" #include "parse.h" #include "environment.h" diff --git a/prune-packed.c b/prune-packed.c index e54daf740a..2bb99c29df 100644 --- a/prune-packed.c +++ b/prune-packed.c @@ -1,10 +1,12 @@ +#define USE_THE_REPOSITORY_VARIABLE + #include "git-compat-util.h" -#include "environment.h" #include "gettext.h" #include "object-store-ll.h" #include "packfile.h" #include "progress.h" #include "prune-packed.h" +#include "repository.h" static struct progress *progress; @@ -37,7 +39,7 @@ void prune_packed_objects(int opts) if (opts & PRUNE_PACKED_VERBOSE) progress = start_delayed_progress(_("Removing duplicate objects"), 256); - for_each_loose_file_in_objdir(get_object_directory(), + for_each_loose_file_in_objdir(repo_get_object_directory(the_repository), prune_object, NULL, prune_subdir, &opts); /* Ensure we show 100% before finishing progress */ diff --git a/read-cache-ll.h b/read-cache-ll.h index e0e39607ef..b5d11d07a8 100644 --- a/read-cache-ll.h +++ b/read-cache-ll.h @@ -151,7 +151,7 @@ enum sparse_index_mode { /* * The index has already been collapsed to sparse directories - * whereever possible. + * wherever possible. */ INDEX_COLLAPSED, diff --git a/read-cache.c b/read-cache.c index 4e67dc182e..764fdfec46 100644 --- a/read-cache.c +++ b/read-cache.c @@ -31,6 +31,7 @@ #include "path.h" #include "preload-index.h" #include "read-cache.h" +#include "repository.h" #include "resolve-undo.h" #include "revision.h" #include "strbuf.h" @@ -3238,10 +3239,11 @@ static int should_delete_shared_index(const char *shared_index_path) static int clean_shared_index_files(const char *current_hex) { struct dirent *de; - DIR *dir = opendir(get_git_dir()); + DIR *dir = opendir(repo_get_git_dir(the_repository)); if (!dir) - return error_errno(_("unable to open git dir: %s"), get_git_dir()); + return error_errno(_("unable to open git dir: %s"), + repo_get_git_dir(the_repository)); while ((de = readdir(dir)) != NULL) { const char *sha1_hex; @@ -11,7 +11,7 @@ * The callers that care if (any) rebase is requested should say * if (REBASE_TRUE <= rebase_parse_value(string)) * - * The callers that want to differenciate an unrecognised value and + * The callers that want to differentiate an unrecognised value and * false can do so by treating _INVALID and _FALSE differently. */ enum rebase_type rebase_parse_value(const char *value) diff --git a/ref-filter.c b/ref-filter.c index b06e18a569..dd195007ce 100644 --- a/ref-filter.c +++ b/ref-filter.c @@ -13,6 +13,7 @@ #include "object-name.h" #include "object-store-ll.h" #include "oid-array.h" +#include "repo-settings.h" #include "repository.h" #include "commit.h" #include "mailmap.h" @@ -2180,7 +2181,7 @@ static const char *show_ref(struct refname_atom *atom, const char *refname) if (atom->option == R_SHORT) return refs_shorten_unambiguous_ref(get_main_ref_store(the_repository), refname, - warn_ambiguous_refs); + repo_settings_get_warn_ambiguous_refs(the_repository)); else if (atom->option == R_LSTRIP) return lstrip_ref_components(refname, atom->lstrip); else if (atom->option == R_RSTRIP) @@ -2384,7 +2385,7 @@ static int populate_value(struct ref_array_item *ref, struct strbuf *err) CALLOC_ARRAY(ref->value, used_atom_cnt); /** - * NEEDSWORK: The following code might be unncessary if all codepaths + * NEEDSWORK: The following code might be unnecessary if all codepaths * that call populate_value() populates the symref member of ref_array_item * like in apply_ref_filter(). Currently pretty_print_ref() is the only codepath * that calls populate_value() without first populating symref. @@ -24,7 +24,7 @@ #include "submodule.h" #include "worktree.h" #include "strvec.h" -#include "repository.h" +#include "repo-settings.h" #include "setup.h" #include "sigchain.h" #include "date.h" @@ -730,7 +730,7 @@ int expand_ref(struct repository *repo, const char *str, int len, if (r) { if (!refs_found++) *ref = xstrdup(r); - if (!warn_ambiguous_refs) + if (!repo_settings_get_warn_ambiguous_refs(repo)) break; } else if ((flag & REF_ISSYMREF) && strcmp(fullref.buf, "HEAD")) { warning(_("ignoring dangling symref %s"), fullref.buf); @@ -775,7 +775,7 @@ int repo_dwim_log(struct repository *r, const char *str, int len, if (oid) oidcpy(oid, &hash); } - if (!warn_ambiguous_refs) + if (!repo_settings_get_warn_ambiguous_refs(r)) break; } strbuf_release(&path); @@ -958,7 +958,8 @@ static char *normalize_reflog_message(const char *msg) return strbuf_detach(&sb, NULL); } -int should_autocreate_reflog(const char *refname) +int should_autocreate_reflog(enum log_refs_config log_all_ref_updates, + const char *refname) { switch (log_all_ref_updates) { case LOG_REFS_ALWAYS: @@ -1517,6 +1518,19 @@ const char **hidden_refs_to_excludes(const struct strvec *hide_refs) return hide_refs->v; } +const char **get_namespaced_exclude_patterns(const char **exclude_patterns, + const char *namespace, + struct strvec *out) +{ + if (!namespace || !*namespace || !exclude_patterns || !*exclude_patterns) + return exclude_patterns; + + for (size_t i = 0; exclude_patterns[i]; i++) + strvec_pushf(out, "%s%s", namespace, exclude_patterns[i]); + + return out->v; +} + const char *find_descendant_ref(const char *dirname, const struct string_list *extras, const struct string_list *skip) @@ -1634,11 +1648,19 @@ int refs_for_each_namespaced_ref(struct ref_store *refs, const char **exclude_patterns, each_ref_fn fn, void *cb_data) { - struct strbuf buf = STRBUF_INIT; + struct strvec namespaced_exclude_patterns = STRVEC_INIT; + struct strbuf prefix = STRBUF_INIT; int ret; - strbuf_addf(&buf, "%srefs/", get_git_namespace()); - ret = do_for_each_ref(refs, buf.buf, exclude_patterns, fn, 0, 0, cb_data); - strbuf_release(&buf); + + exclude_patterns = get_namespaced_exclude_patterns(exclude_patterns, + get_git_namespace(), + &namespaced_exclude_patterns); + + strbuf_addf(&prefix, "%srefs/", get_git_namespace()); + ret = do_for_each_ref(refs, prefix.buf, exclude_patterns, fn, 0, 0, cb_data); + + strvec_clear(&namespaced_exclude_patterns); + strbuf_release(&prefix); return ret; } @@ -1719,6 +1741,7 @@ int refs_for_each_fullref_in_prefixes(struct ref_store *ref_store, const char **exclude_patterns, each_ref_fn fn, void *cb_data) { + struct strvec namespaced_exclude_patterns = STRVEC_INIT; struct string_list prefixes = STRING_LIST_INIT_DUP; struct string_list_item *prefix; struct strbuf buf = STRBUF_INIT; @@ -1730,6 +1753,10 @@ int refs_for_each_fullref_in_prefixes(struct ref_store *ref_store, strbuf_addstr(&buf, namespace); namespace_len = buf.len; + exclude_patterns = get_namespaced_exclude_patterns(exclude_patterns, + namespace, + &namespaced_exclude_patterns); + for_each_string_list_item(prefix, &prefixes) { strbuf_addstr(&buf, prefix->string); ret = refs_for_each_fullref_in(ref_store, buf.buf, @@ -1739,6 +1766,7 @@ int refs_for_each_fullref_in_prefixes(struct ref_store *ref_store, strbuf_setlen(&buf, namespace_len); } + strvec_clear(&namespaced_exclude_patterns); string_list_clear(&prefixes, 0); strbuf_release(&buf); return ret; @@ -3,6 +3,7 @@ #include "commit.h" #include "repository.h" +#include "repo-settings.h" struct fsck_options; struct object_id; @@ -16,7 +17,7 @@ enum ref_storage_format ref_storage_format_by_name(const char *name); const char *ref_storage_format_to_name(enum ref_storage_format ref_storage_format); /* - * Resolve a reference, recursively following symbolic refererences. + * Resolve a reference, recursively following symbolic references. * * Return the name of the non-symbolic reference that ultimately pointed * at the resolved object name. The return value, if not NULL, is a @@ -111,7 +112,8 @@ int refs_verify_refname_available(struct ref_store *refs, int refs_ref_exists(struct ref_store *refs, const char *refname); -int should_autocreate_reflog(const char *refname); +int should_autocreate_reflog(enum log_refs_config log_all_ref_updates, + const char *refname); int is_branch(const char *refname); @@ -488,7 +490,7 @@ int refs_delete_reflog(struct ref_store *refs, const char *refname); * from UTC. Its absolute value is formed by multiplying the hour * part by 100 and adding the minute part. For example, 1 hour ahead * of UTC, CET == "+0100", is represented as positive one hundred (not - * postiive sixty). + * positive sixty). * * The msg parameter is a single complete line; a reflog message given * to refs_delete_ref, refs_update_ref, etc. is returned to the @@ -859,6 +861,15 @@ int ref_is_hidden(const char *, const char *, const struct strvec *); */ const char **hidden_refs_to_excludes(const struct strvec *hide_refs); +/* + * Prefix all exclude patterns with the namespace, if any. This is required + * because exclude patterns apply to the stripped reference name, not the full + * reference name with the namespace. + */ +const char **get_namespaced_exclude_patterns(const char **exclude_patterns, + const char *namespace, + struct strvec *out); + /* Is this a per-worktree ref living in the refs/ namespace? */ int is_per_worktree_ref(const char *refname); @@ -986,7 +997,7 @@ struct ref_store *get_worktree_ref_store(const struct worktree *wt); /* * Some of the names specified by refs have special meaning to Git. - * Organize these namespaces in a comon 'ref_namespace' array for + * Organize these namespaces in a common 'ref_namespace' array for * reference from multiple places in the codebase. */ diff --git a/refs/files-backend.c b/refs/files-backend.c index c7f3f4e591..0824c0b8a9 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -1,4 +1,7 @@ +#define USE_THE_REPOSITORY_VARIABLE + #include "../git-compat-util.h" +#include "../config.h" #include "../copy.h" #include "../environment.h" #include "../gettext.h" @@ -6,6 +9,7 @@ #include "../hex.h" #include "../fsck.h" #include "../refs.h" +#include "../repo-settings.h" #include "refs-internal.h" #include "ref-cache.h" #include "packed-backend.h" @@ -72,6 +76,8 @@ struct files_ref_store { unsigned int store_flags; char *gitcommondir; + enum log_refs_config log_all_ref_updates; + int prefer_symlink_refs; struct ref_cache *loose; @@ -104,6 +110,8 @@ static struct ref_store *files_ref_store_init(struct repository *repo, refs->gitcommondir = strbuf_detach(&sb, NULL); refs->packed_ref_store = packed_ref_store_init(repo, refs->gitcommondir, flags); + refs->log_all_ref_updates = repo_settings_get_log_all_ref_updates(repo); + repo_config_get_bool(repo, "core.prefersymlinkrefs", &refs->prefer_symlink_refs); chdir_notify_reparent("files-backend $GIT_DIR", &refs->base.gitdir); chdir_notify_reparent("files-backend $GIT_COMMONDIR", @@ -1506,6 +1514,7 @@ static int write_ref_to_lockfile(struct files_ref_store *refs, static int commit_ref_update(struct files_ref_store *refs, struct ref_lock *lock, const struct object_id *oid, const char *logmsg, + int flags, struct strbuf *err); /* @@ -1649,7 +1658,7 @@ static int files_copy_or_rename_ref(struct ref_store *ref_store, oidcpy(&lock->old_oid, &orig_oid); if (write_ref_to_lockfile(refs, lock, &orig_oid, 0, &err) || - commit_ref_update(refs, lock, &orig_oid, logmsg, &err)) { + commit_ref_update(refs, lock, &orig_oid, logmsg, 0, &err)) { error("unable to write current sha1 into %s: %s", newrefname, err.buf); strbuf_release(&err); goto rollback; @@ -1666,14 +1675,11 @@ static int files_copy_or_rename_ref(struct ref_store *ref_store, goto rollbacklog; } - flag = log_all_ref_updates; - log_all_ref_updates = LOG_REFS_NONE; if (write_ref_to_lockfile(refs, lock, &orig_oid, 0, &err) || - commit_ref_update(refs, lock, &orig_oid, NULL, &err)) { + commit_ref_update(refs, lock, &orig_oid, NULL, REF_SKIP_CREATE_REFLOG, &err)) { error("unable to write current sha1 into %s: %s", oldrefname, err.buf); strbuf_release(&err); } - log_all_ref_updates = flag; rollbacklog: if (logmoved && rename(sb_newref.buf, sb_oldref.buf)) @@ -1768,13 +1774,17 @@ static int log_ref_setup(struct files_ref_store *refs, const char *refname, int force_create, int *logfd, struct strbuf *err) { + enum log_refs_config log_refs_cfg = refs->log_all_ref_updates; struct strbuf logfile_sb = STRBUF_INIT; char *logfile; + if (log_refs_cfg == LOG_REFS_UNSET) + log_refs_cfg = is_bare_repository() ? LOG_REFS_NONE : LOG_REFS_NORMAL; + files_reflog_path(refs, &logfile_sb, refname); logfile = strbuf_detach(&logfile_sb, NULL); - if (force_create || should_autocreate_reflog(refname)) { + if (force_create || should_autocreate_reflog(log_refs_cfg, refname)) { if (raceproof_create_file(logfile, open_or_create_logfile, logfd)) { if (errno == ENOENT) strbuf_addf(err, "unable to create directory for '%s': " @@ -1863,9 +1873,6 @@ static int files_log_ref_write(struct files_ref_store *refs, if (flags & REF_SKIP_CREATE_REFLOG) return 0; - if (log_all_ref_updates == LOG_REFS_UNSET) - log_all_ref_updates = is_bare_repository() ? LOG_REFS_NONE : LOG_REFS_NORMAL; - result = log_ref_setup(refs, refname, flags & REF_FORCE_CREATE_REFLOG, &logfd, err); @@ -1954,6 +1961,7 @@ static int write_ref_to_lockfile(struct files_ref_store *refs, static int commit_ref_update(struct files_ref_store *refs, struct ref_lock *lock, const struct object_id *oid, const char *logmsg, + int flags, struct strbuf *err) { files_assert_main_repository(refs, "commit_ref_update"); @@ -1961,7 +1969,7 @@ static int commit_ref_update(struct files_ref_store *refs, clear_loose_ref_cache(refs); if (files_log_ref_write(refs, lock->ref_name, &lock->old_oid, oid, - logmsg, 0, err)) { + logmsg, flags, err)) { char *old_msg = strbuf_detach(err, NULL); strbuf_addf(err, "cannot update the ref '%s': %s", lock->ref_name, old_msg); @@ -1994,7 +2002,7 @@ static int commit_ref_update(struct files_ref_store *refs, struct strbuf log_err = STRBUF_INIT; if (files_log_ref_write(refs, "HEAD", &lock->old_oid, oid, - logmsg, 0, &log_err)) { + logmsg, flags, &log_err)) { error("%s", log_err.buf); strbuf_release(&log_err); } @@ -3005,7 +3013,7 @@ static int files_transaction_finish(struct ref_store *ref_store, * We try creating a symlink, if that succeeds we continue to the * next update. If not, we try and create a regular symref. */ - if (update->new_target && prefer_symlink_refs) + if (update->new_target && refs->prefer_symlink_refs) if (!create_ref_symlink(lock, update->new_target)) continue; diff --git a/refs/reftable-backend.c b/refs/reftable-backend.c index efe2b0258c..3c96fbf66f 100644 --- a/refs/reftable-backend.c +++ b/refs/reftable-backend.c @@ -19,8 +19,10 @@ #include "../reftable/reftable-record.h" #include "../reftable/reftable-error.h" #include "../reftable/reftable-iterator.h" +#include "../repo-settings.h" #include "../setup.h" #include "../strmap.h" +#include "../trace2.h" #include "parse.h" #include "refs-internal.h" @@ -51,6 +53,7 @@ struct reftable_ref_store { struct reftable_write_options write_options; unsigned int store_flags; + enum log_refs_config log_all_ref_updates; int err; }; @@ -156,22 +159,23 @@ static struct reftable_stack *stack_for(struct reftable_ref_store *store, } } -static int should_write_log(struct ref_store *refs, const char *refname) +static int should_write_log(struct reftable_ref_store *refs, const char *refname) { - if (log_all_ref_updates == LOG_REFS_UNSET) - log_all_ref_updates = is_bare_repository() ? LOG_REFS_NONE : LOG_REFS_NORMAL; + enum log_refs_config log_refs_cfg = refs->log_all_ref_updates; + if (log_refs_cfg == LOG_REFS_UNSET) + log_refs_cfg = is_bare_repository() ? LOG_REFS_NONE : LOG_REFS_NORMAL; - switch (log_all_ref_updates) { + switch (log_refs_cfg) { case LOG_REFS_NONE: - return refs_reflog_exists(refs, refname); + return refs_reflog_exists(&refs->base, refname); case LOG_REFS_ALWAYS: return 1; case LOG_REFS_NORMAL: - if (should_autocreate_reflog(refname)) + if (should_autocreate_reflog(log_refs_cfg, refname)) return 1; - return refs_reflog_exists(refs, refname); + return refs_reflog_exists(&refs->base, refname); default: - BUG("unhandled core.logAllRefUpdates value %d", log_all_ref_updates); + BUG("unhandled core.logAllRefUpdates value %d", log_refs_cfg); } } @@ -283,6 +287,7 @@ static struct ref_store *reftable_be_init(struct repository *repo, base_ref_store_init(&refs->base, repo, gitdir, &refs_be_reftable); strmap_init(&refs->worktree_stacks); refs->store_flags = store_flags; + refs->log_all_ref_updates = repo_settings_get_log_all_ref_updates(repo); refs->write_options.hash_id = repo->hash_algo->format_id; refs->write_options.default_permissions = calc_shared_perm(0666 & ~mask); @@ -455,10 +460,81 @@ struct reftable_ref_iterator { const char *prefix; size_t prefix_len; + char **exclude_patterns; + size_t exclude_patterns_index; + size_t exclude_patterns_strlen; unsigned int flags; int err; }; +/* + * Handle exclude patterns. Returns either `1`, which tells the caller that the + * current reference shall not be shown. Or `0`, which indicates that it should + * be shown. + */ +static int should_exclude_current_ref(struct reftable_ref_iterator *iter) +{ + while (iter->exclude_patterns[iter->exclude_patterns_index]) { + const char *pattern = iter->exclude_patterns[iter->exclude_patterns_index]; + char *ref_after_pattern; + int cmp; + + /* + * Lazily cache the pattern length so that we don't have to + * recompute it every time this function is called. + */ + if (!iter->exclude_patterns_strlen) + iter->exclude_patterns_strlen = strlen(pattern); + + /* + * When the reference name is lexicographically bigger than the + * current exclude pattern we know that it won't ever match any + * of the following references, either. We thus advance to the + * next pattern and re-check whether it matches. + * + * Otherwise, if it's smaller, then we do not have a match and + * thus want to show the current reference. + */ + cmp = strncmp(iter->ref.refname, pattern, + iter->exclude_patterns_strlen); + if (cmp > 0) { + iter->exclude_patterns_index++; + iter->exclude_patterns_strlen = 0; + continue; + } + if (cmp < 0) + return 0; + + /* + * The reference shares a prefix with the exclude pattern and + * shall thus be omitted. We skip all references that match the + * pattern by seeking to the first reference after the block of + * matches. + * + * This is done by appending the highest possible character to + * the pattern. Consequently, all references that have the + * pattern as prefix and whose suffix starts with anything in + * the range [0x00, 0xfe] are skipped. And given that 0xff is a + * non-printable character that shouldn't ever be in a ref name, + * we'd not yield any such record, either. + * + * Note that the seeked-to reference may also be excluded. This + * is not handled here though, but the caller is expected to + * loop and re-verify the next reference for us. + */ + ref_after_pattern = xstrfmt("%s%c", pattern, 0xff); + iter->err = reftable_iterator_seek_ref(&iter->iter, ref_after_pattern); + iter->exclude_patterns_index++; + iter->exclude_patterns_strlen = 0; + trace2_counter_add(TRACE2_COUNTER_ID_REFTABLE_RESEEKS, 1); + + free(ref_after_pattern); + return 1; + } + + return 0; +} + static int reftable_ref_iterator_advance(struct ref_iterator *ref_iterator) { struct reftable_ref_iterator *iter = @@ -489,6 +565,9 @@ static int reftable_ref_iterator_advance(struct ref_iterator *ref_iterator) break; } + if (iter->exclude_patterns && should_exclude_current_ref(iter)) + continue; + if (iter->flags & DO_FOR_EACH_PER_WORKTREE_ONLY && parse_worktree_ref(iter->ref.refname, NULL, NULL, NULL) != REF_WORKTREE_CURRENT) @@ -578,6 +657,11 @@ static int reftable_ref_iterator_abort(struct ref_iterator *ref_iterator) (struct reftable_ref_iterator *)ref_iterator; reftable_ref_record_release(&iter->ref); reftable_iterator_destroy(&iter->iter); + if (iter->exclude_patterns) { + for (size_t i = 0; iter->exclude_patterns[i]; i++) + free(iter->exclude_patterns[i]); + free(iter->exclude_patterns); + } free(iter); return ITER_DONE; } @@ -588,9 +672,53 @@ static struct ref_iterator_vtable reftable_ref_iterator_vtable = { .abort = reftable_ref_iterator_abort }; +static int qsort_strcmp(const void *va, const void *vb) +{ + const char *a = *(const char **)va; + const char *b = *(const char **)vb; + return strcmp(a, b); +} + +static char **filter_exclude_patterns(const char **exclude_patterns) +{ + size_t filtered_size = 0, filtered_alloc = 0; + char **filtered = NULL; + + if (!exclude_patterns) + return NULL; + + for (size_t i = 0; ; i++) { + const char *exclude_pattern = exclude_patterns[i]; + int has_glob = 0; + + if (!exclude_pattern) + break; + + for (const char *p = exclude_pattern; *p; p++) { + has_glob = is_glob_special(*p); + if (has_glob) + break; + } + if (has_glob) + continue; + + ALLOC_GROW(filtered, filtered_size + 1, filtered_alloc); + filtered[filtered_size++] = xstrdup(exclude_pattern); + } + + if (filtered_size) { + QSORT(filtered, filtered_size, qsort_strcmp); + ALLOC_GROW(filtered, filtered_size + 1, filtered_alloc); + filtered[filtered_size++] = NULL; + } + + return filtered; +} + static struct reftable_ref_iterator *ref_iterator_for_stack(struct reftable_ref_store *refs, struct reftable_stack *stack, const char *prefix, + const char **exclude_patterns, int flags) { struct reftable_ref_iterator *iter; @@ -603,6 +731,7 @@ static struct reftable_ref_iterator *ref_iterator_for_stack(struct reftable_ref_ iter->base.oid = &iter->oid; iter->flags = flags; iter->refs = refs; + iter->exclude_patterns = filter_exclude_patterns(exclude_patterns); ret = refs->err; if (ret) @@ -624,7 +753,7 @@ done: static struct ref_iterator *reftable_be_iterator_begin(struct ref_store *ref_store, const char *prefix, - const char **exclude_patterns UNUSED, + const char **exclude_patterns, unsigned int flags) { struct reftable_ref_iterator *main_iter, *worktree_iter; @@ -635,7 +764,8 @@ static struct ref_iterator *reftable_be_iterator_begin(struct ref_store *ref_sto required_flags |= REF_STORE_ODB; refs = reftable_be_downcast(ref_store, required_flags, "ref_iterator_begin"); - main_iter = ref_iterator_for_stack(refs, refs->main_stack, prefix, flags); + main_iter = ref_iterator_for_stack(refs, refs->main_stack, prefix, + exclude_patterns, flags); /* * The worktree stack is only set when we're in an actual worktree @@ -649,7 +779,8 @@ static struct ref_iterator *reftable_be_iterator_begin(struct ref_store *ref_sto * Otherwise we merge both the common and the per-worktree refs into a * single iterator. */ - worktree_iter = ref_iterator_for_stack(refs, refs->worktree_stack, prefix, flags); + worktree_iter = ref_iterator_for_stack(refs, refs->worktree_stack, prefix, + exclude_patterns, flags); return merge_ref_iterator_begin(&worktree_iter->base, &main_iter->base, ref_iterator_select, NULL); } @@ -1227,7 +1358,7 @@ static int write_transaction_table(struct reftable_writer *writer, void *cb_data } else if (!(u->flags & REF_SKIP_CREATE_REFLOG) && (u->flags & REF_HAVE_NEW) && (u->flags & REF_FORCE_CREATE_REFLOG || - should_write_log(&arg->refs->base, u->refname))) { + should_write_log(arg->refs, u->refname))) { struct reftable_log_record *log; int create_reflog = 1; diff --git a/reftable/reader.c b/reftable/reader.c index f877099087..6494ce2e32 100644 --- a/reftable/reader.c +++ b/reftable/reader.c @@ -328,6 +328,7 @@ static int table_iter_seek_to(struct table_iter *ti, uint64_t off, uint8_t typ) ti->typ = block_reader_type(&ti->br); ti->block_off = off; block_iter_seek_start(&ti->bi, &ti->br); + ti->is_finished = 0; return 0; } @@ -1123,6 +1123,7 @@ void free_one_ref(struct ref *ref) return; free_one_ref(ref->peer_ref); free(ref->remote_status); + free(ref->tracking_ref); free(ref->symref); free(ref); } @@ -2620,8 +2621,10 @@ static int remote_tracking(struct remote *remote, const char *refname, dst = apply_refspecs(&remote->fetch, refname); if (!dst) return -1; /* no tracking ref for refname at remote */ - if (refs_read_ref(get_main_ref_store(the_repository), dst, oid)) + if (refs_read_ref(get_main_ref_store(the_repository), dst, oid)) { + free(dst); return -1; /* we know what the tracking ref is but we cannot read it */ + } *dst_refname = dst; return 0; @@ -2771,6 +2774,7 @@ static void check_if_includes_upstream(struct ref *remote) if (is_reachable_in_reflog(local->name, remote) <= 0) remote->unreachable = 1; + free_one_ref(local); } static void apply_cas(struct push_cas_option *cas, diff --git a/repo-settings.c b/repo-settings.c index 2b4e68731b..4699b4b365 100644 --- a/repo-settings.c +++ b/repo-settings.c @@ -1,5 +1,6 @@ #include "git-compat-util.h" #include "config.h" +#include "repo-settings.h" #include "repository.h" #include "midx.h" @@ -19,6 +20,7 @@ static void repo_cfg_int(struct repository *r, const char *key, int *dest, void prepare_repo_settings(struct repository *r) { + const struct repo_settings defaults = REPO_SETTINGS_INIT; int experimental; int value; const char *strval; @@ -28,13 +30,11 @@ void prepare_repo_settings(struct repository *r) if (!r->gitdir) BUG("Cannot add settings for uninitialized repository"); - if (r->settings.initialized++) + if (r->settings.initialized) return; - /* Defaults */ - r->settings.index_version = -1; - r->settings.core_untracked_cache = UNTRACKED_CACHE_KEEP; - r->settings.fetch_negotiation_algorithm = FETCH_NEGOTIATION_CONSECUTIVE; + memcpy(&r->settings, &defaults, sizeof(defaults)); + r->settings.initialized++; /* Booleans config or default, cascades to other settings */ repo_cfg_bool(r, "feature.manyfiles", &manyfiles, 0); @@ -124,3 +124,28 @@ void prepare_repo_settings(struct repository *r) */ r->settings.command_requires_full_index = 1; } + +enum log_refs_config repo_settings_get_log_all_ref_updates(struct repository *repo) +{ + const char *value; + + if (!repo_config_get_string_tmp(repo, "core.logallrefupdates", &value)) { + if (value && !strcasecmp(value, "always")) + return LOG_REFS_ALWAYS; + else if (git_config_bool("core.logallrefupdates", value)) + return LOG_REFS_NORMAL; + else + return LOG_REFS_NONE; + } + + return LOG_REFS_UNSET; +} + +int repo_settings_get_warn_ambiguous_refs(struct repository *repo) +{ + prepare_repo_settings(repo); + if (repo->settings.warn_ambiguous_refs < 0) + repo_cfg_bool(repo, "core.warnambiguousrefs", + &repo->settings.warn_ambiguous_refs, 1); + return repo->settings.warn_ambiguous_refs; +} diff --git a/repo-settings.h b/repo-settings.h new file mode 100644 index 0000000000..51d6156a11 --- /dev/null +++ b/repo-settings.h @@ -0,0 +1,75 @@ +#ifndef REPO_SETTINGS_H +#define REPO_SETTINGS_H + +struct fsmonitor_settings; +struct repository; + +enum untracked_cache_setting { + UNTRACKED_CACHE_KEEP, + UNTRACKED_CACHE_REMOVE, + UNTRACKED_CACHE_WRITE, +}; + +enum fetch_negotiation_setting { + FETCH_NEGOTIATION_CONSECUTIVE, + FETCH_NEGOTIATION_SKIPPING, + FETCH_NEGOTIATION_NOOP, +}; + +enum log_refs_config { + LOG_REFS_UNSET = -1, + LOG_REFS_NONE = 0, + LOG_REFS_NORMAL, + LOG_REFS_ALWAYS +}; + +struct repo_settings { + int initialized; + + int core_commit_graph; + int commit_graph_generation_version; + int commit_graph_changed_paths_version; + int gc_write_commit_graph; + int fetch_write_commit_graph; + int command_requires_full_index; + int sparse_index; + int pack_read_reverse_index; + int pack_use_bitmap_boundary_traversal; + int pack_use_multi_pack_reuse; + + /* + * Does this repository have core.useReplaceRefs=true (on by + * default)? This provides a repository-scoped version of this + * config, though it could be disabled process-wide via some Git + * builtins or the --no-replace-objects option. See + * replace_refs_enabled() for more details. + */ + int read_replace_refs; + + struct fsmonitor_settings *fsmonitor; /* lazily loaded */ + + int index_version; + int index_skip_hash; + enum untracked_cache_setting core_untracked_cache; + + int pack_use_sparse; + enum fetch_negotiation_setting fetch_negotiation_algorithm; + + int core_multi_pack_index; + int warn_ambiguous_refs; /* lazily loaded via accessor */ +}; +#define REPO_SETTINGS_INIT { \ + .index_version = -1, \ + .core_untracked_cache = UNTRACKED_CACHE_KEEP, \ + .fetch_negotiation_algorithm = FETCH_NEGOTIATION_CONSECUTIVE, \ + .warn_ambiguous_refs = -1, \ +} + +void prepare_repo_settings(struct repository *r); + +/* Read the value for "core.logAllRefUpdates". */ +enum log_refs_config repo_settings_get_log_all_ref_updates(struct repository *repo); +/* Read the value for "core.warnAmbiguousRefs". */ +int repo_settings_get_warn_ambiguous_refs(struct repository *repo); + +#endif /* REPO_SETTINGS_H */ diff --git a/repository.c b/repository.c index 9825a30899..f988b8ae68 100644 --- a/repository.c +++ b/repository.c @@ -54,7 +54,7 @@ void initialize_repository(struct repository *repo) { repo->objects = raw_object_store_new(); repo->remote_state = remote_state_new(); - repo->parsed_objects = parsed_object_pool_new(); + repo->parsed_objects = parsed_object_pool_new(repo); ALLOC_ARRAY(repo->index, 1); index_state_init(repo->index, repo); @@ -91,6 +91,46 @@ static void expand_base_dir(char **out, const char *in, *out = xstrfmt("%s/%s", base_dir, def_in); } +const char *repo_get_git_dir(struct repository *repo) +{ + if (!repo->gitdir) + BUG("repository hasn't been set up"); + return repo->gitdir; +} + +const char *repo_get_common_dir(struct repository *repo) +{ + if (!repo->commondir) + BUG("repository hasn't been set up"); + return repo->commondir; +} + +const char *repo_get_object_directory(struct repository *repo) +{ + if (!repo->objects->odb) + BUG("repository hasn't been set up"); + return repo->objects->odb->path; +} + +const char *repo_get_index_file(struct repository *repo) +{ + if (!repo->index_file) + BUG("repository hasn't been set up"); + return repo->index_file; +} + +const char *repo_get_graft_file(struct repository *repo) +{ + if (!repo->graft_file) + BUG("repository hasn't been set up"); + return repo->graft_file; +} + +const char *repo_get_work_tree(struct repository *repo) +{ + return repo->worktree; +} + static void repo_set_commondir(struct repository *repo, const char *commondir) { diff --git a/repository.h b/repository.h index af6ea0a62c..24a66a496a 100644 --- a/repository.h +++ b/repository.h @@ -2,9 +2,9 @@ #define REPOSITORY_H #include "strmap.h" +#include "repo-settings.h" struct config_set; -struct fsmonitor_settings; struct git_hash_algo; struct index_state; struct lock_file; @@ -14,59 +14,12 @@ struct submodule_cache; struct promisor_remote_config; struct remote_state; -enum untracked_cache_setting { - UNTRACKED_CACHE_KEEP, - UNTRACKED_CACHE_REMOVE, - UNTRACKED_CACHE_WRITE, -}; - -enum fetch_negotiation_setting { - FETCH_NEGOTIATION_CONSECUTIVE, - FETCH_NEGOTIATION_SKIPPING, - FETCH_NEGOTIATION_NOOP, -}; - enum ref_storage_format { REF_STORAGE_FORMAT_UNKNOWN, REF_STORAGE_FORMAT_FILES, REF_STORAGE_FORMAT_REFTABLE, }; -struct repo_settings { - int initialized; - - int core_commit_graph; - int commit_graph_generation_version; - int commit_graph_changed_paths_version; - int gc_write_commit_graph; - int fetch_write_commit_graph; - int command_requires_full_index; - int sparse_index; - int pack_read_reverse_index; - int pack_use_bitmap_boundary_traversal; - int pack_use_multi_pack_reuse; - - /* - * Does this repository have core.useReplaceRefs=true (on by - * default)? This provides a repository-scoped version of this - * config, though it could be disabled process-wide via some Git - * builtins or the --no-replace-objects option. See - * replace_refs_enabled() for more details. - */ - int read_replace_refs; - - struct fsmonitor_settings *fsmonitor; /* lazily loaded */ - - int index_version; - int index_skip_hash; - enum untracked_cache_setting core_untracked_cache; - - int pack_use_sparse; - enum fetch_negotiation_setting fetch_negotiation_algorithm; - - int core_multi_pack_index; -}; - struct repo_path_cache { char *squash_msg; char *merge_msg; @@ -206,6 +159,13 @@ struct repository { extern struct repository *the_repository; #endif +const char *repo_get_git_dir(struct repository *repo); +const char *repo_get_common_dir(struct repository *repo); +const char *repo_get_object_directory(struct repository *repo); +const char *repo_get_index_file(struct repository *repo); +const char *repo_get_graft_file(struct repository *repo); +const char *repo_get_work_tree(struct repository *repo); + /* * Define a custom repository layout. Any field can be NULL, which * will default back to the path according to the default layout. @@ -266,8 +226,6 @@ int repo_read_index_unmerged(struct repository *); */ void repo_update_index_if_able(struct repository *, struct lock_file *); -void prepare_repo_settings(struct repository *r); - /* * Return 1 if upgrade repository format to target_version succeeded, * 0 if no upgrade is necessary, and -1 when upgrade is not possible. diff --git a/revision.h b/revision.h index 0e470d1df1..71e984c452 100644 --- a/revision.h +++ b/revision.h @@ -549,7 +549,7 @@ int rewrite_parents(struct rev_info *revs, * The log machinery saves the original parent list so that * get_saved_parents() can later tell what the real parents of the * commits are, when commit->parents has been modified by history - * simpification. + * simplification. * * get_saved_parents() will transparently return commit->parents if * history simplification is off. diff --git a/run-command.h b/run-command.h index 03e7222d8b..0df25e445f 100644 --- a/run-command.h +++ b/run-command.h @@ -535,7 +535,7 @@ enum start_bg_result { /* timeout expired waiting for child to become "ready" */ SBGR_TIMEOUT, - /* child process exited or was signalled before becomming "ready" */ + /* child process exited or was signalled before becoming "ready" */ SBGR_DIED, }; diff --git a/send-pack.c b/send-pack.c index 5d0c23772a..6677c44e8a 100644 --- a/send-pack.c +++ b/send-pack.c @@ -353,7 +353,8 @@ static int generate_push_cert(struct strbuf *req_buf, { const struct ref *ref; struct string_list_item *item; - char *signing_key_id = xstrdup(get_signing_key_id()); + char *signing_key_id = get_signing_key_id(); + char *signing_key = get_signing_key(); const char *cp, *np; struct strbuf cert = STRBUF_INIT; int update_seen = 0; @@ -386,7 +387,7 @@ static int generate_push_cert(struct strbuf *req_buf, if (!update_seen) goto free_return; - if (sign_buffer(&cert, &cert, get_signing_key())) + if (sign_buffer(&cert, &cert, signing_key)) die(_("failed to sign the push certificate")); packet_buf_write(req_buf, "push-cert%c%s", 0, cap_string); @@ -399,6 +400,7 @@ static int generate_push_cert(struct strbuf *req_buf, free_return: free(signing_key_id); + free(signing_key); strbuf_release(&cert); return update_seen; } @@ -506,14 +508,15 @@ int send_pack(struct send_pack_args *args, unsigned cmds_sent = 0; int ret; struct async demux; - const char *push_cert_nonce = NULL; + char *push_cert_nonce = NULL; struct packet_reader reader; int use_bitmaps; if (!remote_refs) { fprintf(stderr, "No refs in common and none specified; doing nothing.\n" "Perhaps you should specify a branch.\n"); - return 0; + ret = 0; + goto out; } git_config_get_bool("push.negotiate", &push_negotiate); @@ -557,10 +560,11 @@ int send_pack(struct send_pack_args *args, if (args->push_cert != SEND_PACK_PUSH_CERT_NEVER) { size_t len; - push_cert_nonce = server_feature_value("push-cert", &len); - if (push_cert_nonce) { - reject_invalid_nonce(push_cert_nonce, len); - push_cert_nonce = xmemdupz(push_cert_nonce, len); + const char *nonce = server_feature_value("push-cert", &len); + + if (nonce) { + reject_invalid_nonce(nonce, len); + push_cert_nonce = xmemdupz(nonce, len); } else if (args->push_cert == SEND_PACK_PUSH_CERT_ALWAYS) { die(_("the receiving end does not support --signed push")); } else if (args->push_cert == SEND_PACK_PUSH_CERT_IF_ASKED) { @@ -623,12 +627,11 @@ int send_pack(struct send_pack_args *args, * atomically, abort the whole operation. */ if (use_atomic) { - strbuf_release(&req_buf); - strbuf_release(&cap_buf); reject_atomic_push(remote_refs, args->send_mirror); error("atomic push failed for ref %s. status: %d", ref->name, ref->status); - return args->porcelain ? 0 : -1; + ret = args->porcelain ? 0 : -1; + goto out; } /* else fallthrough */ default: @@ -692,8 +695,6 @@ int send_pack(struct send_pack_args *args, write_or_die(out, req_buf.buf, req_buf.len); packet_flush(out); } - strbuf_release(&req_buf); - strbuf_release(&cap_buf); if (use_sideband && cmds_sent) { memset(&demux, 0, sizeof(demux)); @@ -731,7 +732,9 @@ int send_pack(struct send_pack_args *args, finish_async(&demux); } fd[1] = -1; - return -1; + + ret = -1; + goto out; } if (!args->stateless_rpc) /* Closed by pack_objects() via start_command() */ @@ -756,10 +759,12 @@ int send_pack(struct send_pack_args *args, } if (ret < 0) - return ret; + goto out; - if (args->porcelain) - return 0; + if (args->porcelain) { + ret = 0; + goto out; + } for (ref = remote_refs; ref; ref = ref->next) { switch (ref->status) { @@ -768,8 +773,17 @@ int send_pack(struct send_pack_args *args, case REF_STATUS_OK: break; default: - return -1; + ret = -1; + goto out; } } - return 0; + + ret = 0; + +out: + oid_array_clear(&commons); + strbuf_release(&req_buf); + strbuf_release(&cap_buf); + free(push_cert_nonce); + return ret; } diff --git a/server-info.c b/server-info.c index 1508fa6f82..c5af4cd98a 100644 --- a/server-info.c +++ b/server-info.c @@ -2,7 +2,6 @@ #include "git-compat-util.h" #include "dir.h" -#include "environment.h" #include "hex.h" #include "repository.h" #include "refs.h" @@ -342,7 +341,8 @@ static int write_pack_info_file(struct update_info_ctx *uic) static int update_info_packs(int force) { - char *infofile = mkpathdup("%s/info/packs", get_object_directory()); + char *infofile = mkpathdup("%s/info/packs", + repo_get_object_directory(the_repository)); int ret; init_pack_info(infofile, force); @@ -7,16 +7,22 @@ #include "exec-cmd.h" #include "gettext.h" #include "hex.h" +#include "object-file.h" #include "object-name.h" #include "refs.h" +#include "replace-object.h" #include "repository.h" #include "config.h" #include "dir.h" #include "setup.h" +#include "shallow.h" #include "string-list.h" +#include "strvec.h" #include "chdir-notify.h" #include "path.h" #include "quote.h" +#include "tmp-objdir.h" +#include "trace.h" #include "trace2.h" #include "worktree.h" #include "exec-cmd.h" @@ -51,7 +57,7 @@ static int abspath_part_inside_repo(char *path) size_t wtlen; char *path0; int off; - const char *work_tree = precompose_string_if_needed(get_git_work_tree()); + const char *work_tree = precompose_string_if_needed(repo_get_work_tree(the_repository)); struct strbuf realpath = STRBUF_INIT; if (!work_tree) @@ -147,9 +153,9 @@ char *prefix_path(const char *prefix, int len, const char *path) { char *r = prefix_path_gently(prefix, len, NULL, path); if (!r) { - const char *hint_path = get_git_work_tree(); + const char *hint_path = repo_get_work_tree(the_repository); if (!hint_path) - hint_path = get_git_dir(); + hint_path = repo_get_git_dir(the_repository); die(_("'%s' is outside repository at '%s'"), path, absolute_path(hint_path)); } @@ -468,14 +474,14 @@ int is_nonbare_repository_dir(struct strbuf *path) int is_inside_git_dir(void) { if (inside_git_dir < 0) - inside_git_dir = is_inside_dir(get_git_dir()); + inside_git_dir = is_inside_dir(repo_get_git_dir(the_repository)); return inside_git_dir; } int is_inside_work_tree(void) { if (inside_work_tree < 0) - inside_work_tree = is_inside_dir(get_git_work_tree()); + inside_work_tree = is_inside_dir(repo_get_work_tree(the_repository)); return inside_work_tree; } @@ -490,7 +496,7 @@ void setup_work_tree(void) if (work_tree_config_is_bogus) die(_("unable to set up work tree using invalid config")); - work_tree = get_git_work_tree(); + work_tree = repo_get_work_tree(the_repository); if (!work_tree || chdir_notify(work_tree)) die(_("this operation must be run in a work tree")); @@ -518,7 +524,7 @@ static void setup_original_cwd(void) * directory we inherited from our parent process, which is a * directory we want to avoid removing. * - * For convience, we would like to have the path relative to the + * For convenience, we would like to have the path relative to the * worktree instead of an absolute path. * * Yes, startup_info->original_cwd is usually the same as 'prefix', @@ -547,7 +553,7 @@ static void setup_original_cwd(void) * Get our worktree; we only protect the current working directory * if it's in the worktree. */ - worktree = get_git_work_tree(); + worktree = repo_get_work_tree(the_repository); if (!worktree) goto no_prevention_needed; @@ -1062,9 +1068,9 @@ static const char *setup_explicit_git_dir(const char *gitdirenv, set_git_work_tree("."); /* set_git_work_tree() must have been called by now */ - worktree = get_git_work_tree(); + worktree = repo_get_work_tree(the_repository); - /* both get_git_work_tree() and cwd are already normalized */ + /* both repo_get_work_tree() and cwd are already normalized */ if (!strcmp(cwd->buf, worktree)) { /* cwd == worktree */ set_git_dir(gitdirenv, 0); free(gitfile); @@ -1613,6 +1619,106 @@ enum discovery_result discover_git_directory_reason(struct strbuf *commondir, return result; } +void setup_git_env(const char *git_dir) +{ + char *git_replace_ref_base; + const char *shallow_file; + const char *replace_ref_base; + struct set_gitdir_args args = { NULL }; + struct strvec to_free = STRVEC_INIT; + + args.commondir = getenv_safe(&to_free, GIT_COMMON_DIR_ENVIRONMENT); + args.object_dir = getenv_safe(&to_free, DB_ENVIRONMENT); + args.graft_file = getenv_safe(&to_free, GRAFT_ENVIRONMENT); + args.index_file = getenv_safe(&to_free, INDEX_ENVIRONMENT); + args.alternate_db = getenv_safe(&to_free, ALTERNATE_DB_ENVIRONMENT); + if (getenv(GIT_QUARANTINE_ENVIRONMENT)) { + args.disable_ref_updates = 1; + } + + repo_set_gitdir(the_repository, git_dir, &args); + strvec_clear(&to_free); + + if (getenv(NO_REPLACE_OBJECTS_ENVIRONMENT)) + disable_replace_refs(); + replace_ref_base = getenv(GIT_REPLACE_REF_BASE_ENVIRONMENT); + git_replace_ref_base = xstrdup(replace_ref_base ? replace_ref_base + : "refs/replace/"); + update_ref_namespace(NAMESPACE_REPLACE, git_replace_ref_base); + + shallow_file = getenv(GIT_SHALLOW_FILE_ENVIRONMENT); + if (shallow_file) + set_alternate_shallow_file(the_repository, shallow_file, 0); + + if (git_env_bool(NO_LAZY_FETCH_ENVIRONMENT, 0)) + fetch_if_missing = 0; +} + +static void set_git_dir_1(const char *path) +{ + xsetenv(GIT_DIR_ENVIRONMENT, path, 1); + setup_git_env(path); +} + +static void update_relative_gitdir(const char *name UNUSED, + const char *old_cwd, + const char *new_cwd, + void *data UNUSED) +{ + char *path = reparent_relative_path(old_cwd, new_cwd, + repo_get_git_dir(the_repository)); + struct tmp_objdir *tmp_objdir = tmp_objdir_unapply_primary_odb(); + + trace_printf_key(&trace_setup_key, + "setup: move $GIT_DIR to '%s'", + path); + set_git_dir_1(path); + if (tmp_objdir) + tmp_objdir_reapply_primary_odb(tmp_objdir, old_cwd, new_cwd); + free(path); +} + +void set_git_dir(const char *path, int make_realpath) +{ + struct strbuf realpath = STRBUF_INIT; + + if (make_realpath) { + strbuf_realpath(&realpath, path, 1); + path = realpath.buf; + } + + set_git_dir_1(path); + if (!is_absolute_path(path)) + chdir_notify_register(NULL, update_relative_gitdir, NULL); + + strbuf_release(&realpath); +} + +static int git_work_tree_initialized; + +/* + * Note. This works only before you used a work tree. This was added + * primarily to support git-clone to work in a new repository it just + * created, and is not meant to flip between different work trees. + */ +void set_git_work_tree(const char *new_work_tree) +{ + if (git_work_tree_initialized) { + struct strbuf realpath = STRBUF_INIT; + + strbuf_realpath(&realpath, new_work_tree, 1); + new_work_tree = realpath.buf; + if (strcmp(new_work_tree, the_repository->worktree)) + die("internal error: work tree has already been set\n" + "Current worktree: %s\nNew worktree: %s", + the_repository->worktree, new_work_tree); + strbuf_release(&realpath); + return; + } + git_work_tree_initialized = 1; + repo_set_worktree(the_repository, new_work_tree); +} + const char *setup_git_directory_gently(int *nongit_ok) { static struct strbuf cwd = STRBUF_INIT; @@ -1836,7 +1942,7 @@ void check_repository_format(struct repository_format *fmt) struct repository_format repo_fmt = REPOSITORY_FORMAT_INIT; if (!fmt) fmt = &repo_fmt; - check_repository_format_gently(get_git_dir(), fmt, NULL); + check_repository_format_gently(repo_get_git_dir(the_repository), fmt, NULL); startup_info->have_repository = 1; repo_set_hash_algo(the_repository, fmt->hash_algo); repo_set_compat_hash_algo(the_repository, fmt->compat_hash_algo); @@ -2068,7 +2174,7 @@ static void copy_templates(const char *option_template) goto close_free_return; } - strbuf_addstr(&path, get_git_common_dir()); + strbuf_addstr(&path, repo_get_common_dir(the_repository)); strbuf_complete(&path, '/'); copy_templates_1(&path, &template_path, dir); close_free_return: @@ -2192,7 +2298,7 @@ static int create_default_files(const char *template_path, char *path; int reinit; int filemode; - const char *work_tree = get_git_work_tree(); + const char *work_tree = repo_get_work_tree(the_repository); /* * First copy the templates -- we might have the default @@ -2224,7 +2330,7 @@ static int create_default_files(const char *template_path, * shared-repository settings, we would need to fix them up. */ if (get_shared_repository()) { - adjust_shared_perm(get_git_dir()); + adjust_shared_perm(repo_get_git_dir(the_repository)); } initialize_repository_version(fmt->hash_algo, fmt->ref_storage_format, 0); @@ -2248,7 +2354,7 @@ static int create_default_files(const char *template_path, else { git_config_set("core.bare", "false"); /* allow template config file to override the default */ - if (log_all_ref_updates == LOG_REFS_UNSET) + if (repo_settings_get_log_all_ref_updates(the_repository) == LOG_REFS_UNSET) git_config_set("core.logallrefupdates", "true"); if (needs_work_tree_config(original_git_dir, work_tree)) git_config_set("core.worktree", work_tree); @@ -2282,7 +2388,7 @@ static void create_object_directory(void) struct strbuf path = STRBUF_INIT; size_t baselen; - strbuf_addstr(&path, get_object_directory()); + strbuf_addstr(&path, repo_get_object_directory(the_repository)); baselen = path.len; safe_create_dir(path.buf, 1); @@ -2434,12 +2540,12 @@ int init_db(const char *git_dir, const char *real_git_dir, die(_("%s already exists"), real_git_dir); set_git_dir(real_git_dir, 1); - git_dir = get_git_dir(); + git_dir = repo_get_git_dir(the_repository); separate_git_dir(git_dir, original_git_dir); } else { set_git_dir(git_dir, 1); - git_dir = get_git_dir(); + git_dir = repo_get_git_dir(the_repository); } startup_info->have_repository = 1; @@ -94,6 +94,9 @@ static inline int discover_git_directory(struct strbuf *commondir, return 0; } +void set_git_dir(const char *path, int make_realpath); +void set_git_work_tree(const char *tree); + const char *setup_git_directory_gently(int *); const char *setup_git_directory(void); char *prefix_path(const char *prefix, int len, const char *path); @@ -176,7 +179,7 @@ int verify_repository_format(const struct repository_format *format, struct strbuf *err); /* - * Check the repository format version in the path found in get_git_dir(), + * Check the repository format version in the path found in repo_get_git_dir(the_repository), * and die if it is a version we don't understand. Generally one would * set_git_dir() before calling this, and use it only for "are we in a valid * repo?". @@ -51,10 +51,12 @@ int unregister_shallow(const struct object_id *oid) int pos = commit_graft_pos(the_repository, oid); if (pos < 0) return -1; - if (pos + 1 < the_repository->parsed_objects->grafts_nr) + if (pos + 1 < the_repository->parsed_objects->grafts_nr) { + free(the_repository->parsed_objects->grafts[pos]); MOVE_ARRAY(the_repository->parsed_objects->grafts + pos, the_repository->parsed_objects->grafts + pos + 1, the_repository->parsed_objects->grafts_nr - pos - 1); + } the_repository->parsed_objects->grafts_nr--; return 0; } @@ -97,7 +99,7 @@ static void reset_repository_shallow(struct repository *r) { r->parsed_objects->is_shallow = -1; stat_validity_clear(r->parsed_objects->shallow_stat); - reset_commit_grafts(r); + parsed_object_pool_reset_commit_grafts(r->parsed_objects); } int commit_shallow_file(struct repository *r, struct shallow_lock *lk) @@ -487,6 +489,15 @@ void prepare_shallow_info(struct shallow_info *info, struct oid_array *sa) void clear_shallow_info(struct shallow_info *info) { + if (info->used_shallow) { + for (size_t i = 0; i < info->shallow->nr; i++) + free(info->used_shallow[i]); + free(info->used_shallow); + } + + free(info->need_reachability_test); + free(info->reachable); + free(info->shallow_ref); free(info->ours); free(info->theirs); } diff --git a/sideband.c b/sideband.c index 4e816be4e9..02805573fa 100644 --- a/sideband.c +++ b/sideband.c @@ -191,7 +191,7 @@ int demultiplex_sideband(const char *me, int status, int linelen = brk - b; /* - * For message accross packet boundary, there would have + * For message across packet boundary, there would have * a nonempty "scratch" buffer from last call of this * function, and there may have a leading CR/LF in "buf". * For this case we should add a clear-to-eol suffix to diff --git a/sparse-index.c b/sparse-index.c index 9958656ded..542ca5f411 100644 --- a/sparse-index.c +++ b/sparse-index.c @@ -1,3 +1,5 @@ +#define USE_THE_REPOSITORY_VARIABLE + #include "git-compat-util.h" #include "environment.h" #include "gettext.h" diff --git a/statinfo.c b/statinfo.c index 3c6bc049c1..30a164b0e6 100644 --- a/statinfo.c +++ b/statinfo.c @@ -1,3 +1,5 @@ +#define USE_THE_REPOSITORY_VARIABLE + #include "git-compat-util.h" #include "environment.h" #include "statinfo.h" diff --git a/submodule.c b/submodule.c index 97516b0fec..4e71ac0dfd 100644 --- a/submodule.c +++ b/submodule.c @@ -1883,6 +1883,8 @@ int fetch_submodules(struct repository *r, out: free_submodules_data(&spf.changed_submodule_names); string_list_clear(&spf.seen_submodule_names, 0); + strbuf_release(&spf.submodules_with_errors); + free(spf.oid_fetch_tasks); return spf.result; } @@ -2462,7 +2464,7 @@ void absorb_git_dir_into_superproject(const char *path, } else { /* Is it already absorbed into the superprojects git dir? */ char *real_sub_git_dir = real_pathdup(sub_git_dir, 1); - char *real_common_git_dir = real_pathdup(get_git_common_dir(), 1); + char *real_common_git_dir = real_pathdup(repo_get_common_dir(the_repository), 1); if (!starts_with(real_sub_git_dir, real_common_git_dir)) relocate_single_git_dir_into_superproject(path, super_prefix); @@ -386,6 +386,9 @@ GIT_TEST_PASSING_SANITIZE_LEAK=check when combined with "--immediate" will run to completion faster, and result in the same failing tests. +GIT_TEST_PASSING_SANITIZE_LEAK=check-failing behaves the same as "check", +but skips all tests which are already marked as leak-free. + GIT_TEST_PROTOCOL_VERSION=<n>, when set, makes 'protocol.version' default to n. diff --git a/t/helper/test-config.c b/t/helper/test-config.c index e193079ed5..33247f0e92 100644 --- a/t/helper/test-config.c +++ b/t/helper/test-config.c @@ -96,7 +96,8 @@ int cmd__config(int argc, const char **argv) struct config_set cs; if (argc == 3 && !strcmp(argv[1], "read_early_config")) { - read_early_config(early_config_cb, (void *)argv[2]); + read_early_config(the_repository, early_config_cb, + (void *)argv[2]); return 0; } diff --git a/t/helper/test-path-utils.c b/t/helper/test-path-utils.c index fd6e6cc4a5..3129aa28fd 100644 --- a/t/helper/test-path-utils.c +++ b/t/helper/test-path-utils.c @@ -1,3 +1,5 @@ +#define USE_THE_REPOSITORY_VARIABLE + #include "test-tool.h" #include "abspath.h" #include "environment.h" diff --git a/t/interop/README b/t/interop/README index 72d42bd856..4e0608f857 100644 --- a/t/interop/README +++ b/t/interop/README @@ -83,3 +83,10 @@ You can then use test_expect_success as usual, with a few differences: should create one with the appropriate version of git. At the end of the script, call test_done as usual. + +Some older versions may need a few build knobs tweaked (e.g., ancient +versions of Git no longer build with modern OpenSSL). Your script can +set MAKE_OPTS_A and MAKE_OPTS_B, which will be passed alongside +GIT_INTEROP_MAKE_OPTS. Users can override them per-script by setting +GIT_INTEROP_MAKE_OPTS_{A,B} in the environment, just like they can set +GIT_TEST_VERSION_{A,B}. diff --git a/t/interop/i5500-git-daemon.sh b/t/interop/i5500-git-daemon.sh index 4d22e42f84..88712d1b5d 100755 --- a/t/interop/i5500-git-daemon.sh +++ b/t/interop/i5500-git-daemon.sh @@ -2,6 +2,7 @@ VERSION_A=. VERSION_B=v1.0.0 +MAKE_OPTS_B="NO_OPENSSL=TooOld" : ${LIB_GIT_DAEMON_PORT:=5500} LIB_GIT_DAEMON_COMMAND='git.a daemon' diff --git a/t/interop/interop-lib.sh b/t/interop/interop-lib.sh index 62f4481b6e..1b5864d2a7 100644 --- a/t/interop/interop-lib.sh +++ b/t/interop/interop-lib.sh @@ -45,7 +45,7 @@ build_version () { ( cd "$dir" && - make $GIT_INTEROP_MAKE_OPTS >&2 && + make $2 $GIT_INTEROP_MAKE_OPTS >&2 && touch .built ) || return 1 @@ -76,9 +76,11 @@ generate_wrappers () { VERSION_A=${GIT_TEST_VERSION_A:-$VERSION_A} VERSION_B=${GIT_TEST_VERSION_B:-$VERSION_B} +MAKE_OPTS_A=${GIT_INTEROP_MAKE_OPTS_A:-$MAKE_OPTS_A} +MAKE_OPTS_B=${GIT_INTEROP_MAKE_OPTS_B:-$MAKE_OPTS_B} -if ! DIR_A=$(build_version "$VERSION_A") || - ! DIR_B=$(build_version "$VERSION_B") +if ! DIR_A=$(build_version "$VERSION_A" "$MAKE_OPTS_A") || + ! DIR_B=$(build_version "$VERSION_B" "$MAKE_OPTS_B") then echo >&2 "fatal: unable to build git versions" exit 1 diff --git a/t/t0211-trace2-perf.sh b/t/t0211-trace2-perf.sh index 070fe7a5da..dddc130560 100755 --- a/t/t0211-trace2-perf.sh +++ b/t/t0211-trace2-perf.sh @@ -337,7 +337,8 @@ test_expect_success 'expect def_params for query command' ' # remote-curl.c rather than git.c. Confirm that we get def_param # events from both layers. # -test_expect_success 'expect def_params for remote-curl and _run_dashed_' ' +test_expect_success LIBCURL \ + 'expect def_params for remote-curl and _run_dashed_' ' test_when_finished "rm prop.perf actual" && test_config_global "trace2.configParams" "cfg.prop.*" && @@ -366,7 +367,8 @@ test_expect_success 'expect def_params for remote-curl and _run_dashed_' ' # an executable built from http-fetch.c. Confirm that we get # def_param events from both layers. # -test_expect_success 'expect def_params for http-fetch and _run_dashed_' ' +test_expect_success LIBCURL \ + 'expect def_params for http-fetch and _run_dashed_' ' test_when_finished "rm prop.perf actual" && test_config_global "trace2.configParams" "cfg.prop.*" && diff --git a/t/t1419-exclude-refs.sh b/t/t1419-exclude-refs.sh index 1359574419..3256e4462f 100755 --- a/t/t1419-exclude-refs.sh +++ b/t/t1419-exclude-refs.sh @@ -8,12 +8,6 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh -if test_have_prereq !REFFILES -then - skip_all='skipping `git for-each-ref --exclude` tests; need files backend' - test_done -fi - for_each_ref__exclude () { GIT_TRACE2_PERF=1 test-tool ref-store main \ for-each-ref--exclude "$@" >actual.raw @@ -28,7 +22,14 @@ assert_jumps () { local nr="$1" local trace="$2" - grep -q "name:jumps_made value:$nr$" $trace + case "$GIT_DEFAULT_REF_FORMAT" in + files) + grep -q "name:jumps_made value:$nr$" $trace;; + reftable) + grep -q "name:reseeks_made value:$nr$" $trace;; + *) + BUG "unhandled ref format $GIT_DEFAULT_REF_FORMAT";; + esac } assert_no_jumps () { @@ -89,7 +90,14 @@ test_expect_success 'adjacent, non-overlapping excluded regions' ' for_each_ref refs/heads/foo refs/heads/quux >expect && test_cmp expect actual && - assert_jumps 1 perf + case "$GIT_DEFAULT_REF_FORMAT" in + files) + assert_jumps 1 perf;; + reftable) + assert_jumps 2 perf;; + *) + BUG "unhandled ref format $GIT_DEFAULT_REF_FORMAT";; + esac ' test_expect_success 'overlapping excluded regions' ' @@ -106,7 +114,30 @@ test_expect_success 'several overlapping excluded regions' ' for_each_ref refs/heads/quux >expect && test_cmp expect actual && - assert_jumps 1 perf + case "$GIT_DEFAULT_REF_FORMAT" in + files) + assert_jumps 1 perf;; + reftable) + assert_jumps 3 perf;; + *) + BUG "unhandled ref format $GIT_DEFAULT_REF_FORMAT";; + esac +' + +test_expect_success 'unordered excludes' ' + for_each_ref__exclude refs/heads \ + refs/heads/foo refs/heads/baz >actual 2>perf && + for_each_ref refs/heads/bar refs/heads/quux >expect && + + test_cmp expect actual && + case "$GIT_DEFAULT_REF_FORMAT" in + files) + assert_jumps 1 perf;; + reftable) + assert_jumps 2 perf;; + *) + BUG "unhandled ref format $GIT_DEFAULT_REF_FORMAT";; + esac ' test_expect_success 'non-matching excluded section' ' diff --git a/t/t1517-outside-repo.sh b/t/t1517-outside-repo.sh index 990a036582..342defbb61 100755 --- a/t/t1517-outside-repo.sh +++ b/t/t1517-outside-repo.sh @@ -98,7 +98,7 @@ test_expect_success 'stripspace outside repository' ' nongit git stripspace -s </dev/null ' -test_expect_success 'remote-http outside repository' ' +test_expect_success LIBCURL 'remote-http outside repository' ' test_must_fail git remote-http 2>actual && test_grep "^error: remote-curl" actual && ( diff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh index bd8bcc381a..09f230eefb 100755 --- a/t/t3400-rebase.sh +++ b/t/t3400-rebase.sh @@ -145,7 +145,9 @@ test_expect_success 'Show verbose error when HEAD could not be detached' ' test_when_finished "rm -f B" && test_must_fail git rebase topic 2>output.err >output.out && test_grep "The following untracked working tree files would be overwritten by checkout:" output.err && - test_grep B output.err + test_grep B output.err && + test_must_fail git rebase --quit 2>err && + test_grep "no rebase in progress" err ' test_expect_success 'fail when upstream arg is missing and not on branch' ' @@ -428,7 +430,9 @@ test_expect_success 'refuse to switch to branch checked out elsewhere' ' git checkout main && git worktree add wt && test_must_fail git -C wt rebase main main 2>err && - test_grep "already used by worktree at" err + test_grep "already used by worktree at" err && + test_must_fail git -C wt rebase --quit 2>err && + test_grep "no rebase in progress" err ' test_expect_success 'rebase when inside worktree subdirectory' ' diff --git a/t/t3413-rebase-hook.sh b/t/t3413-rebase-hook.sh index e8456831e8..426ff098e1 100755 --- a/t/t3413-rebase-hook.sh +++ b/t/t3413-rebase-hook.sh @@ -110,7 +110,9 @@ test_expect_success 'pre-rebase hook stops rebase (1)' ' git reset --hard side && test_must_fail git rebase main && test "z$(git symbolic-ref HEAD)" = zrefs/heads/test && - test 0 = $(git rev-list HEAD...side | wc -l) + test 0 = $(git rev-list HEAD...side | wc -l) && + test_must_fail git rebase --quit 2>err && + test_grep "no rebase in progress" err ' test_expect_success 'pre-rebase hook stops rebase (2)' ' diff --git a/t/t3420-rebase-autostash.sh b/t/t3420-rebase-autostash.sh index 63e400b89f..b43046b3b0 100755 --- a/t/t3420-rebase-autostash.sh +++ b/t/t3420-rebase-autostash.sh @@ -82,6 +82,46 @@ testrebase () { type=$1 dotest=$2 + test_expect_success "rebase$type: restore autostash when pre-rebase hook fails" ' + git checkout -f feature-branch && + test_hook pre-rebase <<-\EOF && + exit 1 + EOF + + echo changed >file0 && + test_must_fail git rebase $type --autostash -f HEAD^ && + test_must_fail git rebase --quit 2>err && + test_grep "no rebase in progress" err && + echo changed >expect && + test_cmp expect file0 + ' + + test_expect_success "rebase$type: restore autostash when checkout onto fails" ' + git checkout -f --detach feature-branch && + echo uncommitted-content >file0 && + echo untracked >file4 && + test_when_finished "rm file4" && + test_must_fail git rebase $type --autostash \ + unrelated-onto-branch && + test_must_fail git rebase --quit 2>err && + test_grep "no rebase in progress" err && + echo uncommitted-content >expect && + test_cmp expect file0 + ' + + test_expect_success "rebase$type: restore autostash when branch checkout fails" ' + git checkout -f unrelated-onto-branch^ && + echo uncommitted-content >file0 && + echo untracked >file4 && + test_when_finished "rm file4" && + test_must_fail git rebase $type --autostash HEAD \ + unrelated-onto-branch && + test_must_fail git rebase --quit 2>err && + test_grep "no rebase in progress" err && + echo uncommitted-content >expect && + test_cmp expect file0 + ' + test_expect_success "rebase$type: dirty worktree, --no-autostash" ' test_config rebase.autostash true && git reset --hard && diff --git a/t/t3436-rebase-more-options.sh b/t/t3436-rebase-more-options.sh index 94671d3c46..4d9744e5fc 100755 --- a/t/t3436-rebase-more-options.sh +++ b/t/t3436-rebase-more-options.sh @@ -5,6 +5,7 @@ test_description='tests to ensure compatibility between am and interactive backends' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-rebase.sh diff --git a/t/t4017-diff-retval.sh b/t/t4017-diff-retval.sh index d644310e22..1cea73ef5a 100755 --- a/t/t4017-diff-retval.sh +++ b/t/t4017-diff-retval.sh @@ -145,6 +145,14 @@ test_expect_success 'option errors are not confused by --exit-code' ' for option in --exit-code --quiet do + test_expect_success "git diff $option returns 1 for changed binary file" " + test_when_finished 'rm -f .gitattributes' && + git reset --hard && + echo a binary >.gitattributes && + echo 2 >>a && + test_expect_code 1 git diff $option + " + test_expect_success "git diff $option returns 1 for copied file" " git reset --hard && cp a copy && diff --git a/t/t4107-apply-ignore-whitespace.sh b/t/t4107-apply-ignore-whitespace.sh index ac72eeaf27..5e6e203aa5 100755 --- a/t/t4107-apply-ignore-whitespace.sh +++ b/t/t4107-apply-ignore-whitespace.sh @@ -3,9 +3,9 @@ # Copyright (c) 2009 Giuseppe Bilotta # -test_description='git-apply --ignore-whitespace. +test_description='git-apply --ignore-whitespace.' -' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # This primes main.c file that indents without using HT at all. diff --git a/t/t4124-apply-ws-rule.sh b/t/t4124-apply-ws-rule.sh index 485c7d2d12..cdffee0273 100755 --- a/t/t4124-apply-ws-rule.sh +++ b/t/t4124-apply-ws-rule.sh @@ -2,6 +2,7 @@ test_description='core.whitespace rules and git apply' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh prepare_test_file () { diff --git a/t/t4125-apply-ws-fuzz.sh b/t/t4125-apply-ws-fuzz.sh index 090987c89b..f248cc2a00 100755 --- a/t/t4125-apply-ws-fuzz.sh +++ b/t/t4125-apply-ws-fuzz.sh @@ -2,6 +2,7 @@ test_description='applying patch that has broken whitespaces in context' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t4138-apply-ws-expansion.sh b/t/t4138-apply-ws-expansion.sh index 8bbf8260fa..7981931b4e 100755 --- a/t/t4138-apply-ws-expansion.sh +++ b/t/t4138-apply-ws-expansion.sh @@ -5,6 +5,7 @@ test_description='git apply test patches with whitespace expansion.' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t5509-fetch-push-namespaces.sh b/t/t5509-fetch-push-namespaces.sh index 05090feaf9..f029ae0d28 100755 --- a/t/t5509-fetch-push-namespaces.sh +++ b/t/t5509-fetch-push-namespaces.sh @@ -96,6 +96,7 @@ test_expect_success 'hide namespaced refs with transfer.hideRefs' ' ' test_expect_success 'check that transfer.hideRefs does not match unstripped refs' ' + git -C pushee pack-refs --all && GIT_NAMESPACE=namespace \ git -C pushee -c transfer.hideRefs=refs/namespaces/namespace/refs/tags \ ls-remote "ext::git %s ." >actual && @@ -123,6 +124,14 @@ test_expect_success 'try to update a ref that is not hidden' ' git -C original push pushee-namespaced main ' +test_expect_success 'git-receive-pack(1) with transfer.hideRefs does not match unstripped refs during advertisement' ' + git -C pushee update-ref refs/namespaces/namespace/refs/heads/foo/1 refs/namespaces/namespace/refs/heads/main && + git -C pushee pack-refs --all && + test_config -C pushee transfer.hideRefs refs/namespaces/namespace/refs/heads/foo && + GIT_TRACE_PACKET="$(pwd)/trace" git -C original push pushee-namespaced main && + test_grep refs/heads/foo/1 trace +' + test_expect_success 'try to update a hidden full ref' ' test_config -C pushee transfer.hideRefs "^refs/namespaces/namespace/refs/heads/main" && test_must_fail git -C original push pushee-namespaced main diff --git a/t/t5512-ls-remote.sh b/t/t5512-ls-remote.sh index d64b40e408..64b3491e4e 100755 --- a/t/t5512-ls-remote.sh +++ b/t/t5512-ls-remote.sh @@ -406,6 +406,7 @@ test_expect_success 'v0 clients can handle multiple symrefs' ' test_expect_success 'helper with refspec capability fails gracefully' ' mkdir test-bin && write_script test-bin/git-remote-foo <<-EOF && + read capabilities echo import echo refspec ${SQ}*:*${SQ} EOF diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh index 9d693eb57f..331778bd42 100755 --- a/t/t5516-fetch-push.sh +++ b/t/t5516-fetch-push.sh @@ -19,6 +19,7 @@ GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME TEST_CREATE_REPO_NO_TEMPLATE=1 +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh D=$(pwd) diff --git a/t/t5526-fetch-submodules.sh b/t/t5526-fetch-submodules.sh index 5e566205ba..2cfb5bd6bb 100755 --- a/t/t5526-fetch-submodules.sh +++ b/t/t5526-fetch-submodules.sh @@ -6,6 +6,7 @@ test_description='Recursive "git fetch" for submodules' GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB=1 export GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh pwd=$(pwd) diff --git a/t/t5531-deep-submodule-push.sh b/t/t5531-deep-submodule-push.sh index f3fff55744..135823630a 100755 --- a/t/t5531-deep-submodule-push.sh +++ b/t/t5531-deep-submodule-push.sh @@ -8,6 +8,7 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB=1 export GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t5533-push-cas.sh b/t/t5533-push-cas.sh index cba26a872d..6365d99777 100755 --- a/t/t5533-push-cas.sh +++ b/t/t5533-push-cas.sh @@ -5,6 +5,7 @@ test_description='compare & swap push force/delete safety' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh setup_srcdst_basic () { diff --git a/t/t5534-push-signed.sh b/t/t5534-push-signed.sh index c91a62b77a..d43aee0c32 100755 --- a/t/t5534-push-signed.sh +++ b/t/t5534-push-signed.sh @@ -5,6 +5,7 @@ test_description='signed push' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-gpg.sh diff --git a/t/t5537-fetch-shallow.sh b/t/t5537-fetch-shallow.sh index 37f7547a4c..cae4d400f3 100755 --- a/t/t5537-fetch-shallow.sh +++ b/t/t5537-fetch-shallow.sh @@ -5,6 +5,7 @@ test_description='fetch/clone from a shallow clone' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh commit() { diff --git a/t/t5538-push-shallow.sh b/t/t5538-push-shallow.sh index e91fcc173e..6adc3a20a4 100755 --- a/t/t5538-push-shallow.sh +++ b/t/t5538-push-shallow.sh @@ -5,6 +5,7 @@ test_description='push from/to a shallow clone' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh commit() { diff --git a/t/t5549-fetch-push-http.sh b/t/t5549-fetch-push-http.sh index 2cdebcb735..6377fb6d99 100755 --- a/t/t5549-fetch-push-http.sh +++ b/t/t5549-fetch-push-http.sh @@ -5,6 +5,7 @@ test_description='fetch/push functionality using the HTTP protocol' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-httpd.sh start_httpd diff --git a/t/t5552-skipping-fetch-negotiator.sh b/t/t5552-skipping-fetch-negotiator.sh index b55a9f65e6..4f2e5ae8df 100755 --- a/t/t5552-skipping-fetch-negotiator.sh +++ b/t/t5552-skipping-fetch-negotiator.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='test skipping fetch negotiator' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'fetch.negotiationalgorithm config' ' diff --git a/t/t5616-partial-clone.sh b/t/t5616-partial-clone.sh index 8415884754..c53e93be2f 100755 --- a/t/t5616-partial-clone.sh +++ b/t/t5616-partial-clone.sh @@ -5,6 +5,7 @@ test_description='git partial clone' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # create a normal "src" repo where we can later create new commits. diff --git a/t/t5801-remote-helpers.sh b/t/t5801-remote-helpers.sh index 20f43f7b7d..d21877150e 100755 --- a/t/t5801-remote-helpers.sh +++ b/t/t5801-remote-helpers.sh @@ -344,4 +344,15 @@ test_expect_success 'fetch tag' ' compare_refs local v1.0 server v1.0 ' +test_expect_success 'totally broken helper reports failure message' ' + write_script git-remote-broken <<-\EOF && + read cap_cmd + exit 1 + EOF + test_must_fail \ + env PATH="$PWD:$PATH" \ + git clone broken://example.com/foo.git 2>stderr && + grep aborted stderr +' + test_done diff --git a/t/t6132-pathspec-exclude.sh b/t/t6132-pathspec-exclude.sh index 9fdafeb1e9..f31c09c056 100755 --- a/t/t6132-pathspec-exclude.sh +++ b/t/t6132-pathspec-exclude.sh @@ -2,6 +2,7 @@ test_description='test case exclude pathspec' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t6135-pathspec-with-attrs.sh b/t/t6135-pathspec-with-attrs.sh index 120dcd74a5..794bc7daf0 100755 --- a/t/t6135-pathspec-with-attrs.sh +++ b/t/t6135-pathspec-with-attrs.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='test labels in pathspecs' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup a tree' ' diff --git a/t/t6200-fmt-merge-msg.sh b/t/t6200-fmt-merge-msg.sh index 5a221f8ef1..ac57b0e4ae 100755 --- a/t/t6200-fmt-merge-msg.sh +++ b/t/t6200-fmt-merge-msg.sh @@ -8,6 +8,7 @@ test_description='fmt-merge-msg test' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY/lib-gpg.sh" diff --git a/t/t6409-merge-subtree.sh b/t/t6409-merge-subtree.sh index e9ba6f1690..528615b981 100755 --- a/t/t6409-merge-subtree.sh +++ b/t/t6409-merge-subtree.sh @@ -5,6 +5,7 @@ test_description='subtree merge strategy' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t6423-merge-rename-directories.sh b/t/t6423-merge-rename-directories.sh index 88d1cf2cde..4aaaf38be6 100755 --- a/t/t6423-merge-rename-directories.sh +++ b/t/t6423-merge-rename-directories.sh @@ -25,6 +25,7 @@ test_description="recursive merge with directory renames" # underscore notation is to differentiate different # files that might be renamed into each other's paths.) +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-merge.sh diff --git a/t/t6500-gc.sh b/t/t6500-gc.sh index 5378455968..ee074b99b7 100755 --- a/t/t6500-gc.sh +++ b/t/t6500-gc.sh @@ -3,6 +3,7 @@ test_description='basic git gc tests ' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-terminal.sh diff --git a/t/t7703-repack-geometric.sh b/t/t7703-repack-geometric.sh index 9fc1626fbf..8877aea98b 100755 --- a/t/t7703-repack-geometric.sh +++ b/t/t7703-repack-geometric.sh @@ -2,6 +2,7 @@ test_description='git repack --geometric works correctly' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh GIT_TEST_MULTI_PACK_INDEX=0 diff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh index df5336bb7e..e2430f7bfa 100755 --- a/t/t9001-send-email.sh +++ b/t/t9001-send-email.sh @@ -1324,7 +1324,7 @@ test_expect_success $PREREQ 'cc list is sanitized' ' Reviewed-by: Füñný Nâmé <odd_?=mail@example.com> Reported-by: bugger on Jira Reported-by: Douglas Reporter <doug@example.com> [from Jira profile] - BugID: 12345 + BugID: 12345should-not-appear Co-developed-by: "C. O. Developer" <codev@example.com> Signed-off-by: A. U. Thor <thor.au@example.com> EOF @@ -1337,7 +1337,7 @@ test_expect_success $PREREQ 'cc list is sanitized' ' " <odd_?=mail@example.com>" actual-show-all-headers && test_grep "^(body) Ignoring Reported-by .* bugger on Jira" actual-show-all-headers && test_grep "^(body) Adding cc: Douglas Reporter <doug@example.com>" actual-show-all-headers && - test_grep ! "12345" actual-show-all-headers && + test_grep ! "12345should-not-appear" actual-show-all-headers && test_grep "^(body) Adding cc: \"C. O. Developer\" <codev@example.com>" actual-show-all-headers && test_grep "^(body) Adding cc: \"A. U. Thor\" <thor.au@example.com>" actual-show-all-headers ' diff --git a/t/t9700-perl-git.sh b/t/t9700-perl-git.sh index ccc8212d73..4431697122 100755 --- a/t/t9700-perl-git.sh +++ b/t/t9700-perl-git.sh @@ -45,7 +45,8 @@ test_expect_success 'set up test repository' ' ' test_expect_success 'set up bare repository' ' - git init --bare bare.git + git init --bare bare.git && + git -C bare.git --work-tree=. commit --allow-empty -m "bare commit" ' test_expect_success 'use t9700/test.pl to test Git.pm' ' diff --git a/t/t9700/test.pl b/t/t9700/test.pl index d8e85482ab..2e1d50d4d1 100755 --- a/t/t9700/test.pl +++ b/t/t9700/test.pl @@ -147,6 +147,11 @@ close TEMPFILE3; unlink $tmpfile3; chdir($abs_repo_dir); +# open alternate bare repo +my $r4 = Git->repository(Directory => "$abs_repo_dir/bare.git"); +is($r4->command_oneline(qw(log --format=%s)), "bare commit", + "log of bare repo works"); + # unquoting paths is(Git::unquote_path('abc'), 'abc', 'unquote unquoted path'); is(Git::unquote_path('"abc def"'), 'abc def', 'unquote simple quoted path'); diff --git a/t/test-lib.sh b/t/test-lib.sh index 278d1215f1..e718efe4c6 100644 --- a/t/test-lib.sh +++ b/t/test-lib.sh @@ -1558,8 +1558,16 @@ then passes_sanitize_leak=t fi - if test "$GIT_TEST_PASSING_SANITIZE_LEAK" = "check" + if test "$GIT_TEST_PASSING_SANITIZE_LEAK" = "check" || + test "$GIT_TEST_PASSING_SANITIZE_LEAK" = "check-failing" then + if test "$GIT_TEST_PASSING_SANITIZE_LEAK" = "check-failing" && + test -n "$passes_sanitize_leak" + then + skip_all="skipping leak-free $this_test under GIT_TEST_PASSING_SANITIZE_LEAK=check-failing" + test_done + fi + sanitize_leak_check=t if test -n "$invert_exit_code" then @@ -1597,6 +1605,7 @@ then export LSAN_OPTIONS elif test "$GIT_TEST_PASSING_SANITIZE_LEAK" = "check" || + test "$GIT_TEST_PASSING_SANITIZE_LEAK" = "check-failing" || test_bool_env GIT_TEST_PASSING_SANITIZE_LEAK false then BAIL_OUT_ENV_NEEDS_SANITIZE_LEAK "GIT_TEST_PASSING_SANITIZE_LEAK=true" diff --git a/t/unit-tests/lib-reftable.c b/t/unit-tests/lib-reftable.c new file mode 100644 index 0000000000..ab1fa44a28 --- /dev/null +++ b/t/unit-tests/lib-reftable.c @@ -0,0 +1,93 @@ +#include "lib-reftable.h" +#include "test-lib.h" +#include "reftable/constants.h" +#include "reftable/writer.h" + +void t_reftable_set_hash(uint8_t *p, int i, uint32_t id) +{ + memset(p, (uint8_t)i, hash_size(id)); +} + +static ssize_t strbuf_writer_write(void *b, const void *data, size_t sz) +{ + strbuf_add(b, data, sz); + return sz; +} + +static int strbuf_writer_flush(void *arg UNUSED) +{ + return 0; +} + +struct reftable_writer *t_reftable_strbuf_writer(struct strbuf *buf, + struct reftable_write_options *opts) +{ + return reftable_new_writer(&strbuf_writer_write, + &strbuf_writer_flush, + buf, opts); +} + +void t_reftable_write_to_buf(struct strbuf *buf, + struct reftable_ref_record *refs, + size_t nrefs, + struct reftable_log_record *logs, + size_t nlogs, + struct reftable_write_options *_opts) +{ + struct reftable_write_options opts = { 0 }; + const struct reftable_stats *stats; + struct reftable_writer *writer; + uint64_t min = 0xffffffff; + uint64_t max = 0; + int ret; + + if (_opts) + opts = *_opts; + + for (size_t i = 0; i < nrefs; i++) { + uint64_t ui = refs[i].update_index; + if (ui > max) + max = ui; + if (ui < min) + min = ui; + } + for (size_t i = 0; i < nlogs; i++) { + uint64_t ui = logs[i].update_index; + if (ui > max) + max = ui; + if (ui < min) + min = ui; + } + + writer = t_reftable_strbuf_writer(buf, &opts); + reftable_writer_set_limits(writer, min, max); + + if (nrefs) { + ret = reftable_writer_add_refs(writer, refs, nrefs); + check_int(ret, ==, 0); + } + + if (nlogs) { + ret = reftable_writer_add_logs(writer, logs, nlogs); + check_int(ret, ==, 0); + } + + ret = reftable_writer_close(writer); + check_int(ret, ==, 0); + + stats = reftable_writer_stats(writer); + for (size_t i = 0; i < stats->ref_stats.blocks; i++) { + size_t off = i * (opts.block_size ? opts.block_size + : DEFAULT_BLOCK_SIZE); + if (!off) + off = header_size(opts.hash_id == GIT_SHA256_FORMAT_ID ? 2 : 1); + check_char(buf->buf[off], ==, 'r'); + } + + if (nrefs) + check_int(stats->ref_stats.blocks, >, 0); + if (nlogs) + check_int(stats->log_stats.blocks, >, 0); + + reftable_writer_free(writer); +} diff --git a/t/unit-tests/lib-reftable.h b/t/unit-tests/lib-reftable.h new file mode 100644 index 0000000000..d115419084 --- /dev/null +++ b/t/unit-tests/lib-reftable.h @@ -0,0 +1,20 @@ +#ifndef LIB_REFTABLE_H +#define LIB_REFTABLE_H + +#include "git-compat-util.h" +#include "strbuf.h" +#include "reftable/reftable-writer.h" + +void t_reftable_set_hash(uint8_t *p, int i, uint32_t id); + +struct reftable_writer *t_reftable_strbuf_writer(struct strbuf *buf, + struct reftable_write_options *opts); + +void t_reftable_write_to_buf(struct strbuf *buf, + struct reftable_ref_record *refs, + size_t nrecords, + struct reftable_log_record *logs, + size_t nlogs, + struct reftable_write_options *opts); + +#endif diff --git a/t/unit-tests/t-reftable-merged.c b/t/unit-tests/t-reftable-merged.c index e9d100a01e..19e54bdfb8 100644 --- a/t/unit-tests/t-reftable-merged.c +++ b/t/unit-tests/t-reftable-merged.c @@ -7,6 +7,7 @@ https://developers.google.com/open-source/licenses/bsd */ #include "test-lib.h" +#include "lib-reftable.h" #include "reftable/blocksource.h" #include "reftable/constants.h" #include "reftable/merged.h" @@ -15,77 +16,6 @@ https://developers.google.com/open-source/licenses/bsd #include "reftable/reftable-merged.h" #include "reftable/reftable-writer.h" -static ssize_t strbuf_add_void(void *b, const void *data, const size_t sz) -{ - strbuf_add(b, data, sz); - return sz; -} - -static int noop_flush(void *arg UNUSED) -{ - return 0; -} - -static void write_test_table(struct strbuf *buf, - struct reftable_ref_record refs[], const size_t n) -{ - uint64_t min = 0xffffffff; - uint64_t max = 0; - size_t i; - int err; - - struct reftable_write_options opts = { - .block_size = 256, - }; - struct reftable_writer *w = NULL; - for (i = 0; i < n; i++) { - uint64_t ui = refs[i].update_index; - if (ui > max) - max = ui; - if (ui < min) - min = ui; - } - - w = reftable_new_writer(&strbuf_add_void, &noop_flush, buf, &opts); - reftable_writer_set_limits(w, min, max); - - for (i = 0; i < n; i++) { - uint64_t before = refs[i].update_index; - int n = reftable_writer_add_ref(w, &refs[i]); - check_int(n, ==, 0); - check_int(before, ==, refs[i].update_index); - } - - err = reftable_writer_close(w); - check(!err); - - reftable_writer_free(w); -} - -static void write_test_log_table(struct strbuf *buf, struct reftable_log_record logs[], - const size_t n, const uint64_t update_index) -{ - int err; - - struct reftable_write_options opts = { - .block_size = 256, - .exact_log_message = 1, - }; - struct reftable_writer *w = NULL; - w = reftable_new_writer(&strbuf_add_void, &noop_flush, buf, &opts); - reftable_writer_set_limits(w, update_index, update_index); - - for (size_t i = 0; i < n; i++) { - int err = reftable_writer_add_log(w, &logs[i]); - check(!err); - } - - err = reftable_writer_close(w); - check(!err); - - reftable_writer_free(w); -} - static struct reftable_merged_table * merged_table_from_records(struct reftable_ref_record **refs, struct reftable_block_source **source, @@ -93,13 +23,16 @@ merged_table_from_records(struct reftable_ref_record **refs, struct strbuf *buf, const size_t n) { struct reftable_merged_table *mt = NULL; + struct reftable_write_options opts = { + .block_size = 256, + }; int err; REFTABLE_CALLOC_ARRAY(*readers, n); REFTABLE_CALLOC_ARRAY(*source, n); for (size_t i = 0; i < n; i++) { - write_test_table(&buf[i], refs[i], sizes[i]); + t_reftable_write_to_buf(&buf[i], refs[i], sizes[i], NULL, 0, &opts); block_source_from_strbuf(&(*source)[i], &buf[i]); err = reftable_reader_new(&(*readers)[i], &(*source)[i], @@ -261,6 +194,81 @@ static void t_merged_refs(void) reftable_free(bs); } +static void t_merged_seek_multiple_times(void) +{ + struct reftable_ref_record r1[] = { + { + .refname = (char *) "a", + .update_index = 1, + .value_type = REFTABLE_REF_VAL1, + .value.val1 = { 1 }, + }, + { + .refname = (char *) "c", + .update_index = 1, + .value_type = REFTABLE_REF_VAL1, + .value.val1 = { 2 }, + } + }; + struct reftable_ref_record r2[] = { + { + .refname = (char *) "b", + .update_index = 2, + .value_type = REFTABLE_REF_VAL1, + .value.val1 = { 3 }, + }, + { + .refname = (char *) "d", + .update_index = 2, + .value_type = REFTABLE_REF_VAL1, + .value.val1 = { 4 }, + }, + }; + struct reftable_ref_record *refs[] = { + r1, r2, + }; + size_t sizes[] = { + ARRAY_SIZE(r1), ARRAY_SIZE(r2), + }; + struct strbuf bufs[] = { + STRBUF_INIT, STRBUF_INIT, + }; + struct reftable_block_source *sources = NULL; + struct reftable_reader **readers = NULL; + struct reftable_ref_record rec = { 0 }; + struct reftable_iterator it = { 0 }; + struct reftable_merged_table *mt; + + mt = merged_table_from_records(refs, &sources, &readers, sizes, bufs, 2); + merged_table_init_iter(mt, &it, BLOCK_TYPE_REF); + + for (size_t i = 0; i < 5; i++) { + int err = reftable_iterator_seek_ref(&it, "c"); + check(!err); + + err = reftable_iterator_next_ref(&it, &rec); + check(!err); + err = reftable_ref_record_equal(&rec, &r1[1], GIT_SHA1_RAWSZ); + check(err == 1); + + err = reftable_iterator_next_ref(&it, &rec); + check(!err); + err = reftable_ref_record_equal(&rec, &r2[1], GIT_SHA1_RAWSZ); + check(err == 1); + + err = reftable_iterator_next_ref(&it, &rec); + check(err > 0); + } + + for (size_t i = 0; i < ARRAY_SIZE(bufs); i++) + strbuf_release(&bufs[i]); + readers_destroy(readers, ARRAY_SIZE(refs)); + reftable_ref_record_release(&rec); + reftable_iterator_destroy(&it); + reftable_merged_table_free(mt); + reftable_free(sources); +} + static struct reftable_merged_table * merged_table_from_log_records(struct reftable_log_record **logs, struct reftable_block_source **source, @@ -268,13 +276,17 @@ merged_table_from_log_records(struct reftable_log_record **logs, struct strbuf *buf, const size_t n) { struct reftable_merged_table *mt = NULL; + struct reftable_write_options opts = { + .block_size = 256, + .exact_log_message = 1, + }; int err; REFTABLE_CALLOC_ARRAY(*readers, n); REFTABLE_CALLOC_ARRAY(*source, n); for (size_t i = 0; i < n; i++) { - write_test_log_table(&buf[i], logs[i], sizes[i], i + 1); + t_reftable_write_to_buf(&buf[i], NULL, 0, logs[i], sizes[i], &opts); block_source_from_strbuf(&(*source)[i], &buf[i]); err = reftable_reader_new(&(*readers)[i], &(*source)[i], @@ -402,9 +414,7 @@ static void t_default_write_opts(void) { struct reftable_write_options opts = { 0 }; struct strbuf buf = STRBUF_INIT; - struct reftable_writer *w = - reftable_new_writer(&strbuf_add_void, &noop_flush, &buf, &opts); - + struct reftable_writer *w = t_reftable_strbuf_writer(&buf, &opts); struct reftable_ref_record rec = { .refname = (char *) "master", .update_index = 1, @@ -448,6 +458,7 @@ int cmd_main(int argc UNUSED, const char *argv[] UNUSED) TEST(t_default_write_opts(), "merged table with default write opts"); TEST(t_merged_logs(), "merged table with multiple log updates for same ref"); TEST(t_merged_refs(), "merged table with multiple updates to same ref"); + TEST(t_merged_seek_multiple_times(), "merged table can seek multiple times"); TEST(t_merged_single_record(), "ref ocurring in only one record can be fetched"); return test_done(); diff --git a/t/unit-tests/t-reftable-reader.c b/t/unit-tests/t-reftable-reader.c new file mode 100644 index 0000000000..eea86966c0 --- /dev/null +++ b/t/unit-tests/t-reftable-reader.c @@ -0,0 +1,96 @@ +#include "test-lib.h" +#include "lib-reftable.h" +#include "reftable/blocksource.h" +#include "reftable/reader.h" + +static int t_reader_seek_once(void) +{ + struct reftable_ref_record records[] = { + { + .refname = (char *) "refs/heads/main", + .value_type = REFTABLE_REF_VAL1, + .value.val1 = { 42 }, + }, + }; + struct reftable_block_source source = { 0 }; + struct reftable_ref_record ref = { 0 }; + struct reftable_iterator it = { 0 }; + struct reftable_reader *reader; + struct strbuf buf = STRBUF_INIT; + int ret; + + t_reftable_write_to_buf(&buf, records, ARRAY_SIZE(records), NULL, 0, NULL); + block_source_from_strbuf(&source, &buf); + + ret = reftable_reader_new(&reader, &source, "name"); + check(!ret); + + reftable_reader_init_ref_iterator(reader, &it); + ret = reftable_iterator_seek_ref(&it, ""); + check(!ret); + ret = reftable_iterator_next_ref(&it, &ref); + check(!ret); + + ret = reftable_ref_record_equal(&ref, &records[0], GIT_SHA1_RAWSZ); + check_int(ret, ==, 1); + + ret = reftable_iterator_next_ref(&it, &ref); + check_int(ret, ==, 1); + + reftable_ref_record_release(&ref); + reftable_iterator_destroy(&it); + reftable_reader_decref(reader); + strbuf_release(&buf); + return 0; +} + +static int t_reader_reseek(void) +{ + struct reftable_ref_record records[] = { + { + .refname = (char *) "refs/heads/main", + .value_type = REFTABLE_REF_VAL1, + .value.val1 = { 42 }, + }, + }; + struct reftable_block_source source = { 0 }; + struct reftable_ref_record ref = { 0 }; + struct reftable_iterator it = { 0 }; + struct reftable_reader *reader; + struct strbuf buf = STRBUF_INIT; + int ret; + + t_reftable_write_to_buf(&buf, records, ARRAY_SIZE(records), NULL, 0, NULL); + block_source_from_strbuf(&source, &buf); + + ret = reftable_reader_new(&reader, &source, "name"); + check(!ret); + + reftable_reader_init_ref_iterator(reader, &it); + + for (size_t i = 0; i < 5; i++) { + ret = reftable_iterator_seek_ref(&it, ""); + check(!ret); + ret = reftable_iterator_next_ref(&it, &ref); + check(!ret); + + ret = reftable_ref_record_equal(&ref, &records[0], GIT_SHA1_RAWSZ); + check_int(ret, ==, 1); + + ret = reftable_iterator_next_ref(&it, &ref); + check_int(ret, ==, 1); + } + + reftable_ref_record_release(&ref); + reftable_iterator_destroy(&it); + reftable_reader_decref(reader); + strbuf_release(&buf); + return 0; +} + +int cmd_main(int argc UNUSED, const char *argv[] UNUSED) +{ + TEST(t_reader_seek_once(), "reader can seek once"); + TEST(t_reader_reseek(), "reader can reseek multiple times"); + return test_done(); +} diff --git a/t/unit-tests/t-reftable-readwrite.c b/t/unit-tests/t-reftable-readwrite.c index 82bfaf3287..e1b235a5f1 100644 --- a/t/unit-tests/t-reftable-readwrite.c +++ b/t/unit-tests/t-reftable-readwrite.c @@ -7,6 +7,7 @@ https://developers.google.com/open-source/licenses/bsd */ #include "test-lib.h" +#include "lib-reftable.h" #include "reftable/basics.h" #include "reftable/blocksource.h" #include "reftable/reader.h" @@ -15,22 +16,6 @@ https://developers.google.com/open-source/licenses/bsd static const int update_index = 5; -static void set_test_hash(uint8_t *p, int i) -{ - memset(p, (uint8_t)i, hash_size(GIT_SHA1_FORMAT_ID)); -} - -static ssize_t strbuf_add_void(void *b, const void *data, size_t sz) -{ - strbuf_add(b, data, sz); - return sz; -} - -static int noop_flush(void *arg UNUSED) -{ - return 0; -} - static void t_buffer(void) { struct strbuf buf = STRBUF_INIT; @@ -62,61 +47,34 @@ static void write_table(char ***names, struct strbuf *buf, int N, .block_size = block_size, .hash_id = hash_id, }; - struct reftable_writer *w = - reftable_new_writer(&strbuf_add_void, &noop_flush, buf, &opts); - struct reftable_ref_record ref = { 0 }; - int i = 0, n; - struct reftable_log_record log = { 0 }; - const struct reftable_stats *stats = NULL; + struct reftable_ref_record *refs; + struct reftable_log_record *logs; + int i; REFTABLE_CALLOC_ARRAY(*names, N + 1); + REFTABLE_CALLOC_ARRAY(refs, N); + REFTABLE_CALLOC_ARRAY(logs, N); - reftable_writer_set_limits(w, update_index, update_index); for (i = 0; i < N; i++) { - char name[100]; - int n; - - snprintf(name, sizeof(name), "refs/heads/branch%02d", i); - - ref.refname = name; - ref.update_index = update_index; - ref.value_type = REFTABLE_REF_VAL1; - set_test_hash(ref.value.val1, i); - (*names)[i] = xstrdup(name); - - n = reftable_writer_add_ref(w, &ref); - check_int(n, ==, 0); + refs[i].refname = (*names)[i] = xstrfmt("refs/heads/branch%02d", i); + refs[i].update_index = update_index; + refs[i].value_type = REFTABLE_REF_VAL1; + t_reftable_set_hash(refs[i].value.val1, i, GIT_SHA1_FORMAT_ID); } for (i = 0; i < N; i++) { - char name[100]; - int n; - - snprintf(name, sizeof(name), "refs/heads/branch%02d", i); - - log.refname = name; - log.update_index = update_index; - log.value_type = REFTABLE_LOG_UPDATE; - set_test_hash(log.value.update.new_hash, i); - log.value.update.message = (char *) "message"; - - n = reftable_writer_add_log(w, &log); - check_int(n, ==, 0); + logs[i].refname = (*names)[i]; + logs[i].update_index = update_index; + logs[i].value_type = REFTABLE_LOG_UPDATE; + t_reftable_set_hash(logs[i].value.update.new_hash, i, + GIT_SHA1_FORMAT_ID); + logs[i].value.update.message = (char *) "message"; } - n = reftable_writer_close(w); - check_int(n, ==, 0); - - stats = reftable_writer_stats(w); - for (i = 0; i < stats->ref_stats.blocks; i++) { - int off = i * opts.block_size; - if (!off) - off = header_size((hash_id == GIT_SHA256_FORMAT_ID) ? 2 : 1); - check_char(buf->buf[off], ==, 'r'); - } + t_reftable_write_to_buf(buf, refs, N, logs, N, &opts); - check_int(stats->log_stats.blocks, >, 0); - reftable_writer_free(w); + free(refs); + free(logs); } static void t_log_buffer_size(void) @@ -138,8 +96,7 @@ static void t_log_buffer_size(void) .time = 0x5e430672, .message = (char *) "commit: 9\n", } } }; - struct reftable_writer *w = - reftable_new_writer(&strbuf_add_void, &noop_flush, &buf, &opts); + struct reftable_writer *w = t_reftable_strbuf_writer(&buf, &opts); /* This tests buffer extension for log compression. Must use a random hash, to ensure that the compressed part is larger than the original. @@ -181,8 +138,7 @@ static void t_log_overflow(void) }, }, }; - struct reftable_writer *w = - reftable_new_writer(&strbuf_add_void, &noop_flush, &buf, &opts); + struct reftable_writer *w = t_reftable_strbuf_writer(&buf, &opts); memset(msg, 'x', sizeof(msg) - 1); reftable_writer_set_limits(w, update_index, update_index); @@ -208,8 +164,7 @@ static void t_log_write_read(void) struct reftable_reader *reader; struct reftable_block_source source = { 0 }; struct strbuf buf = STRBUF_INIT; - struct reftable_writer *w = - reftable_new_writer(&strbuf_add_void, &noop_flush, &buf, &opts); + struct reftable_writer *w = t_reftable_strbuf_writer(&buf, &opts); const struct reftable_stats *stats = NULL; reftable_writer_set_limits(w, 0, N); for (i = 0; i < N; i++) { @@ -229,8 +184,10 @@ static void t_log_write_read(void) log.refname = names[i]; log.update_index = i; log.value_type = REFTABLE_LOG_UPDATE; - set_test_hash(log.value.update.old_hash, i); - set_test_hash(log.value.update.new_hash, i + 1); + t_reftable_set_hash(log.value.update.old_hash, i, + GIT_SHA1_FORMAT_ID); + t_reftable_set_hash(log.value.update.new_hash, i + 1, + GIT_SHA1_FORMAT_ID); err = reftable_writer_add_log(w, &log); check(!err); @@ -297,8 +254,7 @@ static void t_log_zlib_corruption(void) struct reftable_reader *reader; struct reftable_block_source source = { 0 }; struct strbuf buf = STRBUF_INIT; - struct reftable_writer *w = - reftable_new_writer(&strbuf_add_void, &noop_flush, &buf, &opts); + struct reftable_writer *w = t_reftable_strbuf_writer(&buf, &opts); const struct reftable_stats *stats = NULL; char message[100] = { 0 }; int err, i, n; @@ -528,15 +484,12 @@ static void t_table_refs_for(int indexed) int err; struct reftable_reader *reader; struct reftable_block_source source = { 0 }; - struct strbuf buf = STRBUF_INIT; - struct reftable_writer *w = - reftable_new_writer(&strbuf_add_void, &noop_flush, &buf, &opts); - + struct reftable_writer *w = t_reftable_strbuf_writer(&buf, &opts); struct reftable_iterator it = { 0 }; int j; - set_test_hash(want_hash, 4); + t_reftable_set_hash(want_hash, 4, GIT_SHA1_FORMAT_ID); for (i = 0; i < N; i++) { uint8_t hash[GIT_SHA1_RAWSZ]; @@ -552,8 +505,10 @@ static void t_table_refs_for(int indexed) ref.refname = name; ref.value_type = REFTABLE_REF_VAL2; - set_test_hash(ref.value.val2.value, i / 4); - set_test_hash(ref.value.val2.target_value, 3 + i / 4); + t_reftable_set_hash(ref.value.val2.value, i / 4, + GIT_SHA1_FORMAT_ID); + t_reftable_set_hash(ref.value.val2.target_value, 3 + i / 4, + GIT_SHA1_FORMAT_ID); /* 80 bytes / entry, so 3 entries per block. Yields 17 */ @@ -618,8 +573,7 @@ static void t_write_empty_table(void) { struct reftable_write_options opts = { 0 }; struct strbuf buf = STRBUF_INIT; - struct reftable_writer *w = - reftable_new_writer(&strbuf_add_void, &noop_flush, &buf, &opts); + struct reftable_writer *w = t_reftable_strbuf_writer(&buf, &opts); struct reftable_block_source source = { 0 }; struct reftable_reader *rd = NULL; struct reftable_ref_record rec = { 0 }; @@ -657,8 +611,7 @@ static void t_write_object_id_min_length(void) .block_size = 75, }; struct strbuf buf = STRBUF_INIT; - struct reftable_writer *w = - reftable_new_writer(&strbuf_add_void, &noop_flush, &buf, &opts); + struct reftable_writer *w = t_reftable_strbuf_writer(&buf, &opts); struct reftable_ref_record ref = { .update_index = 1, .value_type = REFTABLE_REF_VAL1, @@ -692,8 +645,7 @@ static void t_write_object_id_length(void) .block_size = 75, }; struct strbuf buf = STRBUF_INIT; - struct reftable_writer *w = - reftable_new_writer(&strbuf_add_void, &noop_flush, &buf, &opts); + struct reftable_writer *w = t_reftable_strbuf_writer(&buf, &opts); struct reftable_ref_record ref = { .update_index = 1, .value_type = REFTABLE_REF_VAL1, @@ -726,8 +678,7 @@ static void t_write_empty_key(void) { struct reftable_write_options opts = { 0 }; struct strbuf buf = STRBUF_INIT; - struct reftable_writer *w = - reftable_new_writer(&strbuf_add_void, &noop_flush, &buf, &opts); + struct reftable_writer *w = t_reftable_strbuf_writer(&buf, &opts); struct reftable_ref_record ref = { .refname = (char *) "", .update_index = 1, @@ -749,8 +700,7 @@ static void t_write_key_order(void) { struct reftable_write_options opts = { 0 }; struct strbuf buf = STRBUF_INIT; - struct reftable_writer *w = - reftable_new_writer(&strbuf_add_void, &noop_flush, &buf, &opts); + struct reftable_writer *w = t_reftable_strbuf_writer(&buf, &opts); struct reftable_ref_record refs[2] = { { .refname = (char *) "b", @@ -798,7 +748,7 @@ static void t_write_multiple_indices(void) struct reftable_reader *reader; int err, i; - writer = reftable_new_writer(&strbuf_add_void, &noop_flush, &writer_buf, &opts); + writer = t_reftable_strbuf_writer(&writer_buf, &opts); reftable_writer_set_limits(writer, 1, 1); for (i = 0; i < 100; i++) { struct reftable_ref_record ref = { @@ -876,7 +826,7 @@ static void t_write_multi_level_index(void) struct reftable_reader *reader; int err; - writer = reftable_new_writer(&strbuf_add_void, &noop_flush, &writer_buf, &opts); + writer = t_reftable_strbuf_writer(&writer_buf, &opts); reftable_writer_set_limits(writer, 1, 1); for (size_t i = 0; i < 200; i++) { struct reftable_ref_record ref = { diff --git a/t/unit-tests/t-reftable-stack.c b/t/unit-tests/t-reftable-stack.c index a37cc698d8..31d563d992 100644 --- a/t/unit-tests/t-reftable-stack.c +++ b/t/unit-tests/t-reftable-stack.c @@ -7,17 +7,13 @@ https://developers.google.com/open-source/licenses/bsd */ #include "test-lib.h" +#include "lib-reftable.h" #include "reftable/merged.h" #include "reftable/reader.h" #include "reftable/reftable-error.h" #include "reftable/stack.h" #include <dirent.h> -static void set_test_hash(uint8_t *p, int i) -{ - memset(p, (uint8_t)i, hash_size(GIT_SHA1_FORMAT_ID)); -} - static void clear_dir(const char *dirname) { struct strbuf path = STRBUF_INIT; @@ -125,7 +121,7 @@ static void write_n_ref_tables(struct reftable_stack *st, strbuf_reset(&buf); strbuf_addf(&buf, "refs/heads/branch-%04"PRIuMAX, (uintmax_t)i); ref.refname = buf.buf; - set_test_hash(ref.value.val1, i); + t_reftable_set_hash(ref.value.val1, i, GIT_SHA1_FORMAT_ID); err = reftable_stack_add(st, &write_test_ref, &ref); check(!err); @@ -532,13 +528,13 @@ static void t_reftable_stack_add(void) refs[i].refname = xstrdup(buf); refs[i].update_index = i + 1; refs[i].value_type = REFTABLE_REF_VAL1; - set_test_hash(refs[i].value.val1, i); + t_reftable_set_hash(refs[i].value.val1, i, GIT_SHA1_FORMAT_ID); logs[i].refname = xstrdup(buf); logs[i].update_index = N + i + 1; logs[i].value_type = REFTABLE_LOG_UPDATE; logs[i].value.update.email = xstrdup("identity@invalid"); - set_test_hash(logs[i].value.update.new_hash, i); + t_reftable_set_hash(logs[i].value.update.new_hash, i, GIT_SHA1_FORMAT_ID); } for (i = 0; i < N; i++) { @@ -624,14 +620,14 @@ static void t_reftable_stack_iterator(void) refs[i].refname = xstrfmt("branch%02"PRIuMAX, (uintmax_t)i); refs[i].update_index = i + 1; refs[i].value_type = REFTABLE_REF_VAL1; - set_test_hash(refs[i].value.val1, i); + t_reftable_set_hash(refs[i].value.val1, i, GIT_SHA1_FORMAT_ID); logs[i].refname = xstrfmt("branch%02"PRIuMAX, (uintmax_t)i); logs[i].update_index = i + 1; logs[i].value_type = REFTABLE_LOG_UPDATE; logs[i].value.update.email = xstrdup("johndoe@invalid"); logs[i].value.update.message = xstrdup("commit\n"); - set_test_hash(logs[i].value.update.new_hash, i); + t_reftable_set_hash(logs[i].value.update.new_hash, i, GIT_SHA1_FORMAT_ID); } for (i = 0; i < N; i++) { @@ -766,7 +762,8 @@ static void t_reftable_stack_tombstone(void) refs[i].update_index = i + 1; if (i % 2 == 0) { refs[i].value_type = REFTABLE_REF_VAL1; - set_test_hash(refs[i].value.val1, i); + t_reftable_set_hash(refs[i].value.val1, i, + GIT_SHA1_FORMAT_ID); } logs[i].refname = xstrdup(buf); @@ -774,7 +771,8 @@ static void t_reftable_stack_tombstone(void) logs[i].update_index = 42; if (i % 2 == 0) { logs[i].value_type = REFTABLE_LOG_UPDATE; - set_test_hash(logs[i].value.update.new_hash, i); + t_reftable_set_hash(logs[i].value.update.new_hash, i, + GIT_SHA1_FORMAT_ID); logs[i].value.update.email = xstrdup("identity@invalid"); } @@ -906,7 +904,8 @@ static void t_reflog_expire(void) logs[i].value_type = REFTABLE_LOG_UPDATE; logs[i].value.update.time = i; logs[i].value.update.email = xstrdup("identity@invalid"); - set_test_hash(logs[i].value.update.new_hash, i); + t_reftable_set_hash(logs[i].value.update.new_hash, i, + GIT_SHA1_FORMAT_ID); } for (i = 1; i <= N; i++) { diff --git a/tmp-objdir.c b/tmp-objdir.c index a8e4553f27..c2fb9f9193 100644 --- a/tmp-objdir.c +++ b/tmp-objdir.c @@ -13,6 +13,7 @@ #include "strvec.h" #include "quote.h" #include "object-store-ll.h" +#include "repository.h" struct tmp_objdir { struct strbuf path; @@ -132,7 +133,8 @@ struct tmp_objdir *tmp_objdir_create(const char *prefix) * can recognize any stale objdirs left behind by a crash and delete * them. */ - strbuf_addf(&t->path, "%s/tmp_objdir-%s-XXXXXX", get_object_directory(), prefix); + strbuf_addf(&t->path, "%s/tmp_objdir-%s-XXXXXX", + repo_get_object_directory(the_repository), prefix); if (!mkdtemp(t->path.buf)) { /* free, not destroy, as we never touched the filesystem */ @@ -152,7 +154,7 @@ struct tmp_objdir *tmp_objdir_create(const char *prefix) } env_append(&t->env, ALTERNATE_DB_ENVIRONMENT, - absolute_path(get_object_directory())); + absolute_path(repo_get_object_directory(the_repository))); env_replace(&t->env, DB_ENVIRONMENT, absolute_path(t->path.buf)); env_replace(&t->env, GIT_QUARANTINE_ENVIRONMENT, absolute_path(t->path.buf)); @@ -267,7 +269,7 @@ int tmp_objdir_migrate(struct tmp_objdir *t) } strbuf_addbuf(&src, &t->path); - strbuf_addstr(&dst, get_object_directory()); + strbuf_addstr(&dst, repo_get_object_directory(the_repository)); ret = migrate_paths(&src, &dst); @@ -21,9 +21,11 @@ * along with this program; if not, see <https://www.gnu.org/licenses/>. */ +#define USE_THE_REPOSITORY_VARIABLE + #include "git-compat-util.h" #include "abspath.h" -#include "environment.h" +#include "repository.h" #include "quote.h" #include "setup.h" #include "trace.h" @@ -305,14 +307,14 @@ void trace_repo_setup(void) cwd = xgetcwd(); - if (!(git_work_tree = get_git_work_tree())) + if (!(git_work_tree = repo_get_work_tree(the_repository))) git_work_tree = "(null)"; if (!startup_info->prefix) prefix = "(null)"; - trace_printf_key(&trace_setup_key, "setup: git_dir: %s\n", quote_crnl(get_git_dir())); - trace_printf_key(&trace_setup_key, "setup: git_common_dir: %s\n", quote_crnl(get_git_common_dir())); + trace_printf_key(&trace_setup_key, "setup: git_dir: %s\n", quote_crnl(repo_get_git_dir(the_repository))); + trace_printf_key(&trace_setup_key, "setup: git_common_dir: %s\n", quote_crnl(repo_get_common_dir(the_repository))); trace_printf_key(&trace_setup_key, "setup: worktree: %s\n", quote_crnl(git_work_tree)); trace_printf_key(&trace_setup_key, "setup: cwd: %s\n", quote_crnl(cwd)); trace_printf_key(&trace_setup_key, "setup: prefix: %s\n", quote_crnl(prefix)); @@ -554,6 +554,7 @@ enum trace2_counter_id { TRACE2_COUNTER_ID_TEST2, /* emits summary and thread events */ TRACE2_COUNTER_ID_PACKED_REFS_JUMPS, /* counts number of jumps */ + TRACE2_COUNTER_ID_REFTABLE_RESEEKS, /* counts number of re-seeks */ /* counts number of fsyncs */ TRACE2_COUNTER_ID_FSYNC_WRITEOUT_ONLY, diff --git a/trace2/tr2_cfg.c b/trace2/tr2_cfg.c index d96d908bb9..22a99a0682 100644 --- a/trace2/tr2_cfg.c +++ b/trace2/tr2_cfg.c @@ -1,3 +1,5 @@ +#define USE_THE_REPOSITORY_VARIABLE + #include "git-compat-util.h" #include "config.h" #include "strbuf.h" @@ -124,7 +126,7 @@ void tr2_cfg_list_config_fl(const char *file, int line) struct tr2_cfg_data data = { file, line }; if (tr2_cfg_load_patterns() > 0) - read_early_config(tr2_cfg_cb, &data); + read_early_config(the_repository, tr2_cfg_cb, &data); } void tr2_list_env_vars_fl(const char *file, int line) diff --git a/trace2/tr2_ctr.c b/trace2/tr2_ctr.c index d3a33715c1..036b643578 100644 --- a/trace2/tr2_ctr.c +++ b/trace2/tr2_ctr.c @@ -31,6 +31,11 @@ static struct tr2_counter_metadata tr2_counter_metadata[TRACE2_NUMBER_OF_COUNTER .name = "jumps_made", .want_per_thread_events = 0, }, + [TRACE2_COUNTER_ID_REFTABLE_RESEEKS] = { + .category = "reftable", + .name = "reseeks_made", + .want_per_thread_events = 0, + }, [TRACE2_COUNTER_ID_FSYNC_WRITEOUT_ONLY] = { .category = "fsync", .name = "writeout-only", diff --git a/transport-helper.c b/transport-helper.c index 09b3560ffd..c688967b8c 100644 --- a/transport-helper.c +++ b/transport-helper.c @@ -89,11 +89,18 @@ static int recvline(struct helper_data *helper, struct strbuf *buffer) return recvline_fh(helper->out, buffer); } -static void write_constant(int fd, const char *str) +static int write_constant_gently(int fd, const char *str) { if (debug) fprintf(stderr, "Debug: Remote helper: -> %s", str); if (write_in_full(fd, str, strlen(str)) < 0) + return -1; + return 0; +} + +static void write_constant(int fd, const char *str) +{ + if (write_constant_gently(fd, str) < 0) die_errno(_("full write to remote helper failed")); } @@ -143,7 +150,7 @@ static struct child_process *get_helper(struct transport *transport) if (have_git_dir()) strvec_pushf(&helper->env, "%s=%s", - GIT_DIR_ENVIRONMENT, get_git_dir()); + GIT_DIR_ENVIRONMENT, repo_get_git_dir(the_repository)); helper->trace2_child_class = helper->args.v[0]; /* "remote-<name>" */ @@ -168,13 +175,16 @@ static struct child_process *get_helper(struct transport *transport) die_errno(_("can't dup helper output fd")); data->out = xfdopen(duped, "r"); - write_constant(helper->in, "capabilities\n"); + sigchain_push(SIGPIPE, SIG_IGN); + if (write_constant_gently(helper->in, "capabilities\n") < 0) + die("remote helper '%s' aborted session", data->name); + sigchain_pop(SIGPIPE); while (1) { const char *capname, *arg; int mandatory = 0; if (recvline(data, &buf)) - exit(128); + die("remote helper '%s' aborted session", data->name); if (!*buf.buf) break; diff --git a/tree-diff.c b/tree-diff.c index 9252481df3..5eab8af631 100644 --- a/tree-diff.c +++ b/tree-diff.c @@ -1,6 +1,9 @@ /* * Helper functions for tree diff generation */ + +#define USE_THE_REPOSITORY_VARIABLE + #include "git-compat-util.h" #include "diff.h" #include "diffcore.h" diff --git a/unicode-width.h b/unicode-width.h index be5bf8c4f2..3ffee123a0 100644 --- a/unicode-width.h +++ b/unicode-width.h @@ -27,7 +27,7 @@ static const struct interval zero_width[] = { { 0x0829, 0x082D }, { 0x0859, 0x085B }, { 0x0890, 0x0891 }, -{ 0x0898, 0x089F }, +{ 0x0897, 0x089F }, { 0x08CA, 0x0902 }, { 0x093A, 0x093A }, { 0x093C, 0x093C }, @@ -227,8 +227,9 @@ static const struct interval zero_width[] = { { 0x10A3F, 0x10A3F }, { 0x10AE5, 0x10AE6 }, { 0x10D24, 0x10D27 }, +{ 0x10D69, 0x10D6D }, { 0x10EAB, 0x10EAC }, -{ 0x10EFD, 0x10EFF }, +{ 0x10EFC, 0x10EFF }, { 0x10F46, 0x10F50 }, { 0x10F82, 0x10F85 }, { 0x11001, 0x11001 }, @@ -261,6 +262,11 @@ static const struct interval zero_width[] = { { 0x11340, 0x11340 }, { 0x11366, 0x1136C }, { 0x11370, 0x11374 }, +{ 0x113BB, 0x113C0 }, +{ 0x113CE, 0x113CE }, +{ 0x113D0, 0x113D0 }, +{ 0x113D2, 0x113D2 }, +{ 0x113E1, 0x113E2 }, { 0x11438, 0x1143F }, { 0x11442, 0x11444 }, { 0x11446, 0x11446 }, @@ -280,7 +286,8 @@ static const struct interval zero_width[] = { { 0x116AD, 0x116AD }, { 0x116B0, 0x116B5 }, { 0x116B7, 0x116B7 }, -{ 0x1171D, 0x1171F }, +{ 0x1171D, 0x1171D }, +{ 0x1171F, 0x1171F }, { 0x11722, 0x11725 }, { 0x11727, 0x1172B }, { 0x1182F, 0x11837 }, @@ -319,8 +326,11 @@ static const struct interval zero_width[] = { { 0x11F36, 0x11F3A }, { 0x11F40, 0x11F40 }, { 0x11F42, 0x11F42 }, +{ 0x11F5A, 0x11F5A }, { 0x13430, 0x13440 }, { 0x13447, 0x13455 }, +{ 0x1611E, 0x16129 }, +{ 0x1612D, 0x1612F }, { 0x16AF0, 0x16AF4 }, { 0x16B30, 0x16B36 }, { 0x16F4F, 0x16F4F }, @@ -351,6 +361,7 @@ static const struct interval zero_width[] = { { 0x1E2AE, 0x1E2AE }, { 0x1E2EC, 0x1E2EF }, { 0x1E4EC, 0x1E4EF }, +{ 0x1E5EE, 0x1E5EF }, { 0x1E8D0, 0x1E8D6 }, { 0x1E944, 0x1E94A }, { 0xE0001, 0xE0001 }, @@ -366,8 +377,10 @@ static const struct interval double_width[] = { { 0x23F3, 0x23F3 }, { 0x25FD, 0x25FE }, { 0x2614, 0x2615 }, +{ 0x2630, 0x2637 }, { 0x2648, 0x2653 }, { 0x267F, 0x267F }, +{ 0x268A, 0x268F }, { 0x2693, 0x2693 }, { 0x26A1, 0x26A1 }, { 0x26AA, 0x26AB }, @@ -401,11 +414,10 @@ static const struct interval double_width[] = { { 0x3099, 0x30FF }, { 0x3105, 0x312F }, { 0x3131, 0x318E }, -{ 0x3190, 0x31E3 }, +{ 0x3190, 0x31E5 }, { 0x31EF, 0x321E }, { 0x3220, 0x3247 }, -{ 0x3250, 0x4DBF }, -{ 0x4E00, 0xA48C }, +{ 0x3250, 0xA48C }, { 0xA490, 0xA4C6 }, { 0xA960, 0xA97C }, { 0xAC00, 0xD7A3 }, @@ -420,7 +432,7 @@ static const struct interval double_width[] = { { 0x16FF0, 0x16FF1 }, { 0x17000, 0x187F7 }, { 0x18800, 0x18CD5 }, -{ 0x18D00, 0x18D08 }, +{ 0x18CFF, 0x18D08 }, { 0x1AFF0, 0x1AFF3 }, { 0x1AFF5, 0x1AFFB }, { 0x1AFFD, 0x1AFFE }, @@ -430,6 +442,8 @@ static const struct interval double_width[] = { { 0x1B155, 0x1B155 }, { 0x1B164, 0x1B167 }, { 0x1B170, 0x1B2FB }, +{ 0x1D300, 0x1D356 }, +{ 0x1D360, 0x1D376 }, { 0x1F004, 0x1F004 }, { 0x1F0CF, 0x1F0CF }, { 0x1F18E, 0x1F18E }, @@ -470,11 +484,10 @@ static const struct interval double_width[] = { { 0x1F93C, 0x1F945 }, { 0x1F947, 0x1F9FF }, { 0x1FA70, 0x1FA7C }, -{ 0x1FA80, 0x1FA88 }, -{ 0x1FA90, 0x1FABD }, -{ 0x1FABF, 0x1FAC5 }, -{ 0x1FACE, 0x1FADB }, -{ 0x1FAE0, 0x1FAE8 }, +{ 0x1FA80, 0x1FA89 }, +{ 0x1FA8F, 0x1FAC6 }, +{ 0x1FACE, 0x1FADC }, +{ 0x1FADF, 0x1FAE9 }, { 0x1FAF0, 0x1FAF8 }, { 0x20000, 0x2FFFD }, { 0x30000, 0x3FFFD } diff --git a/upload-pack.c b/upload-pack.c index f03ba3e98b..6d6e0f9f98 100644 --- a/upload-pack.c +++ b/upload-pack.c @@ -709,10 +709,13 @@ static int get_reachable_list(struct upload_pack_data *data, struct object *o; char namebuf[GIT_MAX_HEXSZ + 2]; /* ^ + hash + LF */ const unsigned hexsz = the_hash_algo->hexsz; + int ret; if (do_reachable_revlist(&cmd, &data->shallows, reachable, - data->allow_uor) < 0) - return -1; + data->allow_uor) < 0) { + ret = -1; + goto out; + } while ((i = read_in_full(cmd.out, namebuf, hexsz + 1)) == hexsz + 1) { struct object_id oid; @@ -736,10 +739,16 @@ static int get_reachable_list(struct upload_pack_data *data, } close(cmd.out); - if (finish_command(&cmd)) - return -1; + if (finish_command(&cmd)) { + ret = -1; + goto out; + } - return 0; + ret = 0; + +out: + child_process_clear(&cmd); + return ret; } static int has_unreachable(struct object_array *src, enum allow_uor allow_uor) @@ -749,7 +758,7 @@ static int has_unreachable(struct object_array *src, enum allow_uor allow_uor) int i; if (do_reachable_revlist(&cmd, src, NULL, allow_uor) < 0) - return 1; + goto error; /* * The commits out of the rev-list are not ancestors of @@ -775,6 +784,7 @@ static int has_unreachable(struct object_array *src, enum allow_uor allow_uor) error: if (cmd.out >= 0) close(cmd.out); + child_process_clear(&cmd); return 1; } @@ -1802,7 +1812,7 @@ int upload_pack_v2(struct repository *r, struct packet_reader *request) } else { /* * Request had 'want's but no 'have's so we can - * immedietly go to construct and send a pack. + * immediately go to construct and send a pack. */ state = FETCH_SEND_PACK; } diff --git a/userdiff.c b/userdiff.c index 989629149f..d43d8360d1 100644 --- a/userdiff.c +++ b/userdiff.c @@ -1,3 +1,5 @@ +#define USE_THE_REPOSITORY_VARIABLE + #include "git-compat-util.h" #include "config.h" #include "userdiff.h" diff --git a/worktree.c b/worktree.c index 30a947426e..0f032ccedf 100644 --- a/worktree.c +++ b/worktree.c @@ -57,7 +57,7 @@ static void add_head_info(struct worktree *wt) static int is_current_worktree(struct worktree *wt) { - char *git_dir = absolute_pathdup(get_git_dir()); + char *git_dir = absolute_pathdup(repo_get_git_dir(the_repository)); const char *wt_git_dir = get_worktree_git_dir(wt); int is_current = !fspathcmp(git_dir, absolute_path(wt_git_dir)); free(git_dir); @@ -72,7 +72,7 @@ static struct worktree *get_main_worktree(int skip_reading_head) struct worktree *worktree = NULL; struct strbuf worktree_path = STRBUF_INIT; - strbuf_add_real_path(&worktree_path, get_git_common_dir()); + strbuf_add_real_path(&worktree_path, repo_get_common_dir(the_repository)); strbuf_strip_suffix(&worktree_path, "/.git"); CALLOC_ARRAY(worktree, 1); @@ -143,7 +143,7 @@ static struct worktree **get_worktrees_internal(int skip_reading_head) list[counter++] = get_main_worktree(skip_reading_head); - strbuf_addf(&path, "%s/worktrees", get_git_common_dir()); + strbuf_addf(&path, "%s/worktrees", repo_get_common_dir(the_repository)); dir = opendir(path.buf); strbuf_release(&path); if (dir) { @@ -171,9 +171,9 @@ struct worktree **get_worktrees(void) const char *get_worktree_git_dir(const struct worktree *wt) { if (!wt) - return get_git_dir(); + return repo_get_git_dir(the_repository); else if (!wt->id) - return get_git_common_dir(); + return repo_get_common_dir(the_repository); else return git_common_path("worktrees/%s", wt->id); } @@ -626,7 +626,7 @@ static int is_main_worktree_path(const char *path) strbuf_add_real_path(&target, path); strbuf_strip_suffix(&target, "/.git"); - strbuf_add_real_path(&maindir, get_git_common_dir()); + strbuf_add_real_path(&maindir, repo_get_common_dir(the_repository)); strbuf_strip_suffix(&maindir, "/.git"); cmp = fspathcmp(maindir.buf, target.buf); diff --git a/wt-status.c b/wt-status.c index 3e16491d0a..6a6397ca8f 100644 --- a/wt-status.c +++ b/wt-status.c @@ -16,6 +16,7 @@ #include "revision.h" #include "diffcore.h" #include "quote.h" +#include "repository.h" #include "run-command.h" #include "strvec.h" #include "remote.h" @@ -152,7 +153,7 @@ void wt_status_prepare(struct repository *r, struct wt_status *s) "HEAD", 0, NULL, NULL); s->reference = "HEAD"; s->fp = stdout; - s->index_file = get_index_file(); + s->index_file = repo_get_index_file(the_repository); s->change.strdup_strings = 1; s->untracked.strdup_strings = 1; s->ignored.strdup_strings = 1; |
