summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/main.yml16
-rw-r--r--.gitlab-ci.yml51
-rw-r--r--Documentation/BreakingChanges.txt21
-rw-r--r--Documentation/RelNotes/2.48.0.txt41
-rw-r--r--Documentation/SubmittingPatches6
-rw-r--r--Documentation/git-worktree.txt2
-rw-r--r--Makefile2
-rw-r--r--builtin/add.c3
-rw-r--r--builtin/annotate.c5
-rw-r--r--builtin/archive.c5
-rw-r--r--builtin/credential-cache.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/buildsystems/CMakeLists.txt6
-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--http.c10
-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-gitweb.sh4
-rw-r--r--t/lib-gpg.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
-rwxr-xr-xt/t0028-working-tree-encoding.sh6
-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/t1401-symbolic-ref.sh2
-rwxr-xr-xt/t1506-rev-parse-diagnosis.sh2
-rwxr-xr-xt/t2082-parallel-checkout-attributes.sh4
-rwxr-xr-xt/t2401-worktree-prune.sh19
-rwxr-xr-xt/t2406-worktree-repair.sh19
-rwxr-xr-xt/t2408-worktree-relative.sh39
-rwxr-xr-xt/t3404-rebase-interactive.sh101
-rwxr-xr-xt/t3434-rebase-i18n.sh6
-rwxr-xr-xt/t3900-i18n-commit.sh6
-rwxr-xr-xt/t3901-i18n-patch.sh6
-rwxr-xr-xt/t4041-diff-submodule-option.sh16
-rwxr-xr-xt/t4058-diff-duplicates.sh19
-rwxr-xr-xt/t4059-diff-submodule-not-initialized.sh16
-rwxr-xr-xt/t4060-diff-submodule-option-diff-format.sh17
-rwxr-xr-xt/t4201-shortlog.sh12
-rwxr-xr-xt/t4205-log-pretty-formats.sh104
-rwxr-xr-xt/t4210-log-i18n.sh6
-rwxr-xr-xt/t4254-am-corrupt.sh6
-rwxr-xr-xt/t5100-mailinfo.sh14
-rwxr-xr-xt/t5500-fetch-pack.sh14
-rwxr-xr-xt/t5550-http-fetch-dumb.sh4
-rwxr-xr-xt/t5572-pull-submodule.sh20
-rwxr-xr-xt/t5601-clone.sh11
-rwxr-xr-xt/t6006-rev-list-format.sh58
-rwxr-xr-xt/t6050-replace.sh133
-rwxr-xr-xt/t7001-mv.sh12
-rwxr-xr-xt/t7011-skip-worktree-reading.sh22
-rwxr-xr-xt/t7102-reset.sh40
-rwxr-xr-xt/t7300-clean.sh2
-rwxr-xr-xt/t8005-blame-i18n.sh6
-rwxr-xr-xt/t9300-fast-import.sh2
-rwxr-xr-xt/t9350-fast-export.sh10
-rw-r--r--t/test-lib.sh3
-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
111 files changed, 1856 insertions, 863 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/BreakingChanges.txt b/Documentation/BreakingChanges.txt
index 112770a9da..27acff86db 100644
--- a/Documentation/BreakingChanges.txt
+++ b/Documentation/BreakingChanges.txt
@@ -59,10 +59,29 @@ over time. If circumstances change, an earlier decision to deprecate or change
something may need to be revisited from time to time. So do not take items on
this list to mean "it is settled, do not waste our time bringing it up again".
+== Procedure
+
+Discussing the desire to make breaking changes, declaring that breaking
+changes are made at a certain version boundary, and recording these
+decisions in this document, are necessary but not sufficient.
+Because such changes are expected to be numerous, and the design and
+implementation of them are expected to span over time, they have to
+be deployable trivially at such a version boundary.
+
+The breaking changes MUST be guarded with the a compile-time switch,
+WITH_BREAKING_CHANGES, to help this process. When built with it,
+the resulting Git binary together with its documentation would
+behave as if these breaking changes slated for the next big version
+boundary are already in effect. We may also want to have a CI job
+or two to exercise the work-in-progress version of Git with these
+breaking changes.
+
+
== Git 3.0
The following subsections document upcoming breaking changes for Git 3.0. There
-is no planned release date for this breaking version yet.
+is no planned release date for this breaking version yet. The early
+adopter configuration used for changes for this release is `feature.git3`.
Proposed changes and removals only include items which are "ready" to be done.
In other words, this is not supposed to be a wishlist of features that should
diff --git a/Documentation/RelNotes/2.48.0.txt b/Documentation/RelNotes/2.48.0.txt
index 0fecb8de27..e5b3de8aff 100644
--- a/Documentation/RelNotes/2.48.0.txt
+++ b/Documentation/RelNotes/2.48.0.txt
@@ -25,6 +25,24 @@ 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.
+
+ * The reftable sub-system grew a new reftable-specific strbuf
+ replacement to reduce its dependency on Git-specific data
+ structures.
+
+ * The ref-filter machinery learns to recognize and avoid cases where
+ sorting would be redundant.
Fixes since v2.47
-----------------
@@ -46,6 +64,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 +92,10 @@ 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).
+ (merge 52acf6771b kh/submitting-patches later to maint).
+ (merge a73070fbd4 ks/t4205-fixup later to maint).
+ (merge 9e362dd060 co/t6050-pipefix later to maint).
+ (merge 91687cd13f sk/t7011-cleanup 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..6f5986b66e 100644
--- a/Makefile
+++ b/Makefile
@@ -3171,6 +3171,7 @@ GIT-BUILD-OPTIONS: FORCE
@echo PYTHON_PATH=\''$(subst ','\'',$(PYTHON_PATH_SQ))'\' >>$@+
@echo TAR=\''$(subst ','\'',$(subst ','\'',$(TAR)))'\' >>$@+
@echo NO_CURL=\''$(subst ','\'',$(subst ','\'',$(NO_CURL)))'\' >>$@+
+ @echo NO_ICONV=\''$(subst ','\'',$(subst ','\'',$(NO_ICONV)))'\' >>$@+
@echo NO_EXPAT=\''$(subst ','\'',$(subst ','\'',$(NO_EXPAT)))'\' >>$@+
@echo USE_LIBPCRE2=\''$(subst ','\'',$(subst ','\'',$(USE_LIBPCRE2)))'\' >>$@+
@echo NO_PERL=\''$(subst ','\'',$(subst ','\'',$(NO_PERL)))'\' >>$@+
@@ -3909,6 +3910,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/credential-cache.c b/builtin/credential-cache.c
index 5de8b9123b..7f733cb756 100644
--- a/builtin/credential-cache.c
+++ b/builtin/credential-cache.c
@@ -30,7 +30,7 @@ static int connection_fatally_broken(int error)
static int connection_closed(int error)
{
- return (error == ECONNRESET);
+ return error == ECONNRESET || error == ECONNABORTED;
}
static int connection_fatally_broken(int error)
@@ -189,7 +189,8 @@ int cmd_credential_cache(int argc,
#else
-int cmd_credential_cache(int argc, const char **argv, const char *prefix)
+int cmd_credential_cache(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
const char * const usage[] = {
"git credential-cache [options] <action>",
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/buildsystems/CMakeLists.txt b/contrib/buildsystems/CMakeLists.txt
index 62af7b33d2..1384c0eb6d 100644
--- a/contrib/buildsystems/CMakeLists.txt
+++ b/contrib/buildsystems/CMakeLists.txt
@@ -1109,6 +1109,7 @@ set(DIFF diff)
set(PYTHON_PATH /usr/bin/python)
set(TAR tar)
set(NO_CURL )
+set(NO_ICONV )
set(NO_EXPAT )
set(USE_LIBPCRE2 )
set(NO_PERL )
@@ -1122,6 +1123,10 @@ if(NOT CURL_FOUND)
set(NO_CURL 1)
endif()
+if(NOT Iconv_FOUND)
+ SET(NO_ICONV 1)
+endif()
+
if(NOT EXPAT_FOUND)
set(NO_EXPAT 1)
endif()
@@ -1145,6 +1150,7 @@ file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "DIFF='${DIFF}'\n")
file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "PYTHON_PATH='${PYTHON_PATH}'\n")
file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "TAR='${TAR}'\n")
file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "NO_CURL='${NO_CURL}'\n")
+file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "NO_ICONV='${NO_ICONV}'\n")
file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "NO_EXPAT='${NO_EXPAT}'\n")
file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "NO_PERL='${NO_PERL}'\n")
file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "NO_PTHREADS='${NO_PTHREADS}'\n")
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/http.c b/http.c
index d59e59f66b..72973175a8 100644
--- a/http.c
+++ b/http.c
@@ -2290,17 +2290,19 @@ static int http_request_reauth(const char *url,
case HTTP_REQUEST_STRBUF:
strbuf_reset(result);
break;
- case HTTP_REQUEST_FILE:
- if (fflush(result)) {
+ case HTTP_REQUEST_FILE: {
+ FILE *f = result;
+ if (fflush(f)) {
error_errno("unable to flush a file");
return HTTP_START_FAILED;
}
- rewind(result);
- if (ftruncate(fileno(result), 0) < 0) {
+ rewind(f);
+ if (ftruncate(fileno(f), 0) < 0) {
error_errno("unable to truncate a file");
return HTTP_START_FAILED;
}
break;
+ }
default:
BUG("Unknown http_request target");
}
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-gitweb.sh b/t/lib-gitweb.sh
index 1f32ca66ea..7f9808ec20 100644
--- a/t/lib-gitweb.sh
+++ b/t/lib-gitweb.sh
@@ -48,8 +48,8 @@ EOF
test -f "$SCRIPT_NAME" ||
error "Cannot find gitweb at $GITWEB_TEST_INSTALLED."
say "# Testing $SCRIPT_NAME"
- else # normal case, use source version of gitweb
- SCRIPT_NAME="$GIT_BUILD_DIR/gitweb/gitweb.perl"
+ else # normal case, use built version of gitweb
+ SCRIPT_NAME="$GIT_BUILD_DIR/gitweb/gitweb.cgi"
fi
export SCRIPT_NAME
}
diff --git a/t/lib-gpg.sh b/t/lib-gpg.sh
index add11e88fc..3845b6ac44 100644
--- a/t/lib-gpg.sh
+++ b/t/lib-gpg.sh
@@ -6,7 +6,7 @@
# executed in an eval'ed subshell that changes the working directory to a
# temporary one.
-GNUPGHOME="$PWD/gpghome"
+GNUPGHOME="$(pwd)/gpghome"
export GNUPGHOME
test_lazy_prereq GPG '
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/t0028-working-tree-encoding.sh b/t/t0028-working-tree-encoding.sh
index ad151a3467..510da4ca12 100755
--- a/t/t0028-working-tree-encoding.sh
+++ b/t/t0028-working-tree-encoding.sh
@@ -12,6 +12,12 @@ TEST_CREATE_REPO_NO_TEMPLATE=1
GIT_TRACE_WORKING_TREE_ENCODING=1 && export GIT_TRACE_WORKING_TREE_ENCODING
+if ! test_have_prereq ICONV
+then
+ skip_all='skipping working tree encoding tests; iconv not available'
+ test_done
+fi
+
test_expect_success 'setup test files' '
git config core.eol lf &&
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/t1401-symbolic-ref.sh b/t/t1401-symbolic-ref.sh
index 5c60d6f812..90af3f955c 100755
--- a/t/t1401-symbolic-ref.sh
+++ b/t/t1401-symbolic-ref.sh
@@ -16,7 +16,7 @@ reset_to_sane() {
test_expect_success 'setup' '
git symbolic-ref HEAD refs/heads/foo &&
test_commit file &&
- "$TAR" cf .git.tar .git/
+ "$TAR" cf .git.tar .git
'
test_expect_success 'symbolic-ref read/write roundtrip' '
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..d02d6a5550 100755
--- a/t/t2082-parallel-checkout-attributes.sh
+++ b/t/t2082-parallel-checkout-attributes.sh
@@ -34,7 +34,7 @@ test_expect_success 'parallel-checkout with ident' '
)
'
-test_expect_success 'parallel-checkout with re-encoding' '
+test_expect_success ICONV 'parallel-checkout with re-encoding' '
set_checkout_config 2 0 &&
git init encoding &&
(
@@ -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/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index 4896a801ee..77cceda14a 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -281,8 +281,9 @@ test_expect_success 'stop on conflicting pick' '
test_cmp expect2 file1 &&
test "$(git diff --name-status |
sed -n -e "/^U/s/^U[^a-z]*//p")" = file1 &&
- test 4 = $(grep -v "^#" < .git/rebase-merge/done | wc -l) &&
- test 0 = $(grep -c "^[^#]" < .git/rebase-merge/git-rebase-todo)
+ grep -v "^#" <.git/rebase-merge/done >actual &&
+ test_line_count = 4 actual &&
+ test 0 = $(grep -c "^[^#]" <.git/rebase-merge/git-rebase-todo)
'
test_expect_success 'show conflicted patch' '
@@ -319,7 +320,8 @@ test_expect_success 'retain authorship' '
GIT_AUTHOR_NAME="Twerp Snog" git commit -m "different author" &&
git tag twerp &&
git rebase -i --onto primary HEAD^ &&
- git show HEAD | grep "^Author: Twerp Snog"
+ git show HEAD >actual &&
+ grep "^Author: Twerp Snog" actual
'
test_expect_success 'retain authorship w/ conflicts' '
@@ -360,7 +362,8 @@ test_expect_success 'squash' '
'
test_expect_success 'retain authorship when squashing' '
- git show HEAD | grep "^Author: Twerp Snog"
+ git show HEAD >actual &&
+ grep "^Author: Twerp Snog" actual
'
test_expect_success '--continue tries to commit' '
@@ -374,7 +377,8 @@ test_expect_success '--continue tries to commit' '
FAKE_COMMIT_MESSAGE="chouette!" git rebase --continue
) &&
test_cmp_rev HEAD^ new-branch1 &&
- git show HEAD | grep chouette
+ git show HEAD >actual &&
+ grep chouette actual
'
test_expect_success 'verbose flag is heeded, even after --continue' '
@@ -397,7 +401,9 @@ test_expect_success 'multi-squash only fires up editor once' '
git rebase -i $base
) &&
test $base = $(git rev-parse HEAD^) &&
- test 1 = $(git show | grep ONCE | wc -l)
+ git show >output &&
+ grep ONCE output >actual &&
+ test_line_count = 1 actual
'
test_expect_success 'multi-fixup does not fire up editor' '
@@ -410,7 +416,8 @@ test_expect_success 'multi-fixup does not fire up editor' '
git rebase -i $base
) &&
test $base = $(git rev-parse HEAD^) &&
- test 0 = $(git show | grep NEVER | wc -l) &&
+ git show >output &&
+ ! grep NEVER output &&
git checkout @{-1} &&
git branch -D multi-fixup
'
@@ -428,7 +435,9 @@ test_expect_success 'commit message used after conflict' '
git rebase --continue
) &&
test $base = $(git rev-parse HEAD^) &&
- test 1 = $(git show | grep ONCE | wc -l) &&
+ git show >output &&
+ grep ONCE output >actual &&
+ test_line_count = 1 actual &&
git checkout @{-1} &&
git branch -D conflict-fixup
'
@@ -446,7 +455,9 @@ test_expect_success 'commit message retained after conflict' '
git rebase --continue
) &&
test $base = $(git rev-parse HEAD^) &&
- test 2 = $(git show | grep TWICE | wc -l) &&
+ git show >output &&
+ grep TWICE output >actual &&
+ test_line_count = 2 actual &&
git checkout @{-1} &&
git branch -D conflict-squash
'
@@ -470,10 +481,10 @@ test_expect_success 'squash and fixup generate correct log messages' '
) &&
git cat-file commit HEAD | sed -e 1,/^\$/d > actual-squash-fixup &&
test_cmp expect-squash-fixup actual-squash-fixup &&
- git cat-file commit HEAD@{2} |
- grep "^# This is a combination of 3 commits\." &&
- git cat-file commit HEAD@{3} |
- grep "^# This is a combination of 2 commits\." &&
+ git cat-file commit HEAD@{2} >actual &&
+ grep "^# This is a combination of 3 commits\." actual &&
+ git cat-file commit HEAD@{3} >actual &&
+ grep "^# This is a combination of 2 commits\." actual &&
git checkout @{-1} &&
git branch -D squash-fixup
'
@@ -489,7 +500,9 @@ test_expect_success 'squash ignores comments' '
git rebase -i $base
) &&
test $base = $(git rev-parse HEAD^) &&
- test 1 = $(git show | grep ONCE | wc -l) &&
+ git show >output &&
+ grep ONCE output >actual &&
+ test_line_count = 1 actual &&
git checkout @{-1} &&
git branch -D skip-comments
'
@@ -505,7 +518,9 @@ test_expect_success 'squash ignores blank lines' '
git rebase -i $base
) &&
test $base = $(git rev-parse HEAD^) &&
- test 1 = $(git show | grep ONCE | wc -l) &&
+ git show >output &&
+ grep ONCE output >actual &&
+ test_line_count = 1 actual &&
git checkout @{-1} &&
git branch -D skip-blank-lines
'
@@ -572,7 +587,8 @@ test_expect_success '--continue tries to commit, even for "edit"' '
FAKE_COMMIT_MESSAGE="chouette!" git rebase --continue
) &&
test edited = $(git show HEAD:file7) &&
- git show HEAD | grep chouette &&
+ git show HEAD >actual &&
+ grep chouette actual &&
test $parent = $(git rev-parse HEAD^)
'
@@ -757,19 +773,23 @@ test_expect_success 'reword' '
set_fake_editor &&
FAKE_LINES="1 2 3 reword 4" FAKE_COMMIT_MESSAGE="E changed" \
git rebase -i A &&
- git show HEAD | grep "E changed" &&
+ git show HEAD >actual &&
+ grep "E changed" actual &&
test $(git rev-parse primary) != $(git rev-parse HEAD) &&
test_cmp_rev primary^ HEAD^ &&
FAKE_LINES="1 2 reword 3 4" FAKE_COMMIT_MESSAGE="D changed" \
git rebase -i A &&
- git show HEAD^ | grep "D changed" &&
+ git show HEAD^ >actual &&
+ grep "D changed" actual &&
FAKE_LINES="reword 1 2 3 4" FAKE_COMMIT_MESSAGE="B changed" \
git rebase -i A &&
- git show HEAD~3 | grep "B changed" &&
+ git show HEAD~3 >actual &&
+ grep "B changed" actual &&
FAKE_LINES="1 r 2 pick 3 p 4" FAKE_COMMIT_MESSAGE="C changed" \
git rebase -i A
) &&
- git show HEAD~2 | grep "C changed"
+ git show HEAD~2 >actual &&
+ grep "C changed" actual
'
test_expect_success 'no uncommitted changes when rewording and the todo list is reloaded' '
@@ -1003,8 +1023,10 @@ test_expect_success 'rebase -i --root retain root commit author and message' '
set_fake_editor &&
FAKE_LINES="2" git rebase -i --root
) &&
- git cat-file commit HEAD | grep -q "^author Twerp Snog" &&
- git cat-file commit HEAD | grep -q "^different author$"
+ git cat-file commit HEAD >output &&
+ grep -q "^author Twerp Snog" output &&
+ git cat-file commit HEAD >actual &&
+ grep -q "^different author$" actual
'
test_expect_success 'rebase -i --root temporary sentinel commit' '
@@ -1013,7 +1035,8 @@ test_expect_success 'rebase -i --root temporary sentinel commit' '
set_fake_editor &&
test_must_fail env FAKE_LINES="2" git rebase -i --root
) &&
- git cat-file commit HEAD | grep "^tree $EMPTY_TREE" &&
+ git cat-file commit HEAD >actual &&
+ grep "^tree $EMPTY_TREE" actual &&
git rebase --abort
'
@@ -1036,7 +1059,8 @@ test_expect_success 'rebase -i --root reword original root commit' '
FAKE_LINES="reword 1 2" FAKE_COMMIT_MESSAGE="A changed" \
git rebase -i --root
) &&
- git show HEAD^ | grep "A changed" &&
+ git show HEAD^ >actual &&
+ grep "A changed" actual &&
test -z "$(git show -s --format=%p HEAD^)"
'
@@ -1048,7 +1072,8 @@ test_expect_success 'rebase -i --root reword new root commit' '
FAKE_LINES="reword 3 1" FAKE_COMMIT_MESSAGE="C changed" \
git rebase -i --root
) &&
- git show HEAD^ | grep "C changed" &&
+ git show HEAD^ >actual &&
+ grep "C changed" actual &&
test -z "$(git show -s --format=%p HEAD^)"
'
@@ -1917,18 +1942,17 @@ test_expect_success '--update-refs updates refs correctly' '
test_cmp_rev HEAD~1 refs/heads/third &&
test_cmp_rev HEAD refs/heads/no-conflict-branch &&
- cat >expect <<-\EOF &&
+ q_to_tab >expect <<-\EOF &&
Successfully rebased and updated refs/heads/update-refs.
Updated the following refs with --update-refs:
- refs/heads/first
- refs/heads/no-conflict-branch
- refs/heads/second
- refs/heads/third
+ Qrefs/heads/first
+ Qrefs/heads/no-conflict-branch
+ Qrefs/heads/second
+ Qrefs/heads/third
EOF
# Clear "Rebasing (X/Y)" progress lines and drop leading tabs.
- sed -e "s/Rebasing.*Successfully/Successfully/g" -e "s/^\t//g" \
- <err >err.trimmed &&
+ sed "s/Rebasing.*Successfully/Successfully/g" <err >err.trimmed &&
test_cmp expect err.trimmed
'
@@ -2178,19 +2202,18 @@ test_expect_success '--update-refs: check failed ref update' '
test_must_fail git rebase --continue 2>err &&
grep "update_ref failed for ref '\''refs/heads/second'\''" err &&
- cat >expect <<-\EOF &&
+ q_to_tab >expect <<-\EOF &&
Updated the following refs with --update-refs:
- refs/heads/first
- refs/heads/no-conflict-branch
- refs/heads/third
+ Qrefs/heads/first
+ Qrefs/heads/no-conflict-branch
+ Qrefs/heads/third
Failed to update the following refs with --update-refs:
- refs/heads/second
+ Qrefs/heads/second
EOF
# Clear "Rebasing (X/Y)" progress lines and drop leading tabs.
tail -n 6 err >err.last &&
- sed -e "s/Rebasing.*Successfully/Successfully/g" -e "s/^\t//g" \
- <err.last >err.trimmed &&
+ sed "s/Rebasing.*Successfully/Successfully/g" <err.last >err.trimmed &&
test_cmp expect err.trimmed
'
diff --git a/t/t3434-rebase-i18n.sh b/t/t3434-rebase-i18n.sh
index 26a48d6b10..97fc9a23f2 100755
--- a/t/t3434-rebase-i18n.sh
+++ b/t/t3434-rebase-i18n.sh
@@ -20,6 +20,12 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
+if ! test_have_prereq ICONV
+then
+ skip_all='skipping rebase i18n tests; iconv not available'
+ test_done
+fi
+
compare_msg () {
iconv -f "$2" -t "$3" "$TEST_DIRECTORY/t3434/$1" >expect &&
git cat-file commit HEAD >raw &&
diff --git a/t/t3900-i18n-commit.sh b/t/t3900-i18n-commit.sh
index db7b403bc1..9d4b5ab1f9 100755
--- a/t/t3900-i18n-commit.sh
+++ b/t/t3900-i18n-commit.sh
@@ -8,6 +8,12 @@ test_description='commit and log output encodings'
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
+if ! test_have_prereq ICONV
+then
+ skip_all='skipping commit i18n tests; iconv not available'
+ test_done
+fi
+
compare_with () {
git show -s $1 | sed -e '1,/^$/d' -e 's/^ //' >current &&
case "$3" in
diff --git a/t/t3901-i18n-patch.sh b/t/t3901-i18n-patch.sh
index 5f0b9afc3f..e0659c9293 100755
--- a/t/t3901-i18n-patch.sh
+++ b/t/t3901-i18n-patch.sh
@@ -11,6 +11,12 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
+if ! test_have_prereq ICONV
+then
+ skip_all='skipping patch i18n tests; iconv not available'
+ test_done
+fi
+
check_encoding () {
# Make sure characters are not corrupted
cnt="$1" header="$2" i=1 j=0
diff --git a/t/t4041-diff-submodule-option.sh b/t/t4041-diff-submodule-option.sh
index 8fc40e75eb..aa149e0085 100755
--- a/t/t4041-diff-submodule-option.sh
+++ b/t/t4041-diff-submodule-option.sh
@@ -15,12 +15,18 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
-# Tested non-UTF-8 encoding
-test_encoding="ISO8859-1"
+# Test non-UTF-8 encoding in case iconv is available.
+if test_have_prereq ICONV
+then
+ test_encoding="ISO8859-1"
+ # String "added" in German (translated with Google Translate), encoded in UTF-8,
+ # used in sample commit log messages in add_file() function below.
+ added=$(printf "hinzugef\303\274gt")
+else
+ test_encoding="UTF-8"
+ added="added"
+fi
-# String "added" in German (translated with Google Translate), encoded in UTF-8,
-# used in sample commit log messages in add_file() function below.
-added=$(printf "hinzugef\303\274gt")
add_file () {
(
cd "$1" &&
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/t4059-diff-submodule-not-initialized.sh b/t/t4059-diff-submodule-not-initialized.sh
index 668f526303..28fd3cdb15 100755
--- a/t/t4059-diff-submodule-not-initialized.sh
+++ b/t/t4059-diff-submodule-not-initialized.sh
@@ -12,12 +12,18 @@ initialized previously but the checkout has since been removed.
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
-# Tested non-UTF-8 encoding
-test_encoding="ISO8859-1"
-# String "added" in German (translated with Google Translate), encoded in UTF-8,
-# used in sample commit log messages in add_file() function below.
-added=$(printf "hinzugef\303\274gt")
+# Test non-UTF-8 encoding in case iconv is available.
+if test_have_prereq ICONV
+then
+ test_encoding="ISO8859-1"
+ # String "added" in German (translated with Google Translate), encoded in UTF-8,
+ # used in sample commit log messages in add_file() function below.
+ added=$(printf "hinzugef\303\274gt")
+else
+ test_encoding="UTF-8"
+ added="added"
+fi
add_file () {
(
diff --git a/t/t4060-diff-submodule-option-diff-format.sh b/t/t4060-diff-submodule-option-diff-format.sh
index 8ce67442d9..918334fa4c 100755
--- a/t/t4060-diff-submodule-option-diff-format.sh
+++ b/t/t4060-diff-submodule-option-diff-format.sh
@@ -13,12 +13,17 @@ This test tries to verify the sanity of --submodule=diff option of git diff.
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
-# Tested non-UTF-8 encoding
-test_encoding="ISO8859-1"
-
-# String "added" in German (translated with Google Translate), encoded in UTF-8,
-# used in sample commit log messages in add_file() function below.
-added=$(printf "hinzugef\303\274gt")
+# Test non-UTF-8 encoding in case iconv is available.
+if test_have_prereq ICONV
+then
+ test_encoding="ISO8859-1"
+ # String "added" in German (translated with Google Translate), encoded in UTF-8,
+ # used in sample commit log messages in add_file() function below.
+ added=$(printf "hinzugef\303\274gt")
+else
+ test_encoding="UTF-8"
+ added="added"
+fi
add_file () {
(
diff --git a/t/t4201-shortlog.sh b/t/t4201-shortlog.sh
index c20c885724..7f47f85c7f 100755
--- a/t/t4201-shortlog.sh
+++ b/t/t4201-shortlog.sh
@@ -105,7 +105,7 @@ test_expect_success 'output from user-defined format is re-wrapped' '
test_cmp expect log.predictable
'
-test_expect_success !MINGW 'shortlog wrapping' '
+test_expect_success !MINGW,ICONV 'shortlog wrapping' '
cat >expect <<\EOF &&
A U Thor (5):
Test
@@ -126,13 +126,13 @@ EOF
test_cmp expect out
'
-test_expect_success !MINGW 'shortlog from non-git directory' '
+test_expect_success !MINGW,ICONV 'shortlog from non-git directory' '
git log --no-expand-tabs HEAD >log &&
GIT_DIR=non-existing git shortlog -w <log >out &&
test_cmp expect out
'
-test_expect_success !MINGW 'shortlog can read --format=raw output' '
+test_expect_success !MINGW,ICONV 'shortlog can read --format=raw output' '
git log --format=raw HEAD >log &&
GIT_DIR=non-existing git shortlog -w <log >out &&
test_cmp expect out
@@ -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):
@@ -182,7 +186,7 @@ $DSCHO (2):
EOF
-test_expect_success !MINGW 'shortlog encoding' '
+test_expect_success !MINGW,ICONV 'shortlog encoding' '
git reset --hard "$commit" &&
git config --unset i18n.commitencoding &&
echo 2 > a1 &&
diff --git a/t/t4205-log-pretty-formats.sh b/t/t4205-log-pretty-formats.sh
index eb63ce011f..f9a9c2145e 100755
--- a/t/t4205-log-pretty-formats.sh
+++ b/t/t4205-log-pretty-formats.sh
@@ -114,19 +114,19 @@ test_expect_success 'alias loop' '
test_must_fail git log --pretty=test-foo
'
-test_expect_success 'NUL separation' '
+test_expect_success ICONV 'NUL separation' '
printf "add bar\0$(commit_msg)" >expected &&
git log -z --pretty="format:%s" >actual &&
test_cmp expected actual
'
-test_expect_success 'NUL termination' '
+test_expect_success ICONV 'NUL termination' '
printf "add bar\0$(commit_msg)\0" >expected &&
git log -z --pretty="tformat:%s" >actual &&
test_cmp expected actual
'
-test_expect_success 'NUL separation with --stat' '
+test_expect_success ICONV 'NUL separation 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\n" >expected &&
@@ -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
'
@@ -181,7 +181,7 @@ test_expect_success 'setup more commits' '
head4=$(git rev-parse --verify --short HEAD~3)
'
-test_expect_success 'left alignment formatting' '
+test_expect_success ICONV 'left alignment formatting' '
git log --pretty="tformat:%<(40)%s" >actual &&
qz_to_tab_space <<-EOF >expected &&
message two Z
@@ -192,7 +192,7 @@ test_expect_success 'left alignment formatting' '
test_cmp expected actual
'
-test_expect_success 'left alignment formatting. i18n.logOutputEncoding' '
+test_expect_success ICONV 'left alignment formatting. i18n.logOutputEncoding' '
git -c i18n.logOutputEncoding=$test_encoding log --pretty="tformat:%<(40)%s" >actual &&
qz_to_tab_space <<-EOF | iconv -f utf-8 -t $test_encoding >expected &&
message two Z
@@ -203,7 +203,7 @@ test_expect_success 'left alignment formatting. i18n.logOutputEncoding' '
test_cmp expected actual
'
-test_expect_success 'left alignment formatting at the nth column' '
+test_expect_success ICONV 'left alignment formatting at the nth column' '
git log --pretty="tformat:%h %<|(40)%s" >actual &&
qz_to_tab_space <<-EOF >expected &&
$head1 message two Z
@@ -214,7 +214,7 @@ test_expect_success 'left alignment formatting at the nth column' '
test_cmp expected actual
'
-test_expect_success 'left alignment formatting at the nth column' '
+test_expect_success ICONV 'left alignment formatting at the nth column' '
COLUMNS=50 git log --pretty="tformat:%h %<|(-10)%s" >actual &&
qz_to_tab_space <<-EOF >expected &&
$head1 message two Z
@@ -225,7 +225,7 @@ test_expect_success 'left alignment formatting at the nth column' '
test_cmp expected actual
'
-test_expect_success 'left alignment formatting at the nth column. i18n.logOutputEncoding' '
+test_expect_success ICONV 'left alignment formatting at the nth column. i18n.logOutputEncoding' '
git -c i18n.logOutputEncoding=$test_encoding log --pretty="tformat:%h %<|(40)%s" >actual &&
qz_to_tab_space <<-EOF | iconv -f utf-8 -t $test_encoding >expected &&
$head1 message two Z
@@ -236,7 +236,7 @@ test_expect_success 'left alignment formatting at the nth column. i18n.logOutput
test_cmp expected actual
'
-test_expect_success 'left alignment formatting with no padding' '
+test_expect_success ICONV 'left alignment formatting with no padding' '
git log --pretty="tformat:%<(1)%s" >actual &&
cat <<-EOF >expected &&
message two
@@ -258,7 +258,7 @@ test_expect_success 'left alignment formatting with no padding. i18n.logOutputEn
test_cmp expected actual
'
-test_expect_success 'left alignment formatting with trunc' '
+test_expect_success ICONV 'left alignment formatting with trunc' '
git log --pretty="tformat:%<(10,trunc)%s" >actual &&
qz_to_tab_space <<-\EOF >expected &&
message ..
@@ -269,7 +269,7 @@ test_expect_success 'left alignment formatting with trunc' '
test_cmp expected actual
'
-test_expect_success 'left alignment formatting with trunc. i18n.logOutputEncoding' '
+test_expect_success ICONV 'left alignment formatting with trunc. i18n.logOutputEncoding' '
git -c i18n.logOutputEncoding=$test_encoding log --pretty="tformat:%<(10,trunc)%s" >actual &&
qz_to_tab_space <<-\EOF | iconv -f utf-8 -t $test_encoding >expected &&
message ..
@@ -280,7 +280,7 @@ test_expect_success 'left alignment formatting with trunc. i18n.logOutputEncodin
test_cmp expected actual
'
-test_expect_success 'left alignment formatting with ltrunc' '
+test_expect_success ICONV 'left alignment formatting with ltrunc' '
git log --pretty="tformat:%<(10,ltrunc)%s" >actual &&
qz_to_tab_space <<-EOF >expected &&
..sage two
@@ -291,7 +291,7 @@ test_expect_success 'left alignment formatting with ltrunc' '
test_cmp expected actual
'
-test_expect_success 'left alignment formatting with ltrunc. i18n.logOutputEncoding' '
+test_expect_success ICONV 'left alignment formatting with ltrunc. i18n.logOutputEncoding' '
git -c i18n.logOutputEncoding=$test_encoding log --pretty="tformat:%<(10,ltrunc)%s" >actual &&
qz_to_tab_space <<-EOF | iconv -f utf-8 -t $test_encoding >expected &&
..sage two
@@ -302,7 +302,7 @@ test_expect_success 'left alignment formatting with ltrunc. i18n.logOutputEncodi
test_cmp expected actual
'
-test_expect_success 'left alignment formatting with mtrunc' '
+test_expect_success ICONV 'left alignment formatting with mtrunc' '
git log --pretty="tformat:%<(10,mtrunc)%s" >actual &&
qz_to_tab_space <<-\EOF >expected &&
mess.. two
@@ -313,7 +313,7 @@ test_expect_success 'left alignment formatting with mtrunc' '
test_cmp expected actual
'
-test_expect_success 'left alignment formatting with mtrunc. i18n.logOutputEncoding' '
+test_expect_success ICONV 'left alignment formatting with mtrunc. i18n.logOutputEncoding' '
git -c i18n.logOutputEncoding=$test_encoding log --pretty="tformat:%<(10,mtrunc)%s" >actual &&
qz_to_tab_space <<-\EOF | iconv -f utf-8 -t $test_encoding >expected &&
mess.. two
@@ -324,7 +324,7 @@ test_expect_success 'left alignment formatting with mtrunc. i18n.logOutputEncodi
test_cmp expected actual
'
-test_expect_success 'right alignment formatting' '
+test_expect_success ICONV 'right alignment formatting' '
git log --pretty="tformat:%>(40)%s" >actual &&
qz_to_tab_space <<-EOF >expected &&
Z message two
@@ -335,7 +335,7 @@ test_expect_success 'right alignment formatting' '
test_cmp expected actual
'
-test_expect_success 'right alignment formatting. i18n.logOutputEncoding' '
+test_expect_success ICONV 'right alignment formatting. i18n.logOutputEncoding' '
git -c i18n.logOutputEncoding=$test_encoding log --pretty="tformat:%>(40)%s" >actual &&
qz_to_tab_space <<-EOF | iconv -f utf-8 -t $test_encoding >expected &&
Z message two
@@ -346,7 +346,7 @@ test_expect_success 'right alignment formatting. i18n.logOutputEncoding' '
test_cmp expected actual
'
-test_expect_success 'right alignment formatting at the nth column' '
+test_expect_success ICONV 'right alignment formatting at the nth column' '
git log --pretty="tformat:%h %>|(40)%s" >actual &&
qz_to_tab_space <<-EOF >expected &&
$head1 message two
@@ -357,7 +357,7 @@ test_expect_success 'right alignment formatting at the nth column' '
test_cmp expected actual
'
-test_expect_success 'right alignment formatting at the nth column' '
+test_expect_success ICONV 'right alignment formatting at the nth column' '
COLUMNS=50 git log --pretty="tformat:%h %>|(-10)%s" >actual &&
qz_to_tab_space <<-EOF >expected &&
$head1 message two
@@ -368,7 +368,7 @@ test_expect_success 'right alignment formatting at the nth column' '
test_cmp expected actual
'
-test_expect_success 'right alignment formatting at the nth column. i18n.logOutputEncoding' '
+test_expect_success ICONV 'right alignment formatting at the nth column. i18n.logOutputEncoding' '
git -c i18n.logOutputEncoding=$test_encoding log --pretty="tformat:%h %>|(40)%s" >actual &&
qz_to_tab_space <<-EOF | iconv -f utf-8 -t $test_encoding >expected &&
$head1 message two
@@ -381,7 +381,7 @@ test_expect_success 'right alignment formatting at the nth column. i18n.logOutpu
# Note: Space between 'message' and 'two' should be in the same column
# as in previous test.
-test_expect_success 'right alignment formatting at the nth column with --graph. i18n.logOutputEncoding' '
+test_expect_success ICONV 'right alignment formatting at the nth column with --graph. i18n.logOutputEncoding' '
git -c i18n.logOutputEncoding=$test_encoding log --graph --pretty="tformat:%h %>|(40)%s" >actual &&
iconv -f utf-8 -t $test_encoding >expected <<-EOF &&
* $head1 message two
@@ -392,7 +392,7 @@ test_expect_success 'right alignment formatting at the nth column with --graph.
test_cmp expected actual
'
-test_expect_success 'right alignment formatting with no padding' '
+test_expect_success ICONV 'right alignment formatting with no padding' '
git log --pretty="tformat:%>(1)%s" >actual &&
cat <<-EOF >expected &&
message two
@@ -403,7 +403,7 @@ test_expect_success 'right alignment formatting with no padding' '
test_cmp expected actual
'
-test_expect_success 'right alignment formatting with no padding and with --graph' '
+test_expect_success ICONV 'right alignment formatting with no padding and with --graph' '
git log --graph --pretty="tformat:%>(1)%s" >actual &&
cat <<-EOF >expected &&
* message two
@@ -414,7 +414,7 @@ test_expect_success 'right alignment formatting with no padding and with --graph
test_cmp expected actual
'
-test_expect_success 'right alignment formatting with no padding. i18n.logOutputEncoding' '
+test_expect_success ICONV 'right alignment formatting with no padding. i18n.logOutputEncoding' '
git -c i18n.logOutputEncoding=$test_encoding log --pretty="tformat:%>(1)%s" >actual &&
cat <<-EOF | iconv -f utf-8 -t $test_encoding >expected &&
message two
@@ -425,7 +425,7 @@ test_expect_success 'right alignment formatting with no padding. i18n.logOutputE
test_cmp expected actual
'
-test_expect_success 'center alignment formatting' '
+test_expect_success ICONV 'center alignment formatting' '
git log --pretty="tformat:%><(40)%s" >actual &&
qz_to_tab_space <<-EOF >expected &&
Z message two Z
@@ -436,7 +436,7 @@ test_expect_success 'center alignment formatting' '
test_cmp expected actual
'
-test_expect_success 'center alignment formatting. i18n.logOutputEncoding' '
+test_expect_success ICONV 'center alignment formatting. i18n.logOutputEncoding' '
git -c i18n.logOutputEncoding=$test_encoding log --pretty="tformat:%><(40)%s" >actual &&
qz_to_tab_space <<-EOF | iconv -f utf-8 -t $test_encoding >expected &&
Z message two Z
@@ -446,7 +446,7 @@ test_expect_success 'center alignment formatting. i18n.logOutputEncoding' '
EOF
test_cmp expected actual
'
-test_expect_success 'center alignment formatting at the nth column' '
+test_expect_success ICONV 'center alignment formatting at the nth column' '
git log --pretty="tformat:%h %><|(40)%s" >actual &&
qz_to_tab_space <<-EOF >expected &&
$head1 message two Z
@@ -457,7 +457,7 @@ test_expect_success 'center alignment formatting at the nth column' '
test_cmp expected actual
'
-test_expect_success 'center alignment formatting at the nth column' '
+test_expect_success ICONV 'center alignment formatting at the nth column' '
COLUMNS=70 git log --pretty="tformat:%h %><|(-30)%s" >actual &&
qz_to_tab_space <<-EOF >expected &&
$head1 message two Z
@@ -468,7 +468,7 @@ test_expect_success 'center alignment formatting at the nth column' '
test_cmp expected actual
'
-test_expect_success 'center alignment formatting at the nth column. i18n.logOutputEncoding' '
+test_expect_success ICONV 'center alignment formatting at the nth column. i18n.logOutputEncoding' '
git -c i18n.logOutputEncoding=$test_encoding log --pretty="tformat:%h %><|(40)%s" >actual &&
qz_to_tab_space <<-EOF | iconv -f utf-8 -t $test_encoding >expected &&
$head1 message two Z
@@ -479,7 +479,7 @@ test_expect_success 'center alignment formatting at the nth column. i18n.logOutp
test_cmp expected actual
'
-test_expect_success 'center alignment formatting with no padding' '
+test_expect_success ICONV 'center alignment formatting with no padding' '
git log --pretty="tformat:%><(1)%s" >actual &&
cat <<-EOF >expected &&
message two
@@ -493,7 +493,7 @@ test_expect_success 'center alignment formatting with no padding' '
# save HEAD's SHA-1 digest (with no abbreviations) to use it below
# as far as the next test amends HEAD
old_head1=$(git rev-parse --verify HEAD~0)
-test_expect_success 'center alignment formatting with no padding. i18n.logOutputEncoding' '
+test_expect_success ICONV 'center alignment formatting with no padding. i18n.logOutputEncoding' '
git -c i18n.logOutputEncoding=$test_encoding log --pretty="tformat:%><(1)%s" >actual &&
cat <<-EOF | iconv -f utf-8 -t $test_encoding >expected &&
message two
@@ -504,7 +504,7 @@ test_expect_success 'center alignment formatting with no padding. i18n.logOutput
test_cmp expected actual
'
-test_expect_success 'left/right alignment formatting with stealing' '
+test_expect_success ICONV 'left/right alignment formatting with stealing' '
git commit --amend -m short --author "long long long <long@me.com>" &&
git log --pretty="tformat:%<(10,trunc)%s%>>(10,ltrunc)% an" >actual &&
cat <<-\EOF >expected &&
@@ -515,7 +515,7 @@ test_expect_success 'left/right alignment formatting with stealing' '
EOF
test_cmp expected actual
'
-test_expect_success 'left/right alignment formatting with stealing. i18n.logOutputEncoding' '
+test_expect_success ICONV 'left/right alignment formatting with stealing. i18n.logOutputEncoding' '
git -c i18n.logOutputEncoding=$test_encoding log --pretty="tformat:%<(10,trunc)%s%>>(10,ltrunc)% an" >actual &&
cat <<-\EOF | iconv -f utf-8 -t $test_encoding >expected &&
short long long long
@@ -564,22 +564,38 @@ test_expect_success 'log decoration properly follows tag chain' '
git tag -d tag1 &&
git commit --amend -m shorter &&
git log --no-walk --tags --pretty="%H %d" --decorate=full >actual &&
- cat <<-EOF >expected &&
- $head2 (tag: refs/tags/message-one)
- $old_head1 (tag: refs/tags/message-two)
- $head1 (tag: refs/tags/tag2)
- EOF
+ if test_have_prereq ICONV
+ then
+ cat <<-EOF >expected
+ $head2 (tag: refs/tags/message-one)
+ $old_head1 (tag: refs/tags/message-two)
+ $head1 (tag: refs/tags/tag2)
+ EOF
+ else
+ cat <<-EOF >expected
+ $head2 (tag: refs/tags/message-one)
+ $old_head1 (tag: refs/tags/tag2, tag: refs/tags/message-two)
+ EOF
+ fi &&
sort -k3 actual >actual1 &&
test_cmp expected actual1
'
test_expect_success 'clean log decoration' '
git log --no-walk --tags --pretty="%H %D" --decorate=full >actual &&
- cat >expected <<-EOF &&
- $head2 tag: refs/tags/message-one
- $old_head1 tag: refs/tags/message-two
- $head1 tag: refs/tags/tag2
- EOF
+ if test_have_prereq ICONV
+ then
+ cat <<-EOF >expected
+ $head2 tag: refs/tags/message-one
+ $old_head1 tag: refs/tags/message-two
+ $head1 tag: refs/tags/tag2
+ EOF
+ else
+ cat <<-EOF >expected
+ $head2 tag: refs/tags/message-one
+ $old_head1 tag: refs/tags/tag2, tag: refs/tags/message-two
+ EOF
+ fi &&
sort -k3 actual >actual1 &&
test_cmp expected actual1
'
diff --git a/t/t4210-log-i18n.sh b/t/t4210-log-i18n.sh
index 7120030b5c..4a12b2b497 100755
--- a/t/t4210-log-i18n.sh
+++ b/t/t4210-log-i18n.sh
@@ -5,6 +5,12 @@ test_description='test log with i18n features'
TEST_PASSES_SANITIZE_LEAK=true
. ./lib-gettext.sh
+if ! test_have_prereq ICONV
+then
+ skip_all='skipping log i18n tests; iconv not available'
+ test_done
+fi
+
# two forms of é
utf8_e=$(printf '\303\251')
latin1_e=$(printf '\351')
diff --git a/t/t4254-am-corrupt.sh b/t/t4254-am-corrupt.sh
index 661feb6070..cb03522d02 100755
--- a/t/t4254-am-corrupt.sh
+++ b/t/t4254-am-corrupt.sh
@@ -5,6 +5,12 @@ test_description='git am with corrupt input'
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
+if ! test_have_prereq ICONV
+then
+ skip_all='skipping am encoding corruption tests; iconv not available'
+ test_done
+fi
+
make_mbox_with_nul () {
space=' '
q_nul_in_subject=
diff --git a/t/t5100-mailinfo.sh b/t/t5100-mailinfo.sh
index 065156c1f3..23b2f21872 100755
--- a/t/t5100-mailinfo.sh
+++ b/t/t5100-mailinfo.sh
@@ -28,7 +28,12 @@ check_mailinfo () {
for mail in 00*
do
- test_expect_success "mailinfo $mail" '
+ case "$mail" in
+ 0004)
+ prereq=ICONV;;
+ esac
+
+ test_expect_success $prereq "mailinfo $mail" '
check_mailinfo "$mail" "" &&
if test -f "$DATA/msg$mail--scissors"
then
@@ -56,7 +61,12 @@ test_expect_success 'split box with rfc2047 samples' \
for mail in rfc2047/00*
do
- test_expect_success "mailinfo $mail" '
+ case "$mail" in
+ rfc2047/0001)
+ prereq=ICONV;;
+ esac
+
+ test_expect_success $prereq "mailinfo $mail" '
git mailinfo -u "$mail-msg" "$mail-patch" <"$mail" >"$mail-info" &&
echo msg &&
test_cmp "$DATA/empty" "$mail-msg" &&
diff --git a/t/t5500-fetch-pack.sh b/t/t5500-fetch-pack.sh
index 605f17240c..416522c86a 100755
--- a/t/t5500-fetch-pack.sh
+++ b/t/t5500-fetch-pack.sh
@@ -774,7 +774,7 @@ do
# file with scheme
for p in file
do
- test_expect_success !MINGW "fetch-pack --diag-url $p://$h/$r" '
+ test_expect_success !WINDOWS "fetch-pack --diag-url $p://$h/$r" '
check_prot_path $p://$h/$r $p "/$r"
'
test_expect_success MINGW "fetch-pack --diag-url $p://$h/$r" '
@@ -784,7 +784,7 @@ do
check_prot_path $p:///$r $p "/$r"
'
# No "/~" -> "~" conversion for file
- test_expect_success !MINGW "fetch-pack --diag-url $p://$h/~$r" '
+ test_expect_success !WINDOWS "fetch-pack --diag-url $p://$h/~$r" '
check_prot_path $p://$h/~$r $p "/~$r"
'
test_expect_success MINGW "fetch-pack --diag-url $p://$h/~$r" '
@@ -806,11 +806,17 @@ do
p=ssh
for h in host [::1]
do
- test_expect_success "fetch-pack --diag-url $h:$r" '
+ expectation="success"
+ if test_have_prereq CYGWIN && test "$h" = "[::1]"
+ then
+ expectation="failure"
+ fi
+
+ test_expect_$expectation "fetch-pack --diag-url $h:$r" '
check_prot_host_port_path $h:$r $p "$h" NONE "$r"
'
# Do "/~" -> "~" conversion
- test_expect_success "fetch-pack --diag-url $h:/~$r" '
+ test_expect_$expectation "fetch-pack --diag-url $h:/~$r" '
check_prot_host_port_path $h:/~$r $p "$h" NONE "~$r"
'
done
diff --git a/t/t5550-http-fetch-dumb.sh b/t/t5550-http-fetch-dumb.sh
index 58189c9f7d..3c873de17e 100755
--- a/t/t5550-http-fetch-dumb.sh
+++ b/t/t5550-http-fetch-dumb.sh
@@ -344,12 +344,12 @@ test_expect_success 'git client shows text/plain with a charset' '
grep "this is the error message" stderr
'
-test_expect_success 'http error messages are reencoded' '
+test_expect_success ICONV 'http error messages are reencoded' '
test_must_fail git clone "$HTTPD_URL/error/utf16" 2>stderr &&
grep "this is the error message" stderr
'
-test_expect_success 'reencoding is robust to whitespace oddities' '
+test_expect_success ICONV 'reencoding is robust to whitespace oddities' '
test_must_fail git clone "$HTTPD_URL/error/odd-spacing" 2>stderr &&
grep "this is the error message" stderr
'
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/t5601-clone.sh b/t/t5601-clone.sh
index 5d7ea147f1..9fe665eadf 100755
--- a/t/t5601-clone.sh
+++ b/t/t5601-clone.sh
@@ -530,10 +530,17 @@ do
'
done
+# Parsing of paths that look like IPv6 addresses is broken on Cygwin.
+expectation_for_ipv6_tests=success
+if test_have_prereq CYGWIN
+then
+ expectation_for_ipv6_tests=failure
+fi
+
#ipv6
for repo in rep rep/home/project 123
do
- test_expect_success "clone [::1]:$repo" '
+ test_expect_$expectation_for_ipv6_tests "clone [::1]:$repo" '
test_clone_url [::1]:$repo ::1 "$repo"
'
done
@@ -542,7 +549,7 @@ test_expect_success "clone host:/~repo" '
test_clone_url host:/~repo host "~repo"
'
-test_expect_success "clone [::1]:/~repo" '
+test_expect_$expectation_for_ipv6_tests "clone [::1]:/~repo" '
test_clone_url [::1]:/~repo ::1 "~repo"
'
diff --git a/t/t6006-rev-list-format.sh b/t/t6006-rev-list-format.sh
index f1623b1c06..b0ec2fe865 100755
--- a/t/t6006-rev-list-format.sh
+++ b/t/t6006-rev-list-format.sh
@@ -13,21 +13,41 @@ TEST_PASSES_SANITIZE_LEAK=true
. "$TEST_DIRECTORY"/lib-terminal.sh
test_tick
-# Tested non-UTF-8 encoding
-test_encoding="ISO8859-1"
-
-# String "added" in German
-# (translated with Google Translate),
-# encoded in UTF-8, used as a commit log message below.
-added_utf8_part=$(printf "\303\274")
-added_utf8_part_iso88591=$(echo "$added_utf8_part" | iconv -f utf-8 -t $test_encoding)
-added=$(printf "added (hinzugef${added_utf8_part}gt) foo")
-added_iso88591=$(echo "$added" | iconv -f utf-8 -t $test_encoding)
-# same but "changed"
-changed_utf8_part=$(printf "\303\244")
-changed_utf8_part_iso88591=$(echo "$changed_utf8_part" | iconv -f utf-8 -t $test_encoding)
-changed=$(printf "changed (ge${changed_utf8_part}ndert) foo")
-changed_iso88591=$(echo "$changed" | iconv -f utf-8 -t $test_encoding)
+
+if test_have_prereq ICONV
+then
+ # Tested non-UTF-8 encoding
+ test_encoding="ISO8859-1"
+
+ # String "added" in German
+ # (translated with Google Translate),
+ # encoded in UTF-8, used as a commit log message below.
+ added_utf8_part=$(printf "\303\274")
+ added_utf8_part_iso88591=$(echo "$added_utf8_part" | iconv -f utf-8 -t $test_encoding)
+ added=$(printf "added (hinzugef${added_utf8_part}gt) foo")
+ added_iso88591=$(echo "$added" | iconv -f utf-8 -t $test_encoding)
+ # same but "changed"
+ changed_utf8_part=$(printf "\303\244")
+ changed_utf8_part_iso88591=$(echo "$changed_utf8_part" | iconv -f utf-8 -t $test_encoding)
+ changed=$(printf "changed (ge${changed_utf8_part}ndert) foo")
+ changed_iso88591=$(echo "$changed" | iconv -f utf-8 -t $test_encoding)
+else
+ # Tested non-UTF-8 encoding
+ test_encoding="UTF-8"
+
+ # String "added" in German
+ # (translated with Google Translate),
+ # encoded in UTF-8, used as a commit log message below.
+ added_utf8_part="u"
+ added_utf8_part_iso88591="u"
+ added=$(printf "added (hinzugef${added_utf8_part}gt) foo")
+ added_iso88591="$added"
+ # same but "changed"
+ changed_utf8_part="a"
+ changed_utf8_part_iso88591="a"
+ changed=$(printf "changed (ge${changed_utf8_part}ndert) foo")
+ changed_iso88591="$changed"
+fi
# Count of char to truncate
# Number is chosen so, that non-ACSII characters
@@ -55,7 +75,7 @@ test_expect_success 'setup' '
git config --unset i18n.commitEncoding
'
-# usage: test_format [argument...] name format_string [failure] <expected_output
+# usage: test_format [argument...] name format_string [success|failure] [prereq] <expected_output
test_format () {
local args=
while true
@@ -69,7 +89,7 @@ test_format () {
esac
done
cat >expect.$1
- test_expect_${3:-success} "format $1" "
+ test_expect_${3:-success} $4 "format $1" "
git rev-list $args --pretty=format:'$2' main >output.$1 &&
test_cmp expect.$1 output.$1
"
@@ -198,7 +218,7 @@ Thu, 7 Apr 2005 15:13:13 -0700
1112911993
EOF
-test_format encoding %e <<EOF
+test_format encoding %e success ICONV <<EOF
commit $head2
$test_encoding
commit $head1
@@ -374,7 +394,7 @@ test_expect_success 'setup complex body' '
head3_short=$(git rev-parse --short $head3)
'
-test_format complex-encoding %e <<EOF
+test_format complex-encoding %e success ICONV <<EOF
commit $head3
$test_encoding
commit $head2
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/t7001-mv.sh b/t/t7001-mv.sh
index 86258f9f43..69c9190772 100755
--- a/t/t7001-mv.sh
+++ b/t/t7001-mv.sh
@@ -551,4 +551,16 @@ test_expect_success 'moving nested submodules' '
git status
'
+test_expect_failure 'nonsense mv triggers assertion failure and partially updated index' '
+ test_when_finished git reset --hard HEAD &&
+ git reset --hard HEAD &&
+ mkdir -p a &&
+ mkdir -p b &&
+ >a/a.txt &&
+ git add a/a.txt &&
+ test_must_fail git mv a/a.txt a b &&
+ git status --porcelain >actual &&
+ grep "^A[ ]*a/a.txt$" actual
+'
+
test_done
diff --git a/t/t7011-skip-worktree-reading.sh b/t/t7011-skip-worktree-reading.sh
index 4adac5acd5..c86abd99bf 100755
--- a/t/t7011-skip-worktree-reading.sh
+++ b/t/t7011-skip-worktree-reading.sh
@@ -32,24 +32,24 @@ setup_absent() {
}
test_absent() {
- echo "100644 $EMPTY_BLOB 0 1" > expected &&
- git ls-files --stage 1 > result &&
+ echo "100644 $EMPTY_BLOB 0 1" >expected &&
+ git ls-files --stage 1 >result &&
test_cmp expected result &&
test ! -f 1
}
setup_dirty() {
git update-index --force-remove 1 &&
- echo dirty > 1 &&
+ echo dirty >1 &&
git update-index --add --cacheinfo 100644 $EMPTY_BLOB 1 &&
git update-index --skip-worktree 1
}
test_dirty() {
- echo "100644 $EMPTY_BLOB 0 1" > expected &&
- git ls-files --stage 1 > result &&
+ echo "100644 $EMPTY_BLOB 0 1" >expected &&
+ git ls-files --stage 1 >result &&
test_cmp expected result &&
- echo dirty > expected
+ echo dirty >expected
test_cmp expected 1
}
@@ -59,7 +59,7 @@ test_expect_success 'setup' '
touch ./1 ./2 sub/1 sub/2 &&
git add 1 2 sub/1 sub/2 &&
git update-index --skip-worktree 1 sub/1 &&
- git ls-files -t > result &&
+ git ls-files -t >result &&
test_cmp expect.skip result
'
@@ -86,7 +86,7 @@ test_expect_success 'update-index --remove' '
setup_dirty &&
git update-index --remove 1 &&
test -z "$(git ls-files 1)" &&
- echo dirty > expected &&
+ echo dirty >expected &&
test_cmp expected 1
'
@@ -110,16 +110,16 @@ test_expect_success 'ls-files --modified' '
test -z "$(git ls-files -m)"
'
-echo ":000000 100644 $ZERO_OID $EMPTY_BLOB A 1" > expected
+echo ":000000 100644 $ZERO_OID $EMPTY_BLOB A 1" >expected
test_expect_success 'diff-index does not examine skip-worktree absent entries' '
setup_absent &&
- git diff-index HEAD -- 1 > result &&
+ git diff-index HEAD -- 1 >result &&
test_cmp expected result
'
test_expect_success 'diff-index does not examine skip-worktree dirty entries' '
setup_dirty &&
- git diff-index HEAD -- 1 > result &&
+ git diff-index HEAD -- 1 >result &&
test_cmp expected result
'
diff --git a/t/t7102-reset.sh b/t/t7102-reset.sh
index 2add26d768..e9a6cc7265 100755
--- a/t/t7102-reset.sh
+++ b/t/t7102-reset.sh
@@ -13,21 +13,31 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
-commit_msg () {
- # String "modify 2nd file (changed)" partly in German
- # (translated with Google Translate),
- # encoded in UTF-8, used as a commit log message below.
- msg="modify 2nd file (ge\303\244ndert)\n"
- if test -n "$1"
- then
- printf "$msg" | iconv -f utf-8 -t "$1"
- else
- printf "$msg"
- fi
-}
-
-# Tested non-UTF-8 encoding
-test_encoding="ISO8859-1"
+if test_have_prereq ICONV
+then
+ commit_msg () {
+ # String "modify 2nd file (changed)" partly in German
+ # (translated with Google Translate),
+ # encoded in UTF-8, used as a commit log message below.
+ msg="modify 2nd file (ge\303\244ndert)\n"
+ if test -n "$1"
+ then
+ printf "$msg" | iconv -f utf-8 -t "$1"
+ else
+ printf "$msg"
+ fi
+ }
+
+ # Tested non-UTF-8 encoding
+ test_encoding="ISO8859-1"
+else
+ commit_msg () {
+ echo "modify 2nd file (geandert)"
+ }
+
+ # Tested non-UTF-8 encoding
+ test_encoding="UTF-8"
+fi
test_expect_success 'creating initial files and commits' '
test_tick &&
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/t8005-blame-i18n.sh b/t/t8005-blame-i18n.sh
index 75da219ed1..7a1f581c24 100755
--- a/t/t8005-blame-i18n.sh
+++ b/t/t8005-blame-i18n.sh
@@ -3,6 +3,12 @@
test_description='git blame encoding conversion'
. ./test-lib.sh
+if ! test_have_prereq ICONV
+then
+ skip_all='skipping blame i18n tests; iconv not available'
+ test_done
+fi
+
. "$TEST_DIRECTORY"/t8005/utf8.txt
. "$TEST_DIRECTORY"/t8005/euc-japan.txt
. "$TEST_DIRECTORY"/t8005/sjis.txt
diff --git a/t/t9300-fast-import.sh b/t/t9300-fast-import.sh
index 3b3c371740..6224f54d4d 100755
--- a/t/t9300-fast-import.sh
+++ b/t/t9300-fast-import.sh
@@ -3676,7 +3676,7 @@ test_expect_success !MINGW 'W: get-mark & empty orphan commit with erroneous thi
### series X (other new features)
###
-test_expect_success 'X: handling encoding' '
+test_expect_success ICONV 'X: handling encoding' '
test_tick &&
cat >input <<-INPUT_END &&
commit refs/heads/encoding
diff --git a/t/t9350-fast-export.sh b/t/t9350-fast-export.sh
index 2bdc02b459..9595dfef2e 100755
--- a/t/t9350-fast-export.sh
+++ b/t/t9350-fast-export.sh
@@ -125,7 +125,7 @@ test_expect_success 'fast-export --show-original-ids | git fast-import' '
test $MUSS = $(git rev-parse --verify refs/tags/muss)
'
-test_expect_success 'reencoding iso-8859-7' '
+test_expect_success ICONV 'reencoding iso-8859-7' '
test_when_finished "git reset --hard HEAD~1" &&
test_config i18n.commitencoding iso-8859-7 &&
@@ -421,7 +421,7 @@ M 100644 :1 there
EOF
-test_expect_success 'dropping tag of filtered out object' '
+test_expect_success ICONV 'dropping tag of filtered out object' '
(
cd limit-by-paths &&
git fast-export --tag-of-filtered-object=drop mytag -- there > output &&
@@ -438,7 +438,7 @@ msg
EOF
-test_expect_success 'rewriting tag of filtered out object' '
+test_expect_success ICONV 'rewriting tag of filtered out object' '
(
cd limit-by-paths &&
git fast-export --tag-of-filtered-object=rewrite mytag -- there > output &&
@@ -667,7 +667,7 @@ M 100644 :13 file
EOF
-test_expect_success 'avoid uninteresting refs' '
+test_expect_success ICONV 'avoid uninteresting refs' '
> tmp-marks &&
git fast-export --import-marks=tmp-marks \
--export-marks=tmp-marks main > /dev/null &&
@@ -686,7 +686,7 @@ from :14
EOF
-test_expect_success 'refs are updated even if no commits need to be exported' '
+test_expect_success ICONV 'refs are updated even if no commits need to be exported' '
> tmp-marks &&
git fast-export --import-marks=tmp-marks \
--export-marks=tmp-marks main > /dev/null &&
diff --git a/t/test-lib.sh b/t/test-lib.sh
index b1a8ee5c00..a278181a05 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -1572,7 +1572,7 @@ then
prepend_var LSAN_OPTIONS : dedup_token_length=9999
prepend_var LSAN_OPTIONS : log_exe_name=1
- prepend_var LSAN_OPTIONS : log_path=\"$TEST_RESULTS_SAN_FILE\"
+ prepend_var LSAN_OPTIONS : log_path="'$TEST_RESULTS_SAN_FILE'"
export LSAN_OPTIONS
elif test "$GIT_TEST_PASSING_SANITIZE_LEAK" = "check" ||
@@ -1743,6 +1743,7 @@ esac
( COLUMNS=1 && test $COLUMNS = 1 ) && test_set_prereq COLUMNS_CAN_BE_1
test -z "$NO_CURL" && test_set_prereq LIBCURL
+test -z "$NO_ICONV" && test_set_prereq ICONV
test -z "$NO_PERL" && test_set_prereq PERL
test -z "$NO_PTHREADS" && test_set_prereq PTHREADS
test -z "$NO_PYTHON" && test_set_prereq PYTHON
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