From 37901a2202e2b806539080bf8cf129d36e4bd003 Mon Sep 17 00:00:00 2001 From: DongHun Kwak Date: Wed, 3 Mar 2021 15:17:10 +0900 Subject: [PATCH] Imported Upstream version 2.25.1 --- .mailmap | 3 ++ Documentation/RelNotes/2.25.1.txt | 55 ++++++++++++++++++++ Documentation/config/http.txt | 12 ++++- Documentation/config/user.txt | 7 ++- Documentation/diff-options.txt | 8 +-- Documentation/fetch-options.txt | 5 +- Documentation/git-commit-tree.txt | 22 +------- Documentation/git-commit.txt | 40 +++++++++++++-- Documentation/git-filter-branch.txt | 6 +-- Documentation/git-grep.txt | 3 +- Documentation/git-submodule.txt | 2 +- Documentation/git-update-index.txt | 16 ++++++ Documentation/git.txt | 27 +++++++++- Documentation/gitcore-tutorial.txt | 2 +- Documentation/technical/bundle-format.txt | 48 ++++++++++++++++++ Documentation/technical/pack-format.txt | 5 +- GIT-VERSION-GEN | 2 +- Makefile | 3 ++ RelNotes | 2 +- builtin/checkout.c | 2 + builtin/commit.c | 1 + builtin/grep.c | 7 ++- ci/test-documentation.sh | 1 + compat/regex/regex.h | 5 ++ compat/vcbuild/scripts/clink.pl | 4 +- contrib/buildsystems/engine.pl | 4 +- convert.c | 2 +- dir.c | 83 ++++++++++++++----------------- object-store.h | 2 - parse-options.c | 4 +- run-command.c | 3 +- sha1-file.c | 38 +++++++------- string-list.h | 6 ++- submodule.c | 30 +++++------ t/t0040-parse-options.sh | 4 +- t/t2070-restore.sh | 17 +++++++ t/t4018-diff-funcname.sh | 1 - t/t5510-fetch.sh | 24 +++++++++ t/t5616-partial-clone.sh | 36 +++++++++----- t/t5702-protocol-v2.sh | 12 +++++ t/t7300-clean.sh | 9 ++++ t/t7500-commit-template-squash-signoff.sh | 9 ++++ t/t7800-difftool.sh | 5 +- t/t7814-grep-recurse-submodules.sh | 11 +++- transport.c | 2 +- unpack-trees.c | 10 ++-- 46 files changed, 437 insertions(+), 163 deletions(-) create mode 100644 Documentation/RelNotes/2.25.1.txt create mode 100644 Documentation/technical/bundle-format.txt diff --git a/.mailmap b/.mailmap index 7c94418..73fd92e 100644 --- a/.mailmap +++ b/.mailmap @@ -59,6 +59,7 @@ David S. Miller David Turner David Turner Derrick Stolee +Derrick Stolee Derrick Stolee via GitGitGadget Deskin Miller Đoàn Trần Công Danh Doan Tran Cong Danh Dirk Süsserott @@ -109,6 +110,7 @@ Jim Meyering Joachim Berdal Haga Joachim Jablon Johannes Schindelin +Johannes Schindelin Johannes Schindelin via GitGitGadget Johannes Sixt Johannes Sixt Johannes Sixt @@ -287,6 +289,7 @@ William Pursell YONETANI Tomokazu YONETANI Tomokazu YOSHIFUJI Hideaki +Yi-Jyun Pan # the two anonymous contributors are different persons: anonymous anonymous diff --git a/Documentation/RelNotes/2.25.1.txt b/Documentation/RelNotes/2.25.1.txt new file mode 100644 index 0000000..cd869b0 --- /dev/null +++ b/Documentation/RelNotes/2.25.1.txt @@ -0,0 +1,55 @@ +Git 2.25.1 Release Notes +======================== + +Fixes since v2.25 +----------------- + + * "git commit" gives output similar to "git status" when there is + nothing to commit, but without honoring the advise.statusHints + configuration variable, which has been corrected. + + * has_object_file() said "no" given an object registered to the + system via pretend_object_file(), making it inconsistent with + read_object_file(), causing lazy fetch to attempt fetching an + empty tree from promisor remotes. + + * The code that tries to skip over the entries for the paths in a + single directory using the cache-tree was not careful enough + against corrupt index file. + + * Complete an update to tutorial that encourages "git switch" over + "git checkout" that was done only half-way. + + * Reduce unnecessary round-trip when running "ls-remote" over the + stateless RPC mechanism. + + * "git restore --staged" did not correctly update the cache-tree + structure, resulting in bogus trees to be written afterwards, which + has been corrected. + + * The code recently added to move to the entry beyond the ones in the + same directory in the index in the sparse-cone mode did not count + the number of entries to skip over incorrectly, which has been + corrected. + + * Work around test breakages caused by custom regex engine used in + libasan, when address sanitizer is used with more recent versions + of gcc and clang. + + * "git fetch --refmap=" option has got a better documentation. + + * Corner case bugs in "git clean" that stems from a (necessarily for + performance reasons) awkward calling convention in the directory + enumeration API has been corrected. + + * "git grep --no-index" should not get affected by the contents of + the .gitmodules file but when "--recurse-submodules" is given or + the "submodule.recurse" variable is set, it did. Now these + settings are ignored in the "--no-index" mode. + + * Technical details of the bundle format has been documented. + + * Unhelpful warning messages during documentation build have been + squelched. + +Also contains various documentation updates, code clean-ups and minor fixups. diff --git a/Documentation/config/http.txt b/Documentation/config/http.txt index 5a32f5b..e806033 100644 --- a/Documentation/config/http.txt +++ b/Documentation/config/http.txt @@ -71,7 +71,7 @@ http.saveCookies:: http.version:: Use the specified HTTP protocol version when communicating with a server. If you want to force the default. The available and default version depend - on libcurl. Actually the possible values of + on libcurl. Currently the possible values of this option are: - HTTP/2 @@ -84,7 +84,7 @@ http.sslVersion:: particular configuration of the crypto library in use. Internally this sets the 'CURLOPT_SSL_VERSION' option; see the libcurl documentation for more details on the format of this option and - for the ssl version supported. Actually the possible values of + for the ssl version supported. Currently the possible values of this option are: - sslv2 @@ -199,6 +199,14 @@ http.postBuffer:: Transfer-Encoding: chunked is used to avoid creating a massive pack file locally. Default is 1 MiB, which is sufficient for most requests. ++ +Note that raising this limit is only effective for disabling chunked +transfer encoding and therefore should be used only where the remote +server or a proxy only supports HTTP/1.0 or is noncompliant with the +HTTP standard. Raising this is not, in general, an effective solution +for most push problems, but can increase memory consumption +significantly since the entire buffer is allocated even for small +pushes. http.lowSpeedLimit, http.lowSpeedTime:: If the HTTP transfer speed is less than 'http.lowSpeedLimit' diff --git a/Documentation/config/user.txt b/Documentation/config/user.txt index 0557cbb..59aec7c 100644 --- a/Documentation/config/user.txt +++ b/Documentation/config/user.txt @@ -13,7 +13,12 @@ committer.email:: Also, all of these can be overridden by the `GIT_AUTHOR_NAME`, `GIT_AUTHOR_EMAIL`, `GIT_COMMITTER_NAME`, `GIT_COMMITTER_EMAIL` and `EMAIL` environment variables. - See linkgit:git-commit-tree[1] for more information. ++ +Note that the `name` forms of these variables conventionally refer to +some form of a personal name. See linkgit:git-commit[1] and the +environment variables section of linkgit:git[1] for more information on +these settings and the `credential.username` option if you're looking +for authentication credentials instead. user.useConfigOnly:: Instruct Git to avoid trying to guess defaults for `user.email` diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt index 09faee3..bb31f0c 100644 --- a/Documentation/diff-options.txt +++ b/Documentation/diff-options.txt @@ -567,13 +567,13 @@ To illustrate the difference between `-S --pickaxe-regex` and file: + ---- -+ return !regexec(regexp, two->ptr, 1, ®match, 0); ++ return frotz(nitfol, two->ptr, 1, 0); ... -- hit = !regexec(regexp, mf2.ptr, 1, ®match, 0); +- hit = frotz(nitfol, mf2.ptr, 1, 0); ---- + -While `git log -G"regexec\(regexp"` will show this commit, `git log --S"regexec\(regexp" --pickaxe-regex` will not (because the number of +While `git log -G"frotz\(nitfol"` will show this commit, `git log +-S"frotz\(nitfol" --pickaxe-regex` will not (because the number of occurrences of that string did not change). + Unless `--text` is supplied patches of binary files without a textconv diff --git a/Documentation/fetch-options.txt b/Documentation/fetch-options.txt index a2f7862..a115a1a 100644 --- a/Documentation/fetch-options.txt +++ b/Documentation/fetch-options.txt @@ -139,7 +139,10 @@ ifndef::git-pull[] specified refspec (can be given more than once) to map the refs to remote-tracking branches, instead of the values of `remote.*.fetch` configuration variables for the remote - repository. See section on "Configured Remote-tracking + repository. Providing an empty `` to the + `--refmap` option causes Git to ignore the configured + refspecs and rely entirely on the refspecs supplied as + command-line arguments. See section on "Configured Remote-tracking Branches" for details. -t:: diff --git a/Documentation/git-commit-tree.txt b/Documentation/git-commit-tree.txt index 4b90b9c..ec15ee8 100644 --- a/Documentation/git-commit-tree.txt +++ b/Documentation/git-commit-tree.txt @@ -69,7 +69,6 @@ OPTIONS Do not GPG-sign commit, to countermand a `--gpg-sign` option given earlier on the command line. - Commit Information ------------------ @@ -79,26 +78,6 @@ A commit encapsulates: - author name, email and date - committer name and email and the commit time. -While parent object ids are provided on the command line, author and -committer information is taken from the following environment variables, -if set: - - GIT_AUTHOR_NAME - GIT_AUTHOR_EMAIL - GIT_AUTHOR_DATE - GIT_COMMITTER_NAME - GIT_COMMITTER_EMAIL - GIT_COMMITTER_DATE - -(nb "<", ">" and "\n"s are stripped) - -In case (some of) these environment variables are not set, the information -is taken from the configuration items user.name and user.email, or, if not -present, the environment variable EMAIL, or, if that is not set, -system user name and the hostname used for outgoing mail (taken -from `/etc/mailname` and falling back to the fully qualified hostname when -that file does not exist). - A commit comment is read from stdin. If a changelog entry is not provided via "<" redirection, 'git commit-tree' will just wait for one to be entered and terminated with ^D. @@ -117,6 +96,7 @@ FILES SEE ALSO -------- linkgit:git-write-tree[1] +linkgit:git-commit[1] GIT --- diff --git a/Documentation/git-commit.txt b/Documentation/git-commit.txt index ced5a9b..13f6539 100644 --- a/Documentation/git-commit.txt +++ b/Documentation/git-commit.txt @@ -367,9 +367,6 @@ changes to tracked files. + For more details, see the 'pathspec' entry in linkgit:gitglossary[7]. -:git-commit: 1 -include::date-formats.txt[] - EXAMPLES -------- When recording your own work, the contents of modified files in @@ -463,6 +460,43 @@ alter the order the changes are committed, because the merge should be recorded as a single commit. In fact, the command refuses to run when given pathnames (but see `-i` option). +COMMIT INFORMATION +------------------ + +Author and committer information is taken from the following environment +variables, if set: + + GIT_AUTHOR_NAME + GIT_AUTHOR_EMAIL + GIT_AUTHOR_DATE + GIT_COMMITTER_NAME + GIT_COMMITTER_EMAIL + GIT_COMMITTER_DATE + +(nb "<", ">" and "\n"s are stripped) + +The author and committer names are by convention some form of a personal name +(that is, the name by which other humans refer to you), although Git does not +enforce or require any particular form. Arbitrary Unicode may be used, subject +to the constraints listed above. This name has no effect on authentication; for +that, see the `credential.username` variable in linkgit:git-config[1]. + +In case (some of) these environment variables are not set, the information +is taken from the configuration items `user.name` and `user.email`, or, if not +present, the environment variable EMAIL, or, if that is not set, +system user name and the hostname used for outgoing mail (taken +from `/etc/mailname` and falling back to the fully qualified hostname when +that file does not exist). + +The `author.name` and `committer.name` and their corresponding email options +override `user.name` and `user.email` if set and are overridden themselves by +the environment variables. + +The typical usage is to set just the `user.name` and `user.email` variables; +the other options are provided for more complex use cases. + +:git-commit: 1 +include::date-formats.txt[] DISCUSSION ---------- diff --git a/Documentation/git-filter-branch.txt b/Documentation/git-filter-branch.txt index a530fef..40ba4aa 100644 --- a/Documentation/git-filter-branch.txt +++ b/Documentation/git-filter-branch.txt @@ -467,9 +467,9 @@ impossible for a backward-compatible implementation to ever be fast: * In editing files, git-filter-branch by design checks out each and every commit as it existed in the original repo. If your repo has - 10\^5 files and 10\^5 commits, but each commit only modifies 5 - files, then git-filter-branch will make you do 10\^10 modifications, - despite only having (at most) 5*10^5 unique blobs. + `10^5` files and `10^5` commits, but each commit only modifies five + files, then git-filter-branch will make you do `10^10` modifications, + despite only having (at most) `5*10^5` unique blobs. * If you try and cheat and try to make git-filter-branch only work on files modified in a commit, then two things happen diff --git a/Documentation/git-grep.txt b/Documentation/git-grep.txt index c89fb56..ffc3a6e 100644 --- a/Documentation/git-grep.txt +++ b/Documentation/git-grep.txt @@ -96,7 +96,8 @@ OPTIONS Recursively search in each submodule that has been initialized and checked out in the repository. When used in combination with the option the prefix of all submodule output will be the name of - the parent project's object. + the parent project's object. This option has no effect + if `--no-index` is given. -a:: --text:: diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt index 5232407..218942a 100644 --- a/Documentation/git-submodule.txt +++ b/Documentation/git-submodule.txt @@ -229,7 +229,7 @@ As an example, the command below will show the path and currently checked out commit for each submodule: + -------------- -git submodule foreach 'echo $path `git rev-parse HEAD`' +git submodule foreach 'echo $sm_path `git rev-parse HEAD`' -------------- sync [--recursive] [--] [...]:: diff --git a/Documentation/git-update-index.txt b/Documentation/git-update-index.txt index c7a6271..1489cb0 100644 --- a/Documentation/git-update-index.txt +++ b/Documentation/git-update-index.txt @@ -549,6 +549,22 @@ The untracked cache extension can be enabled by the `core.untrackedCache` configuration variable (see linkgit:git-config[1]). +NOTES +----- + +Users often try to use the assume-unchanged and skip-worktree bits +to tell Git to ignore changes to files that are tracked. This does not +work as expected, since Git may still check working tree files against +the index when performing certain operations. In general, Git does not +provide a way to ignore changes to tracked files, so alternate solutions +are recommended. + +For example, if the file you want to change is some sort of config file, +the repository can include a sample config file that can then be copied +into the ignored name and modified. The repository can even include a +script to treat the sample file as a template, modifying and copying it +automatically. + SEE ALSO -------- linkgit:git-config[1], diff --git a/Documentation/git.txt b/Documentation/git.txt index b1597ac..0093c64 100644 --- a/Documentation/git.txt +++ b/Documentation/git.txt @@ -482,13 +482,36 @@ double-quotes and respecting backslash escapes. E.g., the value Git Commits ~~~~~~~~~~~ `GIT_AUTHOR_NAME`:: + The human-readable name used in the author identity when creating commit or + tag objects, or when writing reflogs. Overrides the `user.name` and + `author.name` configuration settings. + `GIT_AUTHOR_EMAIL`:: + The email address used in the author identity when creating commit or + tag objects, or when writing reflogs. Overrides the `user.email` and + `author.email` configuration settings. + `GIT_AUTHOR_DATE`:: + The date used for the author identity when creating commit or tag objects, or + when writing reflogs. See linkgit:git-commit[1] for valid formats. + `GIT_COMMITTER_NAME`:: + The human-readable name used in the committer identity when creating commit or + tag objects, or when writing reflogs. Overrides the `user.name` and + `committer.name` configuration settings. + `GIT_COMMITTER_EMAIL`:: + The email address used in the author identity when creating commit or + tag objects, or when writing reflogs. Overrides the `user.email` and + `committer.email` configuration settings. + `GIT_COMMITTER_DATE`:: -'EMAIL':: - see linkgit:git-commit-tree[1] + The date used for the committer identity when creating commit or tag objects, or + when writing reflogs. See linkgit:git-commit[1] for valid formats. + +`EMAIL`:: + The email address used in the author and committer identities if no other + relevant environment variable or configuration setting has been set. Git Diffs ~~~~~~~~~ diff --git a/Documentation/gitcore-tutorial.txt b/Documentation/gitcore-tutorial.txt index f880d21..c0b9525 100644 --- a/Documentation/gitcore-tutorial.txt +++ b/Documentation/gitcore-tutorial.txt @@ -751,7 +751,7 @@ to it. ================================================ If you make the decision to start your new branch at some other point in the history than the current `HEAD`, you can do so by -just telling 'git checkout' what the base of the checkout would be. +just telling 'git switch' what the base of the checkout would be. In other words, if you have an earlier tag or branch, you'd just do ------------ diff --git a/Documentation/technical/bundle-format.txt b/Documentation/technical/bundle-format.txt new file mode 100644 index 0000000..0e82815 --- /dev/null +++ b/Documentation/technical/bundle-format.txt @@ -0,0 +1,48 @@ += Git bundle v2 format + +The Git bundle format is a format that represents both refs and Git objects. + +== Format + +We will use ABNF notation to define the Git bundle format. See +protocol-common.txt for the details. + +---- +bundle = signature *prerequisite *reference LF pack +signature = "# v2 git bundle" LF + +prerequisite = "-" obj-id SP comment LF +comment = *CHAR +reference = obj-id SP refname LF + +pack = ... ; packfile +---- + +== Semantics + +A Git bundle consists of three parts. + +* "Prerequisites" lists the objects that are NOT included in the bundle and the + reader of the bundle MUST already have, in order to use the data in the + bundle. The objects stored in the bundle may refer to prerequisite objects and + anything reachable from them (e.g. a tree object in the bundle can reference + a blob that is reachable from a prerequisite) and/or expressed as a delta + against prerequisite objects. + +* "References" record the tips of the history graph, iow, what the reader of the + bundle CAN "git fetch" from it. + +* "Pack" is the pack data stream "git fetch" would send, if you fetch from a + repository that has the references recorded in the "References" above into a + repository that has references pointing at the objects listed in + "Prerequisites" above. + +In the bundle format, there can be a comment following a prerequisite obj-id. +This is a comment and it has no specific meaning. The writer of the bundle MAY +put any string here. The reader of the bundle MUST ignore the comment. + +=== Note on the shallow clone and a Git bundle + +Note that the prerequisites does not represent a shallow-clone boundary. The +semantics of the prerequisites and the shallow-clone boundaries are different, +and the Git bundle v2 format cannot represent a shallow clone repository. diff --git a/Documentation/technical/pack-format.txt b/Documentation/technical/pack-format.txt index cab5bdd..d3a142c 100644 --- a/Documentation/technical/pack-format.txt +++ b/Documentation/technical/pack-format.txt @@ -315,10 +315,11 @@ CHUNK DATA: Stores two 4-byte values for every object. 1: The pack-int-id for the pack storing this object. 2: The offset within the pack. - If all offsets are less than 2^31, then the large offset chunk + If all offsets are less than 2^32, then the large offset chunk will not exist and offsets are stored as in IDX v1. If there is at least one offset value larger than 2^32-1, then - the large offset chunk must exist. If the large offset chunk + the large offset chunk must exist, and offsets larger than + 2^31-1 must be stored in it instead. If the large offset chunk exists and the 31st bit is on, then removing that bit reveals the row in the large offsets containing the 8-byte offset of this object. diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN index 2b7f62b..2a8e709 100755 --- a/GIT-VERSION-GEN +++ b/GIT-VERSION-GEN @@ -1,7 +1,7 @@ #!/bin/sh GVF=GIT-VERSION-FILE -DEF_VER=v2.25.0 +DEF_VER=v2.25.1 LF=' ' diff --git a/Makefile b/Makefile index 09f98b7..9cd9826 100644 --- a/Makefile +++ b/Makefile @@ -1220,6 +1220,9 @@ endif ifneq ($(filter leak,$(SANITIZERS)),) BASIC_CFLAGS += -DSUPPRESS_ANNOTATED_LEAKS endif +ifneq ($(filter address,$(SANITIZERS)),) +NO_REGEX = NeededForASAN +endif endif ifndef sysconfdir diff --git a/RelNotes b/RelNotes index 091dd02..c63ee7d 120000 --- a/RelNotes +++ b/RelNotes @@ -1 +1 @@ -Documentation/RelNotes/2.25.0.txt \ No newline at end of file +Documentation/RelNotes/2.25.1.txt \ No newline at end of file diff --git a/builtin/checkout.c b/builtin/checkout.c index b52c490..18ef5fb 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -524,6 +524,8 @@ static int checkout_paths(const struct checkout_opts *opts, /* Now we are committed to check them out */ if (opts->checkout_worktree) errs |= checkout_worktree(opts); + else + remove_marked_cache_entries(&the_index, 1); /* * Allow updating the index when checking out from the index. diff --git a/builtin/commit.c b/builtin/commit.c index aa13323..646e845 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -964,6 +964,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix, */ if (!committable && whence != FROM_MERGE && !allow_empty && !(amend && is_a_merge(current_head))) { + s->hints = advice_status_hints; s->display_comment_prefix = old_display_comment_prefix; run_status(stdout, index_file, prefix, 0, s); if (amend) diff --git a/builtin/grep.c b/builtin/grep.c index 50ce8d9..ae2d5bb 100644 --- a/builtin/grep.c +++ b/builtin/grep.c @@ -958,6 +958,9 @@ int cmd_grep(int argc, const char **argv, const char *prefix) /* die the same way as if we did it at the beginning */ setup_git_directory(); } + /* Ignore --recurse-submodules if --no-index is given or implied */ + if (!use_index) + recurse_submodules = 0; /* * skip a -- separator; we know it cannot be @@ -1115,8 +1118,8 @@ int cmd_grep(int argc, const char **argv, const char *prefix) } } - if (recurse_submodules && (!use_index || untracked)) - die(_("option not supported with --recurse-submodules")); + if (recurse_submodules && untracked) + die(_("--untracked not supported with --recurse-submodules")); if (!show_in_pager && !opt.status_only) setup_pager(); diff --git a/ci/test-documentation.sh b/ci/test-documentation.sh index b3e76ef..de41888 100755 --- a/ci/test-documentation.sh +++ b/ci/test-documentation.sh @@ -7,6 +7,7 @@ filter_log () { sed -e '/^GIT_VERSION = /d' \ + -e "/constant Gem::ConfigMap is deprecated/d" \ -e '/^ \* new asciidoc flags$/d' \ -e '/stripped namespace before processing/d' \ -e '/Attributed.*IDs for element/d' \ diff --git a/compat/regex/regex.h b/compat/regex/regex.h index 08a2609..2d34128 100644 --- a/compat/regex/regex.h +++ b/compat/regex/regex.h @@ -41,6 +41,11 @@ extern "C" { #endif +#define regcomp git_regcomp +#define regexec git_regexec +#define regerror git_regerror +#define regfree git_regfree + /* The following two types have to be signed and unsigned integer type wide enough to hold a value of a pointer. For most ANSI compilers ptrdiff_t and size_t should be likely OK. Still size of these two diff --git a/compat/vcbuild/scripts/clink.pl b/compat/vcbuild/scripts/clink.pl index ec95a3b..d9f71b7 100755 --- a/compat/vcbuild/scripts/clink.pl +++ b/compat/vcbuild/scripts/clink.pl @@ -45,9 +45,9 @@ while (@ARGV) { } elsif ("$arg" eq "-liconv") { push(@args, "libiconv.lib"); } elsif ("$arg" eq "-lcrypto") { - push(@args, "libeay32.lib"); + push(@args, "libcrypto.lib"); } elsif ("$arg" eq "-lssl") { - push(@args, "ssleay32.lib"); + push(@args, "libssl.lib"); } elsif ("$arg" eq "-lcurl") { my $lib = ""; # Newer vcpkg definitions call this libcurl_imp.lib; Do we diff --git a/contrib/buildsystems/engine.pl b/contrib/buildsystems/engine.pl index fba8a3f..0709785 100755 --- a/contrib/buildsystems/engine.pl +++ b/contrib/buildsystems/engine.pl @@ -343,9 +343,9 @@ sub handleLinkLine } elsif ("$part" eq "-lz") { push(@libs, "zlib.lib"); } elsif ("$part" eq "-lcrypto") { - push(@libs, "libeay32.lib"); + push(@libs, "libcrypto.lib"); } elsif ("$part" eq "-lssl") { - push(@libs, "ssleay32.lib"); + push(@libs, "libssl.lib"); } elsif ("$part" eq "-lcurl") { push(@libs, "libcurl.lib"); } elsif ("$part" eq "-lexpat") { diff --git a/convert.c b/convert.c index 797e0bd..2b8549e 100644 --- a/convert.c +++ b/convert.c @@ -1940,7 +1940,7 @@ static struct stream_filter *ident_filter(const struct object_id *oid) * the contents cannot be filtered without reading the whole thing * in-core. * - * Note that you would be crazy to set CRLF, smuge/clean or ident to a + * Note that you would be crazy to set CRLF, smudge/clean or ident to a * large binary blob you would want us not to slurp into the memory! */ struct stream_filter *get_stream_filter(const struct index_state *istate, diff --git a/dir.c b/dir.c index 7d25522..b460211 100644 --- a/dir.c +++ b/dir.c @@ -41,7 +41,8 @@ struct cached_dir { int nr_files; int nr_dirs; - struct dirent *de; + const char *d_name; + int d_type; const char *file; struct untracked_cache_dir *ucd; }; @@ -50,8 +51,8 @@ static enum path_treatment read_directory_recursive(struct dir_struct *dir, struct index_state *istate, const char *path, int len, struct untracked_cache_dir *untracked, int check_only, int stop_at_first_file, const struct pathspec *pathspec); -static int get_dtype(struct dirent *de, struct index_state *istate, - const char *path, int len); +static int resolve_dtype(int dtype, struct index_state *istate, + const char *path, int len); int count_slashes(const char *s) { @@ -1215,8 +1216,7 @@ static struct path_pattern *last_matching_pattern_from_list(const char *pathname int prefix = pattern->nowildcardlen; if (pattern->flags & PATTERN_FLAG_MUSTBEDIR) { - if (*dtype == DT_UNKNOWN) - *dtype = get_dtype(NULL, istate, pathname, pathlen); + *dtype = resolve_dtype(*dtype, istate, pathname, pathlen); if (*dtype != DT_DIR) continue; } @@ -1842,10 +1842,9 @@ static int get_index_dtype(struct index_state *istate, return DT_UNKNOWN; } -static int get_dtype(struct dirent *de, struct index_state *istate, - const char *path, int len) +static int resolve_dtype(int dtype, struct index_state *istate, + const char *path, int len) { - int dtype = de ? DTYPE(de) : DT_UNKNOWN; struct stat st; if (dtype != DT_UNKNOWN) @@ -1870,14 +1869,13 @@ static enum path_treatment treat_one_path(struct dir_struct *dir, struct strbuf *path, int baselen, const struct pathspec *pathspec, - int dtype, struct dirent *de) + int dtype) { int exclude; int has_path_in_index = !!index_file_exists(istate, path->buf, path->len, ignore_case); enum path_treatment path_treatment; - if (dtype == DT_UNKNOWN) - dtype = get_dtype(de, istate, path->buf, path->len); + dtype = resolve_dtype(dtype, istate, path->buf, path->len); /* Always exclude indexed files */ if (dtype != DT_DIR && has_path_in_index) @@ -1985,21 +1983,18 @@ static enum path_treatment treat_path(struct dir_struct *dir, int baselen, const struct pathspec *pathspec) { - int dtype; - struct dirent *de = cdir->de; - - if (!de) + if (!cdir->d_name) return treat_path_fast(dir, untracked, cdir, istate, path, baselen, pathspec); - if (is_dot_or_dotdot(de->d_name) || !fspathcmp(de->d_name, ".git")) + if (is_dot_or_dotdot(cdir->d_name) || !fspathcmp(cdir->d_name, ".git")) return path_none; strbuf_setlen(path, baselen); - strbuf_addstr(path, de->d_name); + strbuf_addstr(path, cdir->d_name); if (simplify_away(path->buf, path->len, pathspec)) return path_none; - dtype = DTYPE(de); - return treat_one_path(dir, untracked, istate, path, baselen, pathspec, dtype, de); + return treat_one_path(dir, untracked, istate, path, baselen, pathspec, + cdir->d_type); } static void add_untracked(struct untracked_cache_dir *dir, const char *name) @@ -2087,10 +2082,17 @@ static int open_cached_dir(struct cached_dir *cdir, static int read_cached_dir(struct cached_dir *cdir) { + struct dirent *de; + if (cdir->fdir) { - cdir->de = readdir(cdir->fdir); - if (!cdir->de) + de = readdir(cdir->fdir); + if (!de) { + cdir->d_name = NULL; + cdir->d_type = DT_UNKNOWN; return -1; + } + cdir->d_name = de->d_name; + cdir->d_type = DTYPE(de); return 0; } while (cdir->nr_dirs < cdir->untracked->dirs_nr) { @@ -2216,7 +2218,7 @@ static enum path_treatment read_directory_recursive(struct dir_struct *dir, /* recurse into subdir if instructed by treat_path */ if ((state == path_recurse) || ((state == path_untracked) && - (get_dtype(cdir.de, istate, path.buf, path.len) == DT_DIR) && + (resolve_dtype(cdir.d_type, istate, path.buf, path.len) == DT_DIR) && ((dir->flags & DIR_SHOW_IGNORED_TOO) || (pathspec && do_match_pathspec(istate, pathspec, path.buf, path.len, @@ -2308,16 +2310,16 @@ static int treat_leading_path(struct dir_struct *dir, * WARNING WARNING WARNING: * * Any updates to the traversal logic here may need corresponding - * updates in treat_leading_path(). See the commit message for the - * commit adding this warning as well as the commit preceding it - * for details. + * updates in read_directory_recursive(). See 777b420347 (dir: + * synchronize treat_leading_path() and read_directory_recursive(), + * 2019-12-19) and its parent commit for details. */ struct strbuf sb = STRBUF_INIT; + struct strbuf subdir = STRBUF_INIT; int prevlen, baselen; const char *cp; struct cached_dir cdir; - struct dirent *de; enum path_treatment state = path_none; /* @@ -2342,22 +2344,8 @@ static int treat_leading_path(struct dir_struct *dir, if (!len) return 1; - /* - * We need a manufactured dirent with sufficient space to store a - * leading directory component of path in its d_name. Here, we - * assume that the dirent's d_name is either declared as - * char d_name[BIG_ENOUGH] - * or that it is declared at the end of the struct as - * char d_name[] - * For either case, padding with len+1 bytes at the end will ensure - * sufficient storage space. - */ - de = xcalloc(1, st_add3(sizeof(struct dirent), len, 1)); memset(&cdir, 0, sizeof(cdir)); - cdir.de = de; -#if defined(DT_UNKNOWN) && !defined(NO_D_TYPE_IN_DIRENT) - de->d_type = DT_DIR; -#endif + cdir.d_type = DT_DIR; baselen = 0; prevlen = 0; while (1) { @@ -2374,15 +2362,20 @@ static int treat_leading_path(struct dir_struct *dir, break; strbuf_reset(&sb); strbuf_add(&sb, path, prevlen); - memcpy(de->d_name, path+prevlen, baselen-prevlen); - de->d_name[baselen-prevlen] = '\0'; + strbuf_reset(&subdir); + strbuf_add(&subdir, path+prevlen, baselen-prevlen); + cdir.d_name = subdir.buf; state = treat_path(dir, NULL, &cdir, istate, &sb, prevlen, pathspec); if (state == path_untracked && - get_dtype(cdir.de, istate, sb.buf, sb.len) == DT_DIR && + resolve_dtype(cdir.d_type, istate, sb.buf, sb.len) == DT_DIR && (dir->flags & DIR_SHOW_IGNORED_TOO || do_match_pathspec(istate, pathspec, sb.buf, sb.len, baselen, NULL, DO_MATCH_LEADING_PATHSPEC) == MATCHED_RECURSIVELY_LEADING_PATHSPEC)) { + if (!match_pathspec(istate, pathspec, sb.buf, sb.len, + 0 /* prefix */, NULL, + 0 /* do NOT special case dirs */)) + state = path_none; add_path_to_appropriate_result_list(dir, NULL, &cdir, istate, &sb, baselen, @@ -2399,7 +2392,7 @@ static int treat_leading_path(struct dir_struct *dir, &sb, baselen, pathspec, state); - free(de); + strbuf_release(&subdir); strbuf_release(&sb); return state == path_recurse; } diff --git a/object-store.h b/object-store.h index 55ee639..61b8b13 100644 --- a/object-store.h +++ b/object-store.h @@ -292,8 +292,6 @@ struct object_info { #define OBJECT_INFO_LOOKUP_REPLACE 1 /* Allow reading from a loose object file of unknown/bogus type */ #define OBJECT_INFO_ALLOW_UNKNOWN_TYPE 2 -/* Do not check cached storage */ -#define OBJECT_INFO_SKIP_CACHED 4 /* Do not retry packed storage after checking packed and loose storage */ #define OBJECT_INFO_QUICK 8 /* Do not check loose object */ diff --git a/parse-options.c b/parse-options.c index 60fae3a..c278aff 100644 --- a/parse-options.c +++ b/parse-options.c @@ -420,7 +420,7 @@ static void check_typos(const char *arg, const struct option *options) return; if (starts_with(arg, "no-")) { - error(_("did you mean `--%s` (with two dashes ?)"), arg); + error(_("did you mean `--%s` (with two dashes)?"), arg); exit(129); } @@ -428,7 +428,7 @@ static void check_typos(const char *arg, const struct option *options) if (!options->long_name) continue; if (starts_with(options->long_name, arg)) { - error(_("did you mean `--%s` (with two dashes ?)"), arg); + error(_("did you mean `--%s` (with two dashes)?"), arg); exit(129); } } diff --git a/run-command.c b/run-command.c index 9942f12..f5e1149 100644 --- a/run-command.c +++ b/run-command.c @@ -213,8 +213,9 @@ static char *locate_in_PATH(const char *file) static int exists_in_PATH(const char *file) { char *r = locate_in_PATH(file); + int found = r != NULL; free(r); - return r != NULL; + return found; } int sane_execvp(const char *file, char * const argv[]) diff --git a/sha1-file.c b/sha1-file.c index 188de57..03ae9ae 100644 --- a/sha1-file.c +++ b/sha1-file.c @@ -1417,6 +1417,7 @@ int oid_object_info_extended(struct repository *r, const struct object_id *oid, struct object_info *oi, unsigned flags) { static struct object_info blank_oi = OBJECT_INFO_INIT; + struct cached_object *co; struct pack_entry e; int rtype; const struct object_id *real = oid; @@ -1431,24 +1432,22 @@ int oid_object_info_extended(struct repository *r, const struct object_id *oid, if (!oi) oi = &blank_oi; - if (!(flags & OBJECT_INFO_SKIP_CACHED)) { - struct cached_object *co = find_cached_object(real); - if (co) { - if (oi->typep) - *(oi->typep) = co->type; - if (oi->sizep) - *(oi->sizep) = co->size; - if (oi->disk_sizep) - *(oi->disk_sizep) = 0; - if (oi->delta_base_sha1) - hashclr(oi->delta_base_sha1); - if (oi->type_name) - strbuf_addstr(oi->type_name, type_name(co->type)); - if (oi->contentp) - *oi->contentp = xmemdupz(co->buf, co->size); - oi->whence = OI_CACHED; - return 0; - } + co = find_cached_object(real); + if (co) { + if (oi->typep) + *(oi->typep) = co->type; + if (oi->sizep) + *(oi->sizep) = co->size; + if (oi->disk_sizep) + *(oi->disk_sizep) = 0; + if (oi->delta_base_sha1) + hashclr(oi->delta_base_sha1); + if (oi->type_name) + strbuf_addstr(oi->type_name, type_name(co->type)); + if (oi->contentp) + *oi->contentp = xmemdupz(co->buf, co->size); + oi->whence = OI_CACHED; + return 0; } while (1) { @@ -1932,8 +1931,7 @@ int repo_has_object_file_with_flags(struct repository *r, { if (!startup_info->have_repository) return 0; - return oid_object_info_extended(r, oid, NULL, - flags | OBJECT_INFO_SKIP_CACHED) >= 0; + return oid_object_info_extended(r, oid, NULL, flags) >= 0; } int repo_has_object_file(struct repository *r, diff --git a/string-list.h b/string-list.h index 7bb0ad0..6c5d274 100644 --- a/string-list.h +++ b/string-list.h @@ -4,7 +4,8 @@ /** * The string_list API offers a data structure and functions to handle * sorted and unsorted arrays of strings. A "sorted" list is one whose - * entries are sorted by string value in `strcmp()` order. + * entries are sorted by string value in the order specified by the `cmp` + * member (`strcmp()` by default). * * The caller: * @@ -209,7 +210,8 @@ struct string_list_item *string_list_append(struct string_list *list, const char struct string_list_item *string_list_append_nodup(struct string_list *list, char *string); /** - * Sort the list's entries by string value in `strcmp()` order. + * Sort the list's entries by string value in order specified by list->cmp + * (strcmp() if list->cmp is NULL). */ void string_list_sort(struct string_list *list); diff --git a/submodule.c b/submodule.c index 9da7181..6b86744 100644 --- a/submodule.c +++ b/submodule.c @@ -431,7 +431,7 @@ void handle_ignore_submodules_arg(struct diff_options *diffopt, else if (!strcmp(arg, "dirty")) diffopt->flags.ignore_dirty_submodules = 1; else if (strcmp(arg, "none")) - die("bad --ignore-submodules argument: %s", arg); + die(_("bad --ignore-submodules argument: %s"), arg); /* * Please update _git_status() in git-completion.bash when you * add new options @@ -812,9 +812,9 @@ static void collect_changed_submodules_cb(struct diff_queue_struct *q, submodule = submodule_from_name(me->repo, commit_oid, name); if (submodule) { - warning("Submodule in commit %s at path: " + warning(_("Submodule in commit %s at path: " "'%s' collides with a submodule named " - "the same. Skipping it.", + "the same. Skipping it."), oid_to_hex(commit_oid), p->two->path); name = NULL; } @@ -844,7 +844,7 @@ static void collect_changed_submodules(struct repository *r, repo_init_revisions(r, &rev, NULL); setup_revisions(argv->argc, argv->argv, &rev, NULL); if (prepare_revision_walk(&rev)) - die("revision walk setup failed"); + die(_("revision walk setup failed")); while ((commit = get_revision(&rev))) { struct rev_info diff_rev; @@ -992,7 +992,7 @@ static int submodule_needs_pushing(struct repository *r, cp.out = -1; cp.dir = path; if (start_command(&cp)) - die("Could not run 'git rev-list --not --remotes -n 1' command in submodule %s", + die(_("Could not run 'git rev-list --not --remotes -n 1' command in submodule %s"), path); if (strbuf_read(&buf, cp.out, the_hash_algo->hexsz + 1)) needs_pushing = 1; @@ -1115,7 +1115,7 @@ static void submodule_push_check(const char *path, const char *head, * child process. */ if (run_command(&cp)) - die("process for submodule '%s' failed", path); + die(_("process for submodule '%s' failed"), path); } int push_unpushed_submodules(struct repository *r, @@ -1155,10 +1155,10 @@ int push_unpushed_submodules(struct repository *r, /* Actually push the submodules */ for (i = 0; i < needs_pushing.nr; i++) { const char *path = needs_pushing.items[i].string; - fprintf(stderr, "Pushing submodule '%s'\n", path); + fprintf(stderr, _("Pushing submodule '%s'\n"), path); if (!push_submodule(path, remote, rs, push_options, dry_run)) { - fprintf(stderr, "Unable to push submodule '%s'\n", path); + fprintf(stderr, _("Unable to push submodule '%s'\n"), path); ret = 0; } } @@ -1448,7 +1448,7 @@ static int get_next_submodule(struct child_process *cp, prepare_submodule_repo_env_in_gitdir(&cp->env_array); cp->git_cmd = 1; if (!spf->quiet) - strbuf_addf(err, "Fetching submodule %s%s\n", + strbuf_addf(err, _("Fetching submodule %s%s\n"), spf->prefix, ce->name); argv_array_init(&cp->args); argv_array_pushv(&cp->args, spf->args.argv); @@ -1478,7 +1478,7 @@ static int get_next_submodule(struct child_process *cp, !is_empty_dir(ce->name)) { spf->result = 1; strbuf_addf(err, - _("Could not access submodule '%s'"), + _("Could not access submodule '%s'\n"), ce->name); } } @@ -1610,7 +1610,7 @@ int fetch_populated_submodules(struct repository *r, goto out; if (repo_read_index(r) < 0) - die("index file corrupt"); + die(_("index file corrupt")); argv_array_push(&spf.args, "fetch"); for (i = 0; i < options->argc; i++) @@ -1665,7 +1665,7 @@ unsigned is_submodule_modified(const char *path, int ignore_untracked) cp.out = -1; cp.dir = path; if (start_command(&cp)) - die("Could not run 'git status --porcelain=2' in submodule %s", path); + die(_("Could not run 'git status --porcelain=2' in submodule %s"), path); fp = xfdopen(cp.out, "r"); while (strbuf_getwholeline(&buf, fp, '\n') != EOF) { @@ -1706,7 +1706,7 @@ unsigned is_submodule_modified(const char *path, int ignore_untracked) fclose(fp); if (finish_command(&cp) && !ignore_cp_exit_code) - die("'git status --porcelain=2' failed in submodule %s", path); + die(_("'git status --porcelain=2' failed in submodule %s"), path); strbuf_release(&buf); return dirty_submodule; @@ -1841,7 +1841,7 @@ static int submodule_has_dirty_index(const struct submodule *sub) cp.no_stdout = 1; cp.dir = sub->path; if (start_command(&cp)) - die("could not recurse into submodule '%s'", sub->path); + die(_("could not recurse into submodule '%s'"), sub->path); return finish_command(&cp); } @@ -1862,7 +1862,7 @@ static void submodule_reset_index(const char *path) argv_array_push(&cp.args, empty_tree_oid_hex()); if (run_command(&cp)) - die("could not reset submodule index"); + die(_("could not reset submodule index")); } /** diff --git a/t/t0040-parse-options.sh b/t/t0040-parse-options.sh index 705a136..9d7c7fd 100755 --- a/t/t0040-parse-options.sh +++ b/t/t0040-parse-options.sh @@ -242,7 +242,7 @@ test_expect_success 'Alias options do not contribute to abbreviation' ' ' cat >typo.err <<\EOF -error: did you mean `--boolean` (with two dashes ?) +error: did you mean `--boolean` (with two dashes)? EOF test_expect_success 'detect possible typos' ' @@ -252,7 +252,7 @@ test_expect_success 'detect possible typos' ' ' cat >typo.err <<\EOF -error: did you mean `--ambiguous` (with two dashes ?) +error: did you mean `--ambiguous` (with two dashes)? EOF test_expect_success 'detect possible typos' ' diff --git a/t/t2070-restore.sh b/t/t2070-restore.sh index 21c3f84..076d0df 100755 --- a/t/t2070-restore.sh +++ b/t/t2070-restore.sh @@ -106,4 +106,21 @@ test_expect_success 'restore --staged adds deleted intent-to-add file back to in git diff --cached --exit-code ' +test_expect_success 'restore --staged invalidates cache tree for deletions' ' + test_when_finished git reset --hard && + >new1 && + >new2 && + git add new1 new2 && + + # It is important to commit and then reset here, so that the index + # contains a valid cache-tree for the "both" tree. + git commit -m both && + git reset --soft HEAD^ && + + git restore --staged new1 && + git commit -m "just new2" && + git rev-parse HEAD:new2 && + test_must_fail git rev-parse HEAD:new1 +' + test_done diff --git a/t/t4018-diff-funcname.sh b/t/t4018-diff-funcname.sh index c0f4839..02255a0 100755 --- a/t/t4018-diff-funcname.sh +++ b/t/t4018-diff-funcname.sh @@ -106,7 +106,6 @@ do result=success fi test_expect_$result "hunk header: $i" " - test_when_finished 'cat actual' && # for debugging only git diff -U1 $i >actual && grep '@@ .* @@.*RIGHT' actual " diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh index 4b60282..5f8f1c2 100755 --- a/t/t5510-fetch.sh +++ b/t/t5510-fetch.sh @@ -174,6 +174,30 @@ test_expect_success 'fetch --prune --tags with refspec prunes based on refspec' git rev-parse sometag ' +test_expect_success '--refmap="" ignores configured refspec' ' + cd "$TRASH_DIRECTORY" && + git clone "$D" remote-refs && + git -C remote-refs rev-parse remotes/origin/master >old && + git -C remote-refs update-ref refs/remotes/origin/master master~1 && + git -C remote-refs rev-parse remotes/origin/master >new && + git -C remote-refs fetch --refmap= origin "+refs/heads/*:refs/hidden/origin/*" && + git -C remote-refs rev-parse remotes/origin/master >actual && + test_cmp new actual && + git -C remote-refs fetch origin && + git -C remote-refs rev-parse remotes/origin/master >actual && + test_cmp old actual +' + +test_expect_success '--refmap="" and --prune' ' + git -C remote-refs update-ref refs/remotes/origin/foo/otherbranch master && + git -C remote-refs update-ref refs/hidden/foo/otherbranch master && + git -C remote-refs fetch --prune --refmap="" origin +refs/heads/*:refs/hidden/* && + git -C remote-refs rev-parse remotes/origin/foo/otherbranch && + test_must_fail git -C remote-refs rev-parse refs/hidden/foo/otherbranch && + git -C remote-refs fetch --prune origin && + test_must_fail git -C remote-refs rev-parse remotes/origin/foo/otherbranch +' + test_expect_success 'fetch tags when there is no tags' ' cd "$D" && diff --git a/t/t5616-partial-clone.sh b/t/t5616-partial-clone.sh index fea56cd..9a9178f 100755 --- a/t/t5616-partial-clone.sh +++ b/t/t5616-partial-clone.sh @@ -309,26 +309,36 @@ setup_triangle () { printf "line %d\n" $(test_seq 1 100) >big-blob.txt && - # Create a server with 2 commits: a commit with a big blob and a child + # Create a server with 2 commits: a commit with a big tree and a child # commit with an incremental change. Also, create a partial clone # client that only contains the first commit. git init server && git -C server config --local uploadpack.allowfilter 1 && - cp big-blob.txt server && - git -C server add big-blob.txt && + for i in $(test_seq 1 100) + do + echo "make the tree big" >server/file$i && + git -C server add file$i + done && git -C server commit -m "initial" && git clone --bare --filter=tree:0 "file://$(pwd)/server" client && - echo another line >>server/big-blob.txt && - git -C server commit -am "append line to big blob" && + echo another line >>server/file1 && + git -C server commit -am "incremental change" && - # Create a promisor remote that only contains the blob from the first - # commit, and set it as the promisor remote of client. Thus, whenever - # the client lazy fetches, the lazy fetch will succeed only if it is - # for this blob. + # Create a promisor remote that only contains the tree and blob from + # the first commit. git init promisor-remote && + git -C server config --local uploadpack.allowanysha1inwant 1 && + TREE_HASH=$(git -C server rev-parse HEAD~1^{tree}) && + git -C promisor-remote fetch --keep "file://$(pwd)/server" "$TREE_HASH" && + git -C promisor-remote count-objects -v >object-count && + test_i18ngrep "count: 0" object-count && + test_i18ngrep "in-pack: 2" object-count && + + # Set it as the promisor remote of client. Thus, whenever + # the client lazy fetches, the lazy fetch will succeed only if it is + # for this tree or blob. test_commit -C promisor-remote one && # so that ref advertisement is not empty git -C promisor-remote config --local uploadpack.allowanysha1inwant 1 && - git -C promisor-remote hash-object -w --stdin hash && + git -C server rev-parse HEAD~1^{tree} >hash && grep "want $(cat hash)" trace ' @@ -370,7 +380,7 @@ test_expect_success 'fetch lazy-fetches only to resolve deltas, protocol v2' ' # Verify the assumption that the client needed to fetch the delta base # to resolve the delta. - git hash-object big-blob.txt >hash && + git -C server rev-parse HEAD~1^{tree} >hash && grep "want $(cat hash)" trace ' diff --git a/t/t5702-protocol-v2.sh b/t/t5702-protocol-v2.sh index e73067d..7fd7102 100755 --- a/t/t5702-protocol-v2.sh +++ b/t/t5702-protocol-v2.sh @@ -665,6 +665,18 @@ test_expect_success 'fetch from namespaced repo respects namespaces' ' test_cmp expect actual ' +test_expect_success 'ls-remote with v2 http sends only one POST' ' + test_when_finished "rm -f log" && + + git ls-remote "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" >expect && + GIT_TRACE_CURL="$(pwd)/log" git -c protocol.version=2 \ + ls-remote "$HTTPD_URL/smart/http_parent" >actual && + test_cmp expect actual && + + grep "Send header: POST" log >posts && + test_line_count = 1 posts +' + test_expect_success 'push with http:// and a config of v2 does not request v2' ' test_when_finished "rm -f log" && # Till v2 for push is designed, make sure that if a client has diff --git a/t/t7300-clean.sh b/t/t7300-clean.sh index 6e6d24c..cb5e34d 100755 --- a/t/t7300-clean.sh +++ b/t/t7300-clean.sh @@ -737,4 +737,13 @@ test_expect_success MINGW 'handle clean & core.longpaths = false nicely' ' test_i18ngrep "too long" .git/err ' +test_expect_success 'clean untracked paths by pathspec' ' + git init untracked && + mkdir untracked/dir && + echo >untracked/dir/file.txt && + git -C untracked clean -f dir/file.txt && + ls untracked/dir >actual && + test_must_be_empty actual +' + test_done diff --git a/t/t7500-commit-template-squash-signoff.sh b/t/t7500-commit-template-squash-signoff.sh index 46a5cd4..6d19ece 100755 --- a/t/t7500-commit-template-squash-signoff.sh +++ b/t/t7500-commit-template-squash-signoff.sh @@ -382,4 +382,13 @@ test_expect_success 'check commit with unstaged rename and copy' ' ) ' +test_expect_success 'commit without staging files fails and displays hints' ' + echo "initial" >file && + git add file && + git commit -m initial && + echo "changes" >>file && + test_must_fail git commit -m update >actual && + test_i18ngrep "no changes added to commit (use \"git add\" and/or \"git commit -a\")" actual +' + test_done diff --git a/t/t7800-difftool.sh b/t/t7800-difftool.sh index 6bac9ed..29b9290 100755 --- a/t/t7800-difftool.sh +++ b/t/t7800-difftool.sh @@ -125,15 +125,14 @@ test_expect_success 'difftool stops on error with --trust-exit-code' ' test_when_finished "rm -f for-diff .git/fail-right-file" && test_when_finished "git reset -- for-diff" && write_script .git/fail-right-file <<-\EOF && - echo "$2" + echo failed exit 1 EOF >for-diff && git add for-diff && - echo file >expect && test_must_fail git difftool -y --trust-exit-code \ --extcmd .git/fail-right-file branch >actual && - test_cmp expect actual + test_line_count = 1 actual ' test_expect_success 'difftool honors exit status if command not found' ' diff --git a/t/t7814-grep-recurse-submodules.sh b/t/t7814-grep-recurse-submodules.sh index 946f91f..828cb3b 100755 --- a/t/t7814-grep-recurse-submodules.sh +++ b/t/t7814-grep-recurse-submodules.sh @@ -345,7 +345,16 @@ test_incompatible_with_recurse_submodules () } test_incompatible_with_recurse_submodules --untracked -test_incompatible_with_recurse_submodules --no-index + +test_expect_success 'grep --recurse-submodules --no-index ignores --recurse-submodules' ' + git grep --recurse-submodules --no-index -e "^(.|.)[\d]" >actual && + cat >expect <<-\EOF && + a:(1|2)d(3|4) + submodule/a:(1|2)d(3|4) + submodule/sub/a:(1|2)d(3|4) + EOF + test_cmp expect actual +' test_expect_success 'grep --recurse-submodules should pass the pattern type along' ' # Fixed diff --git a/transport.c b/transport.c index 83379a0..1fdc7da 100644 --- a/transport.c +++ b/transport.c @@ -737,7 +737,7 @@ static int disconnect_git(struct transport *transport) { struct git_transport_data *data = transport->data; if (data->conn) { - if (data->got_remote_heads) + if (data->got_remote_heads && !transport->stateless_rpc) packet_flush(data->fd[1]); close(data->fd[0]); close(data->fd[1]); diff --git a/unpack-trees.c b/unpack-trees.c index 2399b68..191e738 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -694,9 +694,11 @@ static int index_pos_by_traverse_info(struct name_entry *names, if (pos >= 0) BUG("This is a directory and should not exist in index"); pos = -pos - 1; - if (!starts_with(o->src_index->cache[pos]->name, name.buf) || + if (pos >= o->src_index->cache_nr || + !starts_with(o->src_index->cache[pos]->name, name.buf) || (pos > 0 && starts_with(o->src_index->cache[pos-1]->name, name.buf))) - BUG("pos must point at the first entry in this directory"); + BUG("pos %d doesn't point to the first entry of %s in index", + pos, name.buf); strbuf_release(&name); return pos; } @@ -1305,14 +1307,14 @@ static int clear_ce_flags_dir(struct index_state *istate, if (pl->use_cone_patterns && orig_ret == MATCHED_RECURSIVE) { struct cache_entry **ce = cache; - rc = (cache_end - cache) / sizeof(struct cache_entry *); + rc = cache_end - cache; while (ce < cache_end) { (*ce)->ce_flags &= ~clear_mask; ce++; } } else if (pl->use_cone_patterns && orig_ret == NOT_MATCHED) { - rc = (cache_end - cache) / sizeof(struct cache_entry *); + rc = cache_end - cache; } else { rc = clear_ce_flags_1(istate, cache, cache_end - cache, prefix, -- 2.7.4