diff options
95 files changed, 1001 insertions, 553 deletions
diff --git a/Documentation/RelNotes/2.22.0.txt b/Documentation/RelNotes/2.22.0.txt index 114f147fd6..84e1ba6106 100644 --- a/Documentation/RelNotes/2.22.0.txt +++ b/Documentation/RelNotes/2.22.0.txt @@ -99,6 +99,18 @@ UI, Workflows & Features repositories now; also the pathname hash-cache is created by default to avoid making crappy deltas when repacking. + * "git branch new A...B" and "git checkout -b new A...B" have been + taught that in their contexts, the notation A...B means "the merge + base between these two commits", just like "git checkout A...B" + detaches HEAD at that commit. + + * Update "git difftool" and "git mergetool" so that the combinations + of {diff,merge}.{tool,guitool} configuration variables serve as + fallback settings of each other in a sensible order. + + * The "--dir-diff" mode of "git difftool" is not useful in "--no-index" + mode; they are now explicitly marked as mutually incompatible. + Performance, Internal Implementation, Development Support etc. @@ -178,6 +190,27 @@ Performance, Internal Implementation, Development Support etc. * The internal implementation of "git rebase -i" has been updated to avoid forking a separate "rebase--interactive" process. + * Allow DEP and ASLR for Windows build to for security hardening. + + * Performance test framework has been broken and measured the version + of Git that happens to be on $PATH, not the specified one to + measure, for a while, which has been corrected. + + * Optionally "make coccicheck" can feed multiple source files to + spatch, gaining performance while spending more memory. + + * Attempt to use an abbreviated option in "git clone --recurs" is + responded by a request to disambiguate between --recursive and + --recurse-submodules, which is bad because these two are synonyms. + The parse-options API has been extended to define such synonyms + more easily and not produce an unnecessary failure. + + * A pair of private functions in http.c that had names similar to + fread/fwrite did not return the number of elements, which was found + to be confusing. + + * Update collision-detecting SHA-1 code to build properly on HP-UX. + Fixes since v2.21 ----------------- @@ -474,6 +507,41 @@ Fixes since v2.21 files used by these commands in such a situation. (merge 4a72486de9 pw/clean-sequencer-state-upon-final-commit later to maint). + * On a filesystem like HFS+, the names of the refs stored as filesystem + entities may become different from what the end-user expects, just + like files in the working tree get "renamed". Work around the + mismatch by paying attention to the core.precomposeUnicode + configuration. + (merge 8e712ef6fc en/unicode-in-refnames later to maint). + + * The code to generate the multi-pack idx file was not prepared to + see too many packfiles and ran out of open file descriptor, which + has been corrected. + + * To run tests for Git SVN, our scripts for CI used to install the + git-svn package (in the hope that it would bring in the right + dependencies). This has been updated to install the more direct + dependency, namely, libsvn-perl. + (merge db864306cf sg/ci-libsvn-perl later to maint). + + * "git cvsexportcommit" running on msys did not expect cvsnt showed + "cvs status" output with CRLF line endings. + + * The fsmonitor interface got out of sync after the in-core index + file gets discarded, which has been corrected. + (merge 398a3b0899 js/fsmonitor-refresh-after-discarding-index later to maint). + + * "git status" did not know that the "label" instruction in the + todo-list "rebase -i -r" uses should not be shown as a hex object + name. + + * A prerequiste check in the test suite to see if a working jgit is + available was made more robust. + (merge abd0f28983 tz/test-lib-check-working-jgit later to maint). + + * The codepath to parse :<path> that obtains the object name for an + indexed object has been made more robust. + * Code cleanup, docfix, build fix, etc. (merge 11f470aee7 jc/test-yes-doc later to maint). (merge 90503a240b js/doc-symref-in-proto-v1 later to maint). @@ -510,3 +578,13 @@ Fixes since v2.21 (merge d8083e4180 km/t3000-retitle later to maint). (merge 9e4cbccbd7 tz/git-svn-doc-markup-fix later to maint). (merge da9ca955a7 jk/ls-files-doc-markup-fix later to maint). + (merge 6804ba3a58 cw/diff-highlight later to maint). + (merge 1a8787144d nd/submodule-helper-incomplete-line-fix later to maint). + (merge d9ef573837 jk/apache-lsan later to maint). + (merge c871fbee2b js/t6500-use-windows-pid-on-mingw later to maint). + (merge ce4c7bfc90 bl/t4253-exit-code-from-format-patch later to maint). + (merge 397a46db78 js/t5580-unc-alternate-test later to maint). + (merge d4907720a2 cm/notes-comment-fix later to maint). + (merge 9dde06de13 cb/http-push-null-in-message-fix later to maint). + (merge 4c785c0edc js/rebase-config-bitfix later to maint). + (merge 8e9fe16c87 es/doc-gitsubmodules-markup later to maint). diff --git a/Documentation/config/stash.txt b/Documentation/config/stash.txt index c583d46d6b..7710758efb 100644 --- a/Documentation/config/stash.txt +++ b/Documentation/config/stash.txt @@ -1,3 +1,18 @@ +stash.useBuiltin:: + Set to `false` to use the legacy shell script implementation of + linkgit:git-stash[1]. Is `true` by default, which means use + the built-in rewrite of it in C. ++ +The C rewrite is first included with Git version 2.22 (and Git for Windows +version 2.19). This option serves an an escape hatch to re-enable the +legacy version in case any bugs are found in the rewrite. This option and +the shell script version of linkgit:git-stash[1] will be removed in some +future release. ++ +If you find some reason to set this option to `false`, other than +one-off testing, you should report the behavior difference as a bug in +Git (see https://git-scm.com/community for details). + stash.showPatch:: If this is set to true, the `git stash show` command without an option will show the stash entry in patch form. Defaults to false. diff --git a/Documentation/config/trace2.txt b/Documentation/config/trace2.txt index a5f409c1c1..2edbfb02fe 100644 --- a/Documentation/config/trace2.txt +++ b/Documentation/config/trace2.txt @@ -4,17 +4,17 @@ command line arguments are not respected. trace2.normalTarget:: This variable controls the normal target destination. - It may be overridden by the `GIT_TR2` environment variable. + It may be overridden by the `GIT_TRACE2` environment variable. The following table shows possible values. trace2.perfTarget:: This variable controls the performance target destination. - It may be overridden by the `GIT_TR2_PERF` environment variable. + It may be overridden by the `GIT_TRACE2_PERF` environment variable. The following table shows possible values. trace2.eventTarget:: This variable controls the event target destination. - It may be overridden by the `GIT_TR2_EVENT` environment variable. + It may be overridden by the `GIT_TRACE2_EVENT` environment variable. The following table shows possible values. + include::../trace2-target-values.txt[] @@ -22,22 +22,22 @@ include::../trace2-target-values.txt[] trace2.normalBrief:: Boolean. When true `time`, `filename`, and `line` fields are omitted from normal output. May be overridden by the - `GIT_TR2_BRIEF` environment variable. Defaults to false. + `GIT_TRACE2_BRIEF` environment variable. Defaults to false. trace2.perfBrief:: Boolean. When true `time`, `filename`, and `line` fields are omitted from PERF output. May be overridden by the - `GIT_TR2_PERF_BRIEF` environment variable. Defaults to false. + `GIT_TRACE2_PERF_BRIEF` environment variable. Defaults to false. trace2.eventBrief:: Boolean. When true `time`, `filename`, and `line` fields are omitted from event output. May be overridden by the - `GIT_TR2_EVENT_BRIEF` environment variable. Defaults to false. + `GIT_TRACE2_EVENT_BRIEF` environment variable. Defaults to false. trace2.eventNesting:: Integer. Specifies desired depth of nested regions in the event output. Regions deeper than this value will be - omitted. May be overridden by the `GIT_TR2_EVENT_NESTING` + omitted. May be overridden by the `GIT_TRACE2_EVENT_NESTING` environment variable. Defaults to 2. trace2.configParams:: @@ -45,7 +45,7 @@ trace2.configParams:: settings that should be recorded in the trace2 output. For example, `core.*,remote.*.url` would cause the trace2 output to contain events listing each configured remote. - May be overridden by the `GIT_TR2_CONFIG_PARAMS` environment + May be overridden by the `GIT_TRACE2_CONFIG_PARAMS` environment variable. Unset by default. trace2.destinationDebug:: @@ -53,4 +53,4 @@ trace2.destinationDebug:: trace target destination cannot be opened for writing. By default, these errors are suppressed and tracing is silently disabled. May be overridden by the - `GIT_TR2_DST_DEBUG` environment variable. + `GIT_TRACE2_DST_DEBUG` environment variable. diff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt index 0cd87ddeff..6ebd512b4f 100644 --- a/Documentation/git-branch.txt +++ b/Documentation/git-branch.txt @@ -45,7 +45,11 @@ argument is missing it defaults to `HEAD` (i.e. the tip of the current branch). The command's second form creates a new branch head named <branchname> -which points to the current `HEAD`, or <start-point> if given. +which points to the current `HEAD`, or <start-point> if given. As a +special case, for <start-point>, you may use `"A...B"` as a shortcut for +the merge base of `A` and `B` if there is exactly one merge base. You +can leave out at most one of `A` and `B`, in which case it defaults to +`HEAD`. Note that this will create the new branch, but it will not switch the working tree to it; use "git checkout <newbranch>" to switch to the diff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt index 877e5f503a..964f912d29 100644 --- a/Documentation/git-checkout.txt +++ b/Documentation/git-checkout.txt @@ -313,6 +313,10 @@ leave out at most one of `A` and `B`, in which case it defaults to `HEAD`. <start_point>:: The name of a commit at which to start the new branch; see linkgit:git-branch[1] for details. Defaults to HEAD. ++ +As a special case, you may use `"A...B"` as a shortcut for the +merge base of `A` and `B` if there is exactly one merge base. You can +leave out at most one of `A` and `B`, in which case it defaults to `HEAD`. <tree-ish>:: Tree to checkout from (when paths are given). If not specified, diff --git a/Documentation/git-difftool.txt b/Documentation/git-difftool.txt index 96c26e6aa8..484c485fd0 100644 --- a/Documentation/git-difftool.txt +++ b/Documentation/git-difftool.txt @@ -90,7 +90,9 @@ instead. `--no-symlinks` is the default on Windows. When 'git-difftool' is invoked with the `-g` or `--gui` option the default diff tool will be read from the configured `diff.guitool` variable instead of `diff.tool`. The `--no-gui` - option can be used to override this setting. + option can be used to override this setting. If `diff.guitool` + is not set, we will fallback in the order of `merge.guitool`, + `diff.tool`, `merge.tool` until a tool is found. --[no-]trust-exit-code:: 'git-difftool' invokes a diff tool individually on each file. diff --git a/Documentation/git-mergetool--lib.txt b/Documentation/git-mergetool--lib.txt index 055550b2bc..4da9d24096 100644 --- a/Documentation/git-mergetool--lib.txt +++ b/Documentation/git-mergetool--lib.txt @@ -28,7 +28,9 @@ to define the operation mode for the functions listed below. FUNCTIONS --------- get_merge_tool:: - returns a merge tool. + returns a merge tool. the return code is 1 if we returned a guessed + merge tool, else 0. '$GIT_MERGETOOL_GUI' may be set to 'true' to + search for the appropriate guitool. get_merge_tool_cmd:: returns the custom command for a merge tool. diff --git a/Documentation/git-mergetool.txt b/Documentation/git-mergetool.txt index 0c7975a050..6b14702e78 100644 --- a/Documentation/git-mergetool.txt +++ b/Documentation/git-mergetool.txt @@ -83,7 +83,9 @@ success of the resolution after the custom tool has exited. --gui:: When 'git-mergetool' is invoked with the `-g` or `--gui` option the default merge tool will be read from the configured - `merge.guitool` variable instead of `merge.tool`. + `merge.guitool` variable instead of `merge.tool`. If + `merge.guitool` is not set, we will fallback to the tool + configured under `merge.tool`. --no-gui:: This overrides a previous `-g` or `--gui` setting and reads the diff --git a/Documentation/git-pull.txt b/Documentation/git-pull.txt index 118d9d86f7..a5e9501a0a 100644 --- a/Documentation/git-pull.txt +++ b/Documentation/git-pull.txt @@ -112,8 +112,9 @@ When set to `merges`, rebase using `git rebase --rebase-merges` so that the local merge commits are included in the rebase (see linkgit:git-rebase[1] for details). + -When set to preserve, rebase with the `--preserve-merges` option passed -to `git rebase` so that locally created merge commits will not be flattened. +When set to `preserve` (deprecated in favor of `merges`), rebase with the +`--preserve-merges` option passed to `git rebase` so that locally created +merge commits will not be flattened. + When false, merge the current branch into the upstream branch. + diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt index f5e6ae3907..5e4e927647 100644 --- a/Documentation/git-rebase.txt +++ b/Documentation/git-rebase.txt @@ -675,7 +675,8 @@ $ git rebase -i HEAD~5 And move the first patch to the end of the list. -You might want to preserve merges, if you have a history like this: +You might want to recreate merge commits, e.g. if you have a history +like this: ------------------ X @@ -689,7 +690,7 @@ Suppose you want to rebase the side branch starting at "A" to "Q". Make sure that the current HEAD is "B", and call ----------------------------- -$ git rebase -i -p --onto Q O +$ git rebase -i -r --onto Q O ----------------------------- Reordering and editing commits usually creates untested intermediate diff --git a/Documentation/git.txt b/Documentation/git.txt index 6d1f2fd9ae..6ddc1e2ca6 100644 --- a/Documentation/git.txt +++ b/Documentation/git.txt @@ -660,6 +660,54 @@ of clones and fetches. When a curl trace is enabled (see `GIT_TRACE_CURL` above), do not dump data (that is, only dump info lines and headers). +`GIT_TRACE2`:: + Enables more detailed trace messages from the "trace2" library. + Output from `GIT_TRACE2` is a simple text-based format for human + readability. ++ +If this variable is set to "1", "2" or "true" (comparison +is case insensitive), trace messages will be printed to +stderr. ++ +If the variable is set to an integer value greater than 2 +and lower than 10 (strictly) then Git will interpret this +value as an open file descriptor and will try to write the +trace messages into this file descriptor. ++ +Alternatively, if the variable is set to an absolute path +(starting with a '/' character), Git will interpret this +as a file path and will try to append the trace messages +to it. If the path already exists and is a directory, the +trace messages will be written to files (one per process) +in that directory, named according to the last component +of the SID and an optional counter (to avoid filename +collisions). ++ +In addition, if the variable is set to +`af_unix:[<socket_type>:]<absolute-pathname>`, Git will try +to open the path as a Unix Domain Socket. The socket type +can be either `stream` or `dgram`. ++ +Unsetting the variable, or setting it to empty, "0" or +"false" (case insensitive) disables trace messages. ++ +See link:technical/api-trace2.html[Trace2 documentation] +for full details. + + +`GIT_TRACE2_EVENT`:: + This setting writes a JSON-based format that is suited for machine + interpretation. + See `GIT_TRACE2` for available trace output options and + link:technical/api-trace2.html[Trace2 documentation] for full details. + +`GIT_TRACE2_PERF`:: + In addition to the text-based messages available in `GIT_TRACE2`, this + setting writes a column-based format for understanding nesting + regions. + See `GIT_TRACE2` for available trace output options and + link:technical/api-trace2.html[Trace2 documentation] for full details. + `GIT_REDACT_COOKIES`:: This can be set to a comma-separated list of strings. When a curl trace is enabled (see `GIT_TRACE_CURL` above), whenever a "Cookies:" header diff --git a/Documentation/gitsubmodules.txt b/Documentation/gitsubmodules.txt index 57999e9f36..0a890205b8 100644 --- a/Documentation/gitsubmodules.txt +++ b/Documentation/gitsubmodules.txt @@ -169,15 +169,15 @@ ACTIVE SUBMODULES A submodule is considered active, - a. if `submodule.<name>.active` is set to `true` + 1. if `submodule.<name>.active` is set to `true` + or - b. if the submodule's path matches the pathspec in `submodule.active` + 2. if the submodule's path matches the pathspec in `submodule.active` + or - c. if `submodule.<name>.url` is set. + 3. if `submodule.<name>.url` is set. and these are evaluated in this order. @@ -193,11 +193,11 @@ For example: url = https://example.org/baz In the above config only the submodule 'bar' and 'baz' are active, -'bar' due to (a) and 'baz' due to (c). 'foo' is inactive because -(a) takes precedence over (c) +'bar' due to (1) and 'baz' due to (3). 'foo' is inactive because +(1) takes precedence over (3) -Note that (c) is a historical artefact and will be ignored if the -(a) and (b) specify that the submodule is not active. In other words, +Note that (3) is a historical artefact and will be ignored if the +(1) and (2) specify that the submodule is not active. In other words, if we have a `submodule.<name>.active` set to `false` or if the submodule's path is excluded in the pathspec in `submodule.active`, the url doesn't matter whether it is present or not. This is illustrated in diff --git a/Documentation/technical/api-trace2.txt b/Documentation/technical/api-trace2.txt index 9e585b8e79..23c3cc7a37 100644 --- a/Documentation/technical/api-trace2.txt +++ b/Documentation/technical/api-trace2.txt @@ -23,7 +23,7 @@ formats in the future. This might be used to define a binary format, for example. Trace2 is controlled using `trace2.*` config values in the system and -global config files and `GIT_TR2*` environment variables. Trace2 does +global config files and `GIT_TRACE2*` environment variables. Trace2 does not read from repo local or worktree config files or respect `-c` command line config settings. @@ -42,7 +42,7 @@ config setting. For example ------------ -$ export GIT_TR2=~/log.normal +$ export GIT_TRACE2=~/log.normal $ git version git version 2.20.1.155.g426c96fcdb ------------ @@ -71,13 +71,13 @@ $ cat ~/log.normal The performance format target (PERF) is a column-based format to replace GIT_TRACE_PERFORMANCE and is suitable for development and testing, possibly to complement tools like gprof. This format is -enabled with the `GIT_TR2_PERF` environment variable or the +enabled with the `GIT_TRACE2_PERF` environment variable or the `trace2.perfTarget` system or global config setting. For example ------------ -$ export GIT_TR2_PERF=~/log.perf +$ export GIT_TRACE2_PERF=~/log.perf $ git version git version 2.20.1.155.g426c96fcdb ------------ @@ -104,14 +104,14 @@ $ cat ~/log.perf === The Event Format Target The event format target is a JSON-based format of event data suitable -for telemetry analysis. This format is enabled with the `GIT_TR2_EVENT` +for telemetry analysis. This format is enabled with the `GIT_TRACE2_EVENT` environment variable or the `trace2.eventTarget` system or global config setting. For example ------------ -$ export GIT_TR2_EVENT=~/log.event +$ export GIT_TRACE2_EVENT=~/log.event $ git version git version 2.20.1.155.g426c96fcdb ------------ @@ -273,7 +273,7 @@ significantly affects program performance or behavior, such as Emits a "def_param" messages for "important" configuration settings. + -The environment variable `GIT_TR2_CONFIG_PARAMS` or the `trace2.configParams` +The environment variable `GIT_TRACE2_CONFIG_PARAMS` or the `trace2.configParams` config value can be set to a list of patterns of important configuration settings, for example: `core.*,remote.*.url`. This function will iterate over all config @@ -465,7 +465,7 @@ Events are written as lines of the form: Note that this may contain embedded LF or CRLF characters that are not escaped, so the event may spill across multiple lines. -If `GIT_TR2_BRIEF` or `trace2.normalBrief` is true, the `time`, `filename`, +If `GIT_TRACE2_BRIEF` or `trace2.normalBrief` is true, the `time`, `filename`, and `line` fields are omitted. This target is intended to be more of a summary (like GIT_TRACE) and @@ -533,7 +533,7 @@ This field is in anticipation of in-proc submodules in the future. 15:33:33.532712 wt-status.c:2331 | d0 | main | region_leave | r1 | 0.127568 | 0.001504 | status | label:print ------------ -If `GIT_TR2_PERF_BRIEF` or `trace2.perfBrief` is true, the `time`, `file`, +If `GIT_TRACE2_PERF_BRIEF` or `trace2.perfBrief` is true, the `time`, `file`, and `line` fields are omitted. ------------ @@ -598,7 +598,7 @@ The following key/value pairs are common to all events: `"repo":<repo-id>`:: when present, is the integer repo-id as described previously. -If `GIT_TR2_EVENT_BRIEF` or `trace2.eventBrief` is true, the `file` +If `GIT_TRACE2_EVENT_BRIEF` or `trace2.eventBrief` is true, the `file` and `line` fields are omitted from all events and the `time` field is only present on the "start" and "atexit" events. @@ -911,7 +911,7 @@ visited. The `category` field may be used in a future enhancement to do category-based filtering. + -`GIT_TR2_EVENT_NESTING` or `trace2.eventNesting` can be used to +`GIT_TRACE2_EVENT_NESTING` or `trace2.eventNesting` can be used to filter deeply nested regions and data events. It defaults to "2". `"region_leave"`:: @@ -1039,8 +1039,8 @@ rev-list, and gc. This example also shows that fetch took 5.199 seconds and of that 4.932 was in ssh. + ---------------- -$ export GIT_TR2_BRIEF=1 -$ export GIT_TR2=~/log.normal +$ export GIT_TRACE2_BRIEF=1 +$ export GIT_TRACE2=~/log.normal $ git fetch origin ... ---------------- @@ -1075,8 +1075,8 @@ its name as "gc", it also reports the hierarchy as "fetch/gc". indented for clarity.) + ---------------- -$ export GIT_TR2_BRIEF=1 -$ export GIT_TR2=~/log.normal +$ export GIT_TRACE2_BRIEF=1 +$ export GIT_TRACE2=~/log.normal $ git fetch origin ... ---------------- @@ -1134,8 +1134,8 @@ In this example, scanning for untracked files ran from +0.012568 to +0.027149 (since the process started) and took 0.014581 seconds. + ---------------- -$ export GIT_TR2_PERF_BRIEF=1 -$ export GIT_TR2_PERF=~/log.perf +$ export GIT_TRACE2_PERF_BRIEF=1 +$ export GIT_TRACE2_PERF=~/log.perf $ git status ... @@ -1180,8 +1180,8 @@ static enum path_treatment read_directory_recursive(struct dir_struct *dir, We can further investigate the time spent scanning for untracked files. + ---------------- -$ export GIT_TR2_PERF_BRIEF=1 -$ export GIT_TR2_PERF=~/log.perf +$ export GIT_TRACE2_PERF_BRIEF=1 +$ export GIT_TRACE2_PERF=~/log.perf $ git status ... $ cat ~/log.perf @@ -1236,8 +1236,8 @@ int read_index_from(struct index_state *istate, const char *path, This example shows that the index contained 3552 entries. + ---------------- -$ export GIT_TR2_PERF_BRIEF=1 -$ export GIT_TR2_PERF=~/log.perf +$ export GIT_TRACE2_PERF_BRIEF=1 +$ export GIT_TRACE2_PERF=~/log.perf $ git status ... $ cat ~/log.perf @@ -1310,8 +1310,8 @@ Data events are tagged with the active thread name. They are used to report the per-thread parameters. + ---------------- -$ export GIT_TR2_PERF_BRIEF=1 -$ export GIT_TR2_PERF=~/log.perf +$ export GIT_TRACE2_PERF_BRIEF=1 +$ export GIT_TRACE2_PERF=~/log.perf $ git status ... $ cat ~/log.perf diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN index 8a5009caf9..7a228b2a9c 100755 --- a/GIT-VERSION-GEN +++ b/GIT-VERSION-GEN @@ -1,7 +1,7 @@ #!/bin/sh GVF=GIT-VERSION-FILE -DEF_VER=v2.22.0-rc0 +DEF_VER=v2.22.0-rc2 LF=' ' @@ -1171,8 +1171,11 @@ PTHREAD_CFLAGS = SPARSE_FLAGS ?= SP_EXTRA_FLAGS = -# For the 'coccicheck' target +# For the 'coccicheck' target; setting SPATCH_BATCH_SIZE higher will +# usually result in less CPU usage at the cost of higher peak memory. +# Setting it to 0 will feed all files in a single spatch invocation. SPATCH_FLAGS = --all-includes --patch . +SPATCH_BATCH_SIZE = 1 include config.mak.uname -include config.mak.autogen @@ -2807,12 +2810,14 @@ endif %.cocci.patch: %.cocci $(COCCI_SOURCES) @echo ' ' SPATCH $<; \ - ret=0; \ - for f in $(COCCI_SOURCES); do \ - $(SPATCH) --sp-file $< $$f $(SPATCH_FLAGS) || \ - { ret=$$?; break; }; \ - done >$@+ 2>$@.log; \ - if test $$ret != 0; \ + if test $(SPATCH_BATCH_SIZE) = 0; then \ + limit=; \ + else \ + limit='-n $(SPATCH_BATCH_SIZE)'; \ + fi; \ + if ! echo $(COCCI_SOURCES) | xargs $$limit \ + $(SPATCH) --sp-file $< $(SPATCH_FLAGS) \ + >$@+ 2>$@.log; \ then \ cat $@.log; \ exit 1; \ @@ -269,7 +269,7 @@ void create_branch(struct repository *r, } real_ref = NULL; - if (get_oid(start_name, &oid)) { + if (get_oid_mb(start_name, &oid)) { if (explicit_tracking) { if (advice_set_upstream_failure) { error(_(upstream_missing), start_name); diff --git a/builtin/clone.c b/builtin/clone.c index ffdd94e8f6..85b0d3155d 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -99,10 +99,7 @@ static struct option builtin_clone_options[] = { N_("don't use local hardlinks, always copy")), OPT_BOOL('s', "shared", &option_shared, N_("setup as shared repository")), - { OPTION_CALLBACK, 0, "recursive", &option_recurse_submodules, - N_("pathspec"), N_("initialize submodules in the clone"), - PARSE_OPT_OPTARG | PARSE_OPT_HIDDEN, recurse_submodules_cb, - (intptr_t)"." }, + OPT_ALIAS(0, "recursive", "recurse-submodules"), { OPTION_CALLBACK, 0, "recurse-submodules", &option_recurse_submodules, N_("pathspec"), N_("initialize submodules in the clone"), PARSE_OPT_OPTARG, recurse_submodules_cb, (intptr_t)"." }, diff --git a/builtin/difftool.c b/builtin/difftool.c index 04ffa1d943..16eb8b70ea 100644 --- a/builtin/difftool.c +++ b/builtin/difftool.c @@ -24,7 +24,6 @@ #include "object-store.h" #include "dir.h" -static char *diff_gui_tool; static int trust_exit_code; static const char *const builtin_difftool_usage[] = { @@ -34,11 +33,6 @@ static const char *const builtin_difftool_usage[] = { static int difftool_config(const char *var, const char *value, void *cb) { - if (!strcmp(var, "diff.guitool")) { - diff_gui_tool = xstrdup(value); - return 0; - } - if (!strcmp(var, "difftool.trustexitcode")) { trust_exit_code = git_config_bool(var, value); return 0; @@ -733,10 +727,14 @@ int cmd_difftool(int argc, const char **argv, const char *prefix) setup_work_tree(); setenv(GIT_DIR_ENVIRONMENT, absolute_path(get_git_dir()), 1); setenv(GIT_WORK_TREE_ENVIRONMENT, absolute_path(get_git_work_tree()), 1); - } + } else if (dir_diff) + die(_("--dir-diff is incompatible with --no-index")); + + if (use_gui_tool + !!difftool_cmd + !!extcmd > 1) + die(_("--gui, --tool and --extcmd are mutually exclusive")); - if (use_gui_tool && diff_gui_tool && *diff_gui_tool) - setenv("GIT_DIFF_TOOL", diff_gui_tool, 1); + if (use_gui_tool) + setenv("GIT_MERGETOOL_GUI", "true", 1); else if (difftool_cmd) { if (*difftool_cmd) setenv("GIT_DIFF_TOOL", difftool_cmd, 1); diff --git a/builtin/multi-pack-index.c b/builtin/multi-pack-index.c index ae6e476ad5..72dfd3dadc 100644 --- a/builtin/multi-pack-index.c +++ b/builtin/multi-pack-index.c @@ -46,7 +46,7 @@ int cmd_multi_pack_index(int argc, const char **argv, if (!strcmp(argv[0], "write")) return write_midx_file(opts.object_dir); if (!strcmp(argv[0], "verify")) - return verify_midx_file(opts.object_dir); + return verify_midx_file(the_repository, opts.object_dir); die(_("unrecognized verb: %s"), argv[0]); } diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c index 9f424aabab..41d7fc5983 100644 --- a/builtin/pack-objects.c +++ b/builtin/pack-objects.c @@ -1080,7 +1080,7 @@ static int want_object_in_pack(const struct object_id *oid, for (m = get_multi_pack_index(the_repository); m; m = m->next) { struct pack_entry e; - if (fill_midx_entry(oid, &e, m)) { + if (fill_midx_entry(the_repository, oid, &e, m)) { struct packed_git *p = e.p; off_t offset; diff --git a/builtin/pack-refs.c b/builtin/pack-refs.c index f3353564f9..cfbd5c36c7 100644 --- a/builtin/pack-refs.c +++ b/builtin/pack-refs.c @@ -1,4 +1,5 @@ #include "builtin.h" +#include "config.h" #include "parse-options.h" #include "refs.h" #include "repository.h" @@ -16,6 +17,7 @@ int cmd_pack_refs(int argc, const char **argv, const char *prefix) OPT_BIT(0, "prune", &flags, N_("prune loose refs (default)"), PACK_REFS_PRUNE), OPT_END(), }; + git_config(git_default_config, NULL); if (parse_options(argc, argv, prefix, opts, pack_refs_usage, 0)) usage_with_options(pack_refs_usage, opts); return refs_pack_refs(get_main_ref_store(the_repository), flags); diff --git a/builtin/rebase.c b/builtin/rebase.c index ba3a574e40..db6ca9bd7d 100644 --- a/builtin/rebase.c +++ b/builtin/rebase.c @@ -1203,7 +1203,7 @@ static int rebase_config(const char *var, const char *value, void *data) if (git_config_bool(var, value)) opts->flags |= REBASE_DIFFSTAT; else - opts->flags &= !REBASE_DIFFSTAT; + opts->flags &= ~REBASE_DIFFSTAT; return 0; } diff --git a/builtin/show-ref.c b/builtin/show-ref.c index 6a706c02a6..6456da70cc 100644 --- a/builtin/show-ref.c +++ b/builtin/show-ref.c @@ -1,5 +1,6 @@ #include "builtin.h" #include "cache.h" +#include "config.h" #include "refs.h" #include "object-store.h" #include "object.h" @@ -182,6 +183,8 @@ static const struct option show_ref_options[] = { int cmd_show_ref(int argc, const char **argv, const char *prefix) { + git_config(git_default_config, NULL); + argc = parse_options(argc, argv, prefix, show_ref_options, show_ref_usage, 0); diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 8c72ea864c..0bf4aa088e 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -1301,7 +1301,7 @@ static int add_possible_reference_from_superproject( die(_("submodule '%s' cannot add alternate: %s"), sas->submodule_name, err.buf); case SUBMODULE_ALTERNATE_ERROR_INFO: - fprintf(stderr, _("submodule '%s' cannot add alternate: %s"), + fprintf_ln(stderr, _("submodule '%s' cannot add alternate: %s"), sas->submodule_name, err.buf); case SUBMODULE_ALTERNATE_ERROR_IGNORE: ; /* nothing */ diff --git a/builtin/tag.c b/builtin/tag.c index 1debd3a11c..ef37dccf86 100644 --- a/builtin/tag.c +++ b/builtin/tag.c @@ -207,7 +207,7 @@ struct create_tag_options { }; static const char message_advice_nested_tag[] = - N_("You have created a nested tag. The object referred to by your new is\n" + N_("You have created a nested tag. The object referred to by your new tag is\n" "already a tag. If you meant to tag the object that it points to, use:\n" "\n" "\tgit tag -f %s %s^{}"); @@ -341,7 +341,8 @@ struct index_state { initialized : 1, drop_cache_tree : 1, updated_workdir : 1, - updated_skipworktree : 1; + updated_skipworktree : 1, + fsmonitor_has_run_once : 1; struct hashmap name_hash; struct hashmap dir_hash; struct object_id oid; diff --git a/ci/install-dependencies.sh b/ci/install-dependencies.sh index 52a44c690a..7f6acdd803 100755 --- a/ci/install-dependencies.sh +++ b/ci/install-dependencies.sh @@ -12,7 +12,7 @@ case "$jobname" in linux-clang|linux-gcc) sudo apt-add-repository -y "ppa:ubuntu-toolchain-r/test" sudo apt-get -q update - sudo apt-get -q -y install language-pack-is git-svn apache2 + sudo apt-get -q -y install language-pack-is libsvn-perl apache2 case "$jobname" in linux-gcc) sudo apt-get -q -y install gcc-8 diff --git a/commit-graph.c b/commit-graph.c index 7bcc9bb7e0..7c5e54875f 100644 --- a/commit-graph.c +++ b/commit-graph.c @@ -267,8 +267,10 @@ struct commit_graph *parse_commit_graph(void *graph_map, int fd, last_chunk_offset = chunk_offset; } - if (verify_commit_graph_lite(graph)) + if (verify_commit_graph_lite(graph)) { + free(graph); return NULL; + } return graph; } diff --git a/compat/mingw.c b/compat/mingw.c index a2f74aca6a..9b6d2400e1 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -1714,142 +1714,10 @@ int mingw_putenv(const char *namevalue) return result ? 0 : -1; } -/* - * Note, this isn't a complete replacement for getaddrinfo. It assumes - * that service contains a numerical port, or that it is null. It - * does a simple search using gethostbyname, and returns one IPv4 host - * if one was found. - */ -static int WSAAPI getaddrinfo_stub(const char *node, const char *service, - const struct addrinfo *hints, - struct addrinfo **res) -{ - struct hostent *h = NULL; - struct addrinfo *ai; - struct sockaddr_in *sin; - - if (node) { - h = gethostbyname(node); - if (!h) - return WSAGetLastError(); - } - - ai = xmalloc(sizeof(struct addrinfo)); - *res = ai; - ai->ai_flags = 0; - ai->ai_family = AF_INET; - ai->ai_socktype = hints ? hints->ai_socktype : 0; - switch (ai->ai_socktype) { - case SOCK_STREAM: - ai->ai_protocol = IPPROTO_TCP; - break; - case SOCK_DGRAM: - ai->ai_protocol = IPPROTO_UDP; - break; - default: - ai->ai_protocol = 0; - break; - } - ai->ai_addrlen = sizeof(struct sockaddr_in); - if (hints && (hints->ai_flags & AI_CANONNAME)) - ai->ai_canonname = h ? xstrdup(h->h_name) : NULL; - else - ai->ai_canonname = NULL; - - sin = xcalloc(1, ai->ai_addrlen); - sin->sin_family = AF_INET; - /* Note: getaddrinfo is supposed to allow service to be a string, - * which should be looked up using getservbyname. This is - * currently not implemented */ - if (service) - sin->sin_port = htons(atoi(service)); - if (h) - sin->sin_addr = *(struct in_addr *)h->h_addr; - else if (hints && (hints->ai_flags & AI_PASSIVE)) - sin->sin_addr.s_addr = INADDR_ANY; - else - sin->sin_addr.s_addr = INADDR_LOOPBACK; - ai->ai_addr = (struct sockaddr *)sin; - ai->ai_next = NULL; - return 0; -} - -static void WSAAPI freeaddrinfo_stub(struct addrinfo *res) -{ - free(res->ai_canonname); - free(res->ai_addr); - free(res); -} - -static int WSAAPI getnameinfo_stub(const struct sockaddr *sa, socklen_t salen, - char *host, DWORD hostlen, - char *serv, DWORD servlen, int flags) -{ - const struct sockaddr_in *sin = (const struct sockaddr_in *)sa; - if (sa->sa_family != AF_INET) - return EAI_FAMILY; - if (!host && !serv) - return EAI_NONAME; - - if (host && hostlen > 0) { - struct hostent *ent = NULL; - if (!(flags & NI_NUMERICHOST)) - ent = gethostbyaddr((const char *)&sin->sin_addr, - sizeof(sin->sin_addr), AF_INET); - - if (ent) - snprintf(host, hostlen, "%s", ent->h_name); - else if (flags & NI_NAMEREQD) - return EAI_NONAME; - else - snprintf(host, hostlen, "%s", inet_ntoa(sin->sin_addr)); - } - - if (serv && servlen > 0) { - struct servent *ent = NULL; - if (!(flags & NI_NUMERICSERV)) - ent = getservbyport(sin->sin_port, - flags & NI_DGRAM ? "udp" : "tcp"); - - if (ent) - snprintf(serv, servlen, "%s", ent->s_name); - else - snprintf(serv, servlen, "%d", ntohs(sin->sin_port)); - } - - return 0; -} - -static HMODULE ipv6_dll = NULL; -static void (WSAAPI *ipv6_freeaddrinfo)(struct addrinfo *res); -static int (WSAAPI *ipv6_getaddrinfo)(const char *node, const char *service, - const struct addrinfo *hints, - struct addrinfo **res); -static int (WSAAPI *ipv6_getnameinfo)(const struct sockaddr *sa, socklen_t salen, - char *host, DWORD hostlen, - char *serv, DWORD servlen, int flags); -/* - * gai_strerror is an inline function in the ws2tcpip.h header, so we - * don't need to try to load that one dynamically. - */ - -static void socket_cleanup(void) -{ - WSACleanup(); - if (ipv6_dll) - FreeLibrary(ipv6_dll); - ipv6_dll = NULL; - ipv6_freeaddrinfo = freeaddrinfo_stub; - ipv6_getaddrinfo = getaddrinfo_stub; - ipv6_getnameinfo = getnameinfo_stub; -} - static void ensure_socket_initialization(void) { WSADATA wsa; static int initialized = 0; - const char *libraries[] = { "ws2_32.dll", "wship6.dll", NULL }; - const char **name; if (initialized) return; @@ -1858,35 +1726,7 @@ static void ensure_socket_initialization(void) die("unable to initialize winsock subsystem, error %d", WSAGetLastError()); - for (name = libraries; *name; name++) { - ipv6_dll = LoadLibraryExA(*name, NULL, - LOAD_LIBRARY_SEARCH_SYSTEM32); - if (!ipv6_dll) - continue; - - ipv6_freeaddrinfo = (void (WSAAPI *)(struct addrinfo *)) - GetProcAddress(ipv6_dll, "freeaddrinfo"); - ipv6_getaddrinfo = (int (WSAAPI *)(const char *, const char *, - const struct addrinfo *, - struct addrinfo **)) - GetProcAddress(ipv6_dll, "getaddrinfo"); - ipv6_getnameinfo = (int (WSAAPI *)(const struct sockaddr *, - socklen_t, char *, DWORD, - char *, DWORD, int)) - GetProcAddress(ipv6_dll, "getnameinfo"); - if (!ipv6_freeaddrinfo || !ipv6_getaddrinfo || !ipv6_getnameinfo) { - FreeLibrary(ipv6_dll); - ipv6_dll = NULL; - } else - break; - } - if (!ipv6_freeaddrinfo || !ipv6_getaddrinfo || !ipv6_getnameinfo) { - ipv6_freeaddrinfo = freeaddrinfo_stub; - ipv6_getaddrinfo = getaddrinfo_stub; - ipv6_getnameinfo = getnameinfo_stub; - } - - atexit(socket_cleanup); + atexit((void(*)(void)) WSACleanup); initialized = 1; } @@ -1904,24 +1744,12 @@ struct hostent *mingw_gethostbyname(const char *host) return gethostbyname(host); } -void mingw_freeaddrinfo(struct addrinfo *res) -{ - ipv6_freeaddrinfo(res); -} - +#undef getaddrinfo int mingw_getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res) { ensure_socket_initialization(); - return ipv6_getaddrinfo(node, service, hints, res); -} - -int mingw_getnameinfo(const struct sockaddr *sa, socklen_t salen, - char *host, DWORD hostlen, char *serv, DWORD servlen, - int flags) -{ - ensure_socket_initialization(); - return ipv6_getnameinfo(sa, salen, host, hostlen, serv, servlen, flags); + return getaddrinfo(node, service, hints, res); } int mingw_socket(int domain, int type, int protocol) diff --git a/compat/mingw.h b/compat/mingw.h index 4d73f8aa9d..593bdbffe6 100644 --- a/compat/mingw.h +++ b/compat/mingw.h @@ -295,18 +295,10 @@ int mingw_gethostname(char *host, int namelen); struct hostent *mingw_gethostbyname(const char *host); #define gethostbyname mingw_gethostbyname -void mingw_freeaddrinfo(struct addrinfo *res); -#define freeaddrinfo mingw_freeaddrinfo - int mingw_getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res); #define getaddrinfo mingw_getaddrinfo -int mingw_getnameinfo(const struct sockaddr *sa, socklen_t salen, - char *host, DWORD hostlen, char *serv, DWORD servlen, - int flags); -#define getnameinfo mingw_getnameinfo - int mingw_socket(int domain, int type, int protocol); #define socket mingw_socket diff --git a/config.mak.uname b/config.mak.uname index 19ce2f296a..b71688eeb7 100644 --- a/config.mak.uname +++ b/config.mak.uname @@ -576,13 +576,21 @@ else ifneq ($(shell expr "$(uname_R)" : '1\.'),2) # MSys2 prefix = /usr/ + # Enable DEP + BASIC_LDFLAGS += -Wl,--nxcompat + # Enable ASLR (unless debugging) + ifneq (,$(findstring -O,$(filter-out -O0 -Og,$(CFLAGS)))) + BASIC_LDFLAGS += -Wl,--dynamicbase + endif ifeq (MINGW32,$(MSYSTEM)) prefix = /mingw32 HOST_CPU = i686 + BASIC_LDFLAGS += -Wl,--pic-executable,-e,_mainCRTStartup endif ifeq (MINGW64,$(MSYSTEM)) prefix = /mingw64 HOST_CPU = x86_64 + BASIC_LDFLAGS += -Wl,--pic-executable,-e,mainCRTStartup else COMPAT_CFLAGS += -D_USE_32BIT_TIME_T BASIC_LDFLAGS += -Wl,--large-address-aware diff --git a/contrib/diff-highlight/DiffHighlight.pm b/contrib/diff-highlight/DiffHighlight.pm index 536754583b..7440aa1c46 100644 --- a/contrib/diff-highlight/DiffHighlight.pm +++ b/contrib/diff-highlight/DiffHighlight.pm @@ -4,6 +4,11 @@ use 5.008; use warnings FATAL => 'all'; use strict; +# Use the correct value for both UNIX and Windows (/dev/null vs nul) +use File::Spec; + +my $NULL = File::Spec->devnull(); + # Highlight by reversing foreground and background. You could do # other things like bold or underline if you prefer. my @OLD_HIGHLIGHT = ( @@ -134,7 +139,7 @@ sub highlight_stdin { # fallback, which means we will work even if git can't be run. sub color_config { my ($key, $default) = @_; - my $s = `git config --get-color $key 2>/dev/null`; + my $s = `git config --get-color $key 2>$NULL`; return length($s) ? $s : $default; } @@ -5211,9 +5211,11 @@ static int diff_opt_unified(const struct option *opt, BUG_ON_OPT_NEG(unset); - options->context = strtol(arg, &s, 10); - if (*s) - return error(_("%s expects a numerical value"), "--unified"); + if (arg) { + options->context = strtol(arg, &s, 10); + if (*s) + return error(_("%s expects a numerical value"), "--unified"); + } enable_patch_output(&options->output_format); return 0; @@ -5272,7 +5274,7 @@ static void prep_parse_options(struct diff_options *options) DIFF_FORMAT_PATCH, DIFF_FORMAT_NO_OUTPUT), OPT_CALLBACK_F('U', "unified", options, N_("<n>"), N_("generate diffs with <n> lines context"), - PARSE_OPT_NONEG, diff_opt_unified), + PARSE_OPT_NONEG | PARSE_OPT_OPTARG, diff_opt_unified), OPT_BOOL('W', "function-context", &options->flags.funccontext, N_("generate diffs with <n> lines context")), OPT_BIT_F(0, "raw", &options->output_format, @@ -5453,13 +5455,13 @@ static void prep_parse_options(struct diff_options *options) N_("equivalent to --word-diff=color --word-diff-regex=<regex>"), PARSE_OPT_NONEG | PARSE_OPT_OPTARG, diff_opt_color_words), OPT_CALLBACK_F(0, "color-moved", options, N_("<mode>"), - N_("move lines of code are colored differently"), + N_("moved lines of code are colored differently"), PARSE_OPT_OPTARG, diff_opt_color_moved), OPT_CALLBACK_F(0, "color-moved-ws", options, N_("<mode>"), N_("how white spaces are ignored in --color-moved"), 0, diff_opt_color_moved_ws), - OPT_GROUP(N_("Diff other options")), + OPT_GROUP(N_("Other diff options")), OPT_CALLBACK_F(0, "relative", options, N_("<prefix>"), N_("when run from subdir, exclude changes outside and show relative paths"), PARSE_OPT_NONEG | PARSE_OPT_OPTARG, @@ -169,7 +169,7 @@ struct diff_options { const char *prefix; int prefix_length; const char *stat_sep; - long xdl_opts; + int xdl_opts; /* see Documentation/diff-options.txt */ char **anchors; diff --git a/fetch-pack.c b/fetch-pack.c index 3f24d0c8a6..1c10f54e78 100644 --- a/fetch-pack.c +++ b/fetch-pack.c @@ -1115,7 +1115,7 @@ static int send_fetch_request(struct fetch_negotiator *negotiator, int fd_out, server_supports_v2("server-option", 1)) { int i; for (i = 0; i < args->server_options->nr; i++) - packet_write_fmt(fd_out, "server-option=%s", + packet_buf_write(&req_buf, "server-option=%s", args->server_options->items[i].string); } diff --git a/fsmonitor.c b/fsmonitor.c index 665bd2d425..1dee0aded1 100644 --- a/fsmonitor.c +++ b/fsmonitor.c @@ -129,7 +129,6 @@ static void fsmonitor_refresh_callback(struct index_state *istate, const char *n void refresh_fsmonitor(struct index_state *istate) { - static int has_run_once = 0; struct strbuf query_result = STRBUF_INIT; int query_success = 0; size_t bol; /* beginning of line */ @@ -137,9 +136,9 @@ void refresh_fsmonitor(struct index_state *istate) char *buf; int i; - if (!core_fsmonitor || has_run_once) + if (!core_fsmonitor || istate->fsmonitor_has_run_once) return; - has_run_once = 1; + istate->fsmonitor_has_run_once = 1; trace_printf_key(&trace_fsmonitor, "refresh fsmonitor"); /* diff --git a/git-cvsexportcommit.perl b/git-cvsexportcommit.perl index d13f02da95..fc00d5946a 100755 --- a/git-cvsexportcommit.perl +++ b/git-cvsexportcommit.perl @@ -431,6 +431,7 @@ END sub safe_pipe_capture { my @output; if (my $pid = open my $child, '-|') { + binmode($child, ":crlf"); @output = (<$child>); close $child or die join(' ',@_).": $! $?"; } else { diff --git a/git-difftool--helper.sh b/git-difftool--helper.sh index 7bfb6737df..46af3e60b7 100755 --- a/git-difftool--helper.sh +++ b/git-difftool--helper.sh @@ -71,7 +71,7 @@ then then merge_tool="$GIT_DIFF_TOOL" else - merge_tool="$(get_merge_tool)" || exit + merge_tool="$(get_merge_tool)" fi fi diff --git a/git-mergetool--lib.sh b/git-mergetool--lib.sh index aaa4eed0bc..204a5acd66 100644 --- a/git-mergetool--lib.sh +++ b/git-mergetool--lib.sh @@ -80,14 +80,18 @@ show_tool_names () { } } -diff_mode() { +diff_mode () { test "$TOOL_MODE" = diff } -merge_mode() { +merge_mode () { test "$TOOL_MODE" = merge } +gui_mode () { + test "$GIT_MERGETOOL_GUI" = true +} + translate_merge_tool_path () { echo "$1" } @@ -351,20 +355,36 @@ guess_merge_tool () { } get_configured_merge_tool () { - # If first argument is true, find the guitool instead - if test "$1" = true - then - gui_prefix=gui - fi - - # Diff mode first tries diff.(gui)tool and falls back to merge.(gui)tool. - # Merge mode only checks merge.(gui)tool + keys= if diff_mode then - merge_tool=$(git config diff.${gui_prefix}tool || git config merge.${gui_prefix}tool) + if gui_mode + then + keys="diff.guitool merge.guitool diff.tool merge.tool" + else + keys="diff.tool merge.tool" + fi else - merge_tool=$(git config merge.${gui_prefix}tool) + if gui_mode + then + keys="merge.guitool merge.tool" + else + keys="merge.tool" + fi fi + + merge_tool=$( + IFS=' ' + for key in $keys + do + selected=$(git config $key) + if test -n "$selected" + then + echo "$selected" + return + fi + done) + if test -n "$merge_tool" && ! valid_tool "$merge_tool" then echo >&2 "git config option $TOOL_MODE.${gui_prefix}tool set to unknown tool: $merge_tool" @@ -404,14 +424,17 @@ get_merge_tool_path () { } get_merge_tool () { + is_guessed=false # Check if a merge tool has been configured merge_tool=$(get_configured_merge_tool) # Try to guess an appropriate merge tool if no tool has been set. if test -z "$merge_tool" then merge_tool=$(guess_merge_tool) || exit + is_guessed=true fi echo "$merge_tool" + test "$is_guessed" = false } mergetool_find_win32_cmd () { diff --git a/git-mergetool.sh b/git-mergetool.sh index 01b9ad59b2..88fa6a914a 100755 --- a/git-mergetool.sh +++ b/git-mergetool.sh @@ -389,7 +389,7 @@ print_noop_and_exit () { main () { prompt=$(git config --bool mergetool.prompt) - gui_tool=false + GIT_MERGETOOL_GUI=false guessed_merge_tool=false orderfile= @@ -416,10 +416,10 @@ main () { esac ;; --no-gui) - gui_tool=false + GIT_MERGETOOL_GUI=false ;; -g|--gui) - gui_tool=true + GIT_MERGETOOL_GUI=true ;; -y|--no-prompt) prompt=false @@ -449,12 +449,8 @@ main () { if test -z "$merge_tool" then - # Check if a merge tool has been configured - merge_tool=$(get_configured_merge_tool $gui_tool) - # Try to guess an appropriate merge tool if no tool has been set. - if test -z "$merge_tool" + if ! merge_tool=$(get_merge_tool) then - merge_tool=$(guess_merge_tool) || exit guessed_merge_tool=true fi fi diff --git a/http-push.c b/http-push.c index f675a96316..e36561a6db 100644 --- a/http-push.c +++ b/http-push.c @@ -526,8 +526,8 @@ static void finish_request(struct transfer_request *request) if (request->headers != NULL) curl_slist_free_all(request->headers); - /* URL is reused for MOVE after PUT */ - if (request->state != RUN_PUT) { + /* URL is reused for MOVE after PUT and used during FETCH */ + if (request->state != RUN_PUT && request->state != RUN_FETCH_PACKED) { FREE_AND_NULL(request->url); } @@ -176,7 +176,7 @@ size_t fread_buffer(char *ptr, size_t eltsize, size_t nmemb, void *buffer_) memcpy(ptr, buffer->buf.buf + buffer->posn, size); buffer->posn += size; - return size; + return size / eltsize; } #ifndef NO_CURL_IOCTL @@ -204,12 +204,12 @@ size_t fwrite_buffer(char *ptr, size_t eltsize, size_t nmemb, void *buffer_) struct strbuf *buffer = buffer_; strbuf_add(buffer, ptr, size); - return size; + return nmemb; } size_t fwrite_null(char *ptr, size_t eltsize, size_t nmemb, void *strbuf) { - return eltsize * nmemb; + return nmemb; } static void closedown_active_slot(struct active_request_slot *slot) @@ -2319,14 +2319,14 @@ static size_t fwrite_sha1_file(char *ptr, size_t eltsize, size_t nmemb, BUG("curl_easy_getinfo for HTTP code failed: %s", curl_easy_strerror(c)); if (slot->http_code >= 300) - return size; + return nmemb; } do { ssize_t retval = xwrite(freq->localfile, (char *) ptr + posn, size - posn); if (retval < 0) - return posn; + return posn / eltsize; posn += retval; } while (posn < size); @@ -2339,7 +2339,7 @@ static size_t fwrite_sha1_file(char *ptr, size_t eltsize, size_t nmemb, the_hash_algo->update_fn(&freq->c, expn, sizeof(expn) - freq->stream.avail_out); } while (freq->stream.avail_in && freq->zret == Z_OK); - return size; + return nmemb; } struct http_object_request *new_http_object_request(const char *base_url, @@ -192,18 +192,17 @@ void close_midx(struct multi_pack_index *m) m->fd = -1; for (i = 0; i < m->num_packs; i++) { - if (m->packs[i]) { - close_pack(m->packs[i]); - free(m->packs[i]); - } + if (m->packs[i]) + m->packs[i]->multi_pack_index = 0; } FREE_AND_NULL(m->packs); FREE_AND_NULL(m->pack_names); } -int prepare_midx_pack(struct multi_pack_index *m, uint32_t pack_int_id) +int prepare_midx_pack(struct repository *r, struct multi_pack_index *m, uint32_t pack_int_id) { struct strbuf pack_name = STRBUF_INIT; + struct packed_git *p; if (pack_int_id >= m->num_packs) die(_("bad pack-int-id: %u (%u total packs)"), @@ -215,9 +214,18 @@ int prepare_midx_pack(struct multi_pack_index *m, uint32_t pack_int_id) strbuf_addf(&pack_name, "%s/pack/%s", m->object_dir, m->pack_names[pack_int_id]); - m->packs[pack_int_id] = add_packed_git(pack_name.buf, pack_name.len, m->local); + p = add_packed_git(pack_name.buf, pack_name.len, m->local); strbuf_release(&pack_name); - return !m->packs[pack_int_id]; + + if (!p) + return 1; + + p->multi_pack_index = 1; + m->packs[pack_int_id] = p; + install_packed_git(r, p); + list_add_tail(&p->mru, &r->objects->packed_git_mru); + + return 0; } int bsearch_midx(const struct object_id *oid, struct multi_pack_index *m, uint32_t *result) @@ -261,7 +269,10 @@ static uint32_t nth_midxed_pack_int_id(struct multi_pack_index *m, uint32_t pos) return get_be32(m->chunk_object_offsets + pos * MIDX_CHUNK_OFFSET_WIDTH); } -static int nth_midxed_pack_entry(struct multi_pack_index *m, struct pack_entry *e, uint32_t pos) +static int nth_midxed_pack_entry(struct repository *r, + struct multi_pack_index *m, + struct pack_entry *e, + uint32_t pos) { uint32_t pack_int_id; struct packed_git *p; @@ -271,7 +282,7 @@ static int nth_midxed_pack_entry(struct multi_pack_index *m, struct pack_entry * pack_int_id = nth_midxed_pack_int_id(m, pos); - if (prepare_midx_pack(m, pack_int_id)) + if (prepare_midx_pack(r, m, pack_int_id)) die(_("error preparing packfile from multi-pack-index")); p = m->packs[pack_int_id]; @@ -301,14 +312,17 @@ static int nth_midxed_pack_entry(struct multi_pack_index *m, struct pack_entry * return 1; } -int fill_midx_entry(const struct object_id *oid, struct pack_entry *e, struct multi_pack_index *m) +int fill_midx_entry(struct repository * r, + const struct object_id *oid, + struct pack_entry *e, + struct multi_pack_index *m) { uint32_t pos; if (!bsearch_midx(oid, m, &pos)) return 0; - return nth_midxed_pack_entry(m, e, pos); + return nth_midxed_pack_entry(r, m, e, pos); } /* Match "foo.idx" against either "foo.pack" _or_ "foo.idx". */ @@ -1020,7 +1034,7 @@ static int compare_pair_pos_vs_id(const void *_a, const void *_b) display_progress(progress, _n); \ } while (0) -int verify_midx_file(const char *object_dir) +int verify_midx_file(struct repository *r, const char *object_dir) { struct pair_pos_vs_id *pairs = NULL; uint32_t i; @@ -1034,7 +1048,7 @@ int verify_midx_file(const char *object_dir) progress = start_progress(_("Looking for referenced packfiles"), m->num_packs); for (i = 0; i < m->num_packs; i++) { - if (prepare_midx_pack(m, i)) + if (prepare_midx_pack(r, m, i)) midx_report("failed to load pack in position %d", i); display_progress(progress, i + 1); @@ -1099,7 +1113,7 @@ int verify_midx_file(const char *object_dir) nth_midxed_object_oid(&oid, m, pairs[i].pos); - if (!fill_midx_entry(&oid, &e, m)) { + if (!fill_midx_entry(r, &oid, &e, m)) { midx_report(_("failed to load pack entry for oid[%d] = %s"), pairs[i].pos, oid_to_hex(&oid)); continue; @@ -5,6 +5,7 @@ struct object_id; struct pack_entry; +struct repository; #define GIT_TEST_MULTI_PACK_INDEX "GIT_TEST_MULTI_PACK_INDEX" @@ -37,18 +38,18 @@ struct multi_pack_index { }; struct multi_pack_index *load_multi_pack_index(const char *object_dir, int local); -int prepare_midx_pack(struct multi_pack_index *m, uint32_t pack_int_id); +int prepare_midx_pack(struct repository *r, struct multi_pack_index *m, uint32_t pack_int_id); int bsearch_midx(const struct object_id *oid, struct multi_pack_index *m, uint32_t *result); struct object_id *nth_midxed_object_oid(struct object_id *oid, struct multi_pack_index *m, uint32_t n); -int fill_midx_entry(const struct object_id *oid, struct pack_entry *e, struct multi_pack_index *m); +int fill_midx_entry(struct repository *r, const struct object_id *oid, struct pack_entry *e, struct multi_pack_index *m); int midx_contains_pack(struct multi_pack_index *m, const char *idx_or_pack_name); int prepare_multi_pack_index_one(struct repository *r, const char *object_dir, int local); int write_midx_file(const char *object_dir); void clear_midx_file(struct repository *r); -int verify_midx_file(const char *object_dir); +int verify_midx_file(struct repository *r, const char *object_dir); void close_midx(struct multi_pack_index *m); @@ -276,12 +276,10 @@ void init_display_notes(struct display_notes_opt *opt); /* * Append notes for the given 'object_sha1' from all trees set up by - * init_display_notes() to 'sb'. The 'flags' are a bitwise - * combination of + * init_display_notes() to 'sb'. * - * - NOTES_SHOW_HEADER: add a 'Notes (refname):' header - * - * - NOTES_INDENT: indent the notes by 4 places + * If 'raw' is false the note will be indented by 4 places and + * a 'Notes (refname):' header added. * * You *must* call init_display_notes() before using this function. */ diff --git a/object-store.h b/object-store.h index 46a1da79cc..272e01e452 100644 --- a/object-store.h +++ b/object-store.h @@ -76,7 +76,8 @@ struct packed_git { pack_keep_in_core:1, freshened:1, do_not_close:1, - pack_promisor:1; + pack_promisor:1, + multi_pack_index:1; unsigned char hash[GIT_MAX_RAWSZ]; struct revindex_entry *revindex; /* something like ".git/objects/pack/xxxxx.pack" */ @@ -129,12 +130,6 @@ struct raw_object_store { struct list_head packed_git_mru; /* - * A linked list containing all packfiles, starting with those - * contained in the multi_pack_index. - */ - struct packed_git *all_packs; - - /* * A fast, rough count of the number of objects in the repository. * These two fields are not meant for direct access. Use * approximate_object_count() instead. diff --git a/packfile.c b/packfile.c index 9f52af9281..49c8544ff4 100644 --- a/packfile.c +++ b/packfile.c @@ -994,8 +994,6 @@ static void prepare_packed_git(struct repository *r) } rearrange_packed_git(r); - r->objects->all_packs = NULL; - prepare_packed_git_mru(r); r->objects->packed_git_initialized = 1; } @@ -1026,26 +1024,16 @@ struct multi_pack_index *get_multi_pack_index(struct repository *r) struct packed_git *get_all_packs(struct repository *r) { - prepare_packed_git(r); - - if (!r->objects->all_packs) { - struct packed_git *p = r->objects->packed_git; - struct multi_pack_index *m; - - for (m = r->objects->multi_pack_index; m; m = m->next) { - uint32_t i; - for (i = 0; i < m->num_packs; i++) { - if (!prepare_midx_pack(m, i)) { - m->packs[i]->next = p; - p = m->packs[i]; - } - } - } + struct multi_pack_index *m; - r->objects->all_packs = p; + prepare_packed_git(r); + for (m = r->objects->multi_pack_index; m; m = m->next) { + uint32_t i; + for (i = 0; i < m->num_packs; i++) + prepare_midx_pack(r, m, i); } - return r->objects->all_packs; + return r->objects->packed_git; } struct list_head *get_packed_git_mru(struct repository *r) @@ -1998,13 +1986,13 @@ int find_pack_entry(struct repository *r, const struct object_id *oid, struct pa return 0; for (m = r->objects->multi_pack_index; m; m = m->next) { - if (fill_midx_entry(oid, e, m)) + if (fill_midx_entry(r, oid, e, m)) return 1; } list_for_each(pos, &r->objects->packed_git_mru) { struct packed_git *p = list_entry(pos, struct packed_git, mru); - if (fill_pack_entry(oid, e, p)) { + if (!p->multi_pack_index && fill_pack_entry(oid, e, p)) { list_move(&p->mru, &r->objects->packed_git_mru); return 1; } diff --git a/parse-options-cb.c b/parse-options-cb.c index 4b95d04a37..a3de795c58 100644 --- a/parse-options-cb.c +++ b/parse-options-cb.c @@ -16,6 +16,9 @@ int parse_opt_abbrev_cb(const struct option *opt, const char *arg, int unset) if (!arg) { v = unset ? 0 : DEFAULT_ABBREV; } else { + if (!*arg) + return error(_("option `%s' expects a numerical value"), + opt->long_name); v = strtol(arg, (char **)&arg, 10); if (*arg) return error(_("option `%s' expects a numerical value"), diff --git a/parse-options.c b/parse-options.c index cb24f1aa8a..87b26a1d92 100644 --- a/parse-options.c +++ b/parse-options.c @@ -195,6 +195,9 @@ static enum parse_opt_result get_value(struct parse_opt_ctx_t *p, } if (get_arg(p, opt, flags, &arg)) return -1; + if (!*arg) + return error(_("%s expects a numerical value"), + optname(opt, flags)); *(int *)opt->value = strtol(arg, (char **)&s, 10); if (*s) return error(_("%s expects a numerical value"), @@ -261,6 +264,35 @@ static enum parse_opt_result parse_short_opt(struct parse_opt_ctx_t *p, return PARSE_OPT_UNKNOWN; } +static int has_string(const char *it, const char **array) +{ + while (*array) + if (!strcmp(it, *(array++))) + return 1; + return 0; +} + +static int is_alias(struct parse_opt_ctx_t *ctx, + const struct option *one_opt, + const struct option *another_opt) +{ + const char **group; + + if (!ctx->alias_groups) + return 0; + + if (!one_opt->long_name || !another_opt->long_name) + return 0; + + for (group = ctx->alias_groups; *group; group += 3) { + /* it and other are from the same family? */ + if (has_string(one_opt->long_name, group) && + has_string(another_opt->long_name, group)) + return 1; + } + return 0; +} + static enum parse_opt_result parse_long_opt( struct parse_opt_ctx_t *p, const char *arg, const struct option *options) @@ -298,7 +330,8 @@ again: if (!(p->flags & PARSE_OPT_KEEP_UNKNOWN) && !strncmp(long_name, arg, arg_end - arg)) { is_abbreviated: - if (abbrev_option) { + if (abbrev_option && + !is_alias(p, abbrev_option, options)) { /* * If this is abbreviated, it is * ambiguous. So when there is no @@ -447,6 +480,10 @@ static void parse_options_check(const struct option *opts) if (opts->callback) BUG("OPTION_LOWLEVEL_CALLBACK needs no high level callback"); break; + case OPTION_ALIAS: + BUG("OPT_ALIAS() should not remain at this point. " + "Are you using parse_options_step() directly?\n" + "That case is not supported yet."); default: ; /* ok. (usually accepts an argument) */ } @@ -458,11 +495,10 @@ static void parse_options_check(const struct option *opts) exit(128); } -void parse_options_start(struct parse_opt_ctx_t *ctx, - int argc, const char **argv, const char *prefix, - const struct option *options, int flags) +static void parse_options_start_1(struct parse_opt_ctx_t *ctx, + int argc, const char **argv, const char *prefix, + const struct option *options, int flags) { - memset(ctx, 0, sizeof(*ctx)); ctx->argc = argc; ctx->argv = argv; if (!(flags & PARSE_OPT_ONE_SHOT)) { @@ -484,6 +520,14 @@ void parse_options_start(struct parse_opt_ctx_t *ctx, parse_options_check(options); } +void parse_options_start(struct parse_opt_ctx_t *ctx, + int argc, const char **argv, const char *prefix, + const struct option *options, int flags) +{ + memset(ctx, 0, sizeof(*ctx)); + parse_options_start_1(ctx, argc, argv, prefix, options, flags); +} + static void show_negated_gitcomp(const struct option *opts, int nr_noopts) { int printed_dashdash = 0; @@ -575,6 +619,83 @@ static int show_gitcomp(const struct option *opts) return PARSE_OPT_COMPLETE; } +/* + * Scan and may produce a new option[] array, which should be used + * instead of the original 'options'. + * + * Right now this is only used to preprocess and substitue + * OPTION_ALIAS. + */ +static struct option *preprocess_options(struct parse_opt_ctx_t *ctx, + const struct option *options) +{ + struct option *newopt; + int i, nr, alias; + int nr_aliases = 0; + + for (nr = 0; options[nr].type != OPTION_END; nr++) { + if (options[nr].type == OPTION_ALIAS) + nr_aliases++; + } + + if (!nr_aliases) + return NULL; + + ALLOC_ARRAY(newopt, nr + 1); + COPY_ARRAY(newopt, options, nr + 1); + + /* each alias has two string pointers and NULL */ + CALLOC_ARRAY(ctx->alias_groups, 3 * (nr_aliases + 1)); + + for (alias = 0, i = 0; i < nr; i++) { + int short_name; + const char *long_name; + const char *source; + int j; + + if (newopt[i].type != OPTION_ALIAS) + continue; + + short_name = newopt[i].short_name; + long_name = newopt[i].long_name; + source = newopt[i].value; + + if (!long_name) + BUG("An alias must have long option name"); + + for (j = 0; j < nr; j++) { + const char *name = options[j].long_name; + + if (!name || strcmp(name, source)) + continue; + + if (options[j].type == OPTION_ALIAS) + BUG("No please. Nested aliases are not supported."); + + /* + * NEEDSWORK: this is a bit inconsistent because + * usage_with_options() on the original options[] will print + * help string as "alias of %s" but "git cmd -h" will + * print the original help string. + */ + memcpy(newopt + i, options + j, sizeof(*newopt)); + newopt[i].short_name = short_name; + newopt[i].long_name = long_name; + break; + } + + if (j == nr) + BUG("could not find source option '%s' of alias '%s'", + source, newopt[i].long_name); + ctx->alias_groups[alias * 3 + 0] = newopt[i].long_name; + ctx->alias_groups[alias * 3 + 1] = options[j].long_name; + ctx->alias_groups[alias * 3 + 2] = NULL; + alias++; + } + + return newopt; +} + static int usage_with_options_internal(struct parse_opt_ctx_t *, const char * const *, const struct option *, int, int); @@ -714,11 +835,16 @@ int parse_options(int argc, const char **argv, const char *prefix, int flags) { struct parse_opt_ctx_t ctx; + struct option *real_options; disallow_abbreviated_options = git_env_bool("GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS", 0); - parse_options_start(&ctx, argc, argv, prefix, options, flags); + memset(&ctx, 0, sizeof(ctx)); + real_options = preprocess_options(&ctx, options); + if (real_options) + options = real_options; + parse_options_start_1(&ctx, argc, argv, prefix, options, flags); switch (parse_options_step(&ctx, options, usagestr)) { case PARSE_OPT_HELP: case PARSE_OPT_ERROR: @@ -741,6 +867,8 @@ int parse_options(int argc, const char **argv, const char *prefix, } precompose_argv(argc, argv); + free(real_options); + free(ctx.alias_groups); return parse_options_end(&ctx); } @@ -835,6 +963,12 @@ static int usage_with_options_internal(struct parse_opt_ctx_t *ctx, fputc('\n', outfile); pad = USAGE_OPTS_WIDTH; } + if (opts->type == OPTION_ALIAS) { + fprintf(outfile, "%*s", pad + USAGE_GAP, ""); + fprintf_ln(outfile, _("alias of --%s"), + (const char *)opts->value); + continue; + } fprintf(outfile, "%*s%s\n", pad + USAGE_GAP, "", _(opts->help)); } fputc('\n', outfile); diff --git a/parse-options.h b/parse-options.h index bd00cf0049..ac6ba8abf9 100644 --- a/parse-options.h +++ b/parse-options.h @@ -7,6 +7,7 @@ enum parse_opt_type { OPTION_ARGUMENT, OPTION_GROUP, OPTION_NUMBER, + OPTION_ALIAS, /* options with no arguments */ OPTION_BIT, OPTION_NEGBIT, @@ -183,6 +184,9 @@ struct option { N_("no-op (backward compatibility)"), \ PARSE_OPT_HIDDEN | PARSE_OPT_NOARG, parse_opt_noop_cb } +#define OPT_ALIAS(s, l, source_long_name) \ + { OPTION_ALIAS, (s), (l), (source_long_name) } + /* * parse_options() will filter out the processed options and leave the * non-option arguments in argv[]. argv0 is assumed program name and @@ -258,6 +262,8 @@ struct parse_opt_ctx_t { const char *opt; int flags; const char *prefix; + const char **alias_groups; /* must be in groups of 3 elements! */ + struct option *updated_options; }; void parse_options_start(struct parse_opt_ctx_t *ctx, @@ -286,7 +292,9 @@ int parse_opt_commit(const struct option *, const char *, int); int parse_opt_tertiary(const struct option *, const char *, int); int parse_opt_string_list(const struct option *, const char *, int); int parse_opt_noop_cb(const struct option *, const char *, int); -int parse_opt_unknown_cb(struct parse_opt_ctx_t *ctx, const struct option *, const char *, int); +enum parse_opt_result parse_opt_unknown_cb(struct parse_opt_ctx_t *ctx, + const struct option *, + const char *, int); int parse_opt_passthru(const struct option *, const char *, int); int parse_opt_passthru_argv(const struct option *, const char *, int); diff --git a/pkt-line.c b/pkt-line.c index c9ed780d0b..a0e87b1e81 100644 --- a/pkt-line.c +++ b/pkt-line.c @@ -119,7 +119,7 @@ void packet_buf_delim(struct strbuf *buf) strbuf_add(buf, "0001", 4); } -void set_packet_header(char *buf, const int size) +void set_packet_header(char *buf, int size) { static char hexchar[] = "0123456789abcdef"; diff --git a/progress.c b/progress.c index 0318bdd41b..a2e8cf64a8 100644 --- a/progress.c +++ b/progress.c @@ -128,7 +128,7 @@ static void display(struct progress *progress, uint64_t n, const char *done) (int) clear_len, eol); } else if (!done && cols < progress_line_len) { clear_len = progress->title_len + 1 < cols ? - cols - progress->title_len : 0; + cols - progress->title_len - 1 : 0; fprintf(stderr, "%s:%*s\n %s%s", progress->title, (int) clear_len, "", counters_sb->buf, eol); diff --git a/read-cache.c b/read-cache.c index 4fad4e3f9a..22e7b9944e 100644 --- a/read-cache.c +++ b/read-cache.c @@ -2326,6 +2326,7 @@ int discard_index(struct index_state *istate) free_name_hash(istate); cache_tree_free(&(istate->cache_tree)); istate->initialized = 0; + istate->fsmonitor_has_run_once = 0; FREE_AND_NULL(istate->cache); istate->cache_alloc = 0; discard_split_index(istate); diff --git a/sha1-name.c b/sha1-name.c index 775a73d8ad..728e6f1f61 100644 --- a/sha1-name.c +++ b/sha1-name.c @@ -157,6 +157,9 @@ static void unique_in_pack(struct packed_git *p, uint32_t num, i, first = 0; const struct object_id *current = NULL; + if (p->multi_pack_index) + return; + if (open_pack_index(p) || !p->num_objects) return; @@ -625,6 +628,9 @@ static void find_abbrev_len_for_pack(struct packed_git *p, struct object_id oid; const struct object_id *mad_oid; + if (p->multi_pack_index) + return; + if (open_pack_index(p) || !p->num_objects) return; @@ -1837,7 +1843,7 @@ static enum get_oid_result get_oid_with_context_1(struct repository *repo, if (flags & GET_OID_RECORD_PATH) oc->path = xstrdup(cp); - if (!repo->index->cache) + if (!repo->index || !repo->index->cache) repo_read_index(repo); pos = index_name_pos(repo->index, cp, namelen); if (pos < 0) diff --git a/sha1collisiondetection b/sha1collisiondetection -Subproject 16033998da4b273aebd92c84b1e1b12e4aaf700 +Subproject 855827c583bc30645ba427885caa40c5b81764d diff --git a/sha1dc/sha1.c b/sha1dc/sha1.c index 5931cf25d5..9d3cf81d4d 100644 --- a/sha1dc/sha1.c +++ b/sha1dc/sha1.c @@ -93,7 +93,7 @@ #define SHA1DC_BIGENDIAN /* Not under GCC-alike or glibc or *BSD or newlib or <processor whitelist> */ -#elif (defined(_AIX)) +#elif (defined(_AIX) || defined(__hpux)) /* * Defines Big Endian on a whitelist of OSs that are known to be Big diff --git a/t/check-non-portable-shell.pl b/t/check-non-portable-shell.pl index 166d64d4a2..38bfeebd88 100755 --- a/t/check-non-portable-shell.pl +++ b/t/check-non-portable-shell.pl @@ -27,14 +27,14 @@ for my $i (@ARGV) { close $f; } +my $line = ''; while (<>) { chomp; + $line .= $_; # stitch together incomplete lines (those ending with "\") - while (s/\\$//) { - $_ .= readline; - chomp; - } + next if $line =~ s/\\$//; + $_ = $line; /\bcp\s+-a/ and err 'cp -a is not portable'; /\bsed\s+-[^efn]\s+/ and err 'sed option not portable (use only -n, -e, -f)'; /\becho\s+-[neE]/ and err 'echo with option is not portable (use printf)'; @@ -48,6 +48,7 @@ while (<>) { /\bexport\s+[A-Za-z0-9_]*=/ and err '"export FOO=bar" is not portable (use FOO=bar && export FOO)'; /^\s*([A-Z0-9_]+=(\w+|(["']).*?\3)\s+)+(\w+)/ and exists($func{$4}) and err '"FOO=bar shell_func" assignment extends beyond "shell_func"'; + $line = ''; # this resets our $. for each file close ARGV if eof; } diff --git a/t/helper/test-parse-options.c b/t/helper/test-parse-options.c index 2232b2f79e..af82db06ac 100644 --- a/t/helper/test-parse-options.c +++ b/t/helper/test-parse-options.c @@ -149,6 +149,9 @@ int cmd__parse_options(int argc, const char **argv) OPT_CALLBACK(0, "expect", &expect, "string", "expected output in the variable dump", collect_expect), + OPT_GROUP("Alias"), + OPT_STRING('A', "alias-source", &string, "string", "get a string"), + OPT_ALIAS('Z', "alias-target", "alias-source"), OPT_END(), }; int i; diff --git a/t/helper/test-read-cache.c b/t/helper/test-read-cache.c index d674c88ba0..7e79b555de 100644 --- a/t/helper/test-read-cache.c +++ b/t/helper/test-read-cache.c @@ -1,14 +1,36 @@ #include "test-tool.h" #include "cache.h" +#include "config.h" int cmd__read_cache(int argc, const char **argv) { - int i, cnt = 1; + int i, cnt = 1, namelen; + const char *name = NULL; + + if (argc > 1 && skip_prefix(argv[1], "--print-and-refresh=", &name)) { + namelen = strlen(name); + argc--; + argv++; + } + if (argc == 2) cnt = strtol(argv[1], NULL, 0); setup_git_directory(); + git_config(git_default_config, NULL); for (i = 0; i < cnt; i++) { read_cache(); + if (name) { + int pos; + + refresh_index(&the_index, REFRESH_QUIET, + NULL, NULL, NULL); + pos = index_name_pos(&the_index, name, namelen); + if (pos < 0) + die("%s not in index", name); + printf("%s is%s up to date\n", name, + ce_uptodate(the_index.cache[pos]) ? "" : " not"); + write_file(name, "%d\n", i); + } discard_cache(); } return 0; diff --git a/t/lib-httpd/apache.conf b/t/lib-httpd/apache.conf index 06a81b54c7..5c1c86c193 100644 --- a/t/lib-httpd/apache.conf +++ b/t/lib-httpd/apache.conf @@ -76,6 +76,7 @@ PassEnv GIT_VALGRIND PassEnv GIT_VALGRIND_OPTIONS PassEnv GNUPGHOME PassEnv ASAN_OPTIONS +PassEnv LSAN_OPTIONS PassEnv GIT_TRACE PassEnv GIT_CONFIG_NOSYSTEM PassEnv GIT_TEST_SIDEBAND_ALL diff --git a/t/perf/README b/t/perf/README index be12090c38..c7b70e2d28 100644 --- a/t/perf/README +++ b/t/perf/README @@ -45,7 +45,7 @@ call the aggregation script to summarize the results: $ ./p0001-rev-list.sh [...] - $ GIT_BUILD_DIR=/path/to/other/git ./p0001-rev-list.sh + $ ./run /path/to/other/git -- ./p0001-rev-list.sh [...] $ ./aggregate.perl . /path/to/other/git ./p0001-rev-list.sh diff --git a/t/perf/aggregate.perl b/t/perf/aggregate.perl index 76dd48f890..66554d2161 100755 --- a/t/perf/aggregate.perl +++ b/t/perf/aggregate.perl @@ -5,6 +5,7 @@ use strict; use warnings; use Getopt::Long; use Git; +use Cwd qw(realpath); sub get_times { my $name = shift; @@ -98,18 +99,21 @@ usage() unless $rc; while (scalar @ARGV) { my $arg = $ARGV[0]; my $dir; + my $prefix = ''; last if -f $arg or $arg eq "--"; if (! -d $arg) { my $rev = Git::command_oneline(qw(rev-parse --verify), $arg); $dir = "build/".$rev; + } elsif ($arg eq '.') { + $dir = '.'; } else { - $arg =~ s{/*$}{}; - $dir = $arg; - $dirabbrevs{$dir} = $dir; + $dir = realpath($arg); + $dirnames{$dir} = $dir; + $prefix .= 'bindir'; } push @dirs, $dir; - $dirnames{$dir} = $arg; - my $prefix = $dir; + $dirnames{$dir} ||= $arg; + $prefix .= $dir; $prefix =~ tr/^a-zA-Z0-9/_/c; $prefixes{$dir} = $prefix . '.'; shift @ARGV; @@ -311,9 +315,6 @@ sub print_codespeed_results { $environment = $reponame; } elsif (exists $ENV{GIT_PERF_REPO_NAME} and $ENV{GIT_PERF_REPO_NAME} ne "") { $environment = $ENV{GIT_PERF_REPO_NAME}; - } elsif (exists $ENV{GIT_TEST_INSTALLED} and $ENV{GIT_TEST_INSTALLED} ne "") { - $environment = $ENV{GIT_TEST_INSTALLED}; - $environment =~ s|/bin-wrappers$||; } else { $environment = `uname -r`; chomp $environment; diff --git a/t/perf/perf-lib.sh b/t/perf/perf-lib.sh index 169f92eae3..b58a43ea43 100644 --- a/t/perf/perf-lib.sh +++ b/t/perf/perf-lib.sh @@ -21,19 +21,21 @@ # because it will change our working directory. TEST_DIRECTORY=$(pwd)/.. TEST_OUTPUT_DIRECTORY=$(pwd) -ABSOLUTE_GIT_TEST_INSTALLED=$( - test -n "$GIT_TEST_INSTALLED" && cd "$GIT_TEST_INSTALLED" && pwd) TEST_NO_CREATE_REPO=t TEST_NO_MALLOC_CHECK=t . ../test-lib.sh -if test -z "$GIT_TEST_INSTALLED"; then - perf_results_prefix= -else - perf_results_prefix=$(printf "%s" "${GIT_TEST_INSTALLED%/bin-wrappers}" | tr -c "[a-zA-Z0-9]" "[_*]")"." - GIT_TEST_INSTALLED=$ABSOLUTE_GIT_TEST_INSTALLED +if test -n "$GIT_TEST_INSTALLED" -a -z "$PERF_SET_GIT_TEST_INSTALLED" +then + error "Do not use GIT_TEST_INSTALLED with the perf tests. + +Instead use: + + ./run <path-to-git> -- <tests> + +See t/perf/README for details." fi # Variables from test-lib that are normally internal to the tests; we @@ -179,7 +181,7 @@ test_wrapper_ () { base=$(basename "$0" .sh) echo "$test_count" >>"$perf_results_dir"/$base.subtests echo "$1" >"$perf_results_dir"/$base.$test_count.descr - base="$perf_results_dir"/"$perf_results_prefix$(basename "$0" .sh)"."$test_count" + base="$perf_results_dir"/"$PERF_RESULTS_PREFIX$(basename "$0" .sh)"."$test_count" "$test_wrapper_func_" "$@" fi diff --git a/t/perf/run b/t/perf/run index 9aaa733c77..c7b86104e1 100755 --- a/t/perf/run +++ b/t/perf/run @@ -70,6 +70,24 @@ build_git_rev () { ) || die "failed to build revision '$mydir'" } +set_git_test_installed () { + mydir=$1 + + mydir_abs=$(cd $mydir && pwd) + mydir_abs_wrappers="$mydir_abs_wrappers/bin-wrappers" + if test -d "$mydir_abs_wrappers" + then + GIT_TEST_INSTALLED=$mydir_abs_wrappers + else + # Older versions of git lacked bin-wrappers; + # fallback to the files in the root. + GIT_TEST_INSTALLED=$mydir_abs + fi + export GIT_TEST_INSTALLED + PERF_SET_GIT_TEST_INSTALLED=true + export PERF_SET_GIT_TEST_INSTALLED +} + run_dirs_helper () { mydir=${1%/} shift @@ -79,7 +97,16 @@ run_dirs_helper () { if test $# -gt 0 -a "$1" = --; then shift fi - if [ ! -d "$mydir" ]; then + + PERF_RESULTS_PREFIX= + if test "$mydir" = "." + then + unset GIT_TEST_INSTALLED + elif test -d "$mydir" + then + PERF_RESULTS_PREFIX=bindir$(cd $mydir && printf "%s" "$(pwd)" | tr -c "[a-zA-Z0-9]" "_"). + set_git_test_installed "$mydir" + else rev=$(git rev-parse --verify "$mydir" 2>/dev/null) || die "'$mydir' is neither a directory nor a valid revision" if [ ! -d build/$rev ]; then @@ -87,16 +114,12 @@ run_dirs_helper () { fi build_git_rev $rev "$mydir" mydir=build/$rev + + PERF_RESULTS_PREFIX=build_$rev. + set_git_test_installed "$mydir" fi - if test "$mydir" = .; then - unset GIT_TEST_INSTALLED - else - GIT_TEST_INSTALLED="$mydir/bin-wrappers" - # Older versions of git lacked bin-wrappers; fallback to the - # files in the root. - test -d "$GIT_TEST_INSTALLED" || GIT_TEST_INSTALLED=$mydir - export GIT_TEST_INSTALLED - fi + export PERF_RESULTS_PREFIX + run_one_dir "$@" } diff --git a/t/t0001-init.sh b/t/t0001-init.sh index 1f462204ea..77a224aafb 100755 --- a/t/t0001-init.sh +++ b/t/t0001-init.sh @@ -93,7 +93,7 @@ test_expect_success 'No extra GIT_* on alias scripts' ' sed -n \ -e "/^GIT_PREFIX=/d" \ -e "/^GIT_TEXTDOMAINDIR=/d" \ - -e "/^GIT_TR2_PARENT/d" \ + -e "/^GIT_TRACE2_PARENT/d" \ -e "/^GIT_/s/=.*//p" | sort EOF diff --git a/t/t0040-parse-options.sh b/t/t0040-parse-options.sh index 800b3ea5f5..cebc77fab0 100755 --- a/t/t0040-parse-options.sh +++ b/t/t0040-parse-options.sh @@ -48,6 +48,12 @@ Standard options -q, --quiet be quiet --expect <string> expected output in the variable dump +Alias + -A, --alias-source <string> + get a string + -Z, --alias-target <string> + get a string + EOF test_expect_success 'test help' ' @@ -224,6 +230,17 @@ test_expect_success 'non ambiguous option (after two options it abbreviates)' ' test-tool parse-options --expect="string: 123" --st 123 ' +test_expect_success 'Alias options do not contribute to abbreviation' ' + test-tool parse-options --alias-source 123 >output && + grep "^string: 123" output && + test-tool parse-options --alias-target 123 >output && + grep "^string: 123" output && + test_must_fail test-tool parse-options --alias && + GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS=false \ + test-tool parse-options --alias 123 >output && + grep "^string: 123" output +' + cat >typo.err <<\EOF error: did you mean `--boolean` (with two dashes ?) EOF diff --git a/t/t0210-trace2-normal.sh b/t/t0210-trace2-normal.sh index 71194a3623..ce7574edb1 100755 --- a/t/t0210-trace2-normal.sh +++ b/t/t0210-trace2-normal.sh @@ -4,9 +4,9 @@ test_description='test trace2 facility (normal target)' . ./test-lib.sh # Turn off any inherited trace2 settings for this test. -sane_unset GIT_TR2 GIT_TR2_PERF GIT_TR2_EVENT -sane_unset GIT_TR2_BRIEF -sane_unset GIT_TR2_CONFIG_PARAMS +sane_unset GIT_TRACE2 GIT_TRACE2_PERF GIT_TRACE2_EVENT +sane_unset GIT_TRACE2_BRIEF +sane_unset GIT_TRACE2_CONFIG_PARAMS # Add t/helper directory to PATH so that we can use a relative # path to run nested instances of test-tool.exe (see 004child). @@ -27,12 +27,12 @@ V=$(git version | sed -e 's/^git version //') && export V # to whatever filtering that target decides to do). # This script tests the normal target in isolation. # -# Defer setting GIT_TR2 until the actual command line we want to test +# Defer setting GIT_TRACE2 until the actual command line we want to test # because hidden git and test-tool commands run by the test harness # can contaminate our output. # Enable "brief" feature which turns off "<clock> <file>:<line> " prefix. -GIT_TR2_BRIEF=1 && export GIT_TR2_BRIEF +GIT_TRACE2_BRIEF=1 && export GIT_TRACE2_BRIEF # Basic tests of the trace2 normal stream. Since this stream is used # primarily with printf-style debugging/tracing, we do limited testing @@ -54,7 +54,7 @@ GIT_TR2_BRIEF=1 && export GIT_TR2_BRIEF test_expect_success 'normal stream, return code 0' ' test_when_finished "rm trace.normal actual expect" && - GIT_TR2="$(pwd)/trace.normal" test-tool trace2 001return 0 && + GIT_TRACE2="$(pwd)/trace.normal" test-tool trace2 001return 0 && perl "$TEST_DIRECTORY/t0210/scrub_normal.perl" <trace.normal >actual && cat >expect <<-EOF && version $V @@ -68,7 +68,7 @@ test_expect_success 'normal stream, return code 0' ' test_expect_success 'normal stream, return code 1' ' test_when_finished "rm trace.normal actual expect" && - test_must_fail env GIT_TR2="$(pwd)/trace.normal" test-tool trace2 001return 1 && + test_must_fail env GIT_TRACE2="$(pwd)/trace.normal" test-tool trace2 001return 1 && perl "$TEST_DIRECTORY/t0210/scrub_normal.perl" <trace.normal >actual && cat >expect <<-EOF && version $V @@ -83,7 +83,7 @@ test_expect_success 'normal stream, return code 1' ' test_expect_success 'automatic filename' ' test_when_finished "rm -r traces actual expect" && mkdir traces && - GIT_TR2="$(pwd)/traces" test-tool trace2 001return 0 && + GIT_TRACE2="$(pwd)/traces" test-tool trace2 001return 0 && perl "$TEST_DIRECTORY/t0210/scrub_normal.perl" <"$(ls traces/*)" >actual && cat >expect <<-EOF && version $V @@ -101,7 +101,7 @@ test_expect_success 'automatic filename' ' test_expect_success 'normal stream, exit code 0' ' test_when_finished "rm trace.normal actual expect" && - GIT_TR2="$(pwd)/trace.normal" test-tool trace2 002exit 0 && + GIT_TRACE2="$(pwd)/trace.normal" test-tool trace2 002exit 0 && perl "$TEST_DIRECTORY/t0210/scrub_normal.perl" <trace.normal >actual && cat >expect <<-EOF && version $V @@ -115,7 +115,7 @@ test_expect_success 'normal stream, exit code 0' ' test_expect_success 'normal stream, exit code 1' ' test_when_finished "rm trace.normal actual expect" && - test_must_fail env GIT_TR2="$(pwd)/trace.normal" test-tool trace2 002exit 1 && + test_must_fail env GIT_TRACE2="$(pwd)/trace.normal" test-tool trace2 002exit 1 && perl "$TEST_DIRECTORY/t0210/scrub_normal.perl" <trace.normal >actual && cat >expect <<-EOF && version $V @@ -133,7 +133,7 @@ test_expect_success 'normal stream, exit code 1' ' test_expect_success 'normal stream, error event' ' test_when_finished "rm trace.normal actual expect" && - GIT_TR2="$(pwd)/trace.normal" test-tool trace2 003error "hello world" "this is a test" && + GIT_TRACE2="$(pwd)/trace.normal" test-tool trace2 003error "hello world" "this is a test" && perl "$TEST_DIRECTORY/t0210/scrub_normal.perl" <trace.normal >actual && cat >expect <<-EOF && version $V @@ -147,7 +147,7 @@ test_expect_success 'normal stream, error event' ' test_cmp expect actual ' -sane_unset GIT_TR2_BRIEF +sane_unset GIT_TRACE2_BRIEF # Now test without environment variables and get all Trace2 settings # from the global config. diff --git a/t/t0211-trace2-perf.sh b/t/t0211-trace2-perf.sh index b501e867af..2c3ad6e8c1 100755 --- a/t/t0211-trace2-perf.sh +++ b/t/t0211-trace2-perf.sh @@ -4,9 +4,9 @@ test_description='test trace2 facility (perf target)' . ./test-lib.sh # Turn off any inherited trace2 settings for this test. -sane_unset GIT_TR2 GIT_TR2_PERF GIT_TR2_EVENT -sane_unset GIT_TR2_PERF_BRIEF -sane_unset GIT_TR2_CONFIG_PARAMS +sane_unset GIT_TRACE2 GIT_TRACE2_PERF GIT_TRACE2_EVENT +sane_unset GIT_TRACE2_PERF_BRIEF +sane_unset GIT_TRACE2_CONFIG_PARAMS # Add t/helper directory to PATH so that we can use a relative # path to run nested instances of test-tool.exe (see 004child). @@ -27,13 +27,13 @@ V=$(git version | sed -e 's/^git version //') && export V # to whatever filtering that target decides to do). # Test each target independently. # -# Defer setting GIT_TR2_PERF until the actual command we want to +# Defer setting GIT_TRACE2_PERF until the actual command we want to # test because hidden git and test-tool commands in the test # harness can contaminate our output. # Enable "brief" feature which turns off the prefix: # "<clock> <file>:<line> | <nr_parents> | " -GIT_TR2_PERF_BRIEF=1 && export GIT_TR2_PERF_BRIEF +GIT_TRACE2_PERF_BRIEF=1 && export GIT_TRACE2_PERF_BRIEF # Repeat some of the t0210 tests using the perf target stream instead of # the normal stream. @@ -46,7 +46,7 @@ GIT_TR2_PERF_BRIEF=1 && export GIT_TR2_PERF_BRIEF test_expect_success 'perf stream, return code 0' ' test_when_finished "rm trace.perf actual expect" && - GIT_TR2_PERF="$(pwd)/trace.perf" test-tool trace2 001return 0 && + GIT_TRACE2_PERF="$(pwd)/trace.perf" test-tool trace2 001return 0 && perl "$TEST_DIRECTORY/t0211/scrub_perf.perl" <trace.perf >actual && cat >expect <<-EOF && d0|main|version|||||$V @@ -60,7 +60,7 @@ test_expect_success 'perf stream, return code 0' ' test_expect_success 'perf stream, return code 1' ' test_when_finished "rm trace.perf actual expect" && - test_must_fail env GIT_TR2_PERF="$(pwd)/trace.perf" test-tool trace2 001return 1 && + test_must_fail env GIT_TRACE2_PERF="$(pwd)/trace.perf" test-tool trace2 001return 1 && perl "$TEST_DIRECTORY/t0211/scrub_perf.perl" <trace.perf >actual && cat >expect <<-EOF && d0|main|version|||||$V @@ -78,7 +78,7 @@ test_expect_success 'perf stream, return code 1' ' test_expect_success 'perf stream, error event' ' test_when_finished "rm trace.perf actual expect" && - GIT_TR2_PERF="$(pwd)/trace.perf" test-tool trace2 003error "hello world" "this is a test" && + GIT_TRACE2_PERF="$(pwd)/trace.perf" test-tool trace2 003error "hello world" "this is a test" && perl "$TEST_DIRECTORY/t0211/scrub_perf.perl" <trace.perf >actual && cat >expect <<-EOF && d0|main|version|||||$V @@ -124,7 +124,7 @@ test_expect_success 'perf stream, error event' ' test_expect_success 'perf stream, child processes' ' test_when_finished "rm trace.perf actual expect" && - GIT_TR2_PERF="$(pwd)/trace.perf" test-tool trace2 004child test-tool trace2 004child test-tool trace2 001return 0 && + GIT_TRACE2_PERF="$(pwd)/trace.perf" test-tool trace2 004child test-tool trace2 004child test-tool trace2 001return 0 && perl "$TEST_DIRECTORY/t0211/scrub_perf.perl" <trace.perf >actual && cat >expect <<-EOF && d0|main|version|||||$V @@ -150,7 +150,7 @@ test_expect_success 'perf stream, child processes' ' test_cmp expect actual ' -sane_unset GIT_TR2_PERF_BRIEF +sane_unset GIT_TRACE2_PERF_BRIEF # Now test without environment variables and get all Trace2 settings # from the global config. diff --git a/t/t0212-trace2-event.sh b/t/t0212-trace2-event.sh index 59adae8123..ff5b9cc729 100755 --- a/t/t0212-trace2-event.sh +++ b/t/t0212-trace2-event.sh @@ -4,9 +4,9 @@ test_description='test trace2 facility' . ./test-lib.sh # Turn off any inherited trace2 settings for this test. -sane_unset GIT_TR2 GIT_TR2_PERF GIT_TR2_EVENT -sane_unset GIT_TR2_BARE -sane_unset GIT_TR2_CONFIG_PARAMS +sane_unset GIT_TRACE2 GIT_TRACE2_PERF GIT_TRACE2_EVENT +sane_unset GIT_TRACE2_BARE +sane_unset GIT_TRACE2_CONFIG_PARAMS perl -MJSON::PP -e 0 >/dev/null 2>&1 && test_set_prereq JSON_PP @@ -29,7 +29,7 @@ V=$(git version | sed -e 's/^git version //') && export V # to whatever filtering that target decides to do). # Test each target independently. # -# Defer setting GIT_TR2_PERF until the actual command we want to +# Defer setting GIT_TRACE2_PERF until the actual command we want to # test because hidden git and test-tool commands in the test # harness can contaminate our output. @@ -42,7 +42,7 @@ V=$(git version | sed -e 's/^git version //') && export V test_expect_success JSON_PP 'event stream, error event' ' test_when_finished "rm trace.event actual expect" && - GIT_TR2_EVENT="$(pwd)/trace.event" test-tool trace2 003error "hello world" "this is a test" && + GIT_TRACE2_EVENT="$(pwd)/trace.event" test-tool trace2 003error "hello world" "this is a test" && perl "$TEST_DIRECTORY/t0212/parse_events.perl" <trace.event >actual && sed -e "s/^|//" >expect <<-EOF && |VAR1 = { @@ -79,7 +79,7 @@ test_expect_success JSON_PP 'event stream, error event' ' test_expect_success JSON_PP 'event stream, return code 0' ' test_when_finished "rm trace.event actual expect" && - GIT_TR2_EVENT="$(pwd)/trace.event" test-tool trace2 004child test-tool trace2 004child test-tool trace2 001return 0 && + GIT_TRACE2_EVENT="$(pwd)/trace.event" test-tool trace2 004child test-tool trace2 004child test-tool trace2 001return 0 && perl "$TEST_DIRECTORY/t0212/parse_events.perl" <trace.event >actual && sed -e "s/^|//" >expect <<-EOF && |VAR1 = { @@ -168,7 +168,7 @@ test_expect_success JSON_PP 'event stream, list config' ' test_when_finished "rm trace.event actual expect" && git config --local t0212.abc 1 && git config --local t0212.def "hello world" && - GIT_TR2_EVENT="$(pwd)/trace.event" GIT_TR2_CONFIG_PARAMS="t0212.*" test-tool trace2 001return 0 && + GIT_TRACE2_EVENT="$(pwd)/trace.event" GIT_TRACE2_CONFIG_PARAMS="t0212.*" test-tool trace2 001return 0 && perl "$TEST_DIRECTORY/t0212/parse_events.perl" <trace.event >actual && sed -e "s/^|//" >expect <<-EOF && |VAR1 = { @@ -201,7 +201,7 @@ test_expect_success JSON_PP 'event stream, list config' ' test_expect_success JSON_PP 'basic trace2_data' ' test_when_finished "rm trace.event actual expect" && - GIT_TR2_EVENT="$(pwd)/trace.event" test-tool trace2 006data test_category k1 v1 test_category k2 v2 && + GIT_TRACE2_EVENT="$(pwd)/trace.event" test-tool trace2 006data test_category k1 v1 test_category k2 v2 && perl "$TEST_DIRECTORY/t0212/parse_events.perl" <trace.event >actual && sed -e "s/^|//" >expect <<-EOF && |VAR1 = { diff --git a/t/t0212/parse_events.perl b/t/t0212/parse_events.perl index a2776ba216..6584bb5634 100644 --- a/t/t0212/parse_events.perl +++ b/t/t0212/parse_events.perl @@ -26,7 +26,7 @@ use Getopt::Long; # The version of the trace2 event target format that we understand. # This is reported in the 'version' event in the 'evt' field. -# It comes from the GIT_TR2_EVENT_VERSION macro in trace2/tr2_tgt_event.c +# It comes from the GIT_TRACE2_EVENT_VERSION macro in trace2/tr2_tgt_event.c my $evt_version = '1'; my $show_children = 1; diff --git a/t/t2018-checkout-branch.sh b/t/t2018-checkout-branch.sh index c5014ad9a6..822381dd9d 100755 --- a/t/t2018-checkout-branch.sh +++ b/t/t2018-checkout-branch.sh @@ -60,38 +60,47 @@ test_expect_success 'setup' ' ' test_expect_success 'checkout -b to a new branch, set to HEAD' ' + test_when_finished " + git checkout branch1 && + test_might_fail git branch -D branch2" && do_checkout branch2 ' -test_expect_success 'checkout -b to a new branch, set to an explicit ref' ' - git checkout branch1 && - git branch -D branch2 && +test_expect_success 'checkout -b to a merge base' ' + test_when_finished " + git checkout branch1 && + test_might_fail git branch -D branch2" && + git checkout -b branch2 branch1... +' +test_expect_success 'checkout -b to a new branch, set to an explicit ref' ' + test_when_finished " + git checkout branch1 && + test_might_fail git branch -D branch2" && do_checkout branch2 $HEAD1 ' test_expect_success 'checkout -b to a new branch with unmergeable changes fails' ' - git checkout branch1 && - - # clean up from previous test - git branch -D branch2 && - setup_dirty_unmergeable && test_must_fail do_checkout branch2 $HEAD1 && test_dirty_unmergeable ' test_expect_success 'checkout -f -b to a new branch with unmergeable changes discards changes' ' + test_when_finished " + git checkout branch1 && + test_might_fail git branch -D branch2" && + # still dirty and on branch1 do_checkout branch2 $HEAD1 "-f -b" && test_must_fail test_dirty_unmergeable ' test_expect_success 'checkout -b to a new branch preserves mergeable changes' ' - git checkout branch1 && - - # clean up from previous test - git branch -D branch2 && + test_when_finished " + git reset --hard && + git checkout branch1 && + test_might_fail git branch -D branch2" && setup_dirty_mergeable && do_checkout branch2 $HEAD1 && @@ -99,27 +108,18 @@ test_expect_success 'checkout -b to a new branch preserves mergeable changes' ' ' test_expect_success 'checkout -f -b to a new branch with mergeable changes discards changes' ' - # clean up from previous test - git reset --hard && - - git checkout branch1 && - - # clean up from previous test - git branch -D branch2 && - + test_when_finished git reset --hard HEAD && setup_dirty_mergeable && do_checkout branch2 $HEAD1 "-f -b" && test_must_fail test_dirty_mergeable ' test_expect_success 'checkout -b to an existing branch fails' ' - git reset --hard HEAD && - + test_when_finished git reset --hard HEAD && test_must_fail do_checkout branch2 $HEAD2 ' test_expect_success 'checkout -b to @{-1} fails with the right branch name' ' - git reset --hard HEAD && git checkout branch1 && git checkout branch2 && echo >expect "fatal: A branch named '\''branch1'\'' already exists." && @@ -133,6 +133,12 @@ test_expect_success 'checkout -B to an existing branch resets branch to HEAD' ' do_checkout branch2 "" -B ' +test_expect_success 'checkout -B to a merge base' ' + git checkout branch1 && + + git checkout -B branch2 branch1... +' + test_expect_success 'checkout -B to an existing branch from detached HEAD resets branch to HEAD' ' git checkout $(git rev-parse --verify HEAD) && @@ -160,6 +166,7 @@ test_expect_success 'checkout -f -B to an existing branch with unmergeable chang ' test_expect_success 'checkout -B to an existing branch preserves mergeable changes' ' + test_when_finished git reset --hard && git checkout branch1 && setup_dirty_mergeable && @@ -168,9 +175,6 @@ test_expect_success 'checkout -B to an existing branch preserves mergeable chang ' test_expect_success 'checkout -f -B to an existing branch with mergeable changes discards changes' ' - # clean up from previous test - git reset --hard && - git checkout branch1 && setup_dirty_mergeable && diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh index e9ad50b66d..e9d7084d19 100755 --- a/t/t3200-branch.sh +++ b/t/t3200-branch.sh @@ -42,6 +42,10 @@ test_expect_success 'git branch a/b/c should create a branch' ' git branch a/b/c && test_path_is_file .git/refs/heads/a/b/c ' +test_expect_success 'git branch mb master... should create a branch' ' + git branch mb master... && test_path_is_file .git/refs/heads/mb +' + test_expect_success 'git branch HEAD should fail' ' test_must_fail git branch HEAD ' @@ -316,8 +320,8 @@ test_expect_success 'git branch --list -v with --abbrev' ' test_expect_success 'git branch --column' ' COLUMNS=81 git branch --column=column >actual && cat >expected <<\EOF && - a/b/c bam foo l * master n o/p r - abc bar j/k m/m master2 o/o q + a/b/c bam foo l * master mb o/o q + abc bar j/k m/m master2 n o/p r EOF test_cmp expected actual ' @@ -339,6 +343,7 @@ test_expect_success 'git branch --column with an extremely long branch name' ' m/m * master master2 + mb n o/o o/p @@ -356,8 +361,8 @@ test_expect_success 'git branch with column.*' ' git config --unset column.branch && git config --unset column.ui && cat >expected <<\EOF && - a/b/c bam foo l * master n o/p r - abc bar j/k m/m master2 o/o q + a/b/c bam foo l * master mb o/o q + abc bar j/k m/m master2 n o/p r EOF test_cmp expected actual ' @@ -381,6 +386,7 @@ test_expect_success 'git branch -v with column.ui ignored' ' m/m * master master2 + mb n o/o o/p diff --git a/t/t3422-rebase-incompatible-options.sh b/t/t3422-rebase-incompatible-options.sh index bb78a6ec86..a5868ea152 100755 --- a/t/t3422-rebase-incompatible-options.sh +++ b/t/t3422-rebase-incompatible-options.sh @@ -65,12 +65,13 @@ test_rebase_am_only --ignore-whitespace test_rebase_am_only --committer-date-is-author-date test_rebase_am_only -C4 -test_expect_success '--preserve-merges incompatible with --signoff' ' +test_expect_success REBASE_P '--preserve-merges incompatible with --signoff' ' git checkout B^0 && test_must_fail git rebase --preserve-merges --signoff A ' -test_expect_success '--preserve-merges incompatible with --rebase-merges' ' +test_expect_success REBASE_P \ + '--preserve-merges incompatible with --rebase-merges' ' git checkout B^0 && test_must_fail git rebase --preserve-merges --rebase-merges A ' diff --git a/t/t3427-rebase-subtree.sh b/t/t3427-rebase-subtree.sh index 3780877e4e..d8640522a0 100755 --- a/t/t3427-rebase-subtree.sh +++ b/t/t3427-rebase-subtree.sh @@ -38,7 +38,8 @@ test_expect_success 'setup' ' ' # FAILURE: Does not preserve master4. -test_expect_failure 'Rebase -Xsubtree --preserve-merges --onto commit 4' ' +test_expect_failure REBASE_P \ + 'Rebase -Xsubtree --preserve-merges --onto commit 4' ' reset_rebase && git checkout -b rebase-preserve-merges-4 master && git filter-branch --prune-empty -f --subdirectory-filter files_subtree && @@ -48,7 +49,8 @@ test_expect_failure 'Rebase -Xsubtree --preserve-merges --onto commit 4' ' ' # FAILURE: Does not preserve master5. -test_expect_failure 'Rebase -Xsubtree --preserve-merges --onto commit 5' ' +test_expect_failure REBASE_P \ + 'Rebase -Xsubtree --preserve-merges --onto commit 5' ' reset_rebase && git checkout -b rebase-preserve-merges-5 master && git filter-branch --prune-empty -f --subdirectory-filter files_subtree && @@ -58,7 +60,8 @@ test_expect_failure 'Rebase -Xsubtree --preserve-merges --onto commit 5' ' ' # FAILURE: Does not preserve master4. -test_expect_failure 'Rebase -Xsubtree --keep-empty --preserve-merges --onto commit 4' ' +test_expect_failure REBASE_P \ + 'Rebase -Xsubtree --keep-empty --preserve-merges --onto commit 4' ' reset_rebase && git checkout -b rebase-keep-empty-4 master && git filter-branch --prune-empty -f --subdirectory-filter files_subtree && @@ -68,7 +71,8 @@ test_expect_failure 'Rebase -Xsubtree --keep-empty --preserve-merges --onto comm ' # FAILURE: Does not preserve master5. -test_expect_failure 'Rebase -Xsubtree --keep-empty --preserve-merges --onto commit 5' ' +test_expect_failure REBASE_P \ + 'Rebase -Xsubtree --keep-empty --preserve-merges --onto commit 5' ' reset_rebase && git checkout -b rebase-keep-empty-5 master && git filter-branch --prune-empty -f --subdirectory-filter files_subtree && @@ -78,7 +82,8 @@ test_expect_failure 'Rebase -Xsubtree --keep-empty --preserve-merges --onto comm ' # FAILURE: Does not preserve Empty. -test_expect_failure 'Rebase -Xsubtree --keep-empty --preserve-merges --onto empty commit' ' +test_expect_failure REBASE_P \ + 'Rebase -Xsubtree --keep-empty --preserve-merges --onto empty commit' ' reset_rebase && git checkout -b rebase-keep-empty-empty master && git filter-branch --prune-empty -f --subdirectory-filter files_subtree && diff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh index 9f8f0e84ad..a9054d2db1 100755 --- a/t/t4013-diff-various.sh +++ b/t/t4013-diff-various.sh @@ -338,6 +338,8 @@ format-patch --inline --stdout initial..master^^ format-patch --stdout --cover-letter -n initial..master^ diff --abbrev initial..side +diff -U initial..side +diff -U1 initial..side diff -r initial..side diff --stat initial..side diff -r --stat initial..side diff --git a/t/t4013/diff.diff_-U1_initial..side b/t/t4013/diff.diff_-U1_initial..side new file mode 100644 index 0000000000..b69f8f048a --- /dev/null +++ b/t/t4013/diff.diff_-U1_initial..side @@ -0,0 +1,29 @@ +$ git diff -U1 initial..side +diff --git a/dir/sub b/dir/sub +index 35d242b..7289e35 100644 +--- a/dir/sub ++++ b/dir/sub +@@ -2 +2,3 @@ A + B ++1 ++2 +diff --git a/file0 b/file0 +index 01e79c3..f4615da 100644 +--- a/file0 ++++ b/file0 +@@ -3 +3,4 @@ + 3 ++A ++B ++C +diff --git a/file3 b/file3 +new file mode 100644 +index 0000000..7289e35 +--- /dev/null ++++ b/file3 +@@ -0,0 +1,4 @@ ++A ++B ++1 ++2 +$ diff --git a/t/t4013/diff.diff_-U2_initial..side b/t/t4013/diff.diff_-U2_initial..side new file mode 100644 index 0000000000..8ffe04f203 --- /dev/null +++ b/t/t4013/diff.diff_-U2_initial..side @@ -0,0 +1,31 @@ +$ git diff -U2 initial..side +diff --git a/dir/sub b/dir/sub +index 35d242b..7289e35 100644 +--- a/dir/sub ++++ b/dir/sub +@@ -1,2 +1,4 @@ + A + B ++1 ++2 +diff --git a/file0 b/file0 +index 01e79c3..f4615da 100644 +--- a/file0 ++++ b/file0 +@@ -2,2 +2,5 @@ + 2 + 3 ++A ++B ++C +diff --git a/file3 b/file3 +new file mode 100644 +index 0000000..7289e35 +--- /dev/null ++++ b/file3 +@@ -0,0 +1,4 @@ ++A ++B ++1 ++2 +$ diff --git a/t/t4013/diff.diff_-U_initial..side b/t/t4013/diff.diff_-U_initial..side new file mode 100644 index 0000000000..c66c0dd5c6 --- /dev/null +++ b/t/t4013/diff.diff_-U_initial..side @@ -0,0 +1,32 @@ +$ git diff -U initial..side +diff --git a/dir/sub b/dir/sub +index 35d242b..7289e35 100644 +--- a/dir/sub ++++ b/dir/sub +@@ -1,2 +1,4 @@ + A + B ++1 ++2 +diff --git a/file0 b/file0 +index 01e79c3..f4615da 100644 +--- a/file0 ++++ b/file0 +@@ -1,3 +1,6 @@ + 1 + 2 + 3 ++A ++B ++C +diff --git a/file3 b/file3 +new file mode 100644 +index 0000000..7289e35 +--- /dev/null ++++ b/file3 +@@ -0,0 +1,4 @@ ++A ++B ++1 ++2 +$ diff --git a/t/t4253-am-keep-cr-dos.sh b/t/t4253-am-keep-cr-dos.sh index 553fe3e88e..6e1b73ec3a 100755 --- a/t/t4253-am-keep-cr-dos.sh +++ b/t/t4253-am-keep-cr-dos.sh @@ -51,14 +51,16 @@ test_expect_success 'am with dos files without --keep-cr' ' test_expect_success 'am with dos files with --keep-cr' ' git checkout -b dosfiles-keep-cr initial && - git format-patch -k --stdout initial..master | git am --keep-cr -k -3 && + git format-patch -k --stdout initial..master >output && + git am --keep-cr -k -3 output && git diff --exit-code master ' test_expect_success 'am with dos files config am.keepcr' ' git config am.keepcr 1 && git checkout -b dosfiles-conf-keepcr initial && - git format-patch -k --stdout initial..master | git am -k -3 && + git format-patch -k --stdout initial..master >output && + git am -k -3 output && git diff --exit-code master ' diff --git a/t/t5580-clone-push-unc.sh b/t/t5580-clone-push-unc.sh index 217adf3a63..b3c8a92450 100755 --- a/t/t5580-clone-push-unc.sh +++ b/t/t5580-clone-push-unc.sh @@ -62,4 +62,16 @@ test_expect_success MINGW 'remote nick cannot contain backslashes' ' test_i18ngrep ! "unable to access" err ' +test_expect_success 'unc alternates' ' + tree="$(git rev-parse HEAD:)" && + mkdir test-unc-alternate && + ( + cd test-unc-alternate && + git init && + test_must_fail git show $tree && + echo "$UNCPATH/.git/objects" >.git/objects/info/alternates && + git show $tree + ) +' + test_done diff --git a/t/t6500-gc.sh b/t/t6500-gc.sh index 7411bf7fec..515c6735e9 100755 --- a/t/t6500-gc.sh +++ b/t/t6500-gc.sh @@ -181,7 +181,15 @@ test_expect_success 'background auto gc respects lock for all operations' ' # now fake a concurrent gc that holds the lock; we can use our # shell pid so that it looks valid. hostname=$(hostname || echo unknown) && - printf "$$ %s" "$hostname" >.git/gc.pid && + shell_pid=$$ && + if test_have_prereq MINGW && test -f /proc/$shell_pid/winpid + then + # In Git for Windows, Bash (actually, the MSYS2 runtime) has a + # different idea of PIDs than git.exe (actually Windows). Use + # the Windows PID in this case. + shell_pid=$(cat /proc/$shell_pid/winpid) + fi && + printf "%d %s" "$shell_pid" "$hostname" >.git/gc.pid && # our gc should exit zero without doing anything run_and_wait_for_auto_gc && diff --git a/t/t7004-tag.sh b/t/t7004-tag.sh index e285686662..6aeeb279a0 100755 --- a/t/t7004-tag.sh +++ b/t/t7004-tag.sh @@ -1702,7 +1702,7 @@ test_expect_success '--points-at finds annotated tags of tags' ' test_expect_success 'recursive tagging should give advice' ' sed -e "s/|$//" <<-EOF >expect && - hint: You have created a nested tag. The object referred to by your new is + hint: You have created a nested tag. The object referred to by your new tag is hint: already a tag. If you meant to tag the object that it points to, use: hint: | hint: git tag -f nested annotated-v4.0^{} diff --git a/t/t7411-submodule-config.sh b/t/t7411-submodule-config.sh index fcc0fb82d8..ad28e93880 100755 --- a/t/t7411-submodule-config.sh +++ b/t/t7411-submodule-config.sh @@ -243,18 +243,14 @@ test_expect_success 'reading nested submodules config' ' ) ' -# When this test eventually passes, before turning it into -# test_expect_success, remember to replace the test_i18ngrep below with -# a "test_must_be_empty warning" to be sure that the warning is actually -# removed from the code. -test_expect_failure 'reading nested submodules config when .gitmodules is not in the working tree' ' +test_expect_success 'reading nested submodules config when .gitmodules is not in the working tree' ' test_when_finished "git -C super/submodule checkout .gitmodules" && (cd super && echo "./nested_submodule" >expect && rm submodule/.gitmodules && test-tool submodule-nested-repo-config \ submodule submodule.nested_submodule.url >actual 2>warning && - test_i18ngrep "nested submodules without %s in the working tree are not supported yet" warning && + test_must_be_empty warning && test_cmp expect actual ) ' diff --git a/t/t7519-status-fsmonitor.sh b/t/t7519-status-fsmonitor.sh index 3e0a61db23..81a375fa0f 100755 --- a/t/t7519-status-fsmonitor.sh +++ b/t/t7519-status-fsmonitor.sh @@ -346,4 +346,12 @@ test_expect_success UNTRACKED_CACHE 'ignore .git changes when invalidating UNTR' test_cmp before after ' +test_expect_success 'discard_index() also discards fsmonitor info' ' + test_config core.fsmonitor "$TEST_DIRECTORY/t7519/fsmonitor-all" && + test_might_fail git update-index --refresh && + test-tool read-cache --print-and-refresh=tracked 2 >actual && + printf "tracked is%s up to date\n" "" " not" >expect && + test_cmp expect actual +' + test_done diff --git a/t/t7610-mergetool.sh b/t/t7610-mergetool.sh index a9fb971615..5b61c10a9c 100755 --- a/t/t7610-mergetool.sh +++ b/t/t7610-mergetool.sh @@ -130,14 +130,55 @@ test_expect_success 'custom mergetool' ' test_when_finished "git reset --hard" && git checkout -b test$test_count branch1 && git submodule update -N && - test_must_fail git merge master >/dev/null 2>&1 && - ( yes "" | git mergetool both >/dev/null 2>&1 ) && + test_must_fail git merge master && + ( yes "" | git mergetool both ) && ( yes "" | git mergetool file1 file1 ) && - ( yes "" | git mergetool file2 "spaced name" >/dev/null 2>&1 ) && - ( yes "" | git mergetool subdir/file3 >/dev/null 2>&1 ) && - ( yes "d" | git mergetool file11 >/dev/null 2>&1 ) && - ( yes "d" | git mergetool file12 >/dev/null 2>&1 ) && - ( yes "l" | git mergetool submod >/dev/null 2>&1 ) && + ( yes "" | git mergetool file2 "spaced name" ) && + ( yes "" | git mergetool subdir/file3 ) && + ( yes "d" | git mergetool file11 ) && + ( yes "d" | git mergetool file12 ) && + ( yes "l" | git mergetool submod ) && + test "$(cat file1)" = "master updated" && + test "$(cat file2)" = "master new" && + test "$(cat subdir/file3)" = "master new sub" && + test "$(cat submod/bar)" = "branch1 submodule" && + git commit -m "branch1 resolved with mergetool" +' + +test_expect_success 'gui mergetool' ' + test_config merge.guitool myguitool && + test_config mergetool.myguitool.cmd "(printf \"gui \" && cat \"\$REMOTE\") >\"\$MERGED\"" && + test_config mergetool.myguitool.trustExitCode true && + test_when_finished "git reset --hard" && + git checkout -b test$test_count branch1 && + git submodule update -N && + test_must_fail git merge master && + ( yes "" | git mergetool --gui both ) && + ( yes "" | git mergetool -g file1 file1 ) && + ( yes "" | git mergetool --gui file2 "spaced name" ) && + ( yes "" | git mergetool --gui subdir/file3 ) && + ( yes "d" | git mergetool --gui file11 ) && + ( yes "d" | git mergetool --gui file12 ) && + ( yes "l" | git mergetool --gui submod ) && + test "$(cat file1)" = "gui master updated" && + test "$(cat file2)" = "gui master new" && + test "$(cat subdir/file3)" = "gui master new sub" && + test "$(cat submod/bar)" = "branch1 submodule" && + git commit -m "branch1 resolved with mergetool" +' + +test_expect_success 'gui mergetool without merge.guitool set falls back to merge.tool' ' + test_when_finished "git reset --hard" && + git checkout -b test$test_count branch1 && + git submodule update -N && + test_must_fail git merge master && + ( yes "" | git mergetool --gui both ) && + ( yes "" | git mergetool -g file1 file1 ) && + ( yes "" | git mergetool --gui file2 "spaced name" ) && + ( yes "" | git mergetool --gui subdir/file3 ) && + ( yes "d" | git mergetool --gui file11 ) && + ( yes "d" | git mergetool --gui file12 ) && + ( yes "l" | git mergetool --gui submod ) && test "$(cat file1)" = "master updated" && test "$(cat file2)" = "master new" && test "$(cat subdir/file3)" = "master new sub" && @@ -153,15 +194,15 @@ test_expect_success 'mergetool crlf' ' # test_when_finished is LIFO.) test_config core.autocrlf true && git checkout -b test$test_count branch1 && - test_must_fail git merge master >/dev/null 2>&1 && - ( yes "" | git mergetool file1 >/dev/null 2>&1 ) && - ( yes "" | git mergetool file2 >/dev/null 2>&1 ) && - ( yes "" | git mergetool "spaced name" >/dev/null 2>&1 ) && - ( yes "" | git mergetool both >/dev/null 2>&1 ) && - ( yes "" | git mergetool subdir/file3 >/dev/null 2>&1 ) && - ( yes "d" | git mergetool file11 >/dev/null 2>&1 ) && - ( yes "d" | git mergetool file12 >/dev/null 2>&1 ) && - ( yes "r" | git mergetool submod >/dev/null 2>&1 ) && + test_must_fail git merge master && + ( yes "" | git mergetool file1 ) && + ( yes "" | git mergetool file2 ) && + ( yes "" | git mergetool "spaced name" ) && + ( yes "" | git mergetool both ) && + ( yes "" | git mergetool subdir/file3 ) && + ( yes "d" | git mergetool file11 ) && + ( yes "d" | git mergetool file12 ) && + ( yes "r" | git mergetool submod ) && test "$(printf x | cat file1 -)" = "$(printf "master updated\r\nx")" && test "$(printf x | cat file2 -)" = "$(printf "master new\r\nx")" && test "$(printf x | cat subdir/file3 -)" = "$(printf "master new sub\r\nx")" && @@ -176,8 +217,8 @@ test_expect_success 'mergetool in subdir' ' git submodule update -N && ( cd subdir && - test_must_fail git merge master >/dev/null 2>&1 && - ( yes "" | git mergetool file3 >/dev/null 2>&1 ) && + test_must_fail git merge master && + ( yes "" | git mergetool file3 ) && test "$(cat file3)" = "master new sub" ) ' @@ -188,14 +229,14 @@ test_expect_success 'mergetool on file in parent dir' ' git submodule update -N && ( cd subdir && - test_must_fail git merge master >/dev/null 2>&1 && - ( yes "" | git mergetool file3 >/dev/null 2>&1 ) && - ( yes "" | git mergetool ../file1 >/dev/null 2>&1 ) && - ( yes "" | git mergetool ../file2 ../spaced\ name >/dev/null 2>&1 ) && - ( yes "" | git mergetool ../both >/dev/null 2>&1 ) && - ( yes "d" | git mergetool ../file11 >/dev/null 2>&1 ) && - ( yes "d" | git mergetool ../file12 >/dev/null 2>&1 ) && - ( yes "l" | git mergetool ../submod >/dev/null 2>&1 ) && + test_must_fail git merge master && + ( yes "" | git mergetool file3 ) && + ( yes "" | git mergetool ../file1 ) && + ( yes "" | git mergetool ../file2 ../spaced\ name ) && + ( yes "" | git mergetool ../both ) && + ( yes "d" | git mergetool ../file11 ) && + ( yes "d" | git mergetool ../file12 ) && + ( yes "l" | git mergetool ../submod ) && test "$(cat ../file1)" = "master updated" && test "$(cat ../file2)" = "master new" && test "$(cat ../submod/bar)" = "branch1 submodule" && @@ -209,9 +250,9 @@ test_expect_success 'mergetool skips autoresolved' ' git submodule update -N && test_must_fail git merge master && test -n "$(git ls-files -u)" && - ( yes "d" | git mergetool file11 >/dev/null 2>&1 ) && - ( yes "d" | git mergetool file12 >/dev/null 2>&1 ) && - ( yes "l" | git mergetool submod >/dev/null 2>&1 ) && + ( yes "d" | git mergetool file11 ) && + ( yes "d" | git mergetool file12 ) && + ( yes "l" | git mergetool submod ) && output="$(git mergetool --no-prompt)" && test "$output" = "No files need merging" ' @@ -259,9 +300,9 @@ test_expect_success 'mergetool skips resolved paths when rerere is active' ' rm -rf .git/rr-cache && git checkout -b test$test_count branch1 && git submodule update -N && - test_must_fail git merge master >/dev/null 2>&1 && - ( yes "l" | git mergetool --no-prompt submod >/dev/null 2>&1 ) && - ( yes "d" "d" | git mergetool --no-prompt >/dev/null 2>&1 ) && + test_must_fail git merge master && + ( yes "l" | git mergetool --no-prompt submod ) && + ( yes "d" "d" | git mergetool --no-prompt ) && git submodule update -N && output="$(yes "n" | git mergetool --no-prompt)" && test "$output" = "No files need merging" @@ -369,9 +410,9 @@ test_expect_success 'deleted vs modified submodule' ' git checkout -b test$test_count.a test$test_count && test_must_fail git merge master && test -n "$(git ls-files -u)" && - ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) && - ( yes "" | git mergetool both >/dev/null 2>&1 ) && - ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) && + ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 ) && + ( yes "" | git mergetool both ) && + ( yes "d" | git mergetool file11 file12 ) && ( yes "r" | git mergetool submod ) && rmdir submod && mv submod-movedaside submod && test "$(cat submod/bar)" = "branch1 submodule" && @@ -386,9 +427,9 @@ test_expect_success 'deleted vs modified submodule' ' git submodule update -N && test_must_fail git merge master && test -n "$(git ls-files -u)" && - ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) && - ( yes "" | git mergetool both >/dev/null 2>&1 ) && - ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) && + ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 ) && + ( yes "" | git mergetool both ) && + ( yes "d" | git mergetool file11 file12 ) && ( yes "l" | git mergetool submod ) && test ! -e submod && output="$(git mergetool --no-prompt)" && @@ -400,9 +441,9 @@ test_expect_success 'deleted vs modified submodule' ' git submodule update -N && test_must_fail git merge test$test_count && test -n "$(git ls-files -u)" && - ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) && - ( yes "" | git mergetool both >/dev/null 2>&1 ) && - ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) && + ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 ) && + ( yes "" | git mergetool both ) && + ( yes "d" | git mergetool file11 file12 ) && ( yes "r" | git mergetool submod ) && test ! -e submod && test -d submod.orig && @@ -416,9 +457,9 @@ test_expect_success 'deleted vs modified submodule' ' git submodule update -N && test_must_fail git merge test$test_count && test -n "$(git ls-files -u)" && - ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) && - ( yes "" | git mergetool both >/dev/null 2>&1 ) && - ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) && + ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 ) && + ( yes "" | git mergetool both ) && + ( yes "d" | git mergetool file11 file12 ) && ( yes "l" | git mergetool submod ) && test "$(cat submod/bar)" = "master submodule" && git submodule update -N && @@ -440,9 +481,9 @@ test_expect_success 'file vs modified submodule' ' git checkout -b test$test_count.a branch1 && test_must_fail git merge master && test -n "$(git ls-files -u)" && - ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) && - ( yes "" | git mergetool both >/dev/null 2>&1 ) && - ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) && + ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 ) && + ( yes "" | git mergetool both ) && + ( yes "d" | git mergetool file11 file12 ) && ( yes "r" | git mergetool submod ) && rmdir submod && mv submod-movedaside submod && test "$(cat submod/bar)" = "branch1 submodule" && @@ -456,9 +497,9 @@ test_expect_success 'file vs modified submodule' ' git checkout -b test$test_count.b test$test_count && test_must_fail git merge master && test -n "$(git ls-files -u)" && - ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) && - ( yes "" | git mergetool both >/dev/null 2>&1 ) && - ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) && + ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 ) && + ( yes "" | git mergetool both ) && + ( yes "d" | git mergetool file11 file12 ) && ( yes "l" | git mergetool submod ) && git submodule update -N && test "$(cat submod)" = "not a submodule" && @@ -472,9 +513,9 @@ test_expect_success 'file vs modified submodule' ' git submodule update -N && test_must_fail git merge test$test_count && test -n "$(git ls-files -u)" && - ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) && - ( yes "" | git mergetool both >/dev/null 2>&1 ) && - ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) && + ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 ) && + ( yes "" | git mergetool both ) && + ( yes "d" | git mergetool file11 file12 ) && ( yes "r" | git mergetool submod ) && test -d submod.orig && git submodule update -N && @@ -488,9 +529,9 @@ test_expect_success 'file vs modified submodule' ' git submodule update -N && test_must_fail git merge test$test_count && test -n "$(git ls-files -u)" && - ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) && - ( yes "" | git mergetool both>/dev/null 2>&1 ) && - ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) && + ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 ) && + ( yes "" | git mergetool both ) && + ( yes "d" | git mergetool file11 file12 ) && ( yes "l" | git mergetool submod ) && test "$(cat submod/bar)" = "master submodule" && git submodule update -N && @@ -543,7 +584,7 @@ test_expect_success 'submodule in subdirectory' ' git add subdir/subdir_module && git commit -m "change submodule in subdirectory on test$test_count.b" && - test_must_fail git merge test$test_count.a >/dev/null 2>&1 && + test_must_fail git merge test$test_count.a && ( cd subdir && ( yes "l" | git mergetool subdir_module ) @@ -554,7 +595,7 @@ test_expect_success 'submodule in subdirectory' ' git reset --hard && git submodule update -N && - test_must_fail git merge test$test_count.a >/dev/null 2>&1 && + test_must_fail git merge test$test_count.a && ( yes "r" | git mergetool subdir/subdir_module ) && test "$(cat subdir/subdir_module/file15)" = "test$test_count.b" && git submodule update -N && @@ -641,7 +682,7 @@ test_expect_success 'filenames seen by tools start with ./' ' test_config mergetool.myecho.trustExitCode true && test_must_fail git merge master && git mergetool --no-prompt --tool myecho -- both >actual && - grep ^\./both_LOCAL_ actual >/dev/null + grep ^\./both_LOCAL_ actual ' test_lazy_prereq MKTEMP ' @@ -658,8 +699,8 @@ test_expect_success MKTEMP 'temporary filenames are used with mergetool.writeToT test_config mergetool.myecho.trustExitCode true && test_must_fail git merge master && git mergetool --no-prompt --tool myecho -- both >actual && - ! grep ^\./both_LOCAL_ actual >/dev/null && - grep /both_LOCAL_ actual >/dev/null + ! grep ^\./both_LOCAL_ actual && + grep /both_LOCAL_ actual ' test_expect_success 'diff.orderFile configuration is honored' ' diff --git a/t/t7800-difftool.sh b/t/t7800-difftool.sh index 480dd0633f..6bac9ed180 100755 --- a/t/t7800-difftool.sh +++ b/t/t7800-difftool.sh @@ -279,11 +279,27 @@ test_expect_success 'difftool + mergetool config variables' ' echo branch >expect && git difftool --no-prompt branch >actual && test_cmp expect actual && + git difftool --gui --no-prompt branch >actual && + test_cmp expect actual && # set merge.tool to something bogus, diff.tool to test-tool test_config merge.tool bogus-tool && test_config diff.tool test-tool && git difftool --no-prompt branch >actual && + test_cmp expect actual && + git difftool --gui --no-prompt branch >actual && + test_cmp expect actual && + + # set merge.tool, diff.tool to something bogus, merge.guitool to test-tool + test_config diff.tool bogus-tool && + test_config merge.guitool test-tool && + git difftool --gui --no-prompt branch >actual && + test_cmp expect actual && + + # set merge.tool, diff.tool, merge.guitool to something bogus, diff.guitool to test-tool + test_config merge.guitool bogus-tool && + test_config diff.guitool test-tool && + git difftool --gui --no-prompt branch >actual && test_cmp expect actual ' @@ -715,4 +731,12 @@ test_expect_success 'outside worktree' ' test_cmp expect actual ' +test_expect_success 'difftool --gui, --tool and --extcmd are mutually exclusive' ' + difftool_test_setup && + test_must_fail git difftool --gui --tool=test-tool && + test_must_fail git difftool --gui --extcmd=cat && + test_must_fail git difftool --tool=test-tool --extcmd=cat && + test_must_fail git difftool --gui --tool=test-tool --extcmd=cat +' + test_done diff --git a/t/test-lib.sh b/t/test-lib.sh index 908ddb9c46..599fd70e14 100644 --- a/t/test-lib.sh +++ b/t/test-lib.sh @@ -1522,7 +1522,7 @@ test_lazy_prereq NOT_ROOT ' ' test_lazy_prereq JGIT ' - type jgit + jgit --version ' # SANITY is about "can you correctly predict what the filesystem would @@ -130,7 +130,7 @@ void trace2_cmd_alias_fl(const char *file, int line, const char *alias, * list of patterns configured important. For example: * git config --system trace2.configParams 'core.*,remote.*.url' * or: - * GIT_TR2_CONFIG_PARAMS=core.*,remote.*.url" + * GIT_TRACE2_CONFIG_PARAMS=core.*,remote.*.url" * * Note: this routine does a read-only iteration on the config data * (using read_early_config()), so it must not be called until enough diff --git a/trace2/tr2_cmd_name.c b/trace2/tr2_cmd_name.c index e999592b4c..dd313204f5 100644 --- a/trace2/tr2_cmd_name.c +++ b/trace2/tr2_cmd_name.c @@ -1,7 +1,7 @@ #include "cache.h" #include "trace2/tr2_cmd_name.h" -#define TR2_ENVVAR_PARENT_NAME "GIT_TR2_PARENT_NAME" +#define TR2_ENVVAR_PARENT_NAME "GIT_TRACE2_PARENT_NAME" static struct strbuf tr2cmdname_hierarchy = STRBUF_INIT; diff --git a/trace2/tr2_sid.c b/trace2/tr2_sid.c index 5047095478..6948fd4108 100644 --- a/trace2/tr2_sid.c +++ b/trace2/tr2_sid.c @@ -2,7 +2,7 @@ #include "trace2/tr2_tbuf.h" #include "trace2/tr2_sid.h" -#define TR2_ENVVAR_PARENT_SID "GIT_TR2_PARENT_SID" +#define TR2_ENVVAR_PARENT_SID "GIT_TRACE2_PARENT_SID" static struct strbuf tr2sid_buf = STRBUF_INIT; static int tr2sid_nr_git_parents; diff --git a/trace2/tr2_sysenv.c b/trace2/tr2_sysenv.c index 9025b86303..5958cfc424 100644 --- a/trace2/tr2_sysenv.c +++ b/trace2/tr2_sysenv.c @@ -21,33 +21,33 @@ struct tr2_sysenv_entry { * The strings in this table are constant and must match the published * config and environment variable names as described in the documentation. * - * We do not define entries for the GIT_TR2_PARENT_* environment + * We do not define entries for the GIT_TRACE2_PARENT_* environment * variables because they are transient and used to pass information * from parent to child git processes, rather than settings. */ /* clang-format off */ static struct tr2_sysenv_entry tr2_sysenv_settings[] = { - [TR2_SYSENV_CFG_PARAM] = { "GIT_TR2_CONFIG_PARAMS", + [TR2_SYSENV_CFG_PARAM] = { "GIT_TRACE2_CONFIG_PARAMS", "trace2.configparams" }, - [TR2_SYSENV_DST_DEBUG] = { "GIT_TR2_DST_DEBUG", + [TR2_SYSENV_DST_DEBUG] = { "GIT_TRACE2_DST_DEBUG", "trace2.destinationdebug" }, - [TR2_SYSENV_NORMAL] = { "GIT_TR2", + [TR2_SYSENV_NORMAL] = { "GIT_TRACE2", "trace2.normaltarget" }, - [TR2_SYSENV_NORMAL_BRIEF] = { "GIT_TR2_BRIEF", + [TR2_SYSENV_NORMAL_BRIEF] = { "GIT_TRACE2_BRIEF", "trace2.normalbrief" }, - [TR2_SYSENV_EVENT] = { "GIT_TR2_EVENT", + [TR2_SYSENV_EVENT] = { "GIT_TRACE2_EVENT", "trace2.eventtarget" }, - [TR2_SYSENV_EVENT_BRIEF] = { "GIT_TR2_EVENT_BRIEF", + [TR2_SYSENV_EVENT_BRIEF] = { "GIT_TRACE2_EVENT_BRIEF", "trace2.eventbrief" }, - [TR2_SYSENV_EVENT_NESTING] = { "GIT_TR2_EVENT_NESTING", + [TR2_SYSENV_EVENT_NESTING] = { "GIT_TRACE2_EVENT_NESTING", "trace2.eventnesting" }, - [TR2_SYSENV_PERF] = { "GIT_TR2_PERF", + [TR2_SYSENV_PERF] = { "GIT_TRACE2_PERF", "trace2.perftarget" }, - [TR2_SYSENV_PERF_BRIEF] = { "GIT_TR2_PERF_BRIEF", + [TR2_SYSENV_PERF_BRIEF] = { "GIT_TRACE2_PERF_BRIEF", "trace2.perfbrief" }, }; /* clang-format on */ diff --git a/trace2/tr2_sysenv.h b/trace2/tr2_sysenv.h index 369b20bd87..8dd82a7a56 100644 --- a/trace2/tr2_sysenv.h +++ b/trace2/tr2_sysenv.h @@ -7,7 +7,7 @@ * * Note that this set does not contain any of the transient * environment variables used to pass information from parent - * to child git processes, such "GIT_TR2_PARENT_SID". + * to child git processes, such "GIT_TRACE2_PARENT_SID". */ enum tr2_sysenv_variable { TR2_SYSENV_CFG_PARAM = 0, diff --git a/trace2/tr2_tls.c b/trace2/tr2_tls.c index e76d8c5d92..067c23755f 100644 --- a/trace2/tr2_tls.c +++ b/trace2/tr2_tls.c @@ -61,7 +61,12 @@ struct tr2tls_thread_ctx *tr2tls_create_self(const char *thread_name, struct tr2tls_thread_ctx *tr2tls_get_self(void) { - struct tr2tls_thread_ctx *ctx = pthread_getspecific(tr2tls_key); + struct tr2tls_thread_ctx *ctx; + + if (!HAVE_THREADS) + return tr2tls_thread_main; + + ctx = pthread_getspecific(tr2tls_key); /* * If the thread-proc did not call trace2_thread_start(), we won't @@ -76,9 +81,10 @@ struct tr2tls_thread_ctx *tr2tls_get_self(void) int tr2tls_is_main_thread(void) { - struct tr2tls_thread_ctx *ctx = pthread_getspecific(tr2tls_key); + if (!HAVE_THREADS) + return 1; - return ctx == tr2tls_thread_main; + return pthread_getspecific(tr2tls_key) == tr2tls_thread_main; } void tr2tls_unset_self(void) diff --git a/upload-pack.c b/upload-pack.c index d2ea5eb20d..24298913c0 100644 --- a/upload-pack.c +++ b/upload-pack.c @@ -1069,6 +1069,8 @@ static int upload_pack_config(const char *var, const char *value, void *unused) allow_ref_in_want = git_config_bool(var, value); } else if (!strcmp("uploadpack.allowsidebandall", var)) { allow_sideband_all = git_config_bool(var, value); + } else if (!strcmp("core.precomposeunicode", var)) { + precomposed_unicode = git_config_bool(var, value); } if (current_config_scope() != CONFIG_SCOPE_REPO) { diff --git a/wt-status.c b/wt-status.c index e065558c31..d2a1bec226 100644 --- a/wt-status.c +++ b/wt-status.c @@ -1215,7 +1215,9 @@ static void abbrev_sha1_in_line(struct strbuf *line) int i; if (starts_with(line->buf, "exec ") || - starts_with(line->buf, "x ")) + starts_with(line->buf, "x ") || + starts_with(line->buf, "label ") || + starts_with(line->buf, "l ")) return; split = strbuf_split_max(line, ' ', 3); |