aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/main.yml16
-rw-r--r--.gitlab-ci.yml51
-rw-r--r--Documentation/RelNotes/2.48.0.txt30
-rw-r--r--Documentation/SubmittingPatches6
-rw-r--r--Documentation/git-worktree.txt2
-rw-r--r--Makefile1
-rw-r--r--builtin/add.c3
-rw-r--r--builtin/annotate.c5
-rw-r--r--builtin/archive.c5
-rw-r--r--builtin/shortlog.c12
-rw-r--r--builtin/submodule--helper.c9
-rw-r--r--builtin/worktree.c16
-rw-r--r--cache-tree.c102
-rw-r--r--cache-tree.h2
-rwxr-xr-xci/install-sdk.ps112
-rwxr-xr-xci/lib.sh18
-rw-r--r--compat/compiler.h4
-rw-r--r--compat/fsmonitor/fsm-listen-win32.c4
-rw-r--r--compat/mingw.c25
-rw-r--r--compat/regex/regexec.c2
-rw-r--r--compat/simple-ipc/ipc-unix-socket.c2
-rw-r--r--compat/vcbuild/include/unistd.h4
-rw-r--r--contrib/completion/git-completion.bash4
-rwxr-xr-xcontrib/subtree/git-subtree.sh2
-rwxr-xr-xcontrib/subtree/t/t7900-subtree.sh2
-rw-r--r--git.c7
-rw-r--r--read-cache.c5
-rw-r--r--ref-filter.c29
-rw-r--r--reftable/basics.c76
-rw-r--r--reftable/basics.h61
-rw-r--r--reftable/block.c61
-rw-r--r--reftable/block.h14
-rw-r--r--reftable/blocksource.c30
-rw-r--r--reftable/blocksource.h5
-rw-r--r--reftable/iter.c9
-rw-r--r--reftable/iter.h8
-rw-r--r--reftable/reader.c27
-rw-r--r--reftable/record.c114
-rw-r--r--reftable/record.h21
-rw-r--r--reftable/stack.c221
-rw-r--r--reftable/system.h1
-rw-r--r--reftable/writer.c102
-rw-r--r--reftable/writer.h2
-rw-r--r--setup.c2
-rw-r--r--t/README5
-rw-r--r--t/helper/test-rot13-filter.c2
-rw-r--r--t/lib-bundle.sh2
-rw-r--r--t/lib-rebase.sh2
-rw-r--r--t/lib-sudo.sh2
-rwxr-xr-xt/lib-unicode-nfc-nfd.sh2
-rwxr-xr-xt/perf/p7527-builtin-fsmonitor.sh2
-rw-r--r--t/perf/perf-lib.sh4
-rwxr-xr-xt/t0000-basic.sh4
-rwxr-xr-xt/t0021-conversion.sh4
-rw-r--r--t/t0212/parse_events.perl2
-rwxr-xr-xt/t0600-reffiles-backend.sh2
-rwxr-xr-xt/t1016-compatObjectFormat.sh2
-rwxr-xr-xt/t1092-sparse-checkout-compatibility.sh6
-rwxr-xr-xt/t1400-update-ref.sh4
-rwxr-xr-xt/t1506-rev-parse-diagnosis.sh2
-rwxr-xr-xt/t2082-parallel-checkout-attributes.sh2
-rwxr-xr-xt/t2401-worktree-prune.sh19
-rwxr-xr-xt/t2406-worktree-repair.sh19
-rwxr-xr-xt/t2408-worktree-relative.sh39
-rwxr-xr-xt/t4058-diff-duplicates.sh19
-rwxr-xr-xt/t4201-shortlog.sh4
-rwxr-xr-xt/t4205-log-pretty-formats.sh2
-rwxr-xr-xt/t5572-pull-submodule.sh20
-rwxr-xr-xt/t6050-replace.sh133
-rwxr-xr-xt/t7300-clean.sh2
-rw-r--r--t/unit-tests/lib-reftable.c4
-rw-r--r--t/unit-tests/lib-reftable.h7
-rw-r--r--t/unit-tests/t-reftable-basics.c18
-rw-r--r--t/unit-tests/t-reftable-block.c53
-rw-r--r--t/unit-tests/t-reftable-merged.c34
-rw-r--r--t/unit-tests/t-reftable-reader.c12
-rw-r--r--t/unit-tests/t-reftable-readwrite.c134
-rw-r--r--t/unit-tests/t-reftable-record.c74
-rw-r--r--t/unit-tests/t-reftable-stack.c96
-rw-r--r--unpack-trees.c12
-rw-r--r--worktree.c269
-rw-r--r--worktree.h10
82 files changed, 1476 insertions, 687 deletions
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 916a64b673..9301a1edd6 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -113,13 +113,15 @@ jobs:
cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }}
steps:
- uses: actions/checkout@v4
- - uses: git-for-windows/setup-git-for-windows-sdk@v1
+ - name: setup SDK
+ shell: powershell
+ run: ci/install-sdk.ps1
- name: build
- shell: bash
+ shell: powershell
env:
HOME: ${{runner.workspace}}
NO_PERL: 1
- run: . /etc/profile && ci/make-test-artifacts.sh artifacts
+ run: git-sdk/usr/bin/bash.exe -l -c 'ci/make-test-artifacts.sh artifacts'
- name: zip up tracked files
run: git archive -o artifacts/tracked.tar.gz HEAD
- name: upload tracked files and build artifacts
@@ -147,10 +149,12 @@ jobs:
- name: extract tracked files and build artifacts
shell: bash
run: tar xf artifacts.tar.gz && tar xf tracked.tar.gz
- - uses: git-for-windows/setup-git-for-windows-sdk@v1
+ - name: setup SDK
+ shell: powershell
+ run: ci/install-sdk.ps1
- name: test
- shell: bash
- run: . /etc/profile && ci/run-test-slice.sh ${{matrix.nr}} 10
+ shell: powershell
+ run: git-sdk/usr/bin/bash.exe -l -c 'ci/run-test-slice.sh ${{matrix.nr}} 10'
- name: print test failures
if: failure() && env.FAILED_TEST_ARTIFACTS != ''
shell: bash
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 4abfbc3e20..526ecfe030 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,6 +1,11 @@
default:
timeout: 2h
+stages:
+ - build
+ - test
+ - analyze
+
workflow:
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
@@ -9,6 +14,8 @@ workflow:
test:linux:
image: $image
+ stage: test
+ needs: [ ]
tags:
- saas-linux-medium-amd64
variables:
@@ -67,6 +74,8 @@ test:linux:
test:osx:
image: $image
+ stage: test
+ needs: [ ]
tags:
- saas-macos-medium-m1
variables:
@@ -100,8 +109,42 @@ test:osx:
- t/failed-test-artifacts
when: on_failure
+build:mingw64:
+ stage: build
+ tags:
+ - saas-windows-medium-amd64
+ variables:
+ NO_PERL: 1
+ before_script:
+ - ./ci/install-sdk.ps1 -directory "git-sdk"
+ script:
+ - git-sdk/usr/bin/bash.exe -l -c 'ci/make-test-artifacts.sh artifacts'
+ artifacts:
+ paths:
+ - artifacts
+ - git-sdk
+
+test:mingw64:
+ stage: test
+ tags:
+ - saas-windows-medium-amd64
+ needs:
+ - job: "build:mingw64"
+ artifacts: true
+ before_script:
+ - git-sdk/usr/bin/bash.exe -l -c 'tar xf artifacts/artifacts.tar.gz'
+ - New-Item -Path .git/info -ItemType Directory
+ - New-Item .git/info/exclude -ItemType File -Value "/git-sdk"
+ script:
+ - git-sdk/usr/bin/bash.exe -l -c "ci/run-test-slice.sh $CI_NODE_INDEX $CI_NODE_TOTAL"
+ after_script:
+ - git-sdk/usr/bin/bash.exe -l -c 'ci/print-test-failures.sh'
+ parallel: 10
+
test:fuzz-smoke-tests:
image: ubuntu:latest
+ stage: test
+ needs: [ ]
variables:
CC: clang
before_script:
@@ -111,6 +154,8 @@ test:fuzz-smoke-tests:
static-analysis:
image: ubuntu:22.04
+ stage: analyze
+ needs: [ ]
variables:
jobname: StaticAnalysis
before_script:
@@ -121,6 +166,8 @@ static-analysis:
check-whitespace:
image: ubuntu:latest
+ stage: analyze
+ needs: [ ]
before_script:
- ./ci/install-dependencies.sh
# Since $CI_MERGE_REQUEST_TARGET_BRANCH_SHA is only defined for merged
@@ -135,6 +182,8 @@ check-whitespace:
check-style:
image: ubuntu:latest
+ stage: analyze
+ needs: [ ]
allow_failure: true
variables:
CC: clang
@@ -153,6 +202,8 @@ check-style:
documentation:
image: ubuntu:latest
+ stage: analyze
+ needs: [ ]
variables:
jobname: Documentation
before_script:
diff --git a/Documentation/RelNotes/2.48.0.txt b/Documentation/RelNotes/2.48.0.txt
index 0fecb8de27..ec05f45fb3 100644
--- a/Documentation/RelNotes/2.48.0.txt
+++ b/Documentation/RelNotes/2.48.0.txt
@@ -25,6 +25,17 @@ Performance, Internal Implementation, Development Support etc.
allocation function given to it may fail to allocate and to deal
with such an error.
+ * An extra worktree attached to a repository points at each other to
+ allow finding the repository from the worktree and vice versa
+ possible. Turn this linkage to relative paths.
+
+ * Enable Windows-based CI in GitLab.
+
+ * Commands that can also work outside Git have learned to take the
+ repository instance "repo" when we know we are in a repository, and
+ NULL when we are not, in a parameter. The uses of the_repository
+ variable in a few of them have been removed using the new calling
+ convention.
Fixes since v2.47
-----------------
@@ -46,6 +57,22 @@ Fixes since v2.47
reference, which has been corrected.
(merge c95547a394 ps/maintenance-start-crash-fix later to maint).
+ * Fail gracefully instead of crashing when attempting to write the
+ contents of a corrupt in-core index as a tree object.
+ (merge ecb5c4318c ps/cache-tree-w-broken-index-entry later to maint).
+
+ * A "git fetch" from the superproject going down to a submodule used
+ a wrong remote when the default remote names are set differently
+ between them.
+ (merge 0c1a9987da db/submodule-fetch-with-remote-name-fix later to maint).
+
+ * Fixes compile time warnings with 64-bit MSVC.
+ (merge 386d372031 sk/msvc-warnings later to maint).
+
+ * Teaches 'shortlog' to explicitly use SHA-1 when operating outside
+ of a repository.
+ (merge b33001645e wm/shortlog-hash later to maint).
+
* Other code cleanup, docfix, build fix, etc.
(merge 66893a14d0 ps/leakfixes-part-8 later to maint).
(merge 1164e270b5 jk/output-prefix-cleanup later to maint).
@@ -58,3 +85,6 @@ Fixes since v2.47
(merge b8139c8f4e kh/checkout-ignore-other-docfix later to maint).
(merge 6dab49b9fb tc/bundle-uri-leakfix later to maint).
(merge f1ed39987b xx/protocol-v2-doc-markup-fix later to maint).
+ (merge 41869f7447 ak/typofixes later to maint).
+ (merge f1eea0b620 ak/typofix later to maint).
+ (merge dcd590a39d bf/t-readme-mention-reftable later to maint).
diff --git a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches
index d8a8caa791..db17bc7fe2 100644
--- a/Documentation/SubmittingPatches
+++ b/Documentation/SubmittingPatches
@@ -412,13 +412,13 @@ Also notice that a real name is used in the `Signed-off-by` trailer. Please
don't hide your real name.
[[commit-trailers]]
-If you like, you can put extra tags at the end:
+If you like, you can put extra trailers at the end:
. `Reported-by:` is used to credit someone who found the bug that
the patch attempts to fix.
. `Acked-by:` says that the person who is more familiar with the area
the patch attempts to modify liked the patch.
-. `Reviewed-by:`, unlike the other tags, can only be offered by the
+. `Reviewed-by:`, unlike the other trailers, can only be offered by the
reviewers themselves when they are completely satisfied with the
patch after a detailed analysis.
. `Tested-by:` is used to indicate that the person applied the patch
@@ -436,7 +436,7 @@ While you can also create your own trailer if the situation warrants it, we
encourage you to instead use one of the common trailers in this project
highlighted above.
-Only capitalize the very first letter of tags, i.e. favor
+Only capitalize the very first letter of the trailer, i.e. favor
"Signed-off-by" over "Signed-Off-By" and "Acked-by:" over "Acked-By".
[[git-tools]]
diff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt
index 2a240f53ba..70437c815f 100644
--- a/Documentation/git-worktree.txt
+++ b/Documentation/git-worktree.txt
@@ -157,7 +157,7 @@ will reestablish the connection. If multiple linked worktrees are moved,
running `repair` from any worktree with each tree's new `<path>` as an
argument, will reestablish the connection to all the specified paths.
+
-If both the main worktree and linked worktrees have been moved manually,
+If both the main worktree and linked worktrees have been moved or copied manually,
then running `repair` in the main worktree and specifying the new `<path>`
of each linked worktree will reestablish all connections in both
directions.
diff --git a/Makefile b/Makefile
index feeed6f932..8d8cc6ab90 100644
--- a/Makefile
+++ b/Makefile
@@ -3909,6 +3909,7 @@ $(UNIT_TEST_DIR)/clar-decls.h: $(patsubst %,$(UNIT_TEST_DIR)/%.c,$(CLAR_TEST_SUI
done >$@
$(UNIT_TEST_DIR)/clar.suite: $(UNIT_TEST_DIR)/clar-decls.h
$(QUIET_GEN)awk -f $(UNIT_TEST_DIR)/clar-generate.awk $< >$(UNIT_TEST_DIR)/clar.suite
+$(UNIT_TEST_DIR)/clar/clar.o: $(UNIT_TEST_DIR)/clar.suite
$(CLAR_TEST_OBJS): $(UNIT_TEST_DIR)/clar-decls.h
$(CLAR_TEST_OBJS): EXTRA_CPPFLAGS = -I$(UNIT_TEST_DIR)
$(CLAR_TEST_PROG): $(UNIT_TEST_DIR)/clar.suite $(CLAR_TEST_OBJS) $(GITLIBS) GIT-LDFLAGS
diff --git a/builtin/add.c b/builtin/add.c
index 773b7224a4..7d35307792 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -385,7 +385,8 @@ int cmd_add(int argc,
char *ps_matched = NULL;
struct lock_file lock_file = LOCK_INIT;
- repo_config(repo, add_config, NULL);
+ if (repo)
+ repo_config(repo, add_config, NULL);
argc = parse_options(argc, argv, prefix, builtin_add_options,
builtin_add_usage, PARSE_OPT_KEEP_ARGV0);
diff --git a/builtin/annotate.c b/builtin/annotate.c
index 03413c7df8..7f754f2309 100644
--- a/builtin/annotate.c
+++ b/builtin/annotate.c
@@ -4,7 +4,6 @@
* Copyright (C) 2006 Ryan Anderson
*/
-#define USE_THE_REPOSITORY_VARIABLE
#include "git-compat-util.h"
#include "builtin.h"
#include "strvec.h"
@@ -12,7 +11,7 @@
int cmd_annotate(int argc,
const char **argv,
const char *prefix,
- struct repository *repo UNUSED)
+ struct repository *repo)
{
struct strvec args = STRVEC_INIT;
const char **args_copy;
@@ -29,7 +28,7 @@ int cmd_annotate(int argc,
CALLOC_ARRAY(args_copy, args.nr + 1);
COPY_ARRAY(args_copy, args.v, args.nr);
- ret = cmd_blame(args.nr, args_copy, prefix, the_repository);
+ ret = cmd_blame(args.nr, args_copy, prefix, repo);
strvec_clear(&args);
free(args_copy);
diff --git a/builtin/archive.c b/builtin/archive.c
index dc926d1a3d..13ea7308c8 100644
--- a/builtin/archive.c
+++ b/builtin/archive.c
@@ -2,7 +2,6 @@
* 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"
@@ -79,7 +78,7 @@ static int run_remote_archiver(int argc, const char **argv,
int cmd_archive(int argc,
const char **argv,
const char *prefix,
- struct repository *repo UNUSED)
+ struct repository *repo)
{
const char *exec = "git-upload-archive";
char *output = NULL;
@@ -110,7 +109,7 @@ int cmd_archive(int argc,
setvbuf(stderr, NULL, _IOLBF, BUFSIZ);
- ret = write_archive(argc, argv, prefix, the_repository, output, 0);
+ ret = write_archive(argc, argv, prefix, repo, output, 0);
out:
free(output);
diff --git a/builtin/shortlog.c b/builtin/shortlog.c
index 3ed5c46078..c86b75d981 100644
--- a/builtin/shortlog.c
+++ b/builtin/shortlog.c
@@ -407,6 +407,18 @@ int cmd_shortlog(int argc,
struct parse_opt_ctx_t ctx;
+ /*
+ * NEEDSWORK: Later on we'll call parse_revision_opt which relies on
+ * the hash algorithm being set but since we are operating outside of a
+ * Git repository we cannot determine one. This is only needed because
+ * parse_revision_opt expects hexsz for --abbrev which is irrelevant
+ * for shortlog outside of a git repository. For now explicitly set
+ * SHA1, but ideally the parsing machinery would be split between
+ * git/nongit so that we do not have to do this.
+ */
+ if (nongit && !the_hash_algo)
+ repo_set_hash_algo(the_repository, GIT_HASH_SHA1);
+
git_config(git_default_config, NULL);
shortlog_init(&log);
repo_init_revisions(the_repository, &rev, prefix);
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index dc89488a7d..b6b5f1ebde 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -2333,7 +2333,14 @@ static int fetch_in_submodule(const char *module_path, int depth, int quiet,
strvec_pushf(&cp.args, "--depth=%d", depth);
if (oid) {
char *hex = oid_to_hex(oid);
- char *remote = get_default_remote();
+ char *remote;
+ int code;
+
+ code = get_default_remote_submodule(module_path, &remote);
+ if (code) {
+ child_process_clear(&cp);
+ return code;
+ }
strvec_pushl(&cp.args, remote, hex, NULL);
free(remote);
diff --git a/builtin/worktree.c b/builtin/worktree.c
index fc31d072a6..dae63dedf4 100644
--- a/builtin/worktree.c
+++ b/builtin/worktree.c
@@ -414,7 +414,8 @@ static int add_worktree(const char *path, const char *refname,
const struct add_opts *opts)
{
struct strbuf sb_git = STRBUF_INIT, sb_repo = STRBUF_INIT;
- struct strbuf sb = STRBUF_INIT, realpath = STRBUF_INIT;
+ struct strbuf sb = STRBUF_INIT, sb_tmp = STRBUF_INIT;
+ struct strbuf sb_path_realpath = STRBUF_INIT, sb_repo_realpath = STRBUF_INIT;
const char *name;
struct strvec child_env = STRVEC_INIT;
unsigned int counter = 0;
@@ -490,11 +491,10 @@ static int add_worktree(const char *path, const char *refname,
strbuf_reset(&sb);
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, repo_get_common_dir(the_repository), 1);
- write_file(sb_git.buf, "gitdir: %s/worktrees/%s",
- realpath.buf, name);
+ strbuf_realpath(&sb_path_realpath, path, 1);
+ strbuf_realpath(&sb_repo_realpath, sb_repo.buf, 1);
+ write_file(sb.buf, "%s/.git", relative_path(sb_path_realpath.buf, sb_repo_realpath.buf, &sb_tmp));
+ write_file(sb_git.buf, "gitdir: %s", relative_path(sb_repo_realpath.buf, sb_path_realpath.buf, &sb_tmp));
strbuf_reset(&sb);
strbuf_addf(&sb, "%s/commondir", sb_repo.buf);
write_file(sb.buf, "../..");
@@ -578,11 +578,13 @@ done:
strvec_clear(&child_env);
strbuf_release(&sb);
+ strbuf_release(&sb_tmp);
strbuf_release(&symref);
strbuf_release(&sb_repo);
+ strbuf_release(&sb_repo_realpath);
strbuf_release(&sb_git);
+ strbuf_release(&sb_path_realpath);
strbuf_release(&sb_name);
- strbuf_release(&realpath);
free_worktree(wt);
return ret;
}
diff --git a/cache-tree.c b/cache-tree.c
index b482167a69..c595e86120 100644
--- a/cache-tree.c
+++ b/cache-tree.c
@@ -1,6 +1,7 @@
#define USE_THE_REPOSITORY_VARIABLE
#include "git-compat-util.h"
+#include "gettext.h"
#include "hex.h"
#include "lockfile.h"
#include "tree.h"
@@ -865,15 +866,15 @@ int cache_tree_matches_traversal(struct cache_tree *root,
return 0;
}
-static void verify_one_sparse(struct index_state *istate,
- struct strbuf *path,
- int pos)
+static int verify_one_sparse(struct index_state *istate,
+ struct strbuf *path,
+ int pos)
{
struct cache_entry *ce = istate->cache[pos];
-
if (!S_ISSPARSEDIR(ce->ce_mode))
- BUG("directory '%s' is present in index, but not sparse",
- path->buf);
+ return error(_("directory '%s' is present in index, but not sparse"),
+ path->buf);
+ return 0;
}
/*
@@ -882,6 +883,7 @@ static void verify_one_sparse(struct index_state *istate,
* 1 - Restart verification - a call to ensure_full_index() freed the cache
* tree that is being verified and verification needs to be restarted from
* the new toplevel cache tree.
+ * -1 - Verification failed.
*/
static int verify_one(struct repository *r,
struct index_state *istate,
@@ -891,18 +893,23 @@ static int verify_one(struct repository *r,
int i, pos, len = path->len;
struct strbuf tree_buf = STRBUF_INIT;
struct object_id new_oid;
+ int ret;
for (i = 0; i < it->subtree_nr; i++) {
strbuf_addf(path, "%s/", it->down[i]->name);
- if (verify_one(r, istate, it->down[i]->cache_tree, path))
- return 1;
+ ret = verify_one(r, istate, it->down[i]->cache_tree, path);
+ if (ret)
+ goto out;
+
strbuf_setlen(path, len);
}
if (it->entry_count < 0 ||
/* no verification on tests (t7003) that replace trees */
- lookup_replace_object(r, &it->oid) != &it->oid)
- return 0;
+ lookup_replace_object(r, &it->oid) != &it->oid) {
+ ret = 0;
+ goto out;
+ }
if (path->len) {
/*
@@ -912,12 +919,14 @@ static int verify_one(struct repository *r,
*/
int is_sparse = istate->sparse_index;
pos = index_name_pos(istate, path->buf, path->len);
- if (is_sparse && !istate->sparse_index)
- return 1;
+ if (is_sparse && !istate->sparse_index) {
+ ret = 1;
+ goto out;
+ }
if (pos >= 0) {
- verify_one_sparse(istate, path, pos);
- return 0;
+ ret = verify_one_sparse(istate, path, pos);
+ goto out;
}
pos = -pos - 1;
@@ -925,6 +934,11 @@ static int verify_one(struct repository *r,
pos = 0;
}
+ if (it->entry_count + pos > istate->cache_nr) {
+ ret = error(_("corrupted cache-tree has entries not present in index"));
+ goto out;
+ }
+
i = 0;
while (i < it->entry_count) {
struct cache_entry *ce = istate->cache[pos + i];
@@ -935,16 +949,23 @@ static int verify_one(struct repository *r,
unsigned mode;
int entlen;
- if (ce->ce_flags & (CE_STAGEMASK | CE_INTENT_TO_ADD | CE_REMOVE))
- BUG("%s with flags 0x%x should not be in cache-tree",
- ce->name, ce->ce_flags);
+ if (ce->ce_flags & (CE_STAGEMASK | CE_INTENT_TO_ADD | CE_REMOVE)) {
+ ret = error(_("%s with flags 0x%x should not be in cache-tree"),
+ ce->name, ce->ce_flags);
+ goto out;
+ }
+
name = ce->name + path->len;
slash = strchr(name, '/');
if (slash) {
entlen = slash - name;
+
sub = find_subtree(it, ce->name + path->len, entlen, 0);
- if (!sub || sub->cache_tree->entry_count < 0)
- BUG("bad subtree '%.*s'", entlen, name);
+ if (!sub || sub->cache_tree->entry_count < 0) {
+ ret = error(_("bad subtree '%.*s'"), entlen, name);
+ goto out;
+ }
+
oid = &sub->cache_tree->oid;
mode = S_IFDIR;
i += sub->cache_tree->entry_count;
@@ -957,27 +978,50 @@ static int verify_one(struct repository *r,
strbuf_addf(&tree_buf, "%o %.*s%c", mode, entlen, name, '\0');
strbuf_add(&tree_buf, oid->hash, r->hash_algo->rawsz);
}
+
hash_object_file(r->hash_algo, tree_buf.buf, tree_buf.len, OBJ_TREE,
&new_oid);
- if (!oideq(&new_oid, &it->oid))
- BUG("cache-tree for path %.*s does not match. "
- "Expected %s got %s", len, path->buf,
- oid_to_hex(&new_oid), oid_to_hex(&it->oid));
+
+ if (!oideq(&new_oid, &it->oid)) {
+ ret = error(_("cache-tree for path %.*s does not match. "
+ "Expected %s got %s"), len, path->buf,
+ oid_to_hex(&new_oid), oid_to_hex(&it->oid));
+ goto out;
+ }
+
+ ret = 0;
+out:
strbuf_setlen(path, len);
strbuf_release(&tree_buf);
- return 0;
+ return ret;
}
-void cache_tree_verify(struct repository *r, struct index_state *istate)
+int cache_tree_verify(struct repository *r, struct index_state *istate)
{
struct strbuf path = STRBUF_INIT;
+ int ret;
- if (!istate->cache_tree)
- return;
- if (verify_one(r, istate, istate->cache_tree, &path)) {
+ if (!istate->cache_tree) {
+ ret = 0;
+ goto out;
+ }
+
+ ret = verify_one(r, istate, istate->cache_tree, &path);
+ if (ret < 0)
+ goto out;
+ if (ret > 0) {
strbuf_reset(&path);
- if (verify_one(r, istate, istate->cache_tree, &path))
+
+ ret = verify_one(r, istate, istate->cache_tree, &path);
+ if (ret < 0)
+ goto out;
+ if (ret > 0)
BUG("ensure_full_index() called twice while verifying cache tree");
}
+
+ ret = 0;
+
+out:
strbuf_release(&path);
+ return ret;
}
diff --git a/cache-tree.h b/cache-tree.h
index faae88be63..b82c4963e7 100644
--- a/cache-tree.h
+++ b/cache-tree.h
@@ -33,7 +33,7 @@ struct cache_tree *cache_tree_read(const char *buffer, unsigned long size);
int cache_tree_fully_valid(struct cache_tree *);
int cache_tree_update(struct index_state *, int);
-void cache_tree_verify(struct repository *, struct index_state *);
+int cache_tree_verify(struct repository *, struct index_state *);
/* bitmasks to write_index_as_tree flags */
#define WRITE_TREE_MISSING_OK 1
diff --git a/ci/install-sdk.ps1 b/ci/install-sdk.ps1
new file mode 100755
index 0000000000..66f24838a4
--- /dev/null
+++ b/ci/install-sdk.ps1
@@ -0,0 +1,12 @@
+param(
+ [string]$directory='git-sdk',
+ [string]$url='https://github.com/git-for-windows/git-sdk-64/releases/download/ci-artifacts/git-sdk-x86_64-minimal.zip'
+)
+
+Invoke-WebRequest "$url" -OutFile git-sdk.zip
+Expand-Archive -LiteralPath git-sdk.zip -DestinationPath "$directory"
+Remove-Item -Path git-sdk.zip
+
+New-Item -Path .git/info -ItemType Directory -Force
+New-Item -Path .git/info/exclude -ItemType File -Force
+Add-Content -Path .git/info/exclude -Value "/$directory"
diff --git a/ci/lib.sh b/ci/lib.sh
index 74b430be23..95f39a26ea 100755
--- a/ci/lib.sh
+++ b/ci/lib.sh
@@ -250,8 +250,13 @@ then
CI_TYPE=gitlab-ci
CI_BRANCH="$CI_COMMIT_REF_NAME"
CI_COMMIT="$CI_COMMIT_SHA"
- case "$CI_JOB_IMAGE" in
- macos-*)
+
+ case "$OS,$CI_JOB_IMAGE" in
+ Windows_NT,*)
+ CI_OS_NAME=windows
+ JOBS=$NUMBER_OF_PROCESSORS
+ ;;
+ *,macos-*)
# GitLab CI has Python installed via multiple package managers,
# most notably via asdf and Homebrew. Ensure that our builds
# pick up the Homebrew one by prepending it to our PATH as the
@@ -259,9 +264,12 @@ then
export PATH="$(brew --prefix)/bin:$PATH"
CI_OS_NAME=osx
+ JOBS=$(nproc)
+ ;;
+ *,alpine:*|*,fedora:*|*,ubuntu:*)
+ CI_OS_NAME=linux
+ JOBS=$(nproc)
;;
- alpine:*|fedora:*|ubuntu:*)
- CI_OS_NAME=linux;;
*)
echo "Could not identify OS image" >&2
env >&2
@@ -272,6 +280,7 @@ then
CI_JOB_ID="$CI_JOB_ID"
CC="${CC_PACKAGE:-${CC:-gcc}}"
DONT_SKIP_TAGS=t
+
handle_failed_tests () {
create_failed_test_artifacts
return 1
@@ -280,7 +289,6 @@ then
cache_dir="$HOME/none"
distro=$(echo "$CI_JOB_IMAGE" | tr : -)
- JOBS=$(nproc)
else
echo "Could not identify CI type" >&2
env >&2
diff --git a/compat/compiler.h b/compat/compiler.h
index e9ad9db84f..e12e426404 100644
--- a/compat/compiler.h
+++ b/compat/compiler.h
@@ -9,7 +9,7 @@
static inline void get_compiler_info(struct strbuf *info)
{
- int len = info->len;
+ size_t len = info->len;
#ifdef __clang__
strbuf_addf(info, "clang: %s\n", __clang_version__);
#elif defined(__GNUC__)
@@ -27,7 +27,7 @@ static inline void get_compiler_info(struct strbuf *info)
static inline void get_libc_info(struct strbuf *info)
{
- int len = info->len;
+ size_t len = info->len;
#ifdef __GLIBC__
strbuf_addf(info, "glibc: %s\n", gnu_get_libc_version());
diff --git a/compat/fsmonitor/fsm-listen-win32.c b/compat/fsmonitor/fsm-listen-win32.c
index 80e092b511..9a6efc9bea 100644
--- a/compat/fsmonitor/fsm-listen-win32.c
+++ b/compat/fsmonitor/fsm-listen-win32.c
@@ -431,9 +431,9 @@ static int recv_rdcw_watch(struct one_watch *watch)
* but I observed ERROR_ACCESS_DENIED (0x05) errors during
* testing.
*
- * Note that we only get notificaiton events for events
+ * Note that we only get notification events for events
* *within* the directory, not *on* the directory itself.
- * (These might be properies of the parent directory, for
+ * (These might be properties of the parent directory, for
* example).
*
* NEEDSWORK: We might try to check for the deleted directory
diff --git a/compat/mingw.c b/compat/mingw.c
index 0e851ecae2..0ff550cef3 100644
--- a/compat/mingw.c
+++ b/compat/mingw.c
@@ -782,7 +782,7 @@ static inline void filetime_to_timespec(const FILETIME *ft, struct timespec *ts)
*/
static int has_valid_directory_prefix(wchar_t *wfilename)
{
- int n = wcslen(wfilename);
+ size_t n = wcslen(wfilename);
while (n > 0) {
wchar_t c = wfilename[--n];
@@ -891,7 +891,7 @@ static int do_lstat(int follow, const char *file_name, struct stat *buf)
*/
static int do_stat_internal(int follow, const char *file_name, struct stat *buf)
{
- int namelen;
+ size_t namelen;
char alt_name[PATH_MAX];
if (!do_lstat(follow, file_name, buf))
@@ -1274,7 +1274,8 @@ static const char *parse_interpreter(const char *cmd)
{
static char buf[100];
char *p, *opt;
- int n, fd;
+ ssize_t n; /* read() can return negative values */
+ int fd;
/* don't even try a .exe */
n = strlen(cmd);
@@ -1339,7 +1340,7 @@ static char *path_lookup(const char *cmd, int exe_only)
{
const char *path;
char *prog = NULL;
- int len = strlen(cmd);
+ size_t len = strlen(cmd);
int isexe = len >= 4 && !strcasecmp(cmd+len-4, ".exe");
if (strpbrk(cmd, "/\\"))
@@ -1956,7 +1957,7 @@ char *mingw_getenv(const char *name)
#define GETENV_MAX_RETAIN 64
static char *values[GETENV_MAX_RETAIN];
static int value_counter;
- int len_key, len_value;
+ size_t len_key, len_value;
wchar_t *w_key;
char *value;
wchar_t w_value[32768];
@@ -1968,7 +1969,8 @@ char *mingw_getenv(const char *name)
/* We cannot use xcalloc() here because that uses getenv() itself */
w_key = calloc(len_key, sizeof(wchar_t));
if (!w_key)
- die("Out of memory, (tried to allocate %u wchar_t's)", len_key);
+ die("Out of memory, (tried to allocate %"PRIuMAX" wchar_t's)",
+ (uintmax_t)len_key);
xutftowcs(w_key, name, len_key);
/* GetEnvironmentVariableW() only sets the last error upon failure */
SetLastError(ERROR_SUCCESS);
@@ -1983,7 +1985,8 @@ char *mingw_getenv(const char *name)
/* We cannot use xcalloc() here because that uses getenv() itself */
value = calloc(len_value, sizeof(char));
if (!value)
- die("Out of memory, (tried to allocate %u bytes)", len_value);
+ die("Out of memory, (tried to allocate %"PRIuMAX" bytes)",
+ (uintmax_t)len_value);
xwcstoutf(value, w_value, len_value);
/*
@@ -2001,7 +2004,7 @@ char *mingw_getenv(const char *name)
int mingw_putenv(const char *namevalue)
{
- int size;
+ size_t size;
wchar_t *wide, *equal;
BOOL result;
@@ -2011,7 +2014,8 @@ int mingw_putenv(const char *namevalue)
size = strlen(namevalue) * 2 + 1;
wide = calloc(size, sizeof(wchar_t));
if (!wide)
- die("Out of memory, (tried to allocate %u wchar_t's)", size);
+ die("Out of memory, (tried to allocate %" PRIuMAX " wchar_t's)",
+ (uintmax_t)size);
xutftowcs(wide, namevalue, size);
equal = wcschr(wide, L'=');
if (!equal)
@@ -3085,7 +3089,8 @@ static void maybe_redirect_std_handles(void)
*/
int wmain(int argc, const wchar_t **wargv)
{
- int i, maxlen, exit_status;
+ int i, exit_status;
+ size_t maxlen;
char *buffer, **save;
const char **argv;
diff --git a/compat/regex/regexec.c b/compat/regex/regexec.c
index e92be5741d..2eeec82f40 100644
--- a/compat/regex/regexec.c
+++ b/compat/regex/regexec.c
@@ -292,7 +292,7 @@ compat_symbol (libc, __compat_regexec, regexec, GLIBC_2_0);
concerned.
If REGS is not NULL, and BUFP->no_sub is not set, the offsets of the match
- and all groups is stroed in REGS. (For the "_2" variants, the offsets are
+ and all groups are stored in REGS. (For the "_2" variants, the offsets are
computed relative to the concatenation, not relative to the individual
strings.)
diff --git a/compat/simple-ipc/ipc-unix-socket.c b/compat/simple-ipc/ipc-unix-socket.c
index 57d919c6b4..7db3b2a897 100644
--- a/compat/simple-ipc/ipc-unix-socket.c
+++ b/compat/simple-ipc/ipc-unix-socket.c
@@ -713,7 +713,7 @@ static int accept_thread__wait_for_connection(
* Block SIGPIPE in this thread for the life of the thread. This
* avoids any stray SIGPIPE signals when closing pipe fds under
* extremely heavy loads (such as when the fifo queue is full and we
- * drop incomming connections).
+ * drop incoming connections).
*/
static void *accept_thread_proc(void *_accept_thread_data)
{
diff --git a/compat/vcbuild/include/unistd.h b/compat/vcbuild/include/unistd.h
index 3a959d124c..a261a925b7 100644
--- a/compat/vcbuild/include/unistd.h
+++ b/compat/vcbuild/include/unistd.h
@@ -14,7 +14,11 @@ typedef _mode_t mode_t;
#ifndef _SSIZE_T_
#define _SSIZE_T_
+#ifdef _WIN64
+typedef __int64 _ssize_t;
+#else
typedef long _ssize_t;
+#endif /* _WIN64 */
#ifndef _OFF_T_
#define _OFF_T_
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index 60a22d619a..3d4dff3185 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -3296,7 +3296,7 @@ __gitcomp_directories ()
# i.e. which are *already* part of their
# sparse-checkout. Thus, normal file and directory
# completion is always useless for "git
- # sparse-checkout add" and is also probelmatic for
+ # sparse-checkout add" and is also problematic for
# "git sparse-checkout set" unless using it to
# strictly narrow the checkout.
COMPREPLY=( "" )
@@ -3698,7 +3698,7 @@ _git_worktree ()
# Here we are not completing an --option, it's either the
# path or a ref.
case "$prev" in
- -b|-B) # Complete refs for branch to be created/reseted.
+ -b|-B) # Complete refs for branch to be created/reset.
__git_complete_refs
;;
-*) # The previous word is an -o|--option without an
diff --git a/contrib/subtree/git-subtree.sh b/contrib/subtree/git-subtree.sh
index 5dab3f506c..15ae86db1b 100755
--- a/contrib/subtree/git-subtree.sh
+++ b/contrib/subtree/git-subtree.sh
@@ -946,7 +946,7 @@ cmd_split () {
rev=$(git rev-parse -q --verify "$1^{commit}") ||
die "fatal: '$1' does not refer to a commit"
else
- die "fatal: you must provide exactly one revision, and optionnally a repository. Got: '$*'"
+ die "fatal: you must provide exactly one revision, and optionally a repository. Got: '$*'"
fi
repository=""
if test "$#" = 2
diff --git a/contrib/subtree/t/t7900-subtree.sh b/contrib/subtree/t/t7900-subtree.sh
index c3bd2a58b9..3c6103f6d2 100755
--- a/contrib/subtree/t/t7900-subtree.sh
+++ b/contrib/subtree/t/t7900-subtree.sh
@@ -47,7 +47,7 @@ last_commit_subject () {
# pre-2.32.0 versions of 'git subtree' would write the hash of the tag
# (sub1 below), instead of the commit (sub1^{commit}) in the
# "git-subtree-split" trailer.
-# We immitate this behaviour below using a replace ref.
+# We imitate this behaviour below using a replace ref.
# This function creates 3 repositories:
# - $1
# - $1-sub (added as subtree "sub" in $1)
diff --git a/git.c b/git.c
index 2a9752c91c..c2c1b8e22c 100644
--- a/git.c
+++ b/git.c
@@ -444,6 +444,7 @@ static int handle_alias(int *argcp, const char ***argv)
static int run_builtin(struct cmd_struct *p, int argc, const char **argv, struct repository *repo)
{
int status, help;
+ int no_repo = 1;
struct stat st;
const char *prefix;
int run_setup = (p->option & (RUN_SETUP | RUN_SETUP_GENTLY));
@@ -455,9 +456,9 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv, struct
if (run_setup & RUN_SETUP) {
prefix = setup_git_directory();
+ no_repo = 0;
} else if (run_setup & RUN_SETUP_GENTLY) {
- int nongit_ok;
- prefix = setup_git_directory_gently(&nongit_ok);
+ prefix = setup_git_directory_gently(&no_repo);
} else {
prefix = NULL;
}
@@ -480,7 +481,7 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv, struct
trace2_cmd_name(p->cmd);
validate_cache_entries(repo->index);
- status = p->fn(argc, argv, prefix, (p->option & RUN_SETUP)? repo : NULL);
+ status = p->fn(argc, argv, prefix, no_repo ? NULL : repo);
validate_cache_entries(repo->index);
if (status)
diff --git a/read-cache.c b/read-cache.c
index 1148a55873..01d0b3ad22 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -3335,8 +3335,9 @@ int write_locked_index(struct index_state *istate, struct lock_file *lock,
int new_shared_index, ret, test_split_index_env;
struct split_index *si = istate->split_index;
- if (git_env_bool("GIT_TEST_CHECK_CACHE_TREE", 0))
- cache_tree_verify(the_repository, istate);
+ if (git_env_bool("GIT_TEST_CHECK_CACHE_TREE", 0) &&
+ cache_tree_verify(the_repository, istate) < 0)
+ return -1;
if ((flags & SKIP_IF_UNCHANGED) && !istate->cache_changed) {
if (flags & COMMIT_LOCK)
diff --git a/ref-filter.c b/ref-filter.c
index dd195007ce..84c6036107 100644
--- a/ref-filter.c
+++ b/ref-filter.c
@@ -3244,21 +3244,40 @@ int filter_refs(struct ref_array *array, struct ref_filter *filter, unsigned int
return ret;
}
+struct ref_sorting {
+ struct ref_sorting *next;
+ int atom; /* index into used_atom array (internal) */
+ enum ref_sorting_order sort_flags;
+};
+
static inline int can_do_iterative_format(struct ref_filter *filter,
struct ref_sorting *sorting,
struct ref_format *format)
{
/*
+ * Reference backends sort patterns lexicographically by refname, so if
+ * the sorting options ask for exactly that we are able to do iterative
+ * formatting.
+ *
+ * Note that we do not have to worry about multiple name patterns,
+ * either. Those get sorted and deduplicated eventually in
+ * `refs_for_each_fullref_in_prefixes()`, so we return names in the
+ * correct ordering here, too.
+ */
+ if (sorting && (sorting->next ||
+ sorting->sort_flags ||
+ used_atom[sorting->atom].atom_type != ATOM_REFNAME))
+ return 0;
+
+ /*
* Filtering & formatting results within a single ref iteration
* callback is not compatible with options that require
* post-processing a filtered ref_array. These include:
* - filtering on reachability
- * - sorting the filtered results
* - including ahead-behind information in the formatted output
*/
return !(filter->reachable_from ||
filter->unreachable_from ||
- sorting ||
format->bases.nr ||
format->is_base_tips.nr);
}
@@ -3316,12 +3335,6 @@ static int memcasecmp(const void *vs1, const void *vs2, size_t n)
return 0;
}
-struct ref_sorting {
- struct ref_sorting *next;
- int atom; /* index into used_atom array (internal) */
- enum ref_sorting_order sort_flags;
-};
-
static int cmp_ref_sorting(struct ref_sorting *s, struct ref_array_item *a, struct ref_array_item *b)
{
struct atom_value *va, *vb;
diff --git a/reftable/basics.c b/reftable/basics.c
index 9a949e5cf8..bc4fcc9144 100644
--- a/reftable/basics.c
+++ b/reftable/basics.c
@@ -9,6 +9,7 @@ https://developers.google.com/open-source/licenses/bsd
#define REFTABLE_ALLOW_BANNED_ALLOCATORS
#include "basics.h"
#include "reftable-basics.h"
+#include "reftable-error.h"
static void *(*reftable_malloc_ptr)(size_t sz);
static void *(*reftable_realloc_ptr)(void *, size_t);
@@ -69,6 +70,79 @@ void reftable_set_alloc(void *(*malloc)(size_t),
reftable_free_ptr = free;
}
+void reftable_buf_init(struct reftable_buf *buf)
+{
+ struct reftable_buf empty = REFTABLE_BUF_INIT;
+ *buf = empty;
+}
+
+void reftable_buf_release(struct reftable_buf *buf)
+{
+ reftable_free(buf->buf);
+ reftable_buf_init(buf);
+}
+
+void reftable_buf_reset(struct reftable_buf *buf)
+{
+ if (buf->alloc) {
+ buf->len = 0;
+ buf->buf[0] = '\0';
+ }
+}
+
+int reftable_buf_setlen(struct reftable_buf *buf, size_t len)
+{
+ if (len > buf->len)
+ return -1;
+ if (len == buf->len)
+ return 0;
+ buf->buf[len] = '\0';
+ buf->len = len;
+ return 0;
+}
+
+int reftable_buf_cmp(const struct reftable_buf *a, const struct reftable_buf *b)
+{
+ size_t len = a->len < b->len ? a->len : b->len;
+ if (len) {
+ int cmp = memcmp(a->buf, b->buf, len);
+ if (cmp)
+ return cmp;
+ }
+ return a->len < b->len ? -1 : a->len != b->len;
+}
+
+int reftable_buf_add(struct reftable_buf *buf, const void *data, size_t len)
+{
+ size_t newlen = buf->len + len;
+
+ if (newlen + 1 > buf->alloc) {
+ char *reallocated = buf->buf;
+ REFTABLE_ALLOC_GROW(reallocated, newlen + 1, buf->alloc);
+ if (!reallocated)
+ return REFTABLE_OUT_OF_MEMORY_ERROR;
+ buf->buf = reallocated;
+ }
+
+ memcpy(buf->buf + buf->len, data, len);
+ buf->buf[newlen] = '\0';
+ buf->len = newlen;
+
+ return 0;
+}
+
+int reftable_buf_addstr(struct reftable_buf *buf, const char *s)
+{
+ return reftable_buf_add(buf, s, strlen(s));
+}
+
+char *reftable_buf_detach(struct reftable_buf *buf)
+{
+ char *result = buf->buf;
+ reftable_buf_init(buf);
+ return result;
+}
+
void put_be24(uint8_t *out, uint32_t i)
{
out[0] = (uint8_t)((i >> 16) & 0xff);
@@ -186,7 +260,7 @@ int names_equal(const char **a, const char **b)
return a[i] == b[i];
}
-int common_prefix_size(struct strbuf *a, struct strbuf *b)
+int common_prefix_size(struct reftable_buf *a, struct reftable_buf *b)
{
int p = 0;
for (; p < a->len && p < b->len; p++) {
diff --git a/reftable/basics.h b/reftable/basics.h
index 4c9ef0fe6c..7aa46d7c30 100644
--- a/reftable/basics.h
+++ b/reftable/basics.h
@@ -16,6 +16,64 @@ https://developers.google.com/open-source/licenses/bsd
#include "system.h"
#include "reftable-basics.h"
+struct reftable_buf {
+ size_t alloc;
+ size_t len;
+ char *buf;
+};
+#define REFTABLE_BUF_INIT { 0 }
+
+/*
+ * Initialize the buffer such that it is ready for use. This is equivalent to
+ * using REFTABLE_BUF_INIT for stack-allocated variables.
+ */
+void reftable_buf_init(struct reftable_buf *buf);
+
+/*
+ * Release memory associated with the buffer. The buffer is reinitialized such
+ * that it can be reused for subsequent operations.
+ */
+void reftable_buf_release(struct reftable_buf *buf);
+
+/*
+ * Reset the buffer such that it is effectively empty, without releasing the
+ * memory that this structure holds on to. This is equivalent to calling
+ * `reftable_buf_setlen(buf, 0)`.
+ */
+void reftable_buf_reset(struct reftable_buf *buf);
+
+/*
+ * Trim the buffer to a shorter length by updating the `len` member and writing
+ * a NUL byte to `buf[len]`. Returns 0 on success, -1 when `len` points outside
+ * of the array.
+ */
+int reftable_buf_setlen(struct reftable_buf *buf, size_t len);
+
+/*
+ * Lexicographically compare the two buffers. Returns 0 when both buffers have
+ * the same contents, -1 when `a` is lexicographically smaller than `b`, and 1
+ * otherwise.
+ */
+int reftable_buf_cmp(const struct reftable_buf *a, const struct reftable_buf *b);
+
+/*
+ * Append `len` bytes from `data` to the buffer. This function works with
+ * arbitrary byte sequences, including ones that contain embedded NUL
+ * characters. As such, we use `void *` as input type. Returns 0 on success,
+ * REFTABLE_OUT_OF_MEMORY_ERROR on allocation failure.
+ */
+int reftable_buf_add(struct reftable_buf *buf, const void *data, size_t len);
+
+/* Equivalent to `reftable_buf_add(buf, s, strlen(s))`. */
+int reftable_buf_addstr(struct reftable_buf *buf, const char *s);
+
+/*
+ * Detach the buffer from the structure such that the underlying memory is now
+ * owned by the caller. The buffer is reinitialized such that it can be reused
+ * for subsequent operations.
+ */
+char *reftable_buf_detach(struct reftable_buf *buf);
+
/* Bigendian en/decoding of integers */
void put_be24(uint8_t *out, uint32_t i);
@@ -88,8 +146,7 @@ char *reftable_strdup(const char *str);
#endif
/* Find the longest shared prefix size of `a` and `b` */
-struct strbuf;
-int common_prefix_size(struct strbuf *a, struct strbuf *b);
+int common_prefix_size(struct reftable_buf *a, struct reftable_buf *b);
int hash_size(uint32_t id);
diff --git a/reftable/block.c b/reftable/block.c
index 8d41a2f99e..f5b432566a 100644
--- a/reftable/block.c
+++ b/reftable/block.c
@@ -38,9 +38,11 @@ int footer_size(int version)
}
static int block_writer_register_restart(struct block_writer *w, int n,
- int is_restart, struct strbuf *key)
+ int is_restart, struct reftable_buf *key)
{
- int rlen = w->restart_len;
+ int rlen, err;
+
+ rlen = w->restart_len;
if (rlen >= MAX_RESTARTS) {
is_restart = 0;
}
@@ -59,8 +61,11 @@ static int block_writer_register_restart(struct block_writer *w, int n,
w->next += n;
- strbuf_reset(&w->last_key);
- strbuf_addbuf(&w->last_key, key);
+ reftable_buf_reset(&w->last_key);
+ err = reftable_buf_add(&w->last_key, key->buf, key->len);
+ if (err < 0)
+ return err;
+
w->entries++;
return 0;
}
@@ -98,8 +103,8 @@ uint8_t block_writer_type(struct block_writer *bw)
empty key. */
int block_writer_add(struct block_writer *w, struct reftable_record *rec)
{
- struct strbuf empty = STRBUF_INIT;
- struct strbuf last =
+ struct reftable_buf empty = REFTABLE_BUF_INIT;
+ struct reftable_buf last =
w->entries % w->restart_interval == 0 ? empty : w->last_key;
struct string_view out = {
.buf = w->buf + w->next,
@@ -109,11 +114,14 @@ int block_writer_add(struct block_writer *w, struct reftable_record *rec)
struct string_view start = out;
int is_restart = 0;
- struct strbuf key = STRBUF_INIT;
+ struct reftable_buf key = REFTABLE_BUF_INIT;
int n = 0;
- int err = -1;
+ int err;
+
+ err = reftable_record_key(rec, &key);
+ if (err < 0)
+ goto done;
- reftable_record_key(rec, &key);
if (!key.len) {
err = REFTABLE_API_ERROR;
goto done;
@@ -121,19 +129,23 @@ int block_writer_add(struct block_writer *w, struct reftable_record *rec)
n = reftable_encode_key(&is_restart, out, last, key,
reftable_record_val_type(rec));
- if (n < 0)
+ if (n < 0) {
+ err = -1;
goto done;
+ }
string_view_consume(&out, n);
n = reftable_record_encode(rec, out, w->hash_size);
- if (n < 0)
+ if (n < 0) {
+ err = -1;
goto done;
+ }
string_view_consume(&out, n);
err = block_writer_register_restart(w, start.len - out.len, is_restart,
&key);
done:
- strbuf_release(&key);
+ reftable_buf_release(&key);
return err;
}
@@ -325,7 +337,7 @@ uint8_t block_reader_type(const struct block_reader *r)
return r->block.data[r->header_off];
}
-int block_reader_first_key(const struct block_reader *br, struct strbuf *key)
+int block_reader_first_key(const struct block_reader *br, struct reftable_buf *key)
{
int off = br->header_off + 4, n;
struct string_view in = {
@@ -334,7 +346,7 @@ int block_reader_first_key(const struct block_reader *br, struct strbuf *key)
};
uint8_t extra = 0;
- strbuf_reset(key);
+ reftable_buf_reset(key);
n = reftable_decode_key(key, &extra, in);
if (n < 0)
@@ -355,13 +367,13 @@ void block_iter_seek_start(struct block_iter *it, const struct block_reader *br)
it->block = br->block.data;
it->block_len = br->block_len;
it->hash_size = br->hash_size;
- strbuf_reset(&it->last_key);
+ reftable_buf_reset(&it->last_key);
it->next_off = br->header_off + 4;
}
struct restart_needle_less_args {
int error;
- struct strbuf needle;
+ struct reftable_buf needle;
const struct block_reader *reader;
};
@@ -433,7 +445,7 @@ int block_iter_next(struct block_iter *it, struct reftable_record *rec)
void block_iter_reset(struct block_iter *it)
{
- strbuf_reset(&it->last_key);
+ reftable_buf_reset(&it->last_key);
it->next_off = 0;
it->block = NULL;
it->block_len = 0;
@@ -442,12 +454,12 @@ void block_iter_reset(struct block_iter *it)
void block_iter_close(struct block_iter *it)
{
- strbuf_release(&it->last_key);
- strbuf_release(&it->scratch);
+ reftable_buf_release(&it->last_key);
+ reftable_buf_release(&it->scratch);
}
int block_iter_seek_key(struct block_iter *it, const struct block_reader *br,
- struct strbuf *want)
+ struct reftable_buf *want)
{
struct restart_needle_less_args args = {
.needle = *want,
@@ -522,6 +534,10 @@ int block_iter_seek_key(struct block_iter *it, const struct block_reader *br,
goto done;
}
+ err = reftable_record_key(&rec, &it->last_key);
+ if (err < 0)
+ goto done;
+
/*
* Check whether the current key is greater or equal to the
* sought-after key. In case it is greater we know that the
@@ -536,8 +552,7 @@ int block_iter_seek_key(struct block_iter *it, const struct block_reader *br,
* to `last_key` now, and naturally all keys share a prefix
* with themselves.
*/
- reftable_record_key(&rec, &it->last_key);
- if (strbuf_cmp(&it->last_key, want) >= 0) {
+ if (reftable_buf_cmp(&it->last_key, want) >= 0) {
it->next_off = prev_off;
goto done;
}
@@ -554,7 +569,7 @@ void block_writer_release(struct block_writer *bw)
REFTABLE_FREE_AND_NULL(bw->zstream);
REFTABLE_FREE_AND_NULL(bw->restarts);
REFTABLE_FREE_AND_NULL(bw->compressed);
- strbuf_release(&bw->last_key);
+ reftable_buf_release(&bw->last_key);
/* the block is not owned. */
}
diff --git a/reftable/block.h b/reftable/block.h
index 18d7ea0337..9a3effa513 100644
--- a/reftable/block.h
+++ b/reftable/block.h
@@ -38,7 +38,7 @@ struct block_writer {
uint32_t restart_len;
uint32_t restart_cap;
- struct strbuf last_key;
+ struct reftable_buf last_key;
int entries;
};
@@ -98,7 +98,7 @@ void block_reader_release(struct block_reader *br);
uint8_t block_reader_type(const struct block_reader *r);
/* Decodes the first key in the block */
-int block_reader_first_key(const struct block_reader *br, struct strbuf *key);
+int block_reader_first_key(const struct block_reader *br, struct reftable_buf *key);
/* Iterate over entries in a block */
struct block_iter {
@@ -109,13 +109,13 @@ struct block_iter {
int hash_size;
/* key for last entry we read. */
- struct strbuf last_key;
- struct strbuf scratch;
+ struct reftable_buf last_key;
+ struct reftable_buf scratch;
};
#define BLOCK_ITER_INIT { \
- .last_key = STRBUF_INIT, \
- .scratch = STRBUF_INIT, \
+ .last_key = REFTABLE_BUF_INIT, \
+ .scratch = REFTABLE_BUF_INIT, \
}
/* Position `it` at start of the block */
@@ -123,7 +123,7 @@ void block_iter_seek_start(struct block_iter *it, const struct block_reader *br)
/* Position `it` to the `want` key in the block */
int block_iter_seek_key(struct block_iter *it, const struct block_reader *br,
- struct strbuf *want);
+ struct reftable_buf *want);
/* return < 0 for error, 0 for OK, > 0 for EOF. */
int block_iter_next(struct block_iter *it, struct reftable_record *rec);
diff --git a/reftable/blocksource.c b/reftable/blocksource.c
index a2a6a196d5..52e0915a67 100644
--- a/reftable/blocksource.c
+++ b/reftable/blocksource.c
@@ -13,21 +13,21 @@ https://developers.google.com/open-source/licenses/bsd
#include "reftable-blocksource.h"
#include "reftable-error.h"
-static void strbuf_return_block(void *b UNUSED, struct reftable_block *dest)
+static void reftable_buf_return_block(void *b UNUSED, struct reftable_block *dest)
{
if (dest->len)
memset(dest->data, 0xff, dest->len);
reftable_free(dest->data);
}
-static void strbuf_close(void *b UNUSED)
+static void reftable_buf_close(void *b UNUSED)
{
}
-static int strbuf_read_block(void *v, struct reftable_block *dest, uint64_t off,
- uint32_t size)
+static int reftable_buf_read_block(void *v, struct reftable_block *dest,
+ uint64_t off, uint32_t size)
{
- struct strbuf *b = v;
+ struct reftable_buf *b = v;
assert(off + size <= b->len);
REFTABLE_CALLOC_ARRAY(dest->data, size);
if (!dest->data)
@@ -37,23 +37,23 @@ static int strbuf_read_block(void *v, struct reftable_block *dest, uint64_t off,
return size;
}
-static uint64_t strbuf_size(void *b)
+static uint64_t reftable_buf_size(void *b)
{
- return ((struct strbuf *)b)->len;
+ return ((struct reftable_buf *)b)->len;
}
-static struct reftable_block_source_vtable strbuf_vtable = {
- .size = &strbuf_size,
- .read_block = &strbuf_read_block,
- .return_block = &strbuf_return_block,
- .close = &strbuf_close,
+static struct reftable_block_source_vtable reftable_buf_vtable = {
+ .size = &reftable_buf_size,
+ .read_block = &reftable_buf_read_block,
+ .return_block = &reftable_buf_return_block,
+ .close = &reftable_buf_close,
};
-void block_source_from_strbuf(struct reftable_block_source *bs,
- struct strbuf *buf)
+void block_source_from_buf(struct reftable_block_source *bs,
+ struct reftable_buf *buf)
{
assert(!bs->ops);
- bs->ops = &strbuf_vtable;
+ bs->ops = &reftable_buf_vtable;
bs->arg = buf;
}
diff --git a/reftable/blocksource.h b/reftable/blocksource.h
index 659a27b406..a84a3ccd89 100644
--- a/reftable/blocksource.h
+++ b/reftable/blocksource.h
@@ -12,9 +12,10 @@ https://developers.google.com/open-source/licenses/bsd
#include "system.h"
struct reftable_block_source;
+struct reftable_buf;
/* Create an in-memory block source for reading reftables */
-void block_source_from_strbuf(struct reftable_block_source *bs,
- struct strbuf *buf);
+void block_source_from_buf(struct reftable_block_source *bs,
+ struct reftable_buf *buf);
#endif
diff --git a/reftable/iter.c b/reftable/iter.c
index d926db653b..86e801ca9f 100644
--- a/reftable/iter.c
+++ b/reftable/iter.c
@@ -55,7 +55,7 @@ void iterator_set_empty(struct reftable_iterator *it)
static void filtering_ref_iterator_close(void *iter_arg)
{
struct filtering_ref_iterator *fri = iter_arg;
- strbuf_release(&fri->oid);
+ reftable_buf_release(&fri->oid);
reftable_iterator_destroy(&fri->it);
}
@@ -115,7 +115,7 @@ static void indexed_table_ref_iter_close(void *p)
block_iter_close(&it->cur);
reftable_block_done(&it->block_reader.block);
reftable_free(it->offsets);
- strbuf_release(&it->oid);
+ reftable_buf_release(&it->oid);
}
static int indexed_table_ref_iter_next_block(struct indexed_table_ref_iter *it)
@@ -197,7 +197,10 @@ int indexed_table_ref_iter_new(struct indexed_table_ref_iter **dest,
*itr = empty;
itr->r = r;
- strbuf_add(&itr->oid, oid, oid_len);
+
+ err = reftable_buf_add(&itr->oid, oid, oid_len);
+ if (err < 0)
+ goto out;
itr->offsets = offsets;
itr->offset_len = offset_len;
diff --git a/reftable/iter.h b/reftable/iter.h
index b3225bc7ad..40f98893b8 100644
--- a/reftable/iter.h
+++ b/reftable/iter.h
@@ -44,12 +44,12 @@ void iterator_set_empty(struct reftable_iterator *it);
/* iterator that produces only ref records that point to `oid` */
struct filtering_ref_iterator {
- struct strbuf oid;
+ struct reftable_buf oid;
struct reftable_iterator it;
};
#define FILTERING_REF_ITERATOR_INIT \
{ \
- .oid = STRBUF_INIT \
+ .oid = REFTABLE_BUF_INIT \
}
void iterator_from_filtering_ref_iterator(struct reftable_iterator *,
@@ -60,7 +60,7 @@ void iterator_from_filtering_ref_iterator(struct reftable_iterator *,
*/
struct indexed_table_ref_iter {
struct reftable_reader *r;
- struct strbuf oid;
+ struct reftable_buf oid;
/* mutable */
uint64_t *offsets;
@@ -75,7 +75,7 @@ struct indexed_table_ref_iter {
#define INDEXED_TABLE_REF_ITER_INIT { \
.cur = BLOCK_ITER_INIT, \
- .oid = STRBUF_INIT, \
+ .oid = REFTABLE_BUF_INIT, \
}
void iterator_from_indexed_table_ref_iter(struct reftable_iterator *it,
diff --git a/reftable/reader.c b/reftable/reader.c
index 8d37253922..90dc950b57 100644
--- a/reftable/reader.c
+++ b/reftable/reader.c
@@ -350,13 +350,15 @@ static int table_iter_seek_start(struct table_iter *ti, uint8_t typ, int index)
static int table_iter_seek_linear(struct table_iter *ti,
struct reftable_record *want)
{
- struct strbuf want_key = STRBUF_INIT;
- struct strbuf got_key = STRBUF_INIT;
+ struct reftable_buf want_key = REFTABLE_BUF_INIT;
+ struct reftable_buf got_key = REFTABLE_BUF_INIT;
struct reftable_record rec;
int err;
reftable_record_init(&rec, reftable_record_type(want));
- reftable_record_key(want, &want_key);
+ err = reftable_record_key(want, &want_key);
+ if (err < 0)
+ goto done;
/*
* First we need to locate the block that must contain our record. To
@@ -401,7 +403,7 @@ static int table_iter_seek_linear(struct table_iter *ti,
if (err < 0)
goto done;
- if (strbuf_cmp(&got_key, &want_key) > 0) {
+ if (reftable_buf_cmp(&got_key, &want_key) > 0) {
table_iter_block_done(&next);
break;
}
@@ -422,8 +424,8 @@ static int table_iter_seek_linear(struct table_iter *ti,
done:
reftable_record_release(&rec);
- strbuf_release(&want_key);
- strbuf_release(&got_key);
+ reftable_buf_release(&want_key);
+ reftable_buf_release(&got_key);
return err;
}
@@ -431,15 +433,17 @@ static int table_iter_seek_indexed(struct table_iter *ti,
struct reftable_record *rec)
{
struct reftable_record want_index = {
- .type = BLOCK_TYPE_INDEX, .u.idx = { .last_key = STRBUF_INIT }
+ .type = BLOCK_TYPE_INDEX, .u.idx = { .last_key = REFTABLE_BUF_INIT }
};
struct reftable_record index_result = {
.type = BLOCK_TYPE_INDEX,
- .u.idx = { .last_key = STRBUF_INIT },
+ .u.idx = { .last_key = REFTABLE_BUF_INIT },
};
int err;
- reftable_record_key(rec, &want_index.u.idx.last_key);
+ err = reftable_record_key(rec, &want_index.u.idx.last_key);
+ if (err < 0)
+ goto done;
/*
* The index may consist of multiple levels, where each level may have
@@ -765,7 +769,10 @@ static int reftable_reader_refs_for_unindexed(struct reftable_reader *r,
}
*filter = empty;
- strbuf_add(&filter->oid, oid, oid_len);
+ err = reftable_buf_add(&filter->oid, oid, oid_len);
+ if (err < 0)
+ goto out;
+
iterator_from_table_iter(&filter->it, ti);
iterator_from_filtering_ref_iterator(it, filter);
diff --git a/reftable/record.c b/reftable/record.c
index 30d563e16d..fb5652ed57 100644
--- a/reftable/record.c
+++ b/reftable/record.c
@@ -98,19 +98,24 @@ const unsigned char *reftable_ref_record_val2(const struct reftable_ref_record *
}
}
-static int decode_string(struct strbuf *dest, struct string_view in)
+static int decode_string(struct reftable_buf *dest, struct string_view in)
{
int start_len = in.len;
uint64_t tsize = 0;
- int n = get_var_int(&tsize, &in);
+ int n, err;
+
+ n = get_var_int(&tsize, &in);
if (n <= 0)
return -1;
string_view_consume(&in, n);
if (in.len < tsize)
return -1;
- strbuf_reset(dest);
- strbuf_add(dest, in.buf, tsize);
+ reftable_buf_reset(dest);
+ err = reftable_buf_add(dest, in.buf, tsize);
+ if (err < 0)
+ return err;
+
string_view_consume(&in, tsize);
return start_len - in.len;
@@ -133,7 +138,7 @@ static int encode_string(const char *str, struct string_view s)
}
int reftable_encode_key(int *restart, struct string_view dest,
- struct strbuf prev_key, struct strbuf key,
+ struct reftable_buf prev_key, struct reftable_buf key,
uint8_t extra)
{
struct string_view start = dest;
@@ -183,13 +188,13 @@ int reftable_decode_keylen(struct string_view in,
return start_len - in.len;
}
-int reftable_decode_key(struct strbuf *last_key, uint8_t *extra,
+int reftable_decode_key(struct reftable_buf *last_key, uint8_t *extra,
struct string_view in)
{
int start_len = in.len;
uint64_t prefix_len = 0;
uint64_t suffix_len = 0;
- int n;
+ int err, n;
n = reftable_decode_keylen(in, &prefix_len, &suffix_len, extra);
if (n < 0)
@@ -200,19 +205,25 @@ int reftable_decode_key(struct strbuf *last_key, uint8_t *extra,
prefix_len > last_key->len)
return -1;
- strbuf_setlen(last_key, prefix_len);
- strbuf_add(last_key, in.buf, suffix_len);
+ err = reftable_buf_setlen(last_key, prefix_len);
+ if (err < 0)
+ return err;
+
+ err = reftable_buf_add(last_key, in.buf, suffix_len);
+ if (err < 0)
+ return err;
+
string_view_consume(&in, suffix_len);
return start_len - in.len;
}
-static void reftable_ref_record_key(const void *r, struct strbuf *dest)
+static int reftable_ref_record_key(const void *r, struct reftable_buf *dest)
{
const struct reftable_ref_record *rec =
(const struct reftable_ref_record *)r;
- strbuf_reset(dest);
- strbuf_addstr(dest, rec->refname);
+ reftable_buf_reset(dest);
+ return reftable_buf_addstr(dest, rec->refname);
}
static int reftable_ref_record_copy_from(void *rec, const void *src_rec,
@@ -350,9 +361,9 @@ static int reftable_ref_record_encode(const void *rec, struct string_view s,
return start.len - s.len;
}
-static int reftable_ref_record_decode(void *rec, struct strbuf key,
+static int reftable_ref_record_decode(void *rec, struct reftable_buf key,
uint8_t val_type, struct string_view in,
- int hash_size, struct strbuf *scratch)
+ int hash_size, struct reftable_buf *scratch)
{
struct reftable_ref_record *r = rec;
struct string_view start = in;
@@ -415,7 +426,7 @@ static int reftable_ref_record_decode(void *rec, struct strbuf key,
goto done;
}
string_view_consume(&in, n);
- r->value.symref = strbuf_detach(scratch, NULL);
+ r->value.symref = reftable_buf_detach(scratch);
} break;
case REFTABLE_REF_DELETION:
@@ -465,12 +476,12 @@ static struct reftable_record_vtable reftable_ref_record_vtable = {
.cmp = &reftable_ref_record_cmp_void,
};
-static void reftable_obj_record_key(const void *r, struct strbuf *dest)
+static int reftable_obj_record_key(const void *r, struct reftable_buf *dest)
{
const struct reftable_obj_record *rec =
(const struct reftable_obj_record *)r;
- strbuf_reset(dest);
- strbuf_add(dest, rec->hash_prefix, rec->hash_prefix_len);
+ reftable_buf_reset(dest);
+ return reftable_buf_add(dest, rec->hash_prefix, rec->hash_prefix_len);
}
static void reftable_obj_record_release(void *rec)
@@ -547,10 +558,10 @@ static int reftable_obj_record_encode(const void *rec, struct string_view s,
return start.len - s.len;
}
-static int reftable_obj_record_decode(void *rec, struct strbuf key,
+static int reftable_obj_record_decode(void *rec, struct reftable_buf key,
uint8_t val_type, struct string_view in,
int hash_size UNUSED,
- struct strbuf *scratch UNUSED)
+ struct reftable_buf *scratch UNUSED)
{
struct string_view start = in;
struct reftable_obj_record *r = rec;
@@ -664,19 +675,27 @@ static struct reftable_record_vtable reftable_obj_record_vtable = {
.cmp = &reftable_obj_record_cmp_void,
};
-static void reftable_log_record_key(const void *r, struct strbuf *dest)
+static int reftable_log_record_key(const void *r, struct reftable_buf *dest)
{
const struct reftable_log_record *rec =
(const struct reftable_log_record *)r;
- int len = strlen(rec->refname);
+ int len = strlen(rec->refname), err;
uint8_t i64[8];
uint64_t ts = 0;
- strbuf_reset(dest);
- strbuf_add(dest, (uint8_t *)rec->refname, len + 1);
+
+ reftable_buf_reset(dest);
+ err = reftable_buf_add(dest, (uint8_t *)rec->refname, len + 1);
+ if (err < 0)
+ return err;
ts = (~ts) - rec->update_index;
put_be64(&i64[0], ts);
- strbuf_add(dest, i64, sizeof(i64));
+
+ err = reftable_buf_add(dest, i64, sizeof(i64));
+ if (err < 0)
+ return err;
+
+ return 0;
}
static int reftable_log_record_copy_from(void *rec, const void *src_rec,
@@ -807,9 +826,9 @@ static int reftable_log_record_encode(const void *rec, struct string_view s,
return start.len - s.len;
}
-static int reftable_log_record_decode(void *rec, struct strbuf key,
+static int reftable_log_record_decode(void *rec, struct reftable_buf key,
uint8_t val_type, struct string_view in,
- int hash_size, struct strbuf *scratch)
+ int hash_size, struct reftable_buf *scratch)
{
struct string_view start = in;
struct reftable_log_record *r = rec;
@@ -1027,11 +1046,11 @@ static struct reftable_record_vtable reftable_log_record_vtable = {
.cmp = &reftable_log_record_cmp_void,
};
-static void reftable_index_record_key(const void *r, struct strbuf *dest)
+static int reftable_index_record_key(const void *r, struct reftable_buf *dest)
{
const struct reftable_index_record *rec = r;
- strbuf_reset(dest);
- strbuf_addbuf(dest, &rec->last_key);
+ reftable_buf_reset(dest);
+ return reftable_buf_add(dest, rec->last_key.buf, rec->last_key.len);
}
static int reftable_index_record_copy_from(void *rec, const void *src_rec,
@@ -1039,9 +1058,12 @@ static int reftable_index_record_copy_from(void *rec, const void *src_rec,
{
struct reftable_index_record *dst = rec;
const struct reftable_index_record *src = src_rec;
+ int err;
- strbuf_reset(&dst->last_key);
- strbuf_addbuf(&dst->last_key, &src->last_key);
+ reftable_buf_reset(&dst->last_key);
+ err = reftable_buf_add(&dst->last_key, src->last_key.buf, src->last_key.len);
+ if (err < 0)
+ return err;
dst->offset = src->offset;
return 0;
@@ -1050,7 +1072,7 @@ static int reftable_index_record_copy_from(void *rec, const void *src_rec,
static void reftable_index_record_release(void *rec)
{
struct reftable_index_record *idx = rec;
- strbuf_release(&idx->last_key);
+ reftable_buf_release(&idx->last_key);
}
static uint8_t reftable_index_record_val_type(const void *rec UNUSED)
@@ -1074,18 +1096,20 @@ static int reftable_index_record_encode(const void *rec, struct string_view out,
return start.len - out.len;
}
-static int reftable_index_record_decode(void *rec, struct strbuf key,
+static int reftable_index_record_decode(void *rec, struct reftable_buf key,
uint8_t val_type UNUSED,
struct string_view in,
int hash_size UNUSED,
- struct strbuf *scratch UNUSED)
+ struct reftable_buf *scratch UNUSED)
{
struct string_view start = in;
struct reftable_index_record *r = rec;
- int n = 0;
+ int err, n = 0;
- strbuf_reset(&r->last_key);
- strbuf_addbuf(&r->last_key, &key);
+ reftable_buf_reset(&r->last_key);
+ err = reftable_buf_add(&r->last_key, key.buf, key.len);
+ if (err < 0)
+ return err;
n = get_var_int(&r->offset, &in);
if (n < 0)
@@ -1101,14 +1125,14 @@ static int reftable_index_record_equal(const void *a, const void *b,
struct reftable_index_record *ia = (struct reftable_index_record *) a;
struct reftable_index_record *ib = (struct reftable_index_record *) b;
- return ia->offset == ib->offset && !strbuf_cmp(&ia->last_key, &ib->last_key);
+ return ia->offset == ib->offset && !reftable_buf_cmp(&ia->last_key, &ib->last_key);
}
static int reftable_index_record_cmp(const void *_a, const void *_b)
{
const struct reftable_index_record *a = _a;
const struct reftable_index_record *b = _b;
- return strbuf_cmp(&a->last_key, &b->last_key);
+ return reftable_buf_cmp(&a->last_key, &b->last_key);
}
static struct reftable_record_vtable reftable_index_record_vtable = {
@@ -1124,9 +1148,9 @@ static struct reftable_record_vtable reftable_index_record_vtable = {
.cmp = &reftable_index_record_cmp,
};
-void reftable_record_key(struct reftable_record *rec, struct strbuf *dest)
+int reftable_record_key(struct reftable_record *rec, struct reftable_buf *dest)
{
- reftable_record_vtable(rec)->key(reftable_record_data(rec), dest);
+ return reftable_record_vtable(rec)->key(reftable_record_data(rec), dest);
}
int reftable_record_encode(struct reftable_record *rec, struct string_view dest,
@@ -1151,9 +1175,9 @@ uint8_t reftable_record_val_type(struct reftable_record *rec)
return reftable_record_vtable(rec)->val_type(reftable_record_data(rec));
}
-int reftable_record_decode(struct reftable_record *rec, struct strbuf key,
+int reftable_record_decode(struct reftable_record *rec, struct reftable_buf key,
uint8_t extra, struct string_view src, int hash_size,
- struct strbuf *scratch)
+ struct reftable_buf *scratch)
{
return reftable_record_vtable(rec)->decode(reftable_record_data(rec),
key, extra, src, hash_size,
@@ -1294,7 +1318,7 @@ void reftable_record_init(struct reftable_record *rec, uint8_t typ)
case BLOCK_TYPE_OBJ:
return;
case BLOCK_TYPE_INDEX:
- strbuf_init(&rec->u.idx.last_key, 0);
+ reftable_buf_init(&rec->u.idx.last_key);
return;
default:
BUG("unhandled record type");
diff --git a/reftable/record.h b/reftable/record.h
index 0f53ba5443..25aa908c85 100644
--- a/reftable/record.h
+++ b/reftable/record.h
@@ -9,6 +9,7 @@ https://developers.google.com/open-source/licenses/bsd
#ifndef RECORD_H
#define RECORD_H
+#include "basics.h"
#include "system.h"
#include <stdint.h>
@@ -38,8 +39,8 @@ int put_var_int(struct string_view *dest, uint64_t val);
/* Methods for records. */
struct reftable_record_vtable {
- /* encode the key of to a uint8_t strbuf. */
- void (*key)(const void *rec, struct strbuf *dest);
+ /* encode the key of to a uint8_t reftable_buf. */
+ int (*key)(const void *rec, struct reftable_buf *dest);
/* The record type of ('r' for ref). */
uint8_t type;
@@ -54,9 +55,9 @@ struct reftable_record_vtable {
int (*encode)(const void *rec, struct string_view dest, int hash_size);
/* decode data from `src` into the record. */
- int (*decode)(void *rec, struct strbuf key, uint8_t extra,
+ int (*decode)(void *rec, struct reftable_buf key, uint8_t extra,
struct string_view src, int hash_size,
- struct strbuf *scratch);
+ struct reftable_buf *scratch);
/* deallocate and null the record. */
void (*release)(void *rec);
@@ -83,7 +84,7 @@ int reftable_is_block_type(uint8_t typ);
/* Encode `key` into `dest`. Sets `is_restart` to indicate a restart. Returns
* number of bytes written. */
int reftable_encode_key(int *is_restart, struct string_view dest,
- struct strbuf prev_key, struct strbuf key,
+ struct reftable_buf prev_key, struct reftable_buf key,
uint8_t extra);
/* Decode a record's key lengths. */
@@ -96,13 +97,13 @@ int reftable_decode_keylen(struct string_view in,
* Decode into `last_key` and `extra` from `in`. `last_key` is expected to
* contain the decoded key of the preceding record, if any.
*/
-int reftable_decode_key(struct strbuf *last_key, uint8_t *extra,
+int reftable_decode_key(struct reftable_buf *last_key, uint8_t *extra,
struct string_view in);
/* reftable_index_record are used internally to speed up lookups. */
struct reftable_index_record {
uint64_t offset; /* Offset of block */
- struct strbuf last_key; /* Last key of the block. */
+ struct reftable_buf last_key; /* Last key of the block. */
};
/* reftable_obj_record stores an object ID => ref mapping. */
@@ -136,15 +137,15 @@ void reftable_record_init(struct reftable_record *rec, uint8_t typ);
/* see struct record_vtable */
int reftable_record_cmp(struct reftable_record *a, struct reftable_record *b);
int reftable_record_equal(struct reftable_record *a, struct reftable_record *b, int hash_size);
-void reftable_record_key(struct reftable_record *rec, struct strbuf *dest);
+int reftable_record_key(struct reftable_record *rec, struct reftable_buf *dest);
int reftable_record_copy_from(struct reftable_record *rec,
struct reftable_record *src, int hash_size);
uint8_t reftable_record_val_type(struct reftable_record *rec);
int reftable_record_encode(struct reftable_record *rec, struct string_view dest,
int hash_size);
-int reftable_record_decode(struct reftable_record *rec, struct strbuf key,
+int reftable_record_decode(struct reftable_record *rec, struct reftable_buf key,
uint8_t extra, struct string_view src,
- int hash_size, struct strbuf *scratch);
+ int hash_size, struct reftable_buf *scratch);
int reftable_record_is_deletion(struct reftable_record *rec);
static inline uint8_t reftable_record_type(struct reftable_record *rec)
diff --git a/reftable/stack.c b/reftable/stack.c
index 7e617c2591..c33979536e 100644
--- a/reftable/stack.c
+++ b/reftable/stack.c
@@ -31,13 +31,16 @@ static void reftable_addition_close(struct reftable_addition *add);
static int reftable_stack_reload_maybe_reuse(struct reftable_stack *st,
int reuse_open);
-static void stack_filename(struct strbuf *dest, struct reftable_stack *st,
- const char *name)
+static int stack_filename(struct reftable_buf *dest, struct reftable_stack *st,
+ const char *name)
{
- strbuf_reset(dest);
- strbuf_addstr(dest, st->reftable_dir);
- strbuf_addstr(dest, "/");
- strbuf_addstr(dest, name);
+ int err;
+ reftable_buf_reset(dest);
+ if ((err = reftable_buf_addstr(dest, st->reftable_dir)) < 0 ||
+ (err = reftable_buf_addstr(dest, "/")) < 0 ||
+ (err = reftable_buf_addstr(dest, name)) < 0)
+ return err;
+ return 0;
}
static ssize_t reftable_fd_write(void *arg, const void *data, size_t sz)
@@ -56,7 +59,7 @@ static int reftable_fd_flush(void *arg)
int reftable_new_stack(struct reftable_stack **dest, const char *dir,
const struct reftable_write_options *_opts)
{
- struct strbuf list_file_name = STRBUF_INIT;
+ struct reftable_buf list_file_name = REFTABLE_BUF_INIT;
struct reftable_write_options opts = { 0 };
struct reftable_stack *p;
int err;
@@ -74,11 +77,12 @@ int reftable_new_stack(struct reftable_stack **dest, const char *dir,
*dest = NULL;
- strbuf_reset(&list_file_name);
- strbuf_addstr(&list_file_name, dir);
- strbuf_addstr(&list_file_name, "/tables.list");
+ reftable_buf_reset(&list_file_name);
+ if ((err = reftable_buf_addstr(&list_file_name, dir)) < 0 ||
+ (err = reftable_buf_addstr(&list_file_name, "/tables.list")) < 0)
+ goto out;
- p->list_file = strbuf_detach(&list_file_name, NULL);
+ p->list_file = reftable_buf_detach(&list_file_name);
p->list_fd = -1;
p->opts = opts;
p->reftable_dir = reftable_strdup(dir);
@@ -208,21 +212,24 @@ void reftable_stack_destroy(struct reftable_stack *st)
if (st->readers) {
int i = 0;
- struct strbuf filename = STRBUF_INIT;
+ struct reftable_buf filename = REFTABLE_BUF_INIT;
for (i = 0; i < st->readers_len; i++) {
const char *name = reader_name(st->readers[i]);
- strbuf_reset(&filename);
+ int try_unlinking = 1;
+
+ reftable_buf_reset(&filename);
if (names && !has_name(names, name)) {
- stack_filename(&filename, st, name);
+ if (stack_filename(&filename, st, name) < 0)
+ try_unlinking = 0;
}
reftable_reader_decref(st->readers[i]);
- if (filename.len) {
+ if (try_unlinking && filename.len) {
/* On Windows, can only unlink after closing. */
unlink(filename.buf);
}
}
- strbuf_release(&filename);
+ reftable_buf_release(&filename);
st->readers_len = 0;
REFTABLE_FREE_AND_NULL(st->readers);
}
@@ -260,7 +267,7 @@ static int reftable_stack_reload_once(struct reftable_stack *st,
size_t reused_len = 0, reused_alloc = 0, names_len;
size_t new_readers_len = 0;
struct reftable_merged_table *new_merged = NULL;
- struct strbuf table_path = STRBUF_INIT;
+ struct reftable_buf table_path = REFTABLE_BUF_INIT;
int err = 0;
size_t i;
@@ -310,7 +317,10 @@ static int reftable_stack_reload_once(struct reftable_stack *st,
if (!rd) {
struct reftable_block_source src = { NULL };
- stack_filename(&table_path, st, name);
+
+ err = stack_filename(&table_path, st, name);
+ if (err < 0)
+ goto done;
err = reftable_block_source_from_file(&src,
table_path.buf);
@@ -341,7 +351,11 @@ static int reftable_stack_reload_once(struct reftable_stack *st,
for (i = 0; i < cur_len; i++) {
if (cur[i]) {
const char *name = reader_name(cur[i]);
- stack_filename(&table_path, st, name);
+
+ err = stack_filename(&table_path, st, name);
+ if (err < 0)
+ goto done;
+
reftable_reader_decref(cur[i]);
unlink(table_path.buf);
}
@@ -374,7 +388,7 @@ done:
reftable_free(new_readers);
reftable_free(reused);
reftable_free(cur);
- strbuf_release(&table_path);
+ reftable_buf_release(&table_path);
return err;
}
@@ -623,14 +637,14 @@ int reftable_stack_add(struct reftable_stack *st,
return 0;
}
-static void format_name(struct strbuf *dest, uint64_t min, uint64_t max)
+static int format_name(struct reftable_buf *dest, uint64_t min, uint64_t max)
{
char buf[100];
uint32_t rnd = (uint32_t)git_rand();
snprintf(buf, sizeof(buf), "0x%012" PRIx64 "-0x%012" PRIx64 "-%08x",
min, max, rnd);
- strbuf_reset(dest);
- strbuf_addstr(dest, buf);
+ reftable_buf_reset(dest);
+ return reftable_buf_addstr(dest, buf);
}
struct reftable_addition {
@@ -648,7 +662,7 @@ static int reftable_stack_init_addition(struct reftable_addition *add,
struct reftable_stack *st,
unsigned int flags)
{
- struct strbuf lock_file_name = STRBUF_INIT;
+ struct reftable_buf lock_file_name = REFTABLE_BUF_INIT;
int err;
add->stack = st;
@@ -690,18 +704,18 @@ static int reftable_stack_init_addition(struct reftable_addition *add,
done:
if (err)
reftable_addition_close(add);
- strbuf_release(&lock_file_name);
+ reftable_buf_release(&lock_file_name);
return err;
}
static void reftable_addition_close(struct reftable_addition *add)
{
- struct strbuf nm = STRBUF_INIT;
+ struct reftable_buf nm = REFTABLE_BUF_INIT;
size_t i;
for (i = 0; i < add->new_tables_len; i++) {
- stack_filename(&nm, add->stack, add->new_tables[i]);
- unlink(nm.buf);
+ if (!stack_filename(&nm, add->stack, add->new_tables[i]))
+ unlink(nm.buf);
reftable_free(add->new_tables[i]);
add->new_tables[i] = NULL;
}
@@ -711,7 +725,7 @@ static void reftable_addition_close(struct reftable_addition *add)
add->new_tables_cap = 0;
rollback_lock_file(&add->tables_list_lock);
- strbuf_release(&nm);
+ reftable_buf_release(&nm);
}
void reftable_addition_destroy(struct reftable_addition *add)
@@ -725,7 +739,7 @@ void reftable_addition_destroy(struct reftable_addition *add)
int reftable_addition_commit(struct reftable_addition *add)
{
- struct strbuf table_list = STRBUF_INIT;
+ struct reftable_buf table_list = REFTABLE_BUF_INIT;
int lock_file_fd = get_lock_file_fd(&add->tables_list_lock);
int err = 0;
size_t i;
@@ -734,16 +748,18 @@ int reftable_addition_commit(struct reftable_addition *add)
goto done;
for (i = 0; i < add->stack->merged->readers_len; i++) {
- strbuf_addstr(&table_list, add->stack->readers[i]->name);
- strbuf_addstr(&table_list, "\n");
+ if ((err = reftable_buf_addstr(&table_list, add->stack->readers[i]->name)) < 0 ||
+ (err = reftable_buf_addstr(&table_list, "\n")) < 0)
+ goto done;
}
for (i = 0; i < add->new_tables_len; i++) {
- strbuf_addstr(&table_list, add->new_tables[i]);
- strbuf_addstr(&table_list, "\n");
+ if ((err = reftable_buf_addstr(&table_list, add->new_tables[i])) < 0 ||
+ (err = reftable_buf_addstr(&table_list, "\n")) < 0)
+ goto done;
}
err = write_in_full(lock_file_fd, table_list.buf, table_list.len);
- strbuf_release(&table_list);
+ reftable_buf_release(&table_list);
if (err < 0) {
err = REFTABLE_IO_ERROR;
goto done;
@@ -837,19 +853,27 @@ int reftable_addition_add(struct reftable_addition *add,
void *arg),
void *arg)
{
- struct strbuf temp_tab_file_name = STRBUF_INIT;
- struct strbuf tab_file_name = STRBUF_INIT;
- struct strbuf next_name = STRBUF_INIT;
+ struct reftable_buf temp_tab_file_name = REFTABLE_BUF_INIT;
+ struct reftable_buf tab_file_name = REFTABLE_BUF_INIT;
+ struct reftable_buf next_name = REFTABLE_BUF_INIT;
struct reftable_writer *wr = NULL;
struct tempfile *tab_file = NULL;
int err = 0;
int tab_fd;
- strbuf_reset(&next_name);
- format_name(&next_name, add->next_update_index, add->next_update_index);
+ reftable_buf_reset(&next_name);
- stack_filename(&temp_tab_file_name, add->stack, next_name.buf);
- strbuf_addstr(&temp_tab_file_name, ".temp.XXXXXX");
+ err = format_name(&next_name, add->next_update_index, add->next_update_index);
+ if (err < 0)
+ goto done;
+
+ err = stack_filename(&temp_tab_file_name, add->stack, next_name.buf);
+ if (err < 0)
+ goto done;
+
+ err = reftable_buf_addstr(&temp_tab_file_name, ".temp.XXXXXX");
+ if (err < 0)
+ goto done;
tab_file = mks_tempfile(temp_tab_file_name.buf);
if (!tab_file) {
@@ -893,9 +917,17 @@ int reftable_addition_add(struct reftable_addition *add,
goto done;
}
- format_name(&next_name, wr->min_update_index, wr->max_update_index);
- strbuf_addstr(&next_name, ".ref");
- stack_filename(&tab_file_name, add->stack, next_name.buf);
+ err = format_name(&next_name, wr->min_update_index, wr->max_update_index);
+ if (err < 0)
+ goto done;
+
+ err = reftable_buf_addstr(&next_name, ".ref");
+ if (err < 0)
+ goto done;
+
+ err = stack_filename(&tab_file_name, add->stack, next_name.buf);
+ if (err < 0)
+ goto done;
/*
On windows, this relies on rand() picking a unique destination name.
@@ -913,13 +945,13 @@ int reftable_addition_add(struct reftable_addition *add,
err = REFTABLE_OUT_OF_MEMORY_ERROR;
goto done;
}
- add->new_tables[add->new_tables_len++] = strbuf_detach(&next_name, NULL);
+ add->new_tables[add->new_tables_len++] = reftable_buf_detach(&next_name);
done:
delete_tempfile(&tab_file);
- strbuf_release(&temp_tab_file_name);
- strbuf_release(&tab_file_name);
- strbuf_release(&next_name);
+ reftable_buf_release(&temp_tab_file_name);
+ reftable_buf_release(&tab_file_name);
+ reftable_buf_release(&next_name);
reftable_writer_free(wr);
return err;
}
@@ -938,17 +970,24 @@ static int stack_compact_locked(struct reftable_stack *st,
struct reftable_log_expiry_config *config,
struct tempfile **tab_file_out)
{
- struct strbuf next_name = STRBUF_INIT;
- struct strbuf tab_file_path = STRBUF_INIT;
+ struct reftable_buf next_name = REFTABLE_BUF_INIT;
+ struct reftable_buf tab_file_path = REFTABLE_BUF_INIT;
struct reftable_writer *wr = NULL;
struct tempfile *tab_file;
int tab_fd, err = 0;
- format_name(&next_name,
- reftable_reader_min_update_index(st->readers[first]),
- reftable_reader_max_update_index(st->readers[last]));
- stack_filename(&tab_file_path, st, next_name.buf);
- strbuf_addstr(&tab_file_path, ".temp.XXXXXX");
+ err = format_name(&next_name, reftable_reader_min_update_index(st->readers[first]),
+ reftable_reader_max_update_index(st->readers[last]));
+ if (err < 0)
+ goto done;
+
+ err = stack_filename(&tab_file_path, st, next_name.buf);
+ if (err < 0)
+ goto done;
+
+ err = reftable_buf_addstr(&tab_file_path, ".temp.XXXXXX");
+ if (err < 0)
+ goto done;
tab_file = mks_tempfile(tab_file_path.buf);
if (!tab_file) {
@@ -986,8 +1025,8 @@ static int stack_compact_locked(struct reftable_stack *st,
done:
delete_tempfile(&tab_file);
reftable_writer_free(wr);
- strbuf_release(&next_name);
- strbuf_release(&tab_file_path);
+ reftable_buf_release(&next_name);
+ reftable_buf_release(&tab_file_path);
return err;
}
@@ -1111,10 +1150,10 @@ static int stack_compact_range(struct reftable_stack *st,
struct reftable_log_expiry_config *expiry,
unsigned int flags)
{
- struct strbuf tables_list_buf = STRBUF_INIT;
- struct strbuf new_table_name = STRBUF_INIT;
- struct strbuf new_table_path = STRBUF_INIT;
- struct strbuf table_name = STRBUF_INIT;
+ struct reftable_buf tables_list_buf = REFTABLE_BUF_INIT;
+ struct reftable_buf new_table_name = REFTABLE_BUF_INIT;
+ struct reftable_buf new_table_path = REFTABLE_BUF_INIT;
+ struct reftable_buf table_name = REFTABLE_BUF_INIT;
struct lock_file tables_list_lock = LOCK_INIT;
struct lock_file *table_locks = NULL;
struct tempfile *new_table = NULL;
@@ -1167,7 +1206,9 @@ static int stack_compact_range(struct reftable_stack *st,
}
for (i = last + 1; i > first; i--) {
- stack_filename(&table_name, st, reader_name(st->readers[i - 1]));
+ err = stack_filename(&table_name, st, reader_name(st->readers[i - 1]));
+ if (err < 0)
+ goto done;
err = hold_lock_file_for_update(&table_locks[nlocks],
table_name.buf, LOCK_NO_DEREF);
@@ -1370,10 +1411,18 @@ static int stack_compact_range(struct reftable_stack *st,
* it into place now.
*/
if (!is_empty_table) {
- format_name(&new_table_name, st->readers[first]->min_update_index,
- st->readers[last]->max_update_index);
- strbuf_addstr(&new_table_name, ".ref");
- stack_filename(&new_table_path, st, new_table_name.buf);
+ err = format_name(&new_table_name, st->readers[first]->min_update_index,
+ st->readers[last]->max_update_index);
+ if (err < 0)
+ goto done;
+
+ err = reftable_buf_addstr(&new_table_name, ".ref");
+ if (err < 0)
+ goto done;
+
+ err = stack_filename(&new_table_path, st, new_table_name.buf);
+ if (err < 0)
+ goto done;
err = rename_tempfile(&new_table, new_table_path.buf);
if (err < 0) {
@@ -1387,12 +1436,21 @@ static int stack_compact_range(struct reftable_stack *st,
* have just written. In case the compacted table became empty we
* simply skip writing it.
*/
- for (i = 0; i < first_to_replace; i++)
- strbuf_addf(&tables_list_buf, "%s\n", names[i]);
- if (!is_empty_table)
- strbuf_addf(&tables_list_buf, "%s\n", new_table_name.buf);
- for (i = last_to_replace + 1; names[i]; i++)
- strbuf_addf(&tables_list_buf, "%s\n", names[i]);
+ for (i = 0; i < first_to_replace; i++) {
+ if ((err = reftable_buf_addstr(&tables_list_buf, names[i])) < 0 ||
+ (err = reftable_buf_addstr(&tables_list_buf, "\n")) < 0)
+ goto done;
+ }
+ if (!is_empty_table) {
+ if ((err = reftable_buf_addstr(&tables_list_buf, new_table_name.buf)) < 0 ||
+ (err = reftable_buf_addstr(&tables_list_buf, "\n")) < 0)
+ goto done;
+ }
+ for (i = last_to_replace + 1; names[i]; i++) {
+ if ((err = reftable_buf_addstr(&tables_list_buf, names[i])) < 0 ||
+ (err = reftable_buf_addstr(&tables_list_buf, "\n")) < 0)
+ goto done;
+ }
err = write_in_full(get_lock_file_fd(&tables_list_lock),
tables_list_buf.buf, tables_list_buf.len);
@@ -1443,10 +1501,10 @@ done:
reftable_free(table_locks);
delete_tempfile(&new_table);
- strbuf_release(&new_table_name);
- strbuf_release(&new_table_path);
- strbuf_release(&tables_list_buf);
- strbuf_release(&table_name);
+ reftable_buf_release(&new_table_name);
+ reftable_buf_release(&new_table_path);
+ reftable_buf_release(&tables_list_buf);
+ reftable_buf_release(&table_name);
free_names(names);
if (err == REFTABLE_LOCK_ERROR)
@@ -1660,8 +1718,11 @@ static void remove_maybe_stale_table(struct reftable_stack *st, uint64_t max,
uint64_t update_idx = 0;
struct reftable_block_source src = { NULL };
struct reftable_reader *rd = NULL;
- struct strbuf table_path = STRBUF_INIT;
- stack_filename(&table_path, st, name);
+ struct reftable_buf table_path = REFTABLE_BUF_INIT;
+
+ err = stack_filename(&table_path, st, name);
+ if (err < 0)
+ goto done;
err = reftable_block_source_from_file(&src, table_path.buf);
if (err < 0)
@@ -1678,7 +1739,7 @@ static void remove_maybe_stale_table(struct reftable_stack *st, uint64_t max,
unlink(table_path.buf);
}
done:
- strbuf_release(&table_path);
+ reftable_buf_release(&table_path);
}
static int reftable_stack_clean_locked(struct reftable_stack *st)
diff --git a/reftable/system.h b/reftable/system.h
index d0cabd5d17..5ec8583343 100644
--- a/reftable/system.h
+++ b/reftable/system.h
@@ -13,7 +13,6 @@ https://developers.google.com/open-source/licenses/bsd
#include "git-compat-util.h"
#include "lockfile.h"
-#include "strbuf.h"
#include "tempfile.h"
#include "hash.h" /* hash ID, sizes.*/
#include "dir.h" /* remove_dir_recursively, for tests.*/
diff --git a/reftable/writer.c b/reftable/writer.c
index b032a47dec..fd136794d5 100644
--- a/reftable/writer.c
+++ b/reftable/writer.c
@@ -115,7 +115,7 @@ static int writer_reinit_block_writer(struct reftable_writer *w, uint8_t typ)
if (w->next == 0)
block_start = header_size(writer_version(w));
- strbuf_reset(&w->last_key);
+ reftable_buf_reset(&w->last_key);
ret = block_writer_init(&w->block_writer_data, typ, w->block,
w->opts.block_size, block_start,
hash_size(w->opts.hash_id));
@@ -146,8 +146,8 @@ int reftable_writer_new(struct reftable_writer **out,
if (opts.block_size >= (1 << 24))
BUG("configured block size exceeds 16MB");
- strbuf_init(&wp->block_writer_data.last_key, 0);
- strbuf_init(&wp->last_key, 0);
+ reftable_buf_init(&wp->block_writer_data.last_key);
+ reftable_buf_init(&wp->last_key);
REFTABLE_CALLOC_ARRAY(wp->block, opts.block_size);
if (!wp->block) {
reftable_free(wp);
@@ -179,7 +179,7 @@ static void writer_release(struct reftable_writer *w)
block_writer_release(&w->block_writer_data);
w->block_writer = NULL;
writer_clear_index(w);
- strbuf_release(&w->last_key);
+ reftable_buf_release(&w->last_key);
}
}
@@ -190,7 +190,7 @@ void reftable_writer_free(struct reftable_writer *w)
}
struct obj_index_tree_node {
- struct strbuf hash;
+ struct reftable_buf hash;
uint64_t *offsets;
size_t offset_len;
size_t offset_cap;
@@ -198,16 +198,16 @@ struct obj_index_tree_node {
#define OBJ_INDEX_TREE_NODE_INIT \
{ \
- .hash = STRBUF_INIT \
+ .hash = REFTABLE_BUF_INIT \
}
static int obj_index_tree_node_compare(const void *a, const void *b)
{
- return strbuf_cmp(&((const struct obj_index_tree_node *)a)->hash,
+ return reftable_buf_cmp(&((const struct obj_index_tree_node *)a)->hash,
&((const struct obj_index_tree_node *)b)->hash);
}
-static int writer_index_hash(struct reftable_writer *w, struct strbuf *hash)
+static int writer_index_hash(struct reftable_writer *w, struct reftable_buf *hash)
{
uint64_t off = w->next;
struct obj_index_tree_node want = { .hash = *hash };
@@ -217,6 +217,7 @@ static int writer_index_hash(struct reftable_writer *w, struct strbuf *hash)
node = tree_search(w->obj_index_tree, &want, &obj_index_tree_node_compare);
if (!node) {
struct obj_index_tree_node empty = OBJ_INDEX_TREE_NODE_INIT;
+ int err;
key = reftable_malloc(sizeof(*key));
if (!key)
@@ -224,8 +225,10 @@ static int writer_index_hash(struct reftable_writer *w, struct strbuf *hash)
*key = empty;
- strbuf_reset(&key->hash);
- strbuf_addbuf(&key->hash, hash);
+ reftable_buf_reset(&key->hash);
+ err = reftable_buf_add(&key->hash, hash->buf, hash->len);
+ if (err < 0)
+ return err;
tree_insert(&w->obj_index_tree, key,
&obj_index_tree_node_compare);
} else {
@@ -246,17 +249,23 @@ static int writer_index_hash(struct reftable_writer *w, struct strbuf *hash)
static int writer_add_record(struct reftable_writer *w,
struct reftable_record *rec)
{
- struct strbuf key = STRBUF_INIT;
+ struct reftable_buf key = REFTABLE_BUF_INIT;
int err;
- reftable_record_key(rec, &key);
- if (strbuf_cmp(&w->last_key, &key) >= 0) {
+ err = reftable_record_key(rec, &key);
+ if (err < 0)
+ goto done;
+
+ if (reftable_buf_cmp(&w->last_key, &key) >= 0) {
err = REFTABLE_API_ERROR;
goto done;
}
- strbuf_reset(&w->last_key);
- strbuf_addbuf(&w->last_key, &key);
+ reftable_buf_reset(&w->last_key);
+ err = reftable_buf_add(&w->last_key, key.buf, key.len);
+ if (err < 0)
+ goto done;
+
if (!w->block_writer) {
err = writer_reinit_block_writer(w, reftable_record_type(rec));
if (err < 0)
@@ -303,7 +312,7 @@ static int writer_add_record(struct reftable_writer *w,
}
done:
- strbuf_release(&key);
+ reftable_buf_release(&key);
return err;
}
@@ -316,7 +325,7 @@ int reftable_writer_add_ref(struct reftable_writer *w,
.ref = *ref
},
};
- struct strbuf buf = STRBUF_INIT;
+ struct reftable_buf buf = REFTABLE_BUF_INIT;
int err;
if (!ref->refname ||
@@ -331,8 +340,10 @@ int reftable_writer_add_ref(struct reftable_writer *w,
goto out;
if (!w->opts.skip_index_objects && reftable_ref_record_val1(ref)) {
- strbuf_add(&buf, (char *)reftable_ref_record_val1(ref),
- hash_size(w->opts.hash_id));
+ err = reftable_buf_add(&buf, (char *)reftable_ref_record_val1(ref),
+ hash_size(w->opts.hash_id));
+ if (err < 0)
+ goto out;
err = writer_index_hash(w, &buf);
if (err < 0)
@@ -340,9 +351,11 @@ int reftable_writer_add_ref(struct reftable_writer *w,
}
if (!w->opts.skip_index_objects && reftable_ref_record_val2(ref)) {
- strbuf_reset(&buf);
- strbuf_add(&buf, reftable_ref_record_val2(ref),
- hash_size(w->opts.hash_id));
+ reftable_buf_reset(&buf);
+ err = reftable_buf_add(&buf, reftable_ref_record_val2(ref),
+ hash_size(w->opts.hash_id));
+ if (err < 0)
+ goto out;
err = writer_index_hash(w, &buf);
if (err < 0)
@@ -352,7 +365,7 @@ int reftable_writer_add_ref(struct reftable_writer *w,
err = 0;
out:
- strbuf_release(&buf);
+ reftable_buf_release(&buf);
return err;
}
@@ -393,7 +406,7 @@ int reftable_writer_add_log(struct reftable_writer *w,
struct reftable_log_record *log)
{
char *input_log_message = NULL;
- struct strbuf cleaned_message = STRBUF_INIT;
+ struct reftable_buf cleaned_message = REFTABLE_BUF_INIT;
int err = 0;
if (log->value_type == REFTABLE_LOG_DELETION)
@@ -404,24 +417,34 @@ int reftable_writer_add_log(struct reftable_writer *w,
input_log_message = log->value.update.message;
if (!w->opts.exact_log_message && log->value.update.message) {
- strbuf_addstr(&cleaned_message, log->value.update.message);
+ err = reftable_buf_addstr(&cleaned_message, log->value.update.message);
+ if (err < 0)
+ goto done;
+
while (cleaned_message.len &&
- cleaned_message.buf[cleaned_message.len - 1] == '\n')
- strbuf_setlen(&cleaned_message,
- cleaned_message.len - 1);
+ cleaned_message.buf[cleaned_message.len - 1] == '\n') {
+ err = reftable_buf_setlen(&cleaned_message,
+ cleaned_message.len - 1);
+ if (err < 0)
+ goto done;
+ }
if (strchr(cleaned_message.buf, '\n')) {
/* multiple lines not allowed. */
err = REFTABLE_API_ERROR;
goto done;
}
- strbuf_addstr(&cleaned_message, "\n");
+
+ err = reftable_buf_addstr(&cleaned_message, "\n");
+ if (err < 0)
+ goto done;
+
log->value.update.message = cleaned_message.buf;
}
err = reftable_writer_add_log_verbatim(w, log);
log->value.update.message = input_log_message;
done:
- strbuf_release(&cleaned_message);
+ reftable_buf_release(&cleaned_message);
return err;
}
@@ -504,7 +527,7 @@ static int writer_finish_section(struct reftable_writer *w)
return err;
for (i = 0; i < idx_len; i++)
- strbuf_release(&idx[i].last_key);
+ reftable_buf_release(&idx[i].last_key);
reftable_free(idx);
}
@@ -521,13 +544,13 @@ static int writer_finish_section(struct reftable_writer *w)
bstats->max_index_level = max_level;
/* Reinit lastKey, as the next section can start with any key. */
- strbuf_reset(&w->last_key);
+ reftable_buf_reset(&w->last_key);
return 0;
}
struct common_prefix_arg {
- struct strbuf *last;
+ struct reftable_buf *last;
int max;
};
@@ -594,7 +617,7 @@ static void object_record_free(void *void_arg UNUSED, void *key)
struct obj_index_tree_node *entry = key;
REFTABLE_FREE_AND_NULL(entry->offsets);
- strbuf_release(&entry->hash);
+ reftable_buf_release(&entry->hash);
reftable_free(entry);
}
@@ -708,7 +731,7 @@ done:
static void writer_clear_index(struct reftable_writer *w)
{
for (size_t i = 0; w->index && i < w->index_len; i++)
- strbuf_release(&w->index[i].last_key);
+ reftable_buf_release(&w->index[i].last_key);
REFTABLE_FREE_AND_NULL(w->index);
w->index_len = 0;
w->index_cap = 0;
@@ -717,7 +740,7 @@ static void writer_clear_index(struct reftable_writer *w)
static int writer_flush_nonempty_block(struct reftable_writer *w)
{
struct reftable_index_record index_record = {
- .last_key = STRBUF_INIT,
+ .last_key = REFTABLE_BUF_INIT,
};
uint8_t typ = block_writer_type(w->block_writer);
struct reftable_block_stats *bstats;
@@ -777,8 +800,11 @@ static int writer_flush_nonempty_block(struct reftable_writer *w)
return REFTABLE_OUT_OF_MEMORY_ERROR;
index_record.offset = w->next;
- strbuf_reset(&index_record.last_key);
- strbuf_addbuf(&index_record.last_key, &w->block_writer->last_key);
+ reftable_buf_reset(&index_record.last_key);
+ err = reftable_buf_add(&index_record.last_key, w->block_writer->last_key.buf,
+ w->block_writer->last_key.len);
+ if (err < 0)
+ return err;
w->index[w->index_len] = index_record;
w->index_len++;
diff --git a/reftable/writer.h b/reftable/writer.h
index 8d0df9cc52..e8a6fbb785 100644
--- a/reftable/writer.h
+++ b/reftable/writer.h
@@ -19,7 +19,7 @@ struct reftable_writer {
int (*flush)(void *);
void *write_arg;
int pending_padding;
- struct strbuf last_key;
+ struct reftable_buf last_key;
/* offset of next block to write. */
uint64_t next;
diff --git a/setup.c b/setup.c
index 94e79b2e48..7b648de027 100644
--- a/setup.c
+++ b/setup.c
@@ -2420,7 +2420,7 @@ static void separate_git_dir(const char *git_dir, const char *git_link)
if (rename(src, git_dir))
die_errno(_("unable to move %s to %s"), src, git_dir);
- repair_worktrees(NULL, NULL);
+ repair_worktrees_after_gitdir_move(src);
}
write_file(git_link, "gitdir: %s", git_dir);
diff --git a/t/README b/t/README
index 8dcb778e26..8c0319b58e 100644
--- a/t/README
+++ b/t/README
@@ -465,8 +465,9 @@ GIT_TEST_DEFAULT_HASH=<hash-algo> specifies which hash algorithm to
use in the test scripts. Recognized values for <hash-algo> are "sha1"
and "sha256".
-GIT_TEST_DEFAULT_REF_FORMAT=<format> specifies which ref storage format
-to use in the test scripts. Recognized values for <format> are "files".
+GIT_TEST_DEFAULT_REF_FORMAT=<format> specifies which ref storage format to use
+in the test scripts. Recognized values for <format> are "files" and
+"reftable".
GIT_TEST_NO_WRITE_REV_INDEX=<boolean>, when true disables the
'pack.writeReverseIndex' setting.
diff --git a/t/helper/test-rot13-filter.c b/t/helper/test-rot13-filter.c
index 7e1d9e0ee4..ff407b575c 100644
--- a/t/helper/test-rot13-filter.c
+++ b/t/helper/test-rot13-filter.c
@@ -9,7 +9,7 @@
* ("clean", "smudge", etc).
*
* When --always-delay is given all pathnames with the "can-delay" flag
- * that don't appear on the list bellow are delayed with a count of 1
+ * that don't appear on the list below are delayed with a count of 1
* (see more below).
*
* This implementation supports special test cases:
diff --git a/t/lib-bundle.sh b/t/lib-bundle.sh
index cf7ed818b2..62b7bb13c8 100644
--- a/t/lib-bundle.sh
+++ b/t/lib-bundle.sh
@@ -11,7 +11,7 @@ convert_bundle_to_pack () {
}
# Check count of objects in a bundle file.
-# We can use "--thin" opiton to check thin pack, which must be fixed by
+# We can use "--thin" option to check thin pack, which must be fixed by
# command `git-index-pack --fix-thin --stdin`.
test_bundle_object_count () {
thin=
diff --git a/t/lib-rebase.sh b/t/lib-rebase.sh
index 11d2dc9fe3..0dd764310d 100644
--- a/t/lib-rebase.sh
+++ b/t/lib-rebase.sh
@@ -187,7 +187,7 @@ set_reword_editor () {
exit 1
fi
fi &&
- # There should be no uncommited changes
+ # There should be no uncommitted changes
git diff --exit-code HEAD &&
# The todo-list should be re-read after a reword
GIT_SEQUENCE_EDITOR="\"$PWD/reword-sequence-editor.sh\"" \
diff --git a/t/lib-sudo.sh b/t/lib-sudo.sh
index b4d7788f4e..477e0fdc04 100644
--- a/t/lib-sudo.sh
+++ b/t/lib-sudo.sh
@@ -6,7 +6,7 @@ run_with_sudo () {
local RUN="$TEST_DIRECTORY/$$.sh"
write_script "$RUN" "$TEST_SHELL_PATH"
# avoid calling "$RUN" directly so sudo doesn't get a chance to
- # override the shell, add aditional restrictions or even reject
+ # override the shell, add additional restrictions or even reject
# running the script because its security policy deem it unsafe
sudo "$TEST_SHELL_PATH" -c "\"$RUN\""
ret=$?
diff --git a/t/lib-unicode-nfc-nfd.sh b/t/lib-unicode-nfc-nfd.sh
index 22232247ef..aed0a4dd44 100755
--- a/t/lib-unicode-nfc-nfd.sh
+++ b/t/lib-unicode-nfc-nfd.sh
@@ -74,7 +74,7 @@ test_lazy_prereq UNICODE_NFD_PRESERVED '
# Yielding: \xcf \x89 + \xcc \x94 + \xcd \x82
#
# Note that I've used the canonical ordering of the
-# combinining characters. It is also possible to
+# combining characters. It is also possible to
# swap them. My testing shows that that non-standard
# ordering also causes a collision in mkdir. However,
# the resulting names don't draw correctly on the
diff --git a/t/perf/p7527-builtin-fsmonitor.sh b/t/perf/p7527-builtin-fsmonitor.sh
index c3f9a4caa4..90164327e8 100755
--- a/t/perf/p7527-builtin-fsmonitor.sh
+++ b/t/perf/p7527-builtin-fsmonitor.sh
@@ -95,7 +95,7 @@ test_expect_success "Setup borrowed repo (fsm+uc)" "
# time is not useful.
#
# Create a temp branch and do all work relative to it so that we don't
-# accidentially alter the real ballast branch.
+# accidentally alter the real ballast branch.
#
test_expect_success "Setup borrowed repo (temp ballast branch)" "
test_might_fail git -C $REPO checkout $BALLAST_BR &&
diff --git a/t/perf/perf-lib.sh b/t/perf/perf-lib.sh
index ab0c763411..8ab6d9c469 100644
--- a/t/perf/perf-lib.sh
+++ b/t/perf/perf-lib.sh
@@ -282,7 +282,7 @@ test_perf_ () {
# Run the performance test script specified in perf-test with
# optional prerequisite and setup steps.
# Options:
-# --prereq prerequisites: Skip the test if prequisites aren't met
+# --prereq prerequisites: Skip the test if prerequisites aren't met
# --setup "setup-steps": Run setup steps prior to each measured iteration
#
test_perf () {
@@ -309,7 +309,7 @@ test_size_ () {
# prerequisites and setup steps. Returns the numeric value
# returned by size-test.
# Options:
-# --prereq prerequisites: Skip the test if prequisites aren't met
+# --prereq prerequisites: Skip the test if prerequisites aren't met
# --setup "setup-steps": Run setup steps prior to the size measurement
test_size () {
diff --git a/t/t0000-basic.sh b/t/t0000-basic.sh
index 98b81e4d63..35c5c2b4f9 100755
--- a/t/t0000-basic.sh
+++ b/t/t0000-basic.sh
@@ -684,7 +684,7 @@ test_expect_success 'subtest: tests respect lazy prerequisites' '
write_and_run_sub_test_lib_test lazy-prereqs <<-\EOF &&
test_lazy_prereq LAZY_TRUE true
- test_expect_success LAZY_TRUE "lazy prereq is satisifed" "true"
+ test_expect_success LAZY_TRUE "lazy prereq is satisfied" "true"
test_expect_success !LAZY_TRUE "negative lazy prereq" "false"
test_lazy_prereq LAZY_FALSE false
@@ -695,7 +695,7 @@ test_expect_success 'subtest: tests respect lazy prerequisites' '
EOF
check_sub_test_lib_test lazy-prereqs <<-\EOF
- ok 1 - lazy prereq is satisifed
+ ok 1 - lazy prereq is satisfied
ok 2 # skip negative lazy prereq (missing !LAZY_TRUE)
ok 3 # skip lazy prereq not satisfied (missing LAZY_FALSE)
ok 4 - negative false prereq
diff --git a/t/t0021-conversion.sh b/t/t0021-conversion.sh
index eeb2714d9d..9e6c6ee0d4 100755
--- a/t/t0021-conversion.sh
+++ b/t/t0021-conversion.sh
@@ -1116,11 +1116,11 @@ do
test_delayed_checkout_progress test_terminal git checkout $opt
'
- test_expect_success PERL "delayed checkout ommits progress on non-tty ($mode checkout)" '
+ test_expect_success PERL "delayed checkout omits progress on non-tty ($mode checkout)" '
test_delayed_checkout_progress ! git checkout $opt
'
- test_expect_success PERL,TTY "delayed checkout ommits progress with --quiet ($mode checkout)" '
+ test_expect_success PERL,TTY "delayed checkout omits progress with --quiet ($mode checkout)" '
test_delayed_checkout_progress ! test_terminal git checkout --quiet $opt
'
diff --git a/t/t0212/parse_events.perl b/t/t0212/parse_events.perl
index 30a9f51e9f..7146476c69 100644
--- a/t/t0212/parse_events.perl
+++ b/t/t0212/parse_events.perl
@@ -204,7 +204,7 @@ while (<>) {
}
# A series of potentially nested and threaded region and data events
- # is fundamentally incompatibile with the type of summary record we
+ # is fundamentally incompatible with the type of summary record we
# are building in this script. Since they are intended for
# perf-trace-like analysis rather than a result summary, we ignore
# most of them here.
diff --git a/t/t0600-reffiles-backend.sh b/t/t0600-reffiles-backend.sh
index 20df336cc3..bef2b70871 100755
--- a/t/t0600-reffiles-backend.sh
+++ b/t/t0600-reffiles-backend.sh
@@ -271,7 +271,7 @@ test_expect_success 'setup worktree' '
# Some refs (refs/bisect/*, pseudorefs) are kept per worktree, so they should
# only appear in the for-each-reflog output if it is called from the correct
# worktree, which is exercised in this test. This test is poorly written for
-# mulitple reasons: 1) it creates invalidly formatted log entres. 2) it uses
+# multiple reasons: 1) it creates invalidly formatted log entries. 2) it uses
# direct FS access for creating the reflogs. 3) PSEUDO-WT and refs/bisect/random
# do not create reflogs by default, so it is not testing a realistic scenario.
test_expect_success 'for_each_reflog()' '
diff --git a/t/t1016-compatObjectFormat.sh b/t/t1016-compatObjectFormat.sh
index be3206a16f..92024fe51d 100755
--- a/t/t1016-compatObjectFormat.sh
+++ b/t/t1016-compatObjectFormat.sh
@@ -117,7 +117,7 @@ do
git config extensions.objectformat $hash &&
git config extensions.compatobjectformat $(compat_hash $hash) &&
git config gpg.program $TEST_DIRECTORY/t1016/gpg &&
- echo "Hellow World!" > hello &&
+ echo "Hello World!" > hello &&
eval hello_${hash}_oid=$(git hash-object hello) &&
git update-index --add hello &&
git commit -m "Initial commit" &&
diff --git a/t/t1092-sparse-checkout-compatibility.sh b/t/t1092-sparse-checkout-compatibility.sh
index 3d44bd7643..2157f37da3 100755
--- a/t/t1092-sparse-checkout-compatibility.sh
+++ b/t/t1092-sparse-checkout-compatibility.sh
@@ -708,7 +708,7 @@ test_expect_success 'reset with wildcard pathspec' '
test_all_match git ls-files -s -- deep &&
# The following `git reset`s result in updating the index on files with
- # `skip-worktree` enabled. To avoid failing due to discrepencies in reported
+ # `skip-worktree` enabled. To avoid failing due to discrepancies in reported
# "modified" files, `test_sparse_match` reset is performed separately from
# "full-checkout" reset, then the index contents of all repos are verified.
@@ -824,7 +824,7 @@ test_expect_success 'update-index --remove outside sparse definition' '
# Reset the state
test_all_match git reset --hard &&
- # --force-remove supercedes --ignore-skip-worktree-entries, removing
+ # --force-remove supersedes --ignore-skip-worktree-entries, removing
# a skip-worktree file from the index (and disk) when both are specified
# with --remove
test_sparse_match git update-index --force-remove --ignore-skip-worktree-entries folder1/a &&
@@ -2081,7 +2081,7 @@ test_expect_success 'grep is not expanded' '
test_expect_failure 'grep within submodules is not expanded' '
init_repos_as_submodules &&
- # do not use ensure_not_expanded() here, becasue `grep` should be
+ # do not use ensure_not_expanded() here, because `grep` should be
# run in the superproject, not in "./sparse-index"
GIT_TRACE2_EVENT="$(pwd)/trace2.txt" \
git grep --cached --recurse-submodules a -- "*/folder1/*" &&
diff --git a/t/t1400-update-ref.sh b/t/t1400-update-ref.sh
index eb1691860d..bb057596f1 100755
--- a/t/t1400-update-ref.sh
+++ b/t/t1400-update-ref.sh
@@ -1838,10 +1838,10 @@ do
test_expect_success "stdin $type create dangling symref ref works" '
test_when_finished "git symbolic-ref -d refs/heads/symref" &&
- format_command $type "symref-create refs/heads/symref" "refs/heads/unkown" >stdin &&
+ format_command $type "symref-create refs/heads/symref" "refs/heads/unknown" >stdin &&
git update-ref --stdin $type --no-deref <stdin &&
git symbolic-ref refs/heads/symref >expect &&
- echo refs/heads/unkown >actual &&
+ echo refs/heads/unknown >actual &&
test_cmp expect actual
'
diff --git a/t/t1506-rev-parse-diagnosis.sh b/t/t1506-rev-parse-diagnosis.sh
index ef40511d89..a3464976e3 100755
--- a/t/t1506-rev-parse-diagnosis.sh
+++ b/t/t1506-rev-parse-diagnosis.sh
@@ -195,7 +195,7 @@ test_expect_success 'dotdot is not an empty set' '
'
test_expect_success 'dotdot does not peel endpoints' '
- git tag -a -m "annote" annotated HEAD &&
+ git tag -a -m "annotate" annotated HEAD &&
A=$(git rev-parse annotated) &&
H=$(git rev-parse annotated^0) &&
{
diff --git a/t/t2082-parallel-checkout-attributes.sh b/t/t2082-parallel-checkout-attributes.sh
index aec55496eb..da06cafad7 100755
--- a/t/t2082-parallel-checkout-attributes.sh
+++ b/t/t2082-parallel-checkout-attributes.sh
@@ -91,7 +91,7 @@ test_expect_success 'parallel-checkout with eol conversions' '
# Entries that require an external filter are not eligible for parallel
# checkout. Check that both the parallel-eligible and non-eligible entries are
-# properly writen in a single checkout operation.
+# properly written in a single checkout operation.
#
test_expect_success 'parallel-checkout and external filter' '
set_checkout_config 2 0 &&
diff --git a/t/t2401-worktree-prune.sh b/t/t2401-worktree-prune.sh
index 71aa9bcd62..976d048e3e 100755
--- a/t/t2401-worktree-prune.sh
+++ b/t/t2401-worktree-prune.sh
@@ -120,4 +120,23 @@ test_expect_success 'prune duplicate (main/linked)' '
! test -d .git/worktrees/wt
'
+test_expect_success 'not prune proper worktrees when run inside linked worktree' '
+ test_when_finished rm -rf repo wt_ext &&
+ git init repo &&
+ (
+ cd repo &&
+ echo content >file &&
+ git add file &&
+ git commit -m msg &&
+ git worktree add ../wt_ext &&
+ git worktree add wt_int &&
+ cd wt_int &&
+ git worktree prune -v >out &&
+ test_must_be_empty out &&
+ cd ../../wt_ext &&
+ git worktree prune -v >out &&
+ test_must_be_empty out
+ )
+'
+
test_done
diff --git a/t/t2406-worktree-repair.sh b/t/t2406-worktree-repair.sh
index edbf502ec5..7686e60f6a 100755
--- a/t/t2406-worktree-repair.sh
+++ b/t/t2406-worktree-repair.sh
@@ -197,4 +197,23 @@ test_expect_success 'repair moved main and linked worktrees' '
test_cmp expect-gitfile sidemoved/.git
'
+test_expect_success 'repair copied main and linked worktrees' '
+ test_when_finished "rm -rf orig dup" &&
+ mkdir -p orig &&
+ git -C orig init main &&
+ test_commit -C orig/main nothing &&
+ git -C orig/main worktree add ../linked &&
+ cp orig/main/.git/worktrees/linked/gitdir orig/main.expect &&
+ cp orig/linked/.git orig/linked.expect &&
+ cp -R orig dup &&
+ sed "s,orig/linked/\.git$,dup/linked/.git," orig/main.expect >dup/main.expect &&
+ sed "s,orig/main/\.git/worktrees/linked$,dup/main/.git/worktrees/linked," \
+ orig/linked.expect >dup/linked.expect &&
+ git -C dup/main worktree repair ../linked &&
+ test_cmp orig/main.expect orig/main/.git/worktrees/linked/gitdir &&
+ test_cmp orig/linked.expect orig/linked/.git &&
+ test_cmp dup/main.expect dup/main/.git/worktrees/linked/gitdir &&
+ test_cmp dup/linked.expect dup/linked/.git
+'
+
test_done
diff --git a/t/t2408-worktree-relative.sh b/t/t2408-worktree-relative.sh
new file mode 100755
index 0000000000..a3136db7e2
--- /dev/null
+++ b/t/t2408-worktree-relative.sh
@@ -0,0 +1,39 @@
+#!/bin/sh
+
+test_description='test worktrees linked with relative paths'
+
+TEST_PASSES_SANITIZE_LEAK=true
+. ./test-lib.sh
+
+test_expect_success 'links worktrees with relative paths' '
+ test_when_finished rm -rf repo &&
+ git init repo &&
+ (
+ cd repo &&
+ test_commit initial &&
+ git worktree add wt1 &&
+ echo "../../../wt1/.git" >expected_gitdir &&
+ cat .git/worktrees/wt1/gitdir >actual_gitdir &&
+ echo "gitdir: ../.git/worktrees/wt1" >expected_git &&
+ cat wt1/.git >actual_git &&
+ test_cmp expected_gitdir actual_gitdir &&
+ test_cmp expected_git actual_git
+ )
+'
+
+test_expect_success 'move repo without breaking relative internal links' '
+ test_when_finished rm -rf repo moved &&
+ git init repo &&
+ (
+ cd repo &&
+ test_commit initial &&
+ git worktree add wt1 &&
+ cd .. &&
+ mv repo moved &&
+ cd moved/wt1 &&
+ git status >out 2>err &&
+ test_must_be_empty err
+ )
+'
+
+test_done
diff --git a/t/t4058-diff-duplicates.sh b/t/t4058-diff-duplicates.sh
index 2501c89c1c..18e5ac88c3 100755
--- a/t/t4058-diff-duplicates.sh
+++ b/t/t4058-diff-duplicates.sh
@@ -10,6 +10,8 @@
# that the diff output isn't wildly unreasonable.
test_description='test tree diff when trees have duplicate entries'
+
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
# make_tree_entry <mode> <mode> <sha1>
@@ -132,22 +134,23 @@ test_expect_success 'create a few commits' '
rm commit_id up final
'
-test_expect_failure 'git read-tree does not segfault' '
- test_when_finished rm .git/index.lock &&
- test_might_fail git read-tree --reset base
+test_expect_success 'git read-tree does not segfault' '
+ test_must_fail git read-tree --reset base 2>err &&
+ test_grep "error: corrupted cache-tree has entries not present in index" err
'
-test_expect_failure 'reset --hard does not segfault' '
- test_when_finished rm .git/index.lock &&
+test_expect_success 'reset --hard does not segfault' '
git checkout base &&
- test_might_fail git reset --hard
+ test_must_fail git reset --hard 2>err &&
+ test_grep "error: corrupted cache-tree has entries not present in index" err
'
-test_expect_failure 'git diff HEAD does not segfault' '
+test_expect_success 'git diff HEAD does not segfault' '
git checkout base &&
GIT_TEST_CHECK_CACHE_TREE=false &&
git reset --hard &&
- test_might_fail git diff HEAD
+ test_must_fail git diff HEAD 2>err &&
+ test_grep "error: corrupted cache-tree has entries not present in index" err
'
test_expect_failure 'can switch to another branch when status is empty' '
diff --git a/t/t4201-shortlog.sh b/t/t4201-shortlog.sh
index c20c885724..5b5d3b637c 100755
--- a/t/t4201-shortlog.sh
+++ b/t/t4201-shortlog.sh
@@ -143,6 +143,10 @@ test_expect_success 'shortlog from non-git directory refuses extra arguments' '
test_grep "too many arguments" out
'
+test_expect_success 'shortlog --author from non-git directory does not segfault' '
+ nongit git shortlog --author=author </dev/null
+'
+
test_expect_success 'shortlog should add newline when input line matches wraplen' '
cat >expect <<\EOF &&
A U Thor (2):
diff --git a/t/t4205-log-pretty-formats.sh b/t/t4205-log-pretty-formats.sh
index eb63ce011f..57b8b79738 100755
--- a/t/t4205-log-pretty-formats.sh
+++ b/t/t4205-log-pretty-formats.sh
@@ -137,7 +137,7 @@ test_expect_success 'NUL separation with --stat' '
test_expect_failure 'NUL termination with --stat' '
stat0_part=$(git diff --stat HEAD^ HEAD) &&
stat1_part=$(git diff-tree --no-commit-id --stat --root HEAD^) &&
- printf "add bar\n$stat0_part\n\0$(commit_msg)\n$stat1_part\n0" >expected &&
+ printf "add bar\n$stat0_part\n\0$(commit_msg)\n$stat1_part\n\0" >expected &&
git log -z --stat --pretty="tformat:%s" >actual &&
test_cmp expected actual
'
diff --git a/t/t5572-pull-submodule.sh b/t/t5572-pull-submodule.sh
index 916e58c166..9b6cf8d88b 100755
--- a/t/t5572-pull-submodule.sh
+++ b/t/t5572-pull-submodule.sh
@@ -230,6 +230,7 @@ test_expect_success 'branch has no merge base with remote-tracking counterpart'
test_create_repo a-submodule &&
test_commit -C a-submodule foo &&
+ test_commit -C a-submodule bar &&
test_create_repo parent &&
git -C parent submodule add "$(pwd)/a-submodule" &&
@@ -246,4 +247,23 @@ test_expect_success 'branch has no merge base with remote-tracking counterpart'
git -C child pull --recurse-submodules --rebase
'
+test_expect_success 'fetch submodule remote of different name from superproject' '
+ git -C child remote rename origin o1 &&
+ git -C child submodule update --init &&
+
+ # Needs to create unreachable commit from current master branch.
+ git -C a-submodule checkout -b newmain HEAD^ &&
+ test_commit -C a-submodule echo &&
+ test_commit -C a-submodule moreecho &&
+ subc=$(git -C a-submodule rev-parse --short HEAD) &&
+
+ git -C parent/a-submodule fetch &&
+ git -C parent/a-submodule checkout "$subc" &&
+ git -C parent commit -m "update submodule" a-submodule &&
+ git -C a-submodule reset --hard HEAD^^ &&
+
+ git -C child pull --no-recurse-submodules &&
+ git -C child submodule update
+'
+
test_done
diff --git a/t/t6050-replace.sh b/t/t6050-replace.sh
index d7702fc756..deba3ca430 100755
--- a/t/t6050-replace.sh
+++ b/t/t6050-replace.sh
@@ -98,30 +98,42 @@ test_expect_success 'set up buggy branch' '
'
test_expect_success 'replace the author' '
- git cat-file commit $HASH2 | grep "author A U Thor" &&
- R=$(git cat-file commit $HASH2 | sed -e "s/A U/O/" | git hash-object -t commit --stdin -w) &&
- git cat-file commit $R | grep "author O Thor" &&
+ git cat-file commit $HASH2 >actual &&
+ test_grep "author A U Thor" actual &&
+ R=$(sed -e "s/A U/O/" actual | git hash-object -t commit --stdin -w) &&
+ git cat-file commit $R >actual &&
+ test_grep "author O Thor" actual &&
git update-ref refs/replace/$HASH2 $R &&
- git show HEAD~5 | grep "O Thor" &&
- git show $HASH2 | grep "O Thor"
+ git show HEAD~5 >actual &&
+ test_grep "O Thor" actual &&
+ git show $HASH2 >actual &&
+ test_grep "O Thor" actual
'
test_expect_success 'test --no-replace-objects option' '
- git cat-file commit $HASH2 | grep "author O Thor" &&
- git --no-replace-objects cat-file commit $HASH2 | grep "author A U Thor" &&
- git show $HASH2 | grep "O Thor" &&
- git --no-replace-objects show $HASH2 | grep "A U Thor"
+ git cat-file commit $HASH2 >actual &&
+ test_grep "author O Thor" actual &&
+ git --no-replace-objects cat-file commit $HASH2 >actual &&
+ test_grep "author A U Thor" actual &&
+ git show $HASH2 >actual &&
+ test_grep "O Thor" actual &&
+ git --no-replace-objects show $HASH2 >actual &&
+ test_grep "A U Thor" actual
'
test_expect_success 'test GIT_NO_REPLACE_OBJECTS env variable' '
- GIT_NO_REPLACE_OBJECTS=1 git cat-file commit $HASH2 | grep "author A U Thor" &&
- GIT_NO_REPLACE_OBJECTS=1 git show $HASH2 | grep "A U Thor"
+ GIT_NO_REPLACE_OBJECTS=1 git cat-file commit $HASH2 >actual &&
+ test_grep "author A U Thor" actual &&
+ GIT_NO_REPLACE_OBJECTS=1 git show $HASH2 >actual &&
+ test_grep "A U Thor" actual
'
test_expect_success 'test core.usereplacerefs config option' '
test_config core.usereplacerefs false &&
- git cat-file commit $HASH2 | grep "author A U Thor" &&
- git show $HASH2 | grep "A U Thor"
+ git cat-file commit $HASH2 >actual &&
+ test_grep "author A U Thor" actual &&
+ git show $HASH2 >actual &&
+ test_grep "A U Thor" actual
'
cat >tag.sig <<EOF
@@ -148,14 +160,18 @@ test_expect_success 'repack, clone and fetch work' '
git clone --no-hardlinks . clone_dir &&
(
cd clone_dir &&
- git show HEAD~5 | grep "A U Thor" &&
- git show $HASH2 | grep "A U Thor" &&
+ git show HEAD~5 >actual &&
+ test_grep "A U Thor" actual &&
+ git show $HASH2 >actual &&
+ test_grep "A U Thor" actual &&
git cat-file commit $R &&
git repack -a -d &&
test_must_fail git cat-file commit $R &&
git fetch ../ "refs/replace/*:refs/replace/*" &&
- git show HEAD~5 | grep "O Thor" &&
- git show $HASH2 | grep "O Thor" &&
+ git show HEAD~5 >actual &&
+ test_grep "O Thor" actual &&
+ git show $HASH2 >actual &&
+ test_grep "O Thor" actual &&
git cat-file commit $R
)
'
@@ -169,13 +185,15 @@ test_expect_success '"git replace" listing and deleting' '
test_must_fail git replace --delete &&
test_must_fail git replace -l -d $HASH2 &&
git replace -d $HASH2 &&
- git show $HASH2 | grep "A U Thor" &&
+ git show $HASH2 >actual &&
+ test_grep "A U Thor" actual &&
test -z "$(git replace -l)"
'
test_expect_success '"git replace" replacing' '
git replace $HASH2 $R &&
- git show $HASH2 | grep "O Thor" &&
+ git show $HASH2 >actual &&
+ test_grep "O Thor" actual &&
test_must_fail git replace $HASH2 $R &&
git replace -f $HASH2 $R &&
test_must_fail git replace -f &&
@@ -186,7 +204,8 @@ test_expect_success '"git replace" resolves sha1' '
SHORTHASH2=$(git rev-parse --short=8 $HASH2) &&
git replace -d $SHORTHASH2 &&
git replace $SHORTHASH2 $R &&
- git show $HASH2 | grep "O Thor" &&
+ git show $HASH2 >actual &&
+ test_grep "O Thor" actual &&
test_must_fail git replace $HASH2 $R &&
git replace -f $HASH2 $R &&
test_must_fail git replace --force &&
@@ -209,10 +228,12 @@ test_expect_success '"git replace" resolves sha1' '
#
test_expect_success 'create parallel branch without the bug' '
git replace -d $HASH2 &&
- git show $HASH2 | grep "A U Thor" &&
+ git show $HASH2 >actual &&
+ test_grep "A U Thor" actual &&
git checkout $HASH1 &&
git cherry-pick $HASH2 &&
- git show $HASH5 | git apply &&
+ git show $HASH5 >actual &&
+ git apply actual &&
git commit --amend -m "hello: 4 more lines WITHOUT the bug" hello &&
PARA2=$(git rev-parse --verify HEAD) &&
git cherry-pick $HASH3 &&
@@ -225,7 +246,8 @@ test_expect_success 'create parallel branch without the bug' '
git checkout main &&
cur=$(git rev-parse --verify HEAD) &&
test "$cur" = "$HASH7" &&
- git log --pretty=oneline | grep $PARA2 &&
+ git log --pretty=oneline >actual &&
+ test_grep $PARA2 actual &&
git remote add cloned ./clone_dir
'
@@ -234,23 +256,30 @@ test_expect_success 'push to cloned repo' '
(
cd clone_dir &&
git checkout parallel &&
- git log --pretty=oneline | grep $PARA2
+ git log --pretty=oneline >actual &&
+ test_grep $PARA2 actual
)
'
test_expect_success 'push branch with replacement' '
- git cat-file commit $PARA3 | grep "author A U Thor" &&
- S=$(git cat-file commit $PARA3 | sed -e "s/A U/O/" | git hash-object -t commit --stdin -w) &&
- git cat-file commit $S | grep "author O Thor" &&
+ git cat-file commit $PARA3 >actual &&
+ test_grep "author A U Thor" actual &&
+ S=$(sed -e "s/A U/O/" actual | git hash-object -t commit --stdin -w) &&
+ git cat-file commit $S >actual &&
+ test_grep "author O Thor" actual &&
git replace $PARA3 $S &&
- git show $HASH6~2 | grep "O Thor" &&
- git show $PARA3 | grep "O Thor" &&
+ git show $HASH6~2 >actual &&
+ test_grep "O Thor" actual &&
+ git show $PARA3 >actual &&
+ test_grep "O Thor" actual &&
git push cloned $HASH6^:refs/heads/parallel2 &&
(
cd clone_dir &&
git checkout parallel2 &&
- git log --pretty=oneline | grep $PARA3 &&
- git show $PARA3 | grep "A U Thor"
+ git log --pretty=oneline >actual &&
+ test_grep $PARA3 actual &&
+ git show $PARA3 >actual &&
+ test_grep "A U Thor" actual
)
'
@@ -260,14 +289,14 @@ test_expect_success 'fetch branch with replacement' '
cd clone_dir &&
git fetch origin refs/heads/tofetch:refs/heads/parallel3 &&
git log --pretty=oneline parallel3 >output.txt &&
- ! grep $PARA3 output.txt &&
+ test_grep ! $PARA3 output.txt &&
git show $PARA3 >para3.txt &&
- grep "A U Thor" para3.txt &&
+ test_grep "A U Thor" para3.txt &&
git fetch origin "refs/replace/*:refs/replace/*" &&
git log --pretty=oneline parallel3 >output.txt &&
- grep $PARA3 output.txt &&
+ test_grep $PARA3 output.txt &&
git show $PARA3 >para3.txt &&
- grep "O Thor" para3.txt
+ test_grep "O Thor" para3.txt
)
'
@@ -284,8 +313,8 @@ test_expect_success 'bisect and replacements' '
'
test_expect_success 'index-pack and replacements' '
- git --no-replace-objects rev-list --objects HEAD |
- git --no-replace-objects pack-objects test- &&
+ git --no-replace-objects rev-list --objects HEAD >actual &&
+ git --no-replace-objects pack-objects test- <actual &&
git index-pack test-*.pack
'
@@ -319,7 +348,8 @@ test_expect_success '-f option bypasses the type check' '
'
test_expect_success 'git cat-file --batch works on replace objects' '
- git replace | grep $PARA3 &&
+ git replace >actual &&
+ test_grep $PARA3 actual &&
echo $PARA3 | git cat-file --batch
'
@@ -344,7 +374,8 @@ test_expect_success 'test --format medium' '
echo "$PARA3 -> $S" &&
echo "$MYTAG -> $HASH1"
} | sort >expected &&
- git replace -l --format medium | sort >actual &&
+ git replace -l --format medium >output &&
+ sort output >actual &&
test_cmp expected actual
'
@@ -356,7 +387,8 @@ test_expect_success 'test --format long' '
echo "$PARA3 (commit) -> $S (commit)" &&
echo "$MYTAG (tag) -> $HASH1 (commit)"
} | sort >expected &&
- git replace --format=long | sort >actual &&
+ git replace --format=long >output &&
+ sort output >actual &&
test_cmp expected actual
'
@@ -374,12 +406,16 @@ test_expect_success 'setup fake editors' '
test_expect_success '--edit with and without already replaced object' '
test_must_fail env GIT_EDITOR=./fakeeditor git replace --edit "$PARA3" &&
GIT_EDITOR=./fakeeditor git replace --force --edit "$PARA3" &&
- git replace -l | grep "$PARA3" &&
- git cat-file commit "$PARA3" | grep "A fake Thor" &&
+ git replace -l >actual &&
+ test_grep "$PARA3" actual &&
+ git cat-file commit "$PARA3" >actual &&
+ test_grep "A fake Thor" actual &&
git replace -d "$PARA3" &&
GIT_EDITOR=./fakeeditor git replace --edit "$PARA3" &&
- git replace -l | grep "$PARA3" &&
- git cat-file commit "$PARA3" | grep "A fake Thor"
+ git replace -l >actual &&
+ test_grep "$PARA3" actual &&
+ git cat-file commit "$PARA3" >actual &&
+ test_grep "A fake Thor" actual
'
test_expect_success '--edit and change nothing or command failed' '
@@ -387,8 +423,10 @@ test_expect_success '--edit and change nothing or command failed' '
test_must_fail env GIT_EDITOR=true git replace --edit "$PARA3" &&
test_must_fail env GIT_EDITOR="./failingfakeeditor" git replace --edit "$PARA3" &&
GIT_EDITOR=./fakeeditor git replace --edit "$PARA3" &&
- git replace -l | grep "$PARA3" &&
- git cat-file commit "$PARA3" | grep "A fake Thor"
+ git replace -l >actual &&
+ test_grep "$PARA3" actual &&
+ git cat-file commit "$PARA3" >actual &&
+ test_grep "A fake Thor" actual
'
test_expect_success 'replace ref cleanup' '
@@ -468,7 +506,8 @@ test_expect_success GPG 'set up a merge commit with a mergetag' '
git checkout main &&
git merge -s ours test_tag &&
HASH10=$(git rev-parse --verify HEAD) &&
- git cat-file commit $HASH10 | grep "^mergetag object"
+ git cat-file commit $HASH10 >actual &&
+ test_grep "^mergetag object" actual
'
test_expect_success GPG '--graft on a commit with a mergetag' '
diff --git a/t/t7300-clean.sh b/t/t7300-clean.sh
index 5c97eb0dfe..54fed91e39 100755
--- a/t/t7300-clean.sh
+++ b/t/t7300-clean.sh
@@ -747,7 +747,7 @@ test_expect_success MINGW 'handle clean & core.longpaths = false nicely' '
test_must_fail git clean -xdf 2>.git/err &&
# grepping for a strerror string is unportable but it is OK here with
# MINGW prereq
- test_grep "too long" .git/err
+ test_grep -e "too long" -e "No such file or directory" .git/err
'
test_expect_success 'clean untracked paths by pathspec' '
diff --git a/t/unit-tests/lib-reftable.c b/t/unit-tests/lib-reftable.c
index 54c26c43e7..2ddf480588 100644
--- a/t/unit-tests/lib-reftable.c
+++ b/t/unit-tests/lib-reftable.c
@@ -19,7 +19,7 @@ static int strbuf_writer_flush(void *arg UNUSED)
return 0;
}
-struct reftable_writer *t_reftable_strbuf_writer(struct strbuf *buf,
+struct reftable_writer *t_reftable_strbuf_writer(struct reftable_buf *buf,
struct reftable_write_options *opts)
{
struct reftable_writer *writer;
@@ -29,7 +29,7 @@ struct reftable_writer *t_reftable_strbuf_writer(struct strbuf *buf,
return writer;
}
-void t_reftable_write_to_buf(struct strbuf *buf,
+void t_reftable_write_to_buf(struct reftable_buf *buf,
struct reftable_ref_record *refs,
size_t nrefs,
struct reftable_log_record *logs,
diff --git a/t/unit-tests/lib-reftable.h b/t/unit-tests/lib-reftable.h
index d115419084..d4950fed3d 100644
--- a/t/unit-tests/lib-reftable.h
+++ b/t/unit-tests/lib-reftable.h
@@ -2,15 +2,16 @@
#define LIB_REFTABLE_H
#include "git-compat-util.h"
-#include "strbuf.h"
#include "reftable/reftable-writer.h"
+struct reftable_buf;
+
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_writer *t_reftable_strbuf_writer(struct reftable_buf *buf,
struct reftable_write_options *opts);
-void t_reftable_write_to_buf(struct strbuf *buf,
+void t_reftable_write_to_buf(struct reftable_buf *buf,
struct reftable_ref_record *refs,
size_t nrecords,
struct reftable_log_record *logs,
diff --git a/t/unit-tests/t-reftable-basics.c b/t/unit-tests/t-reftable-basics.c
index 1fa77b6faf..65d50df091 100644
--- a/t/unit-tests/t-reftable-basics.c
+++ b/t/unit-tests/t-reftable-basics.c
@@ -54,7 +54,7 @@ int cmd_main(int argc UNUSED, const char *argv[] UNUSED)
}
}
- if_test ("names_length retuns size of a NULL-terminated string array") {
+ if_test ("names_length returns size of a NULL-terminated string array") {
const char *a[] = { "a", "b", NULL };
check_int(names_length(a), ==, 2);
}
@@ -99,8 +99,8 @@ int cmd_main(int argc UNUSED, const char *argv[] UNUSED)
}
if_test ("common_prefix_size works") {
- struct strbuf a = STRBUF_INIT;
- struct strbuf b = STRBUF_INIT;
+ struct reftable_buf a = REFTABLE_BUF_INIT;
+ struct reftable_buf b = REFTABLE_BUF_INIT;
struct {
const char *a, *b;
int want;
@@ -113,14 +113,14 @@ int cmd_main(int argc UNUSED, const char *argv[] UNUSED)
};
for (size_t i = 0; i < ARRAY_SIZE(cases); i++) {
- strbuf_addstr(&a, cases[i].a);
- strbuf_addstr(&b, cases[i].b);
+ check(!reftable_buf_addstr(&a, cases[i].a));
+ check(!reftable_buf_addstr(&b, cases[i].b));
check_int(common_prefix_size(&a, &b), ==, cases[i].want);
- strbuf_reset(&a);
- strbuf_reset(&b);
+ reftable_buf_reset(&a);
+ reftable_buf_reset(&b);
}
- strbuf_release(&a);
- strbuf_release(&b);
+ reftable_buf_release(&a);
+ reftable_buf_release(&b);
}
if_test ("put_be24 and get_be24 work") {
diff --git a/t/unit-tests/t-reftable-block.c b/t/unit-tests/t-reftable-block.c
index d470060e8b..f9af907117 100644
--- a/t/unit-tests/t-reftable-block.c
+++ b/t/unit-tests/t-reftable-block.c
@@ -20,7 +20,7 @@ static void t_ref_block_read_write(void)
const size_t block_size = 1024;
struct reftable_block block = { 0 };
struct block_writer bw = {
- .last_key = STRBUF_INIT,
+ .last_key = REFTABLE_BUF_INIT,
};
struct reftable_record rec = {
.type = BLOCK_TYPE_REF,
@@ -29,12 +29,12 @@ static void t_ref_block_read_write(void)
int ret;
struct block_reader br = { 0 };
struct block_iter it = BLOCK_ITER_INIT;
- struct strbuf want = STRBUF_INIT, buf = STRBUF_INIT;
+ struct reftable_buf want = REFTABLE_BUF_INIT, buf = REFTABLE_BUF_INIT;
REFTABLE_CALLOC_ARRAY(block.data, block_size);
check(block.data != NULL);
block.len = block_size;
- block_source_from_strbuf(&block.source ,&buf);
+ block_source_from_buf(&block.source ,&buf);
ret = block_writer_init(&bw, BLOCK_TYPE_REF, block.data, block_size,
header_off, hash_size(GIT_SHA1_FORMAT_ID));
check(!ret);
@@ -100,8 +100,8 @@ static void t_ref_block_read_write(void)
block_iter_close(&it);
reftable_record_release(&rec);
reftable_block_done(&br.block);
- strbuf_release(&want);
- strbuf_release(&buf);
+ reftable_buf_release(&want);
+ reftable_buf_release(&buf);
for (i = 0; i < N; i++)
reftable_record_release(&recs[i]);
}
@@ -114,7 +114,7 @@ static void t_log_block_read_write(void)
const size_t block_size = 2048;
struct reftable_block block = { 0 };
struct block_writer bw = {
- .last_key = STRBUF_INIT,
+ .last_key = REFTABLE_BUF_INIT,
};
struct reftable_record rec = {
.type = BLOCK_TYPE_LOG,
@@ -123,12 +123,12 @@ static void t_log_block_read_write(void)
int ret;
struct block_reader br = { 0 };
struct block_iter it = BLOCK_ITER_INIT;
- struct strbuf want = STRBUF_INIT, buf = STRBUF_INIT;
+ struct reftable_buf want = REFTABLE_BUF_INIT, buf = REFTABLE_BUF_INIT;
REFTABLE_CALLOC_ARRAY(block.data, block_size);
check(block.data != NULL);
block.len = block_size;
- block_source_from_strbuf(&block.source ,&buf);
+ block_source_from_buf(&block.source ,&buf);
ret = block_writer_init(&bw, BLOCK_TYPE_LOG, block.data, block_size,
header_off, hash_size(GIT_SHA1_FORMAT_ID));
check(!ret);
@@ -166,8 +166,8 @@ static void t_log_block_read_write(void)
for (i = 0; i < N; i++) {
block_iter_reset(&it);
- strbuf_reset(&want);
- strbuf_addstr(&want, recs[i].u.log.refname);
+ reftable_buf_reset(&want);
+ check(!reftable_buf_addstr(&want, recs[i].u.log.refname));
ret = block_iter_seek_key(&it, &br, &want);
check_int(ret, ==, 0);
@@ -190,8 +190,8 @@ static void t_log_block_read_write(void)
block_iter_close(&it);
reftable_record_release(&rec);
reftable_block_done(&br.block);
- strbuf_release(&want);
- strbuf_release(&buf);
+ reftable_buf_release(&want);
+ reftable_buf_release(&buf);
for (i = 0; i < N; i++)
reftable_record_release(&recs[i]);
}
@@ -204,7 +204,7 @@ static void t_obj_block_read_write(void)
const size_t block_size = 1024;
struct reftable_block block = { 0 };
struct block_writer bw = {
- .last_key = STRBUF_INIT,
+ .last_key = REFTABLE_BUF_INIT,
};
struct reftable_record rec = {
.type = BLOCK_TYPE_OBJ,
@@ -213,12 +213,12 @@ static void t_obj_block_read_write(void)
int ret;
struct block_reader br = { 0 };
struct block_iter it = BLOCK_ITER_INIT;
- struct strbuf want = STRBUF_INIT, buf = STRBUF_INIT;
+ struct reftable_buf want = REFTABLE_BUF_INIT, buf = REFTABLE_BUF_INIT;
REFTABLE_CALLOC_ARRAY(block.data, block_size);
check(block.data != NULL);
block.len = block_size;
- block_source_from_strbuf(&block.source, &buf);
+ block_source_from_buf(&block.source, &buf);
ret = block_writer_init(&bw, BLOCK_TYPE_OBJ, block.data, block_size,
header_off, hash_size(GIT_SHA1_FORMAT_ID));
check(!ret);
@@ -273,8 +273,8 @@ static void t_obj_block_read_write(void)
block_iter_close(&it);
reftable_record_release(&rec);
reftable_block_done(&br.block);
- strbuf_release(&want);
- strbuf_release(&buf);
+ reftable_buf_release(&want);
+ reftable_buf_release(&buf);
for (i = 0; i < N; i++)
reftable_record_release(&recs[i]);
}
@@ -287,31 +287,34 @@ static void t_index_block_read_write(void)
const size_t block_size = 1024;
struct reftable_block block = { 0 };
struct block_writer bw = {
- .last_key = STRBUF_INIT,
+ .last_key = REFTABLE_BUF_INIT,
};
struct reftable_record rec = {
.type = BLOCK_TYPE_INDEX,
- .u.idx.last_key = STRBUF_INIT,
+ .u.idx.last_key = REFTABLE_BUF_INIT,
};
size_t i = 0;
int ret;
struct block_reader br = { 0 };
struct block_iter it = BLOCK_ITER_INIT;
- struct strbuf want = STRBUF_INIT, buf = STRBUF_INIT;
+ struct reftable_buf want = REFTABLE_BUF_INIT, buf = REFTABLE_BUF_INIT;
REFTABLE_CALLOC_ARRAY(block.data, block_size);
check(block.data != NULL);
block.len = block_size;
- block_source_from_strbuf(&block.source, &buf);
+ block_source_from_buf(&block.source, &buf);
ret = block_writer_init(&bw, BLOCK_TYPE_INDEX, block.data, block_size,
header_off, hash_size(GIT_SHA1_FORMAT_ID));
check(!ret);
for (i = 0; i < N; i++) {
- strbuf_init(&recs[i].u.idx.last_key, 9);
+ char buf[128];
+ snprintf(buf, sizeof(buf), "branch%02"PRIuMAX, (uintmax_t)i);
+
+ reftable_buf_init(&recs[i].u.idx.last_key);
recs[i].type = BLOCK_TYPE_INDEX;
- strbuf_addf(&recs[i].u.idx.last_key, "branch%02"PRIuMAX, (uintmax_t)i);
+ check(!reftable_buf_addstr(&recs[i].u.idx.last_key, buf));
recs[i].u.idx.offset = i;
ret = block_writer_add(&bw, &recs[i]);
@@ -362,8 +365,8 @@ static void t_index_block_read_write(void)
block_iter_close(&it);
reftable_record_release(&rec);
reftable_block_done(&br.block);
- strbuf_release(&want);
- strbuf_release(&buf);
+ reftable_buf_release(&want);
+ reftable_buf_release(&buf);
for (i = 0; i < N; i++)
reftable_record_release(&recs[i]);
}
diff --git a/t/unit-tests/t-reftable-merged.c b/t/unit-tests/t-reftable-merged.c
index 3c84363e98..4c25ee5334 100644
--- a/t/unit-tests/t-reftable-merged.c
+++ b/t/unit-tests/t-reftable-merged.c
@@ -20,7 +20,7 @@ static struct reftable_merged_table *
merged_table_from_records(struct reftable_ref_record **refs,
struct reftable_block_source **source,
struct reftable_reader ***readers, const size_t *sizes,
- struct strbuf *buf, const size_t n)
+ struct reftable_buf *buf, const size_t n)
{
struct reftable_merged_table *mt = NULL;
struct reftable_write_options opts = {
@@ -35,7 +35,7 @@ merged_table_from_records(struct reftable_ref_record **refs,
for (size_t i = 0; i < n; i++) {
t_reftable_write_to_buf(&buf[i], refs[i], sizes[i], NULL, 0, &opts);
- block_source_from_strbuf(&(*source)[i], &buf[i]);
+ block_source_from_buf(&(*source)[i], &buf[i]);
err = reftable_reader_new(&(*readers)[i], &(*source)[i],
"name");
@@ -75,7 +75,7 @@ static void t_merged_single_record(void)
struct reftable_ref_record *refs[] = { r1, r2, r3 };
size_t sizes[] = { ARRAY_SIZE(r1), ARRAY_SIZE(r2), ARRAY_SIZE(r3) };
- struct strbuf bufs[3] = { STRBUF_INIT, STRBUF_INIT, STRBUF_INIT };
+ struct reftable_buf bufs[3] = { REFTABLE_BUF_INIT, REFTABLE_BUF_INIT, REFTABLE_BUF_INIT };
struct reftable_block_source *bs = NULL;
struct reftable_reader **readers = NULL;
struct reftable_merged_table *mt =
@@ -97,7 +97,7 @@ static void t_merged_single_record(void)
readers_destroy(readers, 3);
reftable_merged_table_free(mt);
for (size_t i = 0; i < ARRAY_SIZE(bufs); i++)
- strbuf_release(&bufs[i]);
+ reftable_buf_release(&bufs[i]);
reftable_free(bs);
}
@@ -152,7 +152,7 @@ static void t_merged_refs(void)
struct reftable_ref_record *refs[] = { r1, r2, r3 };
size_t sizes[3] = { ARRAY_SIZE(r1), ARRAY_SIZE(r2), ARRAY_SIZE(r3) };
- struct strbuf bufs[3] = { STRBUF_INIT, STRBUF_INIT, STRBUF_INIT };
+ struct reftable_buf bufs[3] = { REFTABLE_BUF_INIT, REFTABLE_BUF_INIT, REFTABLE_BUF_INIT };
struct reftable_block_source *bs = NULL;
struct reftable_reader **readers = NULL;
struct reftable_merged_table *mt =
@@ -192,7 +192,7 @@ static void t_merged_refs(void)
reftable_free(out);
for (i = 0; i < 3; i++)
- strbuf_release(&bufs[i]);
+ reftable_buf_release(&bufs[i]);
readers_destroy(readers, 3);
reftable_merged_table_free(mt);
reftable_free(bs);
@@ -234,8 +234,8 @@ static void t_merged_seek_multiple_times(void)
size_t sizes[] = {
ARRAY_SIZE(r1), ARRAY_SIZE(r2),
};
- struct strbuf bufs[] = {
- STRBUF_INIT, STRBUF_INIT,
+ struct reftable_buf bufs[] = {
+ REFTABLE_BUF_INIT, REFTABLE_BUF_INIT,
};
struct reftable_block_source *sources = NULL;
struct reftable_reader **readers = NULL;
@@ -265,7 +265,7 @@ static void t_merged_seek_multiple_times(void)
}
for (size_t i = 0; i < ARRAY_SIZE(bufs); i++)
- strbuf_release(&bufs[i]);
+ reftable_buf_release(&bufs[i]);
readers_destroy(readers, ARRAY_SIZE(refs));
reftable_ref_record_release(&rec);
reftable_iterator_destroy(&it);
@@ -277,7 +277,7 @@ static struct reftable_merged_table *
merged_table_from_log_records(struct reftable_log_record **logs,
struct reftable_block_source **source,
struct reftable_reader ***readers, const size_t *sizes,
- struct strbuf *buf, const size_t n)
+ struct reftable_buf *buf, const size_t n)
{
struct reftable_merged_table *mt = NULL;
struct reftable_write_options opts = {
@@ -293,7 +293,7 @@ merged_table_from_log_records(struct reftable_log_record **logs,
for (size_t i = 0; i < n; i++) {
t_reftable_write_to_buf(&buf[i], NULL, 0, logs[i], sizes[i], &opts);
- block_source_from_strbuf(&(*source)[i], &buf[i]);
+ block_source_from_buf(&(*source)[i], &buf[i]);
err = reftable_reader_new(&(*readers)[i], &(*source)[i],
"name");
@@ -361,7 +361,7 @@ static void t_merged_logs(void)
struct reftable_log_record *logs[] = { r1, r2, r3 };
size_t sizes[3] = { ARRAY_SIZE(r1), ARRAY_SIZE(r2), ARRAY_SIZE(r3) };
- struct strbuf bufs[3] = { STRBUF_INIT, STRBUF_INIT, STRBUF_INIT };
+ struct reftable_buf bufs[3] = { REFTABLE_BUF_INIT, REFTABLE_BUF_INIT, REFTABLE_BUF_INIT };
struct reftable_block_source *bs = NULL;
struct reftable_reader **readers = NULL;
struct reftable_merged_table *mt = merged_table_from_log_records(
@@ -412,7 +412,7 @@ static void t_merged_logs(void)
reftable_free(out);
for (i = 0; i < 3; i++)
- strbuf_release(&bufs[i]);
+ reftable_buf_release(&bufs[i]);
readers_destroy(readers, 3);
reftable_merged_table_free(mt);
reftable_free(bs);
@@ -421,7 +421,7 @@ static void t_merged_logs(void)
static void t_default_write_opts(void)
{
struct reftable_write_options opts = { 0 };
- struct strbuf buf = STRBUF_INIT;
+ struct reftable_buf buf = REFTABLE_BUF_INIT;
struct reftable_writer *w = t_reftable_strbuf_writer(&buf, &opts);
struct reftable_ref_record rec = {
.refname = (char *) "master",
@@ -442,7 +442,7 @@ static void t_default_write_opts(void)
check(!err);
reftable_writer_free(w);
- block_source_from_strbuf(&source, &buf);
+ block_source_from_buf(&source, &buf);
err = reftable_reader_new(&rd, &source, "filename");
check(!err);
@@ -457,7 +457,7 @@ static void t_default_write_opts(void)
reftable_reader_decref(rd);
reftable_merged_table_free(merged);
- strbuf_release(&buf);
+ reftable_buf_release(&buf);
}
@@ -467,7 +467,7 @@ int cmd_main(int argc UNUSED, const char *argv[] UNUSED)
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");
+ TEST(t_merged_single_record(), "ref occurring 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
index eea86966c0..19cb53b641 100644
--- a/t/unit-tests/t-reftable-reader.c
+++ b/t/unit-tests/t-reftable-reader.c
@@ -16,11 +16,11 @@ static int t_reader_seek_once(void)
struct reftable_ref_record ref = { 0 };
struct reftable_iterator it = { 0 };
struct reftable_reader *reader;
- struct strbuf buf = STRBUF_INIT;
+ struct reftable_buf buf = REFTABLE_BUF_INIT;
int ret;
t_reftable_write_to_buf(&buf, records, ARRAY_SIZE(records), NULL, 0, NULL);
- block_source_from_strbuf(&source, &buf);
+ block_source_from_buf(&source, &buf);
ret = reftable_reader_new(&reader, &source, "name");
check(!ret);
@@ -40,7 +40,7 @@ static int t_reader_seek_once(void)
reftable_ref_record_release(&ref);
reftable_iterator_destroy(&it);
reftable_reader_decref(reader);
- strbuf_release(&buf);
+ reftable_buf_release(&buf);
return 0;
}
@@ -57,11 +57,11 @@ static int t_reader_reseek(void)
struct reftable_ref_record ref = { 0 };
struct reftable_iterator it = { 0 };
struct reftable_reader *reader;
- struct strbuf buf = STRBUF_INIT;
+ struct reftable_buf buf = REFTABLE_BUF_INIT;
int ret;
t_reftable_write_to_buf(&buf, records, ARRAY_SIZE(records), NULL, 0, NULL);
- block_source_from_strbuf(&source, &buf);
+ block_source_from_buf(&source, &buf);
ret = reftable_reader_new(&reader, &source, "name");
check(!ret);
@@ -84,7 +84,7 @@ static int t_reader_reseek(void)
reftable_ref_record_release(&ref);
reftable_iterator_destroy(&it);
reftable_reader_decref(reader);
- strbuf_release(&buf);
+ reftable_buf_release(&buf);
return 0;
}
diff --git a/t/unit-tests/t-reftable-readwrite.c b/t/unit-tests/t-reftable-readwrite.c
index 27ce84445e..d279b86df0 100644
--- a/t/unit-tests/t-reftable-readwrite.c
+++ b/t/unit-tests/t-reftable-readwrite.c
@@ -18,13 +18,13 @@ static const int update_index = 5;
static void t_buffer(void)
{
- struct strbuf buf = STRBUF_INIT;
+ struct reftable_buf buf = REFTABLE_BUF_INIT;
struct reftable_block_source source = { 0 };
struct reftable_block out = { 0 };
int n;
uint8_t in[] = "hello";
- strbuf_add(&buf, in, sizeof(in));
- block_source_from_strbuf(&source, &buf);
+ check(!reftable_buf_add(&buf, in, sizeof(in)));
+ block_source_from_buf(&source, &buf);
check_int(block_source_size(&source), ==, 6);
n = block_source_read_block(&source, &out, 0, sizeof(in));
check_int(n, ==, sizeof(in));
@@ -37,10 +37,10 @@ static void t_buffer(void)
reftable_block_done(&out);
block_source_close(&source);
- strbuf_release(&buf);
+ reftable_buf_release(&buf);
}
-static void write_table(char ***names, struct strbuf *buf, int N,
+static void write_table(char ***names, struct reftable_buf *buf, int N,
int block_size, uint32_t hash_id)
{
struct reftable_write_options opts = {
@@ -82,7 +82,7 @@ static void write_table(char ***names, struct strbuf *buf, int N,
static void t_log_buffer_size(void)
{
- struct strbuf buf = STRBUF_INIT;
+ struct reftable_buf buf = REFTABLE_BUF_INIT;
struct reftable_write_options opts = {
.block_size = 4096,
};
@@ -114,12 +114,12 @@ static void t_log_buffer_size(void)
err = reftable_writer_close(w);
check(!err);
reftable_writer_free(w);
- strbuf_release(&buf);
+ reftable_buf_release(&buf);
}
static void t_log_overflow(void)
{
- struct strbuf buf = STRBUF_INIT;
+ struct reftable_buf buf = REFTABLE_BUF_INIT;
char msg[256] = { 0 };
struct reftable_write_options opts = {
.block_size = ARRAY_SIZE(msg),
@@ -148,7 +148,7 @@ static void t_log_overflow(void)
err = reftable_writer_add_log(w, &log);
check_int(err, ==, REFTABLE_ENTRY_TOO_BIG_ERROR);
reftable_writer_free(w);
- strbuf_release(&buf);
+ reftable_buf_release(&buf);
}
static void t_log_write_read(void)
@@ -161,7 +161,7 @@ static void t_log_write_read(void)
struct reftable_iterator it = { 0 };
struct reftable_reader *reader;
struct reftable_block_source source = { 0 };
- struct strbuf buf = STRBUF_INIT;
+ struct reftable_buf buf = REFTABLE_BUF_INIT;
struct reftable_writer *w = t_reftable_strbuf_writer(&buf, &opts);
const struct reftable_stats *stats = NULL;
int N = 2, err, i, n;
@@ -207,7 +207,7 @@ static void t_log_write_read(void)
reftable_writer_free(w);
w = NULL;
- block_source_from_strbuf(&source, &buf);
+ block_source_from_buf(&source, &buf);
err = reftable_reader_new(&reader, &source, "file.log");
check(!err);
@@ -247,7 +247,7 @@ static void t_log_write_read(void)
reftable_iterator_destroy(&it);
/* cleanup. */
- strbuf_release(&buf);
+ reftable_buf_release(&buf);
free_names(names);
reftable_reader_decref(reader);
}
@@ -260,7 +260,7 @@ static void t_log_zlib_corruption(void)
struct reftable_iterator it = { 0 };
struct reftable_reader *reader;
struct reftable_block_source source = { 0 };
- struct strbuf buf = STRBUF_INIT;
+ struct reftable_buf buf = REFTABLE_BUF_INIT;
struct reftable_writer *w = t_reftable_strbuf_writer(&buf, &opts);
const struct reftable_stats *stats = NULL;
char message[100] = { 0 };
@@ -298,7 +298,7 @@ static void t_log_zlib_corruption(void)
/* corrupt the data. */
buf.buf[50] ^= 0x99;
- block_source_from_strbuf(&source, &buf);
+ block_source_from_buf(&source, &buf);
err = reftable_reader_new(&reader, &source, "file.log");
check(!err);
@@ -312,13 +312,13 @@ static void t_log_zlib_corruption(void)
/* cleanup. */
reftable_reader_decref(reader);
- strbuf_release(&buf);
+ reftable_buf_release(&buf);
}
static void t_table_read_write_sequential(void)
{
char **names;
- struct strbuf buf = STRBUF_INIT;
+ struct reftable_buf buf = REFTABLE_BUF_INIT;
int N = 50;
struct reftable_iterator it = { 0 };
struct reftable_block_source source = { 0 };
@@ -328,7 +328,7 @@ static void t_table_read_write_sequential(void)
write_table(&names, &buf, N, 256, GIT_SHA1_FORMAT_ID);
- block_source_from_strbuf(&source, &buf);
+ block_source_from_buf(&source, &buf);
err = reftable_reader_new(&reader, &source, "file.ref");
check(!err);
@@ -352,25 +352,25 @@ static void t_table_read_write_sequential(void)
reftable_iterator_destroy(&it);
reftable_reader_decref(reader);
- strbuf_release(&buf);
+ reftable_buf_release(&buf);
free_names(names);
}
static void t_table_write_small_table(void)
{
char **names;
- struct strbuf buf = STRBUF_INIT;
+ struct reftable_buf buf = REFTABLE_BUF_INIT;
int N = 1;
write_table(&names, &buf, N, 4096, GIT_SHA1_FORMAT_ID);
check_int(buf.len, <, 200);
- strbuf_release(&buf);
+ reftable_buf_release(&buf);
free_names(names);
}
static void t_table_read_api(void)
{
char **names;
- struct strbuf buf = STRBUF_INIT;
+ struct reftable_buf buf = REFTABLE_BUF_INIT;
int N = 50;
struct reftable_reader *reader;
struct reftable_block_source source = { 0 };
@@ -380,7 +380,7 @@ static void t_table_read_api(void)
write_table(&names, &buf, N, 256, GIT_SHA1_FORMAT_ID);
- block_source_from_strbuf(&source, &buf);
+ block_source_from_buf(&source, &buf);
err = reftable_reader_new(&reader, &source, "file.ref");
check(!err);
@@ -393,17 +393,17 @@ static void t_table_read_api(void)
err = reftable_iterator_next_log(&it, &log);
check_int(err, ==, REFTABLE_API_ERROR);
- strbuf_release(&buf);
+ reftable_buf_release(&buf);
free_names(names);
reftable_iterator_destroy(&it);
reftable_reader_decref(reader);
- strbuf_release(&buf);
+ reftable_buf_release(&buf);
}
static void t_table_read_write_seek(int index, int hash_id)
{
char **names;
- struct strbuf buf = STRBUF_INIT;
+ struct reftable_buf buf = REFTABLE_BUF_INIT;
int N = 50;
struct reftable_reader *reader;
struct reftable_block_source source = { 0 };
@@ -411,12 +411,12 @@ static void t_table_read_write_seek(int index, int hash_id)
int i = 0;
struct reftable_iterator it = { 0 };
- struct strbuf pastLast = STRBUF_INIT;
+ struct reftable_buf pastLast = REFTABLE_BUF_INIT;
struct reftable_ref_record ref = { 0 };
write_table(&names, &buf, N, 256, hash_id);
- block_source_from_strbuf(&source, &buf);
+ block_source_from_buf(&source, &buf);
err = reftable_reader_new(&reader, &source, "file.ref");
check(!err);
@@ -443,8 +443,8 @@ static void t_table_read_write_seek(int index, int hash_id)
reftable_iterator_destroy(&it);
}
- strbuf_addstr(&pastLast, names[N - 1]);
- strbuf_addstr(&pastLast, "/");
+ check(!reftable_buf_addstr(&pastLast, names[N - 1]));
+ check(!reftable_buf_addstr(&pastLast, "/"));
err = reftable_reader_init_ref_iterator(reader, &it);
check(!err);
@@ -457,10 +457,10 @@ static void t_table_read_write_seek(int index, int hash_id)
check_int(err, >, 0);
}
- strbuf_release(&pastLast);
+ reftable_buf_release(&pastLast);
reftable_iterator_destroy(&it);
- strbuf_release(&buf);
+ reftable_buf_release(&buf);
free_names(names);
reftable_reader_decref(reader);
}
@@ -492,7 +492,7 @@ static void t_table_refs_for(int indexed)
struct reftable_ref_record ref = { 0 };
struct reftable_reader *reader;
struct reftable_block_source source = { 0 };
- struct strbuf buf = STRBUF_INIT;
+ struct reftable_buf buf = REFTABLE_BUF_INIT;
struct reftable_writer *w = t_reftable_strbuf_writer(&buf, &opts);
struct reftable_iterator it = { 0 };
int N = 50, n, j, err, i;
@@ -538,7 +538,7 @@ static void t_table_refs_for(int indexed)
reftable_writer_free(w);
w = NULL;
- block_source_from_strbuf(&source, &buf);
+ block_source_from_buf(&source, &buf);
err = reftable_reader_new(&reader, &source, "file.ref");
check(!err);
@@ -565,7 +565,7 @@ static void t_table_refs_for(int indexed)
}
check_int(j, ==, want_names_len);
- strbuf_release(&buf);
+ reftable_buf_release(&buf);
free_names(want_names);
reftable_iterator_destroy(&it);
reftable_reader_decref(reader);
@@ -584,7 +584,7 @@ static void t_table_refs_for_obj_index(void)
static void t_write_empty_table(void)
{
struct reftable_write_options opts = { 0 };
- struct strbuf buf = STRBUF_INIT;
+ struct reftable_buf buf = REFTABLE_BUF_INIT;
struct reftable_writer *w = t_reftable_strbuf_writer(&buf, &opts);
struct reftable_block_source source = { 0 };
struct reftable_reader *rd = NULL;
@@ -600,7 +600,7 @@ static void t_write_empty_table(void)
check_int(buf.len, ==, header_size(1) + footer_size(1));
- block_source_from_strbuf(&source, &buf);
+ block_source_from_buf(&source, &buf);
err = reftable_reader_new(&rd, &source, "filename");
check(!err);
@@ -615,7 +615,7 @@ static void t_write_empty_table(void)
reftable_iterator_destroy(&it);
reftable_reader_decref(rd);
- strbuf_release(&buf);
+ reftable_buf_release(&buf);
}
static void t_write_object_id_min_length(void)
@@ -623,7 +623,7 @@ static void t_write_object_id_min_length(void)
struct reftable_write_options opts = {
.block_size = 75,
};
- struct strbuf buf = STRBUF_INIT;
+ struct reftable_buf buf = REFTABLE_BUF_INIT;
struct reftable_writer *w = t_reftable_strbuf_writer(&buf, &opts);
struct reftable_ref_record ref = {
.update_index = 1,
@@ -649,7 +649,7 @@ static void t_write_object_id_min_length(void)
check(!err);
check_int(reftable_writer_stats(w)->object_id_len, ==, 2);
reftable_writer_free(w);
- strbuf_release(&buf);
+ reftable_buf_release(&buf);
}
static void t_write_object_id_length(void)
@@ -657,7 +657,7 @@ static void t_write_object_id_length(void)
struct reftable_write_options opts = {
.block_size = 75,
};
- struct strbuf buf = STRBUF_INIT;
+ struct reftable_buf buf = REFTABLE_BUF_INIT;
struct reftable_writer *w = t_reftable_strbuf_writer(&buf, &opts);
struct reftable_ref_record ref = {
.update_index = 1,
@@ -684,13 +684,13 @@ static void t_write_object_id_length(void)
check(!err);
check_int(reftable_writer_stats(w)->object_id_len, ==, 16);
reftable_writer_free(w);
- strbuf_release(&buf);
+ reftable_buf_release(&buf);
}
static void t_write_empty_key(void)
{
struct reftable_write_options opts = { 0 };
- struct strbuf buf = STRBUF_INIT;
+ struct reftable_buf buf = REFTABLE_BUF_INIT;
struct reftable_writer *w = t_reftable_strbuf_writer(&buf, &opts);
struct reftable_ref_record ref = {
.refname = (char *) "",
@@ -706,13 +706,13 @@ static void t_write_empty_key(void)
err = reftable_writer_close(w);
check_int(err, ==, REFTABLE_EMPTY_TABLE_ERROR);
reftable_writer_free(w);
- strbuf_release(&buf);
+ reftable_buf_release(&buf);
}
static void t_write_key_order(void)
{
struct reftable_write_options opts = { 0 };
- struct strbuf buf = STRBUF_INIT;
+ struct reftable_buf buf = REFTABLE_BUF_INIT;
struct reftable_writer *w = t_reftable_strbuf_writer(&buf, &opts);
struct reftable_ref_record refs[2] = {
{
@@ -745,7 +745,7 @@ static void t_write_key_order(void)
reftable_writer_close(w);
reftable_writer_free(w);
- strbuf_release(&buf);
+ reftable_buf_release(&buf);
}
static void t_write_multiple_indices(void)
@@ -753,12 +753,13 @@ static void t_write_multiple_indices(void)
struct reftable_write_options opts = {
.block_size = 100,
};
- struct strbuf writer_buf = STRBUF_INIT, buf = STRBUF_INIT;
+ struct reftable_buf writer_buf = REFTABLE_BUF_INIT;
struct reftable_block_source source = { 0 };
struct reftable_iterator it = { 0 };
const struct reftable_stats *stats;
struct reftable_writer *writer;
struct reftable_reader *reader;
+ char buf[128];
int err, i;
writer = t_reftable_strbuf_writer(&writer_buf, &opts);
@@ -770,9 +771,8 @@ static void t_write_multiple_indices(void)
.value.val1 = {i},
};
- strbuf_reset(&buf);
- strbuf_addf(&buf, "refs/heads/%04d", i);
- ref.refname = buf.buf,
+ snprintf(buf, sizeof(buf), "refs/heads/%04d", i);
+ ref.refname = buf;
err = reftable_writer_add_ref(writer, &ref);
check(!err);
@@ -788,9 +788,8 @@ static void t_write_multiple_indices(void)
},
};
- strbuf_reset(&buf);
- strbuf_addf(&buf, "refs/heads/%04d", i);
- log.refname = buf.buf,
+ snprintf(buf, sizeof(buf), "refs/heads/%04d", i);
+ log.refname = buf;
err = reftable_writer_add_log(writer, &log);
check(!err);
@@ -807,7 +806,7 @@ static void t_write_multiple_indices(void)
check_int(stats->obj_stats.index_offset, >, 0);
check_int(stats->log_stats.index_offset, >, 0);
- block_source_from_strbuf(&source, &writer_buf);
+ block_source_from_buf(&source, &writer_buf);
err = reftable_reader_new(&reader, &source, "filename");
check(!err);
@@ -823,8 +822,7 @@ static void t_write_multiple_indices(void)
reftable_iterator_destroy(&it);
reftable_writer_free(writer);
reftable_reader_decref(reader);
- strbuf_release(&writer_buf);
- strbuf_release(&buf);
+ reftable_buf_release(&writer_buf);
}
static void t_write_multi_level_index(void)
@@ -832,7 +830,7 @@ static void t_write_multi_level_index(void)
struct reftable_write_options opts = {
.block_size = 100,
};
- struct strbuf writer_buf = STRBUF_INIT, buf = STRBUF_INIT;
+ struct reftable_buf writer_buf = REFTABLE_BUF_INIT, buf = REFTABLE_BUF_INIT;
struct reftable_block_source source = { 0 };
struct reftable_iterator it = { 0 };
const struct reftable_stats *stats;
@@ -848,10 +846,10 @@ static void t_write_multi_level_index(void)
.value_type = REFTABLE_REF_VAL1,
.value.val1 = {i},
};
+ char buf[128];
- strbuf_reset(&buf);
- strbuf_addf(&buf, "refs/heads/%03" PRIuMAX, (uintmax_t)i);
- ref.refname = buf.buf,
+ snprintf(buf, sizeof(buf), "refs/heads/%03" PRIuMAX, (uintmax_t)i);
+ ref.refname = buf;
err = reftable_writer_add_ref(writer, &ref);
check(!err);
@@ -865,7 +863,7 @@ static void t_write_multi_level_index(void)
stats = reftable_writer_stats(writer);
check_int(stats->ref_stats.max_index_level, ==, 2);
- block_source_from_strbuf(&source, &writer_buf);
+ block_source_from_buf(&source, &writer_buf);
err = reftable_reader_new(&reader, &source, "filename");
check(!err);
@@ -880,18 +878,18 @@ static void t_write_multi_level_index(void)
reftable_iterator_destroy(&it);
reftable_writer_free(writer);
reftable_reader_decref(reader);
- strbuf_release(&writer_buf);
- strbuf_release(&buf);
+ reftable_buf_release(&writer_buf);
+ reftable_buf_release(&buf);
}
static void t_corrupt_table_empty(void)
{
- struct strbuf buf = STRBUF_INIT;
+ struct reftable_buf buf = REFTABLE_BUF_INIT;
struct reftable_block_source source = { 0 };
struct reftable_reader *reader;
int err;
- block_source_from_strbuf(&source, &buf);
+ block_source_from_buf(&source, &buf);
err = reftable_reader_new(&reader, &source, "file.log");
check_int(err, ==, REFTABLE_FORMAT_ERROR);
}
@@ -899,17 +897,17 @@ static void t_corrupt_table_empty(void)
static void t_corrupt_table(void)
{
uint8_t zeros[1024] = { 0 };
- struct strbuf buf = STRBUF_INIT;
+ struct reftable_buf buf = REFTABLE_BUF_INIT;
struct reftable_block_source source = { 0 };
struct reftable_reader *reader;
int err;
- strbuf_add(&buf, zeros, sizeof(zeros));
+ check(!reftable_buf_add(&buf, zeros, sizeof(zeros)));
- block_source_from_strbuf(&source, &buf);
+ block_source_from_buf(&source, &buf);
err = reftable_reader_new(&reader, &source, "file.log");
check_int(err, ==, REFTABLE_FORMAT_ERROR);
- strbuf_release(&buf);
+ reftable_buf_release(&buf);
}
int cmd_main(int argc UNUSED, const char *argv[] UNUSED)
diff --git a/t/unit-tests/t-reftable-record.c b/t/unit-tests/t-reftable-record.c
index a7f67d4d9f..eb98bf2da9 100644
--- a/t/unit-tests/t-reftable-record.c
+++ b/t/unit-tests/t-reftable-record.c
@@ -116,7 +116,7 @@ static void t_reftable_ref_record_compare_name(void)
static void t_reftable_ref_record_roundtrip(void)
{
- struct strbuf scratch = STRBUF_INIT;
+ struct reftable_buf scratch = REFTABLE_BUF_INIT;
for (int i = REFTABLE_REF_DELETION; i < REFTABLE_NR_REF_VALUETYPES; i++) {
struct reftable_record in = {
@@ -124,7 +124,7 @@ static void t_reftable_ref_record_roundtrip(void)
.u.ref.value_type = i,
};
struct reftable_record out = { .type = BLOCK_TYPE_REF };
- struct strbuf key = STRBUF_INIT;
+ struct reftable_buf key = REFTABLE_BUF_INIT;
uint8_t buffer[1024] = { 0 };
struct string_view dest = {
.buf = buffer,
@@ -166,11 +166,11 @@ static void t_reftable_ref_record_roundtrip(void)
GIT_SHA1_RAWSZ));
reftable_record_release(&in);
- strbuf_release(&key);
+ reftable_buf_release(&key);
reftable_record_release(&out);
}
- strbuf_release(&scratch);
+ reftable_buf_release(&scratch);
}
static void t_reftable_log_record_comparison(void)
@@ -262,7 +262,7 @@ static void t_reftable_log_record_roundtrip(void)
.value_type = REFTABLE_LOG_UPDATE,
}
};
- struct strbuf scratch = STRBUF_INIT;
+ struct reftable_buf scratch = REFTABLE_BUF_INIT;
set_hash(in[0].value.update.new_hash, 1);
set_hash(in[0].value.update.old_hash, 2);
set_hash(in[2].value.update.new_hash, 3);
@@ -274,7 +274,7 @@ static void t_reftable_log_record_roundtrip(void)
for (size_t i = 0; i < ARRAY_SIZE(in); i++) {
struct reftable_record rec = { .type = BLOCK_TYPE_LOG };
- struct strbuf key = STRBUF_INIT;
+ struct reftable_buf key = REFTABLE_BUF_INIT;
uint8_t buffer[1024] = { 0 };
struct string_view dest = {
.buf = buffer,
@@ -313,11 +313,11 @@ static void t_reftable_log_record_roundtrip(void)
check(reftable_log_record_equal(&in[i], &out.u.log,
GIT_SHA1_RAWSZ));
reftable_log_record_release(&in[i]);
- strbuf_release(&key);
+ reftable_buf_release(&key);
reftable_record_release(&out);
}
- strbuf_release(&scratch);
+ reftable_buf_release(&scratch);
}
static void t_key_roundtrip(void)
@@ -327,30 +327,30 @@ static void t_key_roundtrip(void)
.buf = buffer,
.len = sizeof(buffer),
};
- struct strbuf last_key = STRBUF_INIT;
- struct strbuf key = STRBUF_INIT;
- struct strbuf roundtrip = STRBUF_INIT;
+ struct reftable_buf last_key = REFTABLE_BUF_INIT;
+ struct reftable_buf key = REFTABLE_BUF_INIT;
+ struct reftable_buf roundtrip = REFTABLE_BUF_INIT;
int restart;
uint8_t extra;
int n, m;
uint8_t rt_extra;
- strbuf_addstr(&last_key, "refs/heads/master");
- strbuf_addstr(&key, "refs/tags/bla");
+ check(!reftable_buf_addstr(&last_key, "refs/heads/master"));
+ check(!reftable_buf_addstr(&key, "refs/tags/bla"));
extra = 6;
n = reftable_encode_key(&restart, dest, last_key, key, extra);
check(!restart);
check_int(n, >, 0);
- strbuf_addstr(&roundtrip, "refs/heads/master");
+ check(!reftable_buf_addstr(&roundtrip, "refs/heads/master"));
m = reftable_decode_key(&roundtrip, &rt_extra, dest);
check_int(n, ==, m);
- check(!strbuf_cmp(&key, &roundtrip));
+ check(!reftable_buf_cmp(&key, &roundtrip));
check_int(rt_extra, ==, extra);
- strbuf_release(&last_key);
- strbuf_release(&key);
- strbuf_release(&roundtrip);
+ reftable_buf_release(&last_key);
+ reftable_buf_release(&key);
+ reftable_buf_release(&roundtrip);
}
static void t_reftable_obj_record_comparison(void)
@@ -413,7 +413,7 @@ static void t_reftable_obj_record_roundtrip(void)
.hash_prefix_len = 5,
},
};
- struct strbuf scratch = STRBUF_INIT;
+ struct reftable_buf scratch = REFTABLE_BUF_INIT;
for (size_t i = 0; i < ARRAY_SIZE(recs); i++) {
uint8_t buffer[1024] = { 0 };
@@ -427,7 +427,7 @@ static void t_reftable_obj_record_roundtrip(void)
.obj = recs[i],
},
};
- struct strbuf key = STRBUF_INIT;
+ struct reftable_buf key = REFTABLE_BUF_INIT;
struct reftable_record out = { .type = BLOCK_TYPE_OBJ };
int n, m;
uint8_t extra;
@@ -443,11 +443,11 @@ static void t_reftable_obj_record_roundtrip(void)
check_int(n, ==, m);
check(reftable_record_equal(&in, &out, GIT_SHA1_RAWSZ));
- strbuf_release(&key);
+ reftable_buf_release(&key);
reftable_record_release(&out);
}
- strbuf_release(&scratch);
+ reftable_buf_release(&scratch);
}
static void t_reftable_index_record_comparison(void)
@@ -456,22 +456,22 @@ static void t_reftable_index_record_comparison(void)
{
.type = BLOCK_TYPE_INDEX,
.u.idx.offset = 22,
- .u.idx.last_key = STRBUF_INIT,
+ .u.idx.last_key = REFTABLE_BUF_INIT,
},
{
.type = BLOCK_TYPE_INDEX,
.u.idx.offset = 32,
- .u.idx.last_key = STRBUF_INIT,
+ .u.idx.last_key = REFTABLE_BUF_INIT,
},
{
.type = BLOCK_TYPE_INDEX,
.u.idx.offset = 32,
- .u.idx.last_key = STRBUF_INIT,
+ .u.idx.last_key = REFTABLE_BUF_INIT,
},
};
- strbuf_addstr(&in[0].u.idx.last_key, "refs/heads/master");
- strbuf_addstr(&in[1].u.idx.last_key, "refs/heads/master");
- strbuf_addstr(&in[2].u.idx.last_key, "refs/heads/branch");
+ check(!reftable_buf_addstr(&in[0].u.idx.last_key, "refs/heads/master"));
+ check(!reftable_buf_addstr(&in[1].u.idx.last_key, "refs/heads/master"));
+ check(!reftable_buf_addstr(&in[2].u.idx.last_key, "refs/heads/branch"));
check(!reftable_record_equal(&in[0], &in[1], GIT_SHA1_RAWSZ));
check(!reftable_record_cmp(&in[0], &in[1]));
@@ -493,7 +493,7 @@ static void t_reftable_index_record_roundtrip(void)
.type = BLOCK_TYPE_INDEX,
.u.idx = {
.offset = 42,
- .last_key = STRBUF_INIT,
+ .last_key = REFTABLE_BUF_INIT,
},
};
uint8_t buffer[1024] = { 0 };
@@ -501,21 +501,21 @@ static void t_reftable_index_record_roundtrip(void)
.buf = buffer,
.len = sizeof(buffer),
};
- struct strbuf scratch = STRBUF_INIT;
- struct strbuf key = STRBUF_INIT;
+ struct reftable_buf scratch = REFTABLE_BUF_INIT;
+ struct reftable_buf key = REFTABLE_BUF_INIT;
struct reftable_record out = {
.type = BLOCK_TYPE_INDEX,
- .u.idx = { .last_key = STRBUF_INIT },
+ .u.idx = { .last_key = REFTABLE_BUF_INIT },
};
int n, m;
uint8_t extra;
- strbuf_addstr(&in.u.idx.last_key, "refs/heads/master");
+ check(!reftable_buf_addstr(&in.u.idx.last_key, "refs/heads/master"));
reftable_record_key(&in, &key);
t_copy(&in);
check(!reftable_record_is_deletion(&in));
- check(!strbuf_cmp(&key, &in.u.idx.last_key));
+ check(!reftable_buf_cmp(&key, &in.u.idx.last_key));
n = reftable_record_encode(&in, dest, GIT_SHA1_RAWSZ);
check_int(n, >, 0);
@@ -527,9 +527,9 @@ static void t_reftable_index_record_roundtrip(void)
check(reftable_record_equal(&in, &out, GIT_SHA1_RAWSZ));
reftable_record_release(&out);
- strbuf_release(&key);
- strbuf_release(&scratch);
- strbuf_release(&in.u.idx.last_key);
+ reftable_buf_release(&key);
+ reftable_buf_release(&scratch);
+ reftable_buf_release(&in.u.idx.last_key);
}
int cmd_main(int argc UNUSED, const char *argv[] UNUSED)
diff --git a/t/unit-tests/t-reftable-stack.c b/t/unit-tests/t-reftable-stack.c
index 874095b9ee..72f6747064 100644
--- a/t/unit-tests/t-reftable-stack.c
+++ b/t/unit-tests/t-reftable-stack.c
@@ -16,7 +16,7 @@ https://developers.google.com/open-source/licenses/bsd
static void clear_dir(const char *dirname)
{
- struct strbuf path = STRBUF_INIT;
+ struct strbuf path = REFTABLE_BUF_INIT;
strbuf_addstr(&path, dirname);
remove_dir_recursively(&path, 0);
strbuf_release(&path);
@@ -105,7 +105,6 @@ static int write_test_ref(struct reftable_writer *wr, void *arg)
static void write_n_ref_tables(struct reftable_stack *st,
size_t n)
{
- struct strbuf buf = STRBUF_INIT;
int disable_auto_compact;
int err;
@@ -117,10 +116,10 @@ static void write_n_ref_tables(struct reftable_stack *st,
.update_index = reftable_stack_next_update_index(st),
.value_type = REFTABLE_REF_VAL1,
};
+ char buf[128];
- strbuf_reset(&buf);
- strbuf_addf(&buf, "refs/heads/branch-%04"PRIuMAX, (uintmax_t)i);
- ref.refname = buf.buf;
+ snprintf(buf, sizeof(buf), "refs/heads/branch-%04"PRIuMAX, (uintmax_t)i);
+ ref.refname = buf;
t_reftable_set_hash(ref.value.val1, i, GIT_SHA1_FORMAT_ID);
err = reftable_stack_add(st, &write_test_ref, &ref);
@@ -128,7 +127,6 @@ static void write_n_ref_tables(struct reftable_stack *st,
}
st->opts.disable_auto_compact = disable_auto_compact;
- strbuf_release(&buf);
}
struct write_log_arg {
@@ -147,7 +145,7 @@ static int write_test_log(struct reftable_writer *wr, void *arg)
static void t_reftable_stack_add_one(void)
{
char *dir = get_tmp_dir(__LINE__);
- struct strbuf scratch = STRBUF_INIT;
+ struct reftable_buf scratch = REFTABLE_BUF_INIT;
int mask = umask(002);
struct reftable_write_options opts = {
.default_permissions = 0660,
@@ -174,17 +172,17 @@ static void t_reftable_stack_add_one(void)
check_int(st->readers_len, >, 0);
#ifndef GIT_WINDOWS_NATIVE
- strbuf_addstr(&scratch, dir);
- strbuf_addstr(&scratch, "/tables.list");
+ check(!reftable_buf_addstr(&scratch, dir));
+ check(!reftable_buf_addstr(&scratch, "/tables.list"));
err = stat(scratch.buf, &stat_result);
check(!err);
check_int((stat_result.st_mode & 0777), ==, opts.default_permissions);
- strbuf_reset(&scratch);
- strbuf_addstr(&scratch, dir);
- strbuf_addstr(&scratch, "/");
+ reftable_buf_reset(&scratch);
+ check(!reftable_buf_addstr(&scratch, dir));
+ check(!reftable_buf_addstr(&scratch, "/"));
/* do not try at home; not an external API for reftable. */
- strbuf_addstr(&scratch, st->readers[0]->name);
+ check(!reftable_buf_addstr(&scratch, st->readers[0]->name));
err = stat(scratch.buf, &stat_result);
check(!err);
check_int((stat_result.st_mode & 0777), ==, opts.default_permissions);
@@ -194,7 +192,7 @@ static void t_reftable_stack_add_one(void)
reftable_ref_record_release(&dest);
reftable_stack_destroy(st);
- strbuf_release(&scratch);
+ reftable_buf_release(&scratch);
clear_dir(dir);
umask(mask);
}
@@ -416,7 +414,7 @@ static void t_reftable_stack_auto_compaction_fails_gracefully(void)
};
struct reftable_write_options opts = { 0 };
struct reftable_stack *st;
- struct strbuf table_path = STRBUF_INIT;
+ struct reftable_buf table_path = REFTABLE_BUF_INIT;
char *dir = get_tmp_dir(__LINE__);
int err;
@@ -434,7 +432,10 @@ static void t_reftable_stack_auto_compaction_fails_gracefully(void)
* Adding a new table to the stack should not be impacted by this, even
* though auto-compaction will now fail.
*/
- strbuf_addf(&table_path, "%s/%s.lock", dir, st->readers[0]->name);
+ check(!reftable_buf_addstr(&table_path, dir));
+ check(!reftable_buf_addstr(&table_path, "/"));
+ check(!reftable_buf_addstr(&table_path, st->readers[0]->name));
+ check(!reftable_buf_addstr(&table_path, ".lock"));
write_file_buf(table_path.buf, "", 0);
ref.update_index = 2;
@@ -445,7 +446,7 @@ static void t_reftable_stack_auto_compaction_fails_gracefully(void)
check_int(st->stats.failures, ==, 1);
reftable_stack_destroy(st);
- strbuf_release(&table_path);
+ reftable_buf_release(&table_path);
clear_dir(dir);
}
@@ -515,7 +516,7 @@ static void t_reftable_stack_add(void)
char *dir = get_tmp_dir(__LINE__);
struct reftable_ref_record refs[2] = { 0 };
struct reftable_log_record logs[2] = { 0 };
- struct strbuf path = STRBUF_INIT;
+ struct reftable_buf path = REFTABLE_BUF_INIT;
struct stat stat_result;
size_t i, N = ARRAY_SIZE(refs);
@@ -574,17 +575,17 @@ static void t_reftable_stack_add(void)
}
#ifndef GIT_WINDOWS_NATIVE
- strbuf_addstr(&path, dir);
- strbuf_addstr(&path, "/tables.list");
+ check(!reftable_buf_addstr(&path, dir));
+ check(!reftable_buf_addstr(&path, "/tables.list"));
err = stat(path.buf, &stat_result);
check(!err);
check_int((stat_result.st_mode & 0777), ==, opts.default_permissions);
- strbuf_reset(&path);
- strbuf_addstr(&path, dir);
- strbuf_addstr(&path, "/");
+ reftable_buf_reset(&path);
+ check(!reftable_buf_addstr(&path, dir));
+ check(!reftable_buf_addstr(&path, "/"));
/* do not try at home; not an external API for reftable. */
- strbuf_addstr(&path, st->readers[0]->name);
+ check(!reftable_buf_addstr(&path, st->readers[0]->name));
err = stat(path.buf, &stat_result);
check(!err);
check_int((stat_result.st_mode & 0777), ==, opts.default_permissions);
@@ -598,7 +599,7 @@ static void t_reftable_stack_add(void)
reftable_ref_record_release(&refs[i]);
reftable_log_record_release(&logs[i]);
}
- strbuf_release(&path);
+ reftable_buf_release(&path);
clear_dir(dir);
}
@@ -1062,7 +1063,7 @@ static void t_reftable_stack_auto_compaction_with_locked_tables(void)
.disable_auto_compact = 1,
};
struct reftable_stack *st = NULL;
- struct strbuf buf = STRBUF_INIT;
+ struct reftable_buf buf = REFTABLE_BUF_INIT;
char *dir = get_tmp_dir(__LINE__);
int err;
@@ -1077,8 +1078,10 @@ static void t_reftable_stack_auto_compaction_with_locked_tables(void)
* size, we expect that auto-compaction will want to compact all of the
* tables. Locking any of the tables will keep it from doing so.
*/
- strbuf_reset(&buf);
- strbuf_addf(&buf, "%s/%s.lock", dir, st->readers[2]->name);
+ check(!reftable_buf_addstr(&buf, dir));
+ check(!reftable_buf_addstr(&buf, "/"));
+ check(!reftable_buf_addstr(&buf, st->readers[2]->name));
+ check(!reftable_buf_addstr(&buf, ".lock"));
write_file_buf(buf.buf, "", 0);
/*
@@ -1093,7 +1096,7 @@ static void t_reftable_stack_auto_compaction_with_locked_tables(void)
check_int(st->merged->readers_len, ==, 4);
reftable_stack_destroy(st);
- strbuf_release(&buf);
+ reftable_buf_release(&buf);
clear_dir(dir);
}
@@ -1101,7 +1104,6 @@ static void t_reftable_stack_add_performs_auto_compaction(void)
{
struct reftable_write_options opts = { 0 };
struct reftable_stack *st = NULL;
- struct strbuf refname = STRBUF_INIT;
char *dir = get_tmp_dir(__LINE__);
int err;
size_t i, n = 20;
@@ -1115,6 +1117,7 @@ static void t_reftable_stack_add_performs_auto_compaction(void)
.value_type = REFTABLE_REF_SYMREF,
.value.symref = (char *) "master",
};
+ char buf[128];
/*
* Disable auto-compaction for all but the last runs. Like this
@@ -1123,9 +1126,8 @@ static void t_reftable_stack_add_performs_auto_compaction(void)
*/
st->opts.disable_auto_compact = i != n;
- strbuf_reset(&refname);
- strbuf_addf(&refname, "branch-%04"PRIuMAX, (uintmax_t)i);
- ref.refname = refname.buf;
+ snprintf(buf, sizeof(buf), "branch-%04"PRIuMAX, (uintmax_t)i);
+ ref.refname = buf;
err = reftable_stack_add(st, write_test_ref, &ref);
check(!err);
@@ -1142,7 +1144,6 @@ static void t_reftable_stack_add_performs_auto_compaction(void)
}
reftable_stack_destroy(st);
- strbuf_release(&refname);
clear_dir(dir);
}
@@ -1152,7 +1153,7 @@ static void t_reftable_stack_compaction_with_locked_tables(void)
.disable_auto_compact = 1,
};
struct reftable_stack *st = NULL;
- struct strbuf buf = STRBUF_INIT;
+ struct reftable_buf buf = REFTABLE_BUF_INIT;
char *dir = get_tmp_dir(__LINE__);
int err;
@@ -1163,8 +1164,10 @@ static void t_reftable_stack_compaction_with_locked_tables(void)
check_int(st->merged->readers_len, ==, 3);
/* Lock one of the tables that we're about to compact. */
- strbuf_reset(&buf);
- strbuf_addf(&buf, "%s/%s.lock", dir, st->readers[1]->name);
+ check(!reftable_buf_addstr(&buf, dir));
+ check(!reftable_buf_addstr(&buf, "/"));
+ check(!reftable_buf_addstr(&buf, st->readers[1]->name));
+ check(!reftable_buf_addstr(&buf, ".lock"));
write_file_buf(buf.buf, "", 0);
/*
@@ -1177,7 +1180,7 @@ static void t_reftable_stack_compaction_with_locked_tables(void)
check_int(st->merged->readers_len, ==, 3);
reftable_stack_destroy(st);
- strbuf_release(&buf);
+ reftable_buf_release(&buf);
clear_dir(dir);
}
@@ -1303,7 +1306,7 @@ static void t_reftable_stack_reload_with_missing_table(void)
struct reftable_stack *st = NULL;
struct reftable_ref_record rec = { 0 };
struct reftable_iterator it = { 0 };
- struct strbuf table_path = STRBUF_INIT, content = STRBUF_INIT;
+ struct reftable_buf table_path = REFTABLE_BUF_INIT, content = REFTABLE_BUF_INIT;
char *dir = get_tmp_dir(__LINE__);
int err;
@@ -1321,10 +1324,13 @@ static void t_reftable_stack_reload_with_missing_table(void)
* our old readers. This should trigger a partial reload of the stack,
* where we try to reuse our old readers.
*/
- strbuf_addf(&content, "%s\n", st->readers[0]->name);
- strbuf_addf(&content, "%s\n", st->readers[1]->name);
- strbuf_addstr(&content, "garbage\n");
- strbuf_addf(&table_path, "%s.lock", st->list_file);
+ check(!reftable_buf_addstr(&content, st->readers[0]->name));
+ check(!reftable_buf_addstr(&content, "\n"));
+ check(!reftable_buf_addstr(&content, st->readers[1]->name));
+ check(!reftable_buf_addstr(&content, "\n"));
+ check(!reftable_buf_addstr(&content, "garbage\n"));
+ check(!reftable_buf_addstr(&table_path, st->list_file));
+ check(!reftable_buf_addstr(&table_path, ".lock"));
write_file_buf(table_path.buf, content.buf, content.len);
err = rename(table_path.buf, st->list_file);
check(!err);
@@ -1349,8 +1355,8 @@ static void t_reftable_stack_reload_with_missing_table(void)
reftable_ref_record_release(&rec);
reftable_iterator_destroy(&it);
reftable_stack_destroy(st);
- strbuf_release(&table_path);
- strbuf_release(&content);
+ reftable_buf_release(&table_path);
+ reftable_buf_release(&content);
clear_dir(dir);
}
diff --git a/unpack-trees.c b/unpack-trees.c
index 9a55cb6204..e10a9d1209 100644
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -808,6 +808,8 @@ static int traverse_by_cache_tree(int pos, int nr_entries, int nr_names,
if (!o->merge)
BUG("We need cache-tree to do this optimization");
+ if (nr_entries + pos > o->src_index->cache_nr)
+ return error(_("corrupted cache-tree has entries not present in index"));
/*
* Do what unpack_callback() and unpack_single_entry() normally
@@ -2070,9 +2072,13 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options
if (o->dst_index) {
move_index_extensions(&o->internal.result, o->src_index);
if (!ret) {
- if (git_env_bool("GIT_TEST_CHECK_CACHE_TREE", 0))
- cache_tree_verify(the_repository,
- &o->internal.result);
+ if (git_env_bool("GIT_TEST_CHECK_CACHE_TREE", 0) &&
+ cache_tree_verify(the_repository,
+ &o->internal.result) < 0) {
+ ret = -1;
+ goto done;
+ }
+
if (!o->skip_cache_tree_update &&
!cache_tree_fully_valid(o->internal.result.cache_tree))
cache_tree_update(&o->internal.result,
diff --git a/worktree.c b/worktree.c
index 0f032ccedf..77ff484d3e 100644
--- a/worktree.c
+++ b/worktree.c
@@ -110,6 +110,12 @@ struct worktree *get_linked_worktree(const char *id,
strbuf_rtrim(&worktree_path);
strbuf_strip_suffix(&worktree_path, "/.git");
+ if (!is_absolute_path(worktree_path.buf)) {
+ strbuf_strip_suffix(&path, "gitdir");
+ strbuf_addbuf(&path, &worktree_path);
+ strbuf_realpath_forgiving(&worktree_path, path.buf, 0);
+ }
+
CALLOC_ARRAY(worktree, 1);
worktree->repo = the_repository;
worktree->path = strbuf_detach(&worktree_path, NULL);
@@ -373,18 +379,29 @@ done:
void update_worktree_location(struct worktree *wt, const char *path_)
{
struct strbuf path = STRBUF_INIT;
+ struct strbuf repo = STRBUF_INIT;
+ struct strbuf file = STRBUF_INIT;
+ struct strbuf tmp = STRBUF_INIT;
if (is_main_worktree(wt))
BUG("can't relocate main worktree");
+ strbuf_realpath(&repo, git_common_path("worktrees/%s", wt->id), 1);
strbuf_realpath(&path, path_, 1);
if (fspathcmp(wt->path, path.buf)) {
- write_file(git_common_path("worktrees/%s/gitdir", wt->id),
- "%s/.git", path.buf);
+ strbuf_addf(&file, "%s/gitdir", repo.buf);
+ write_file(file.buf, "%s/.git", relative_path(path.buf, repo.buf, &tmp));
+ strbuf_reset(&file);
+ strbuf_addf(&file, "%s/.git", path.buf);
+ write_file(file.buf, "gitdir: %s", relative_path(repo.buf, path.buf, &tmp));
+
free(wt->path);
wt->path = strbuf_detach(&path, NULL);
}
strbuf_release(&path);
+ strbuf_release(&repo);
+ strbuf_release(&file);
+ strbuf_release(&tmp);
}
int is_worktree_being_rebased(const struct worktree *wt,
@@ -564,38 +581,52 @@ static void repair_gitfile(struct worktree *wt,
{
struct strbuf dotgit = STRBUF_INIT;
struct strbuf repo = STRBUF_INIT;
- char *backlink;
+ struct strbuf backlink = STRBUF_INIT;
+ struct strbuf tmp = STRBUF_INIT;
+ char *dotgit_contents = NULL;
const char *repair = NULL;
int err;
/* missing worktree can't be repaired */
if (!file_exists(wt->path))
- return;
+ goto done;
if (!is_directory(wt->path)) {
fn(1, wt->path, _("not a directory"), cb_data);
- return;
+ goto done;
}
strbuf_realpath(&repo, git_common_path("worktrees/%s", wt->id), 1);
strbuf_addf(&dotgit, "%s/.git", wt->path);
- backlink = xstrdup_or_null(read_gitfile_gently(dotgit.buf, &err));
+ dotgit_contents = xstrdup_or_null(read_gitfile_gently(dotgit.buf, &err));
+
+ if (dotgit_contents) {
+ if (is_absolute_path(dotgit_contents)) {
+ strbuf_addstr(&backlink, dotgit_contents);
+ } else {
+ strbuf_addf(&backlink, "%s/%s", wt->path, dotgit_contents);
+ strbuf_realpath_forgiving(&backlink, backlink.buf, 0);
+ }
+ }
if (err == READ_GITFILE_ERR_NOT_A_FILE)
fn(1, wt->path, _(".git is not a file"), cb_data);
else if (err)
repair = _(".git file broken");
- else if (fspathcmp(backlink, repo.buf))
+ else if (fspathcmp(backlink.buf, repo.buf))
repair = _(".git file incorrect");
if (repair) {
fn(0, wt->path, repair, cb_data);
- write_file(dotgit.buf, "gitdir: %s", repo.buf);
+ write_file(dotgit.buf, "gitdir: %s", relative_path(repo.buf, wt->path, &tmp));
}
- free(backlink);
+done:
+ free(dotgit_contents);
strbuf_release(&repo);
strbuf_release(&dotgit);
+ strbuf_release(&backlink);
+ strbuf_release(&tmp);
}
static void repair_noop(int iserr UNUSED,
@@ -618,6 +649,59 @@ void repair_worktrees(worktree_repair_fn fn, void *cb_data)
free_worktrees(worktrees);
}
+void repair_worktree_after_gitdir_move(struct worktree *wt, const char *old_path)
+{
+ struct strbuf path = STRBUF_INIT;
+ struct strbuf repo = STRBUF_INIT;
+ struct strbuf gitdir = STRBUF_INIT;
+ struct strbuf dotgit = STRBUF_INIT;
+ struct strbuf olddotgit = STRBUF_INIT;
+ struct strbuf tmp = STRBUF_INIT;
+
+ if (is_main_worktree(wt))
+ goto done;
+
+ strbuf_realpath(&repo, git_common_path("worktrees/%s", wt->id), 1);
+ strbuf_addf(&gitdir, "%s/gitdir", repo.buf);
+
+ if (strbuf_read_file(&olddotgit, gitdir.buf, 0) < 0)
+ goto done;
+
+ strbuf_rtrim(&olddotgit);
+ if (is_absolute_path(olddotgit.buf)) {
+ strbuf_addbuf(&dotgit, &olddotgit);
+ } else {
+ strbuf_addf(&dotgit, "%s/worktrees/%s/%s", old_path, wt->id, olddotgit.buf);
+ strbuf_realpath_forgiving(&dotgit, dotgit.buf, 0);
+ }
+
+ if (!file_exists(dotgit.buf))
+ goto done;
+
+ strbuf_addbuf(&path, &dotgit);
+ strbuf_strip_suffix(&path, "/.git");
+
+ write_file(dotgit.buf, "gitdir: %s", relative_path(repo.buf, path.buf, &tmp));
+ write_file(gitdir.buf, "%s", relative_path(dotgit.buf, repo.buf, &tmp));
+done:
+ strbuf_release(&path);
+ strbuf_release(&repo);
+ strbuf_release(&gitdir);
+ strbuf_release(&dotgit);
+ strbuf_release(&olddotgit);
+ strbuf_release(&tmp);
+}
+
+void repair_worktrees_after_gitdir_move(const char *old_path)
+{
+ struct worktree **worktrees = get_worktrees_internal(1);
+ struct worktree **wt = worktrees + 1; /* +1 skips main worktree */
+
+ for (; *wt; wt++)
+ repair_worktree_after_gitdir_move(*wt, old_path);
+ free_worktrees(worktrees);
+}
+
static int is_main_worktree_path(const char *path)
{
struct strbuf target = STRBUF_INIT;
@@ -642,10 +726,9 @@ static int is_main_worktree_path(const char *path)
* be able to infer the gitdir by manually reading /path/to/worktree/.git,
* extracting the <id>, and checking if <repo>/worktrees/<id> exists.
*/
-static char *infer_backlink(const char *gitfile)
+static int infer_backlink(const char *gitfile, struct strbuf *inferred)
{
struct strbuf actual = STRBUF_INIT;
- struct strbuf inferred = STRBUF_INIT;
const char *id;
if (strbuf_read_file(&actual, gitfile, 0) < 0)
@@ -658,17 +741,18 @@ static char *infer_backlink(const char *gitfile)
id++; /* advance past '/' to point at <id> */
if (!*id)
goto error;
- strbuf_git_common_path(&inferred, the_repository, "worktrees/%s", id);
- if (!is_directory(inferred.buf))
+ strbuf_reset(inferred);
+ strbuf_git_common_path(inferred, the_repository, "worktrees/%s", id);
+ if (!is_directory(inferred->buf))
goto error;
strbuf_release(&actual);
- return strbuf_detach(&inferred, NULL);
+ return 1;
error:
strbuf_release(&actual);
- strbuf_release(&inferred);
- return NULL;
+ strbuf_reset(inferred); /* clear invalid path */
+ return 0;
}
/*
@@ -680,9 +764,13 @@ void repair_worktree_at_path(const char *path,
{
struct strbuf dotgit = STRBUF_INIT;
struct strbuf realdotgit = STRBUF_INIT;
+ struct strbuf backlink = STRBUF_INIT;
+ struct strbuf inferred_backlink = STRBUF_INIT;
struct strbuf gitdir = STRBUF_INIT;
struct strbuf olddotgit = STRBUF_INIT;
- char *backlink = NULL;
+ struct strbuf realolddotgit = STRBUF_INIT;
+ struct strbuf tmp = STRBUF_INIT;
+ char *dotgit_contents = NULL;
const char *repair = NULL;
int err;
@@ -698,107 +786,178 @@ void repair_worktree_at_path(const char *path,
goto done;
}
- backlink = xstrdup_or_null(read_gitfile_gently(realdotgit.buf, &err));
- if (err == READ_GITFILE_ERR_NOT_A_FILE) {
+ infer_backlink(realdotgit.buf, &inferred_backlink);
+ strbuf_realpath_forgiving(&inferred_backlink, inferred_backlink.buf, 0);
+ dotgit_contents = xstrdup_or_null(read_gitfile_gently(realdotgit.buf, &err));
+ if (dotgit_contents) {
+ if (is_absolute_path(dotgit_contents)) {
+ strbuf_addstr(&backlink, dotgit_contents);
+ } else {
+ strbuf_addbuf(&backlink, &realdotgit);
+ strbuf_strip_suffix(&backlink, ".git");
+ strbuf_addstr(&backlink, dotgit_contents);
+ strbuf_realpath_forgiving(&backlink, backlink.buf, 0);
+ }
+ } else if (err == READ_GITFILE_ERR_NOT_A_FILE) {
fn(1, realdotgit.buf, _("unable to locate repository; .git is not a file"), cb_data);
goto done;
} else if (err == READ_GITFILE_ERR_NOT_A_REPO) {
- if (!(backlink = infer_backlink(realdotgit.buf))) {
+ if (inferred_backlink.len) {
+ /*
+ * Worktree's .git file does not point at a repository
+ * but we found a .git/worktrees/<id> in this
+ * repository with the same <id> as recorded in the
+ * worktree's .git file so make the worktree point at
+ * the discovered .git/worktrees/<id>.
+ */
+ strbuf_swap(&backlink, &inferred_backlink);
+ } else {
fn(1, realdotgit.buf, _("unable to locate repository; .git file does not reference a repository"), cb_data);
goto done;
}
- } else if (err) {
+ } else {
fn(1, realdotgit.buf, _("unable to locate repository; .git file broken"), cb_data);
goto done;
}
- strbuf_addf(&gitdir, "%s/gitdir", backlink);
+ /*
+ * If we got this far, either the worktree's .git file pointed at a
+ * valid repository (i.e. read_gitfile_gently() returned success) or
+ * the .git file did not point at a repository but we were able to
+ * infer a suitable new value for the .git file by locating a
+ * .git/worktrees/<id> in *this* repository corresponding to the <id>
+ * recorded in the worktree's .git file.
+ *
+ * However, if, at this point, inferred_backlink is non-NULL (i.e. we
+ * found a suitable .git/worktrees/<id> in *this* repository) *and* the
+ * worktree's .git file points at a valid repository *and* those two
+ * paths differ, then that indicates that the user probably *copied*
+ * the main and linked worktrees to a new location as a unit rather
+ * than *moving* them. Thus, the copied worktree's .git file actually
+ * points at the .git/worktrees/<id> in the *original* repository, not
+ * in the "copy" repository. In this case, point the "copy" worktree's
+ * .git file at the "copy" repository.
+ */
+ if (inferred_backlink.len && fspathcmp(backlink.buf, inferred_backlink.buf)) {
+ strbuf_swap(&backlink, &inferred_backlink);
+ }
+
+ strbuf_addf(&gitdir, "%s/gitdir", backlink.buf);
if (strbuf_read_file(&olddotgit, gitdir.buf, 0) < 0)
repair = _("gitdir unreadable");
else {
strbuf_rtrim(&olddotgit);
- if (fspathcmp(olddotgit.buf, realdotgit.buf))
+ if (is_absolute_path(olddotgit.buf)) {
+ strbuf_addbuf(&realolddotgit, &olddotgit);
+ } else {
+ strbuf_addf(&realolddotgit, "%s/%s", backlink.buf, olddotgit.buf);
+ strbuf_realpath_forgiving(&realolddotgit, realolddotgit.buf, 0);
+ }
+ if (fspathcmp(realolddotgit.buf, realdotgit.buf))
repair = _("gitdir incorrect");
}
if (repair) {
fn(0, gitdir.buf, repair, cb_data);
- write_file(gitdir.buf, "%s", realdotgit.buf);
+ write_file(gitdir.buf, "%s", relative_path(realdotgit.buf, backlink.buf, &tmp));
}
done:
- free(backlink);
+ free(dotgit_contents);
strbuf_release(&olddotgit);
+ strbuf_release(&realolddotgit);
+ strbuf_release(&backlink);
+ strbuf_release(&inferred_backlink);
strbuf_release(&gitdir);
strbuf_release(&realdotgit);
strbuf_release(&dotgit);
+ strbuf_release(&tmp);
}
int should_prune_worktree(const char *id, struct strbuf *reason, char **wtpath, timestamp_t expire)
{
struct stat st;
- char *path;
+ struct strbuf dotgit = STRBUF_INIT;
+ struct strbuf gitdir = STRBUF_INIT;
+ struct strbuf repo = STRBUF_INIT;
+ struct strbuf file = STRBUF_INIT;
+ char *path = NULL;
+ int rc = 0;
int fd;
size_t len;
ssize_t read_result;
*wtpath = NULL;
- if (!is_directory(git_path("worktrees/%s", id))) {
+ strbuf_realpath(&repo, git_common_path("worktrees/%s", id), 1);
+ strbuf_addf(&gitdir, "%s/gitdir", repo.buf);
+ if (!is_directory(repo.buf)) {
strbuf_addstr(reason, _("not a valid directory"));
- return 1;
+ rc = 1;
+ goto done;
}
- if (file_exists(git_path("worktrees/%s/locked", id)))
- return 0;
- if (stat(git_path("worktrees/%s/gitdir", id), &st)) {
+ strbuf_addf(&file, "%s/locked", repo.buf);
+ if (file_exists(file.buf)) {
+ goto done;
+ }
+ if (stat(gitdir.buf, &st)) {
strbuf_addstr(reason, _("gitdir file does not exist"));
- return 1;
+ rc = 1;
+ goto done;
}
- fd = open(git_path("worktrees/%s/gitdir", id), O_RDONLY);
+ fd = open(gitdir.buf, O_RDONLY);
if (fd < 0) {
strbuf_addf(reason, _("unable to read gitdir file (%s)"),
strerror(errno));
- return 1;
+ rc = 1;
+ goto done;
}
len = xsize_t(st.st_size);
path = xmallocz(len);
read_result = read_in_full(fd, path, len);
+ close(fd);
if (read_result < 0) {
strbuf_addf(reason, _("unable to read gitdir file (%s)"),
strerror(errno));
- close(fd);
- free(path);
- return 1;
- }
- close(fd);
-
- if (read_result != len) {
+ rc = 1;
+ goto done;
+ } else if (read_result != len) {
strbuf_addf(reason,
_("short read (expected %"PRIuMAX" bytes, read %"PRIuMAX")"),
(uintmax_t)len, (uintmax_t)read_result);
- free(path);
- return 1;
+ rc = 1;
+ goto done;
}
while (len && (path[len - 1] == '\n' || path[len - 1] == '\r'))
len--;
if (!len) {
strbuf_addstr(reason, _("invalid gitdir file"));
- free(path);
- return 1;
+ rc = 1;
+ goto done;
}
path[len] = '\0';
- if (!file_exists(path)) {
- if (stat(git_path("worktrees/%s/index", id), &st) ||
- st.st_mtime <= expire) {
+ if (is_absolute_path(path)) {
+ strbuf_addstr(&dotgit, path);
+ } else {
+ strbuf_addf(&dotgit, "%s/%s", repo.buf, path);
+ strbuf_realpath_forgiving(&dotgit, dotgit.buf, 0);
+ }
+ if (!file_exists(dotgit.buf)) {
+ strbuf_reset(&file);
+ strbuf_addf(&file, "%s/index", repo.buf);
+ if (stat(file.buf, &st) || st.st_mtime <= expire) {
strbuf_addstr(reason, _("gitdir file points to non-existent location"));
- free(path);
- return 1;
- } else {
- *wtpath = path;
- return 0;
+ rc = 1;
+ goto done;
}
}
- *wtpath = path;
- return 0;
+ *wtpath = strbuf_detach(&dotgit, NULL);
+done:
+ free(path);
+ strbuf_release(&dotgit);
+ strbuf_release(&gitdir);
+ strbuf_release(&repo);
+ strbuf_release(&file);
+ return rc;
}
static int move_config_setting(const char *key, const char *value,
diff --git a/worktree.h b/worktree.h
index 11279d0c8f..e961186216 100644
--- a/worktree.h
+++ b/worktree.h
@@ -132,6 +132,16 @@ typedef void (* worktree_repair_fn)(int iserr, const char *path,
void repair_worktrees(worktree_repair_fn, void *cb_data);
/*
+ * Repair the linked worktrees after the gitdir has been moved.
+ */
+void repair_worktrees_after_gitdir_move(const char *old_path);
+
+/*
+ * Repair the linked worktree after the gitdir has been moved.
+ */
+void repair_worktree_after_gitdir_move(struct worktree *wt, const char *old_path);
+
+/*
* Repair administrative files corresponding to the worktree at the given path.
* The worktree's .git file pointing at the repository must be intact for the
* repair to succeed. Useful for re-associating an orphaned worktree with the