diff options
278 files changed, 3531 insertions, 2493 deletions
diff --git a/Documentation/Makefile b/Documentation/Makefile index ecd0b340b1..80d1908a44 100644 --- a/Documentation/Makefile +++ b/Documentation/Makefile @@ -17,6 +17,7 @@ MAN1_TXT += git.txt MAN1_TXT += gitk.txt MAN1_TXT += gitweb.txt +# man5 / man7 guides (note: new guides should also be added to command-list.txt) MAN5_TXT += gitattributes.txt MAN5_TXT += githooks.txt MAN5_TXT += gitignore.txt @@ -294,6 +295,7 @@ cmds_txt = cmds-ancillaryinterrogators.txt \ cmds-plumbingmanipulators.txt \ cmds-synchingrepositories.txt \ cmds-synchelpers.txt \ + cmds-guide.txt \ cmds-purehelpers.txt \ cmds-foreignscminterface.txt @@ -301,7 +303,7 @@ $(cmds_txt): cmd-list.made cmd-list.made: cmd-list.perl ../command-list.txt $(MAN1_TXT) $(QUIET_GEN)$(RM) $@ && \ - $(PERL_PATH) ./cmd-list.perl ../command-list.txt $(QUIET_STDERR) && \ + $(PERL_PATH) ./cmd-list.perl ../command-list.txt $(cmds_txt) $(QUIET_STDERR) && \ date >$@ mergetools_txt = mergetools-diff.txt mergetools-merge.txt diff --git a/Documentation/RelNotes/2.29.0.txt b/Documentation/RelNotes/2.29.0.txt new file mode 100644 index 0000000000..d185557287 --- /dev/null +++ b/Documentation/RelNotes/2.29.0.txt @@ -0,0 +1,106 @@ +Git 2.29 Release Notes +====================== + +Updates since v2.28 +------------------- + +UI, Workflows & Features + + * "git help log" has been enhanced by sharing more material from the + documentation for the underlying "git rev-list" command. + + * "git for-each-ref --format=<>" learned %(contents:size). + + * "git merge" learned to selectively omit " into <branch>" at the end + of the title of default merge message with merge.suppressDest + configuration. + + +Performance, Internal Implementation, Development Support etc. + + * The changed-path Bloom filter is improved using ideas from an + independent implementation. + + * Updates to the changed-paths bloom filter. + + * The test framework has been updated so that most tests will run + with predictable (artificial) timestamps. + + * Preliminary clean-up of the refs API in preparation for adding a + new refs backend "reftable". + + * Dev support to limit the use of test_must_fail to only git commands. + + * While packing many objects in a repository with a promissor remote, + lazily fetching missing objects from the promissor remote one by + one may be inefficient---the code now attempts to fetch all the + missing objects in batch (obviously this won't work for a lazy + clone that lazily fetches tree objects as you cannot even enumerate + what blobs are missing until you learn which trees are missing). + + * The pretend-object mechanism checks if the given object already + exists in the object store before deciding to keep the data + in-core, but the check would have triggered lazy fetching of such + an object from a promissor remote. + + * The argv_array API is useful for not just managing argv but any + "vector" (NULL-terminated array) of strings, and has seen adoption + to a certain degree. It has been renamed to "strvec" to reduce the + barrier to adoption. + + +Fixes since v2.28 +----------------- + + * "git clone --separate-git-dir=$elsewhere" used to stomp on the + contents of the existing directory $elsewhere, which has been + taught to fail when $elsewhere is not an empty directory. + (merge dfaa209a79 bw/fail-cloning-into-non-empty later to maint). + + * With the base fix to 2.27 regresion, any new extensions in a v0 + repository would still be silently honored, which is not quite + right. Instead, complain and die loudly. + (merge ec91ffca04 jk/reject-newer-extensions-in-v0 later to maint). + + * Fetching from a lazily cloned repository resulted at the server + side in attempts to lazy fetch objects that the client side has, + many of which will not be available from the third-party anyway. + (merge 77aa0941ce jt/avoid-lazy-fetching-upon-have-check later to maint). + + * Fix to an ancient bug caused by an over-eager attempt for + optimization. + (merge a98f7fb366 rs/add-index-entry-optim-fix later to maint). + + * Pushing a ref whose name contains non-ASCII character with the + "--force-with-lease" option did not work over smart HTTP protocol, + which has been corrected. + (merge cd85b447bf bc/push-cas-cquoted-refname later to maint). + + * "git mv src dst", when src is an unmerged path, errored out + correctly but with an incorrect error message to claim that src is + not tracked, which has been clarified. + (merge 9b906af657 ct/mv-unmerged-path-error later to maint). + + * Fix to a regression introduced during 2.27 cycle. + (merge cada7308ad en/fill-directory-exponential later to maint). + + * Command line completion (in contrib/) update. + (merge 688b87c81b mp/complete-show-color-moved later to maint). + + * All "mergy" operations that internally use the merge-recursive + machinery should honor the merge.renormalize configuration, but + many of them didn't. + + * Other code cleanup, docfix, build fix, etc. + (merge 84544f2ea3 sk/typofixes later to maint). + (merge b17f411ab5 ar/help-guides-doc later to maint). + (merge 98c6871fad rs/grep-simpler-parse-object-or-die-call later to maint). + (merge 861c4ce141 en/typofixes later to maint). + (merge 60e47f6773 sg/ci-git-path-fix-with-pyenv later to maint). + (merge e2bfa50ac3 jb/doc-packfile-name later to maint). + (merge 918d8ff780 es/worktree-cleanup later to maint). + (merge dc156bc31f ma/t1450-quotefix later to maint). + (merge 56e743426b en/merge-recursive-comment-fixes later to maint). + (merge 7d23ff818f rs/bisect-oid-to-hex-fix later to maint). + (merge de20baf2c9 ny/notes-doc-sample-update later to maint). + (merge f649aaaf82 so/rev-parser-errormessage-fix later to maint). diff --git a/Documentation/cmd-list.perl b/Documentation/cmd-list.perl index 5aa73cfe45..af5da45d28 100755 --- a/Documentation/cmd-list.perl +++ b/Documentation/cmd-list.perl @@ -6,9 +6,14 @@ sub format_one { my ($out, $nameattr) = @_; my ($name, $attr) = @$nameattr; my ($state, $description); + my $mansection; $state = 0; open I, '<', "$name.txt" or die "No such file $name.txt"; while (<I>) { + if (/^git[a-z0-9-]*\(([0-9])\)$/) { + $mansection = $1; + next; + } if (/^NAME$/) { $state = 1; next; @@ -27,7 +32,7 @@ sub format_one { die "No description found in $name.txt"; } if (my ($verify_name, $text) = ($description =~ /^($name) - (.*)/)) { - print $out "linkgit:$name\[1\]::\n\t"; + print $out "linkgit:$name\[$mansection\]::\n\t"; if ($attr =~ / deprecated /) { print $out "(deprecated) "; } @@ -38,12 +43,15 @@ sub format_one { } } -while (<>) { +my ($input, @categories) = @ARGV; + +open IN, "<$input"; +while (<IN>) { last if /^### command list/; } my %cmds = (); -for (sort <>) { +for (sort <IN>) { next if /^#/; chomp; @@ -51,17 +59,10 @@ for (sort <>) { $attr = '' unless defined $attr; push @{$cmds{$cat}}, [$name, " $attr "]; } +close IN; -for my $cat (qw(ancillaryinterrogators - ancillarymanipulators - mainporcelain - plumbinginterrogators - plumbingmanipulators - synchingrepositories - foreignscminterface - purehelpers - synchelpers)) { - my $out = "cmds-$cat.txt"; +for my $out (@categories) { + my ($cat) = $out =~ /^cmds-(.*)\.txt$/; open O, '>', "$out+" or die "Cannot open output file $out+"; for (@{$cmds{$cat}}) { format_one(\*O, $_); diff --git a/Documentation/config.txt b/Documentation/config.txt index ef0768b91a..3042d80978 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -348,6 +348,8 @@ include::config/diff.txt[] include::config/difftool.txt[] +include::config/extensions.txt[] + include::config/fastimport.txt[] include::config/feature.txt[] diff --git a/Documentation/config/extensions.txt b/Documentation/config/extensions.txt new file mode 100644 index 0000000000..4e23d73cdc --- /dev/null +++ b/Documentation/config/extensions.txt @@ -0,0 +1,8 @@ +extensions.objectFormat:: + Specify the hash algorithm to use. The acceptable values are `sha1` and + `sha256`. If not specified, `sha1` is assumed. It is an error to specify + this key unless `core.repositoryFormatVersion` is 1. ++ +Note that this setting should only be set by linkgit:git-init[1] or +linkgit:git-clone[1]. Trying to change it after initialization will not +work and will produce hard-to-diagnose issues. diff --git a/Documentation/config/fmt-merge-msg.txt b/Documentation/config/fmt-merge-msg.txt index c73cfa90b7..a8e8f74d0a 100644 --- a/Documentation/config/fmt-merge-msg.txt +++ b/Documentation/config/fmt-merge-msg.txt @@ -8,3 +8,15 @@ merge.log:: most the specified number of one-line descriptions from the actual commits that are being merged. Defaults to false, and true is a synonym for 20. + +merge.suppressDest:: + By adding a glob that matches the names of integration + branches to this multi-valued configuration variable, the + default merge message computed for merges into these + integration branches will omit " into <branch name>" from + its title. ++ +An element with an empty value can be used to clear the list +of globs accumulated from previous configuration entries. +When there is no `merge.suppressDest` variable defined, the +default value of `master` is used for backward compatibility. diff --git a/Documentation/git-bundle.txt b/Documentation/git-bundle.txt index d34b0964be..53804cad4b 100644 --- a/Documentation/git-bundle.txt +++ b/Documentation/git-bundle.txt @@ -9,7 +9,8 @@ git-bundle - Move objects and refs by archive SYNOPSIS -------- [verse] -'git bundle' create [-q | --quiet | --progress | --all-progress] [--all-progress-implied] <file> <git-rev-list-args> +'git bundle' create [-q | --quiet | --progress | --all-progress] [--all-progress-implied] + [--version=<version>] <file> <git-rev-list-args> 'git bundle' verify [-q | --quiet] <file> 'git bundle' list-heads <file> [<refname>...] 'git bundle' unbundle <file> [<refname>...] @@ -102,6 +103,12 @@ unbundle <file>:: is activated. Unlike --all-progress this flag doesn't actually force any progress display by itself. +--version=<version>:: + Specify the bundle version. Version 2 is the older format and can only be + used with SHA-1 repositories; the newer version 3 contains capabilities that + permit extensions. The default is the oldest supported format, based on the + hash algorithm in use. + -q:: --quiet:: This flag makes the command not to report its progress diff --git a/Documentation/git-commit-graph.txt b/Documentation/git-commit-graph.txt index 8ca1764d3d..17405c73a9 100644 --- a/Documentation/git-commit-graph.txt +++ b/Documentation/git-commit-graph.txt @@ -62,7 +62,10 @@ existing commit-graph file. With the `--changed-paths` option, compute and write information about the paths changed between a commit and its first parent. This operation can take a while on large repositories. It provides significant performance gains -for getting history of a directory or a file with `git log -- <path>`. +for getting history of a directory or a file with `git log -- <path>`. If +this option is given, future commit-graph writes will automatically assume +that this option was intended. Use `--no-changed-paths` to stop storing this +data. + With the `--split[=<strategy>]` option, write the commit-graph as a chain of multiple commit-graph files stored in diff --git a/Documentation/git-for-each-ref.txt b/Documentation/git-for-each-ref.txt index 6dcd39f6f6..2ea71c5f6c 100644 --- a/Documentation/git-for-each-ref.txt +++ b/Documentation/git-for-each-ref.txt @@ -232,12 +232,27 @@ Fields that have name-email-date tuple as its value (`author`, `committer`, and `tagger`) can be suffixed with `name`, `email`, and `date` to extract the named component. -The complete message in a commit and tag object is `contents`. -Its first line is `contents:subject`, where subject is the concatenation -of all lines of the commit message up to the first blank line. The next -line is `contents:body`, where body is all of the lines after the first -blank line. The optional GPG signature is `contents:signature`. The -first `N` lines of the message is obtained using `contents:lines=N`. +The message in a commit or a tag object is `contents`, from which +`contents:<part>` can be used to extract various parts out of: + +contents:size:: + The size in bytes of the commit or tag message. + +contents:subject:: + The first paragraph of the message, which typically is a + single line, is taken as the "subject" of the commit or the + tag message. + +contents:body:: + The remainder of the commit or the tag message that follows + the "subject". + +contents:signature:: + The optional GPG signature of the tag. + +contents:lines=N:: + The first `N` lines of the message. + Additionally, the trailers as interpreted by linkgit:git-interpret-trailers[1] are obtained as `trailers` (or by using the historical alias `contents:trailers`). Non-trailer lines from the trailer block can be omitted diff --git a/Documentation/git-help.txt b/Documentation/git-help.txt index f71db0daa2..44fe8860b3 100644 --- a/Documentation/git-help.txt +++ b/Documentation/git-help.txt @@ -8,7 +8,7 @@ git-help - Display help information about Git SYNOPSIS -------- [verse] -'git help' [-a|--all [--[no-]verbose]] [-g|--guide] +'git help' [-a|--all [--[no-]verbose]] [-g|--guides] [-i|--info|-m|--man|-w|--web] [COMMAND|GUIDE] DESCRIPTION @@ -21,8 +21,8 @@ on the standard output. If the option `--all` or `-a` is given, all available commands are printed on the standard output. -If the option `--guide` or `-g` is given, a list of the useful -Git guides is also printed on the standard output. +If the option `--guides` or `-g` is given, a list of the +Git concept guides is also printed on the standard output. If a command, or a guide, is given, a manual page for that command or guide is brought up. The 'man' program is used by default for this @@ -58,7 +58,7 @@ OPTIONS -g:: --guides:: - Prints a list of useful guides on the standard output. This + Prints a list of the Git concept guides on the standard output. This option overrides any given command or guide name. -i:: diff --git a/Documentation/git-index-pack.txt b/Documentation/git-index-pack.txt index 9316d9a80b..ac74d058e0 100644 --- a/Documentation/git-index-pack.txt +++ b/Documentation/git-index-pack.txt @@ -104,8 +104,8 @@ This option cannot be used with --stdin. NOTES ----- -Once the index has been created, the list of object names is sorted -and the SHA-1 hash of that list is printed to stdout. If --stdin was +Once the index has been created, the hash that goes into the name of +the pack/idx file is printed to stdout. If --stdin was also used then this is prefixed by either "pack\t", or "keep\t" if a new .keep file was successfully created. This is useful to remove a .keep file used as a lock to prevent the race with 'git repack' diff --git a/Documentation/git-log.txt b/Documentation/git-log.txt index 20e6d21a74..3fd26d5212 100644 --- a/Documentation/git-log.txt +++ b/Documentation/git-log.txt @@ -15,9 +15,12 @@ DESCRIPTION ----------- Shows the commit logs. -The command takes options applicable to the `git rev-list` +:git-log: 1 +include::rev-list-description.txt[] + +The command takes options applicable to the linkgit:git-rev-list[1] command to control what is shown and how, and options applicable to -the `git diff-*` commands to control how the changes +the linkgit:git-diff[1] command to control how the changes each commit introduces are shown. diff --git a/Documentation/git-notes.txt b/Documentation/git-notes.txt index ced2e8280e..0a4200674c 100644 --- a/Documentation/git-notes.txt +++ b/Documentation/git-notes.txt @@ -223,7 +223,7 @@ are taken from notes refs. A notes ref is usually a branch which contains "files" whose paths are the object names for the objects they describe, with some directory separators included for performance reasons footnote:[Permitted pathnames have the form -'ab'`/`'cd'`/`'ef'`/`'...'`/`'abcdef...': a sequence of directory +'bf'`/`'fe'`/`'30'`/`'...'`/`'680d5a...': a sequence of directory names of two hexadecimal digits each followed by a filename with the rest of the object ID.]. diff --git a/Documentation/git-rev-list.txt b/Documentation/git-rev-list.txt index 025c911436..5da66232dc 100644 --- a/Documentation/git-rev-list.txt +++ b/Documentation/git-rev-list.txt @@ -14,44 +14,8 @@ SYNOPSIS DESCRIPTION ----------- -List commits that are reachable by following the `parent` links from the -given commit(s), but exclude commits that are reachable from the one(s) -given with a '{caret}' in front of them. The output is given in reverse -chronological order by default. - -You can think of this as a set operation. Commits given on the command -line form a set of commits that are reachable from any of them, and then -commits reachable from any of the ones given with '{caret}' in front are -subtracted from that set. The remaining commits are what comes out in the -command's output. Various other options and paths parameters can be used -to further limit the result. - -Thus, the following command: - ------------------------------------------------------------------------ - $ git rev-list foo bar ^baz ------------------------------------------------------------------------ - -means "list all the commits which are reachable from 'foo' or 'bar', but -not from 'baz'". - -A special notation "'<commit1>'..'<commit2>'" can be used as a -short-hand for "{caret}'<commit1>' '<commit2>'". For example, either of -the following may be used interchangeably: - ------------------------------------------------------------------------ - $ git rev-list origin..HEAD - $ git rev-list HEAD ^origin ------------------------------------------------------------------------ - -Another special notation is "'<commit1>'...'<commit2>'" which is useful -for merges. The resulting set of commits is the symmetric difference -between the two operands. The following two commands are equivalent: - ------------------------------------------------------------------------ - $ git rev-list A B --not $(git merge-base --all A B) - $ git rev-list A...B ------------------------------------------------------------------------ +:git-rev-list: 1 +include::rev-list-description.txt[] 'rev-list' is a very essential Git command, since it provides the ability to build and traverse commit ancestry graphs. For diff --git a/Documentation/git.txt b/Documentation/git.txt index 3e50065198..81349a84e7 100644 --- a/Documentation/git.txt +++ b/Documentation/git.txt @@ -304,6 +304,13 @@ users typically do not use them directly. include::cmds-purehelpers.txt[] +Guides +------ + +The following documentation pages are guides about Git concepts. + +include::cmds-guide.txt[] + Configuration Mechanism ----------------------- diff --git a/Documentation/gitcredentials.txt b/Documentation/gitcredentials.txt index 9e481aec85..758bf39ba3 100644 --- a/Documentation/gitcredentials.txt +++ b/Documentation/gitcredentials.txt @@ -3,7 +3,7 @@ gitcredentials(7) NAME ---- -gitcredentials - providing usernames and passwords to Git +gitcredentials - Providing usernames and passwords to Git SYNOPSIS -------- diff --git a/Documentation/rev-list-description.txt b/Documentation/rev-list-description.txt new file mode 100644 index 0000000000..a9efa7fa27 --- /dev/null +++ b/Documentation/rev-list-description.txt @@ -0,0 +1,61 @@ +List commits that are reachable by following the `parent` links from the +given commit(s), but exclude commits that are reachable from the one(s) +given with a '{caret}' in front of them. The output is given in reverse +chronological order by default. + +You can think of this as a set operation. Commits reachable from any of +the commits given on the command line form a set, and then commits reachable +from any of the ones given with '{caret}' in front are subtracted from that +set. The remaining commits are what comes out in the command's output. +Various other options and paths parameters can be used to further limit the +result. + +Thus, the following command: + +ifdef::git-rev-list[] +----------------------------------------------------------------------- +$ git rev-list foo bar ^baz +----------------------------------------------------------------------- +endif::git-rev-list[] +ifdef::git-log[] +----------------------------------------------------------------------- +$ git log foo bar ^baz +----------------------------------------------------------------------- +endif::git-log[] + +means "list all the commits which are reachable from 'foo' or 'bar', but +not from 'baz'". + +A special notation "'<commit1>'..'<commit2>'" can be used as a +short-hand for "^'<commit1>' '<commit2>'". For example, either of +the following may be used interchangeably: + +ifdef::git-rev-list[] +----------------------------------------------------------------------- +$ git rev-list origin..HEAD +$ git rev-list HEAD ^origin +----------------------------------------------------------------------- +endif::git-rev-list[] +ifdef::git-log[] +----------------------------------------------------------------------- +$ git log origin..HEAD +$ git log HEAD ^origin +----------------------------------------------------------------------- +endif::git-log[] + +Another special notation is "'<commit1>'...'<commit2>'" which is useful +for merges. The resulting set of commits is the symmetric difference +between the two operands. The following two commands are equivalent: + +ifdef::git-rev-list[] +----------------------------------------------------------------------- +$ git rev-list A B --not $(git merge-base --all A B) +$ git rev-list A...B +----------------------------------------------------------------------- +endif::git-rev-list[] +ifdef::git-log[] +----------------------------------------------------------------------- +$ git log A B --not $(git merge-base --all A B) +$ git log A...B +----------------------------------------------------------------------- +endif::git-log[] diff --git a/Documentation/revisions.txt b/Documentation/revisions.txt index 1ad95065c1..d9169c062e 100644 --- a/Documentation/revisions.txt +++ b/Documentation/revisions.txt @@ -254,6 +254,9 @@ specifying a single revision, using the notation described in the previous section, means the set of commits `reachable` from the given commit. +Specifying several revisions means the set of commits reachable from +any of the given commits. + A commit's reachable set is the commit itself and the commits in its ancestry chain. diff --git a/Documentation/technical/api-parse-options.txt b/Documentation/technical/api-parse-options.txt index 2e2e7c10c6..5a60bbfa7f 100644 --- a/Documentation/technical/api-parse-options.txt +++ b/Documentation/technical/api-parse-options.txt @@ -232,9 +232,9 @@ There are some macros to easily define options: will be overwritten, so this should only be used for options where the last one specified on the command line wins. -`OPT_PASSTHRU_ARGV(short, long, &argv_array_var, arg_str, description, flags)`:: +`OPT_PASSTHRU_ARGV(short, long, &strvec_var, arg_str, description, flags)`:: Introduce an option where all instances of it on the command-line will - be reconstructed into an argv_array. This is useful when you need to + be reconstructed into a strvec. This is useful when you need to pass the command-line option, which can be specified multiple times, to another command. diff --git a/Documentation/technical/bundle-format.txt b/Documentation/technical/bundle-format.txt index 0e828151a5..bac558d049 100644 --- a/Documentation/technical/bundle-format.txt +++ b/Documentation/technical/bundle-format.txt @@ -7,6 +7,8 @@ The Git bundle format is a format that represents both refs and Git objects. We will use ABNF notation to define the Git bundle format. See protocol-common.txt for the details. +A v2 bundle looks like this: + ---- bundle = signature *prerequisite *reference LF pack signature = "# v2 git bundle" LF @@ -18,9 +20,28 @@ reference = obj-id SP refname LF pack = ... ; packfile ---- +A v3 bundle looks like this: + +---- +bundle = signature *capability *prerequisite *reference LF pack +signature = "# v3 git bundle" LF + +capability = "@" key ["=" value] LF +prerequisite = "-" obj-id SP comment LF +comment = *CHAR +reference = obj-id SP refname LF +key = 1*(ALPHA / DIGIT / "-") +value = *(%01-09 / %0b-FF) + +pack = ... ; packfile +---- + == Semantics -A Git bundle consists of three parts. +A Git bundle consists of several parts. + +* "Capabilities", which are only in the v3 format, indicate functionality that + the bundle requires to be read properly. * "Prerequisites" lists the objects that are NOT included in the bundle and the reader of the bundle MUST already have, in order to use the data in the @@ -46,3 +67,10 @@ put any string here. The reader of the bundle MUST ignore the comment. Note that the prerequisites does not represent a shallow-clone boundary. The semantics of the prerequisites and the shallow-clone boundaries are different, and the Git bundle v2 format cannot represent a shallow clone repository. + +== Capabilities + +Because there is no opportunity for negotiation, unknown capabilities cause 'git +bundle' to abort. The only known capability is `object-format`, which specifies +the hash algorithm in use, and can take the same values as the +`extensions.objectFormat` configuration value. diff --git a/Documentation/technical/commit-graph-format.txt b/Documentation/technical/commit-graph-format.txt index 1beef17182..440541045d 100644 --- a/Documentation/technical/commit-graph-format.txt +++ b/Documentation/technical/commit-graph-format.txt @@ -32,7 +32,7 @@ the body into "chunks" and provide a binary lookup table at the beginning of the body. The header includes certain values, such as number of chunks and hash type. -All 4-byte numbers are in network order. +All multi-byte numbers are in network byte order. HEADER: @@ -828,7 +828,6 @@ LIB_OBJS += apply.o LIB_OBJS += archive-tar.o LIB_OBJS += archive-zip.o LIB_OBJS += archive.o -LIB_OBJS += argv-array.o LIB_OBJS += attr.o LIB_OBJS += base85.o LIB_OBJS += bisect.o @@ -986,6 +985,7 @@ LIB_OBJS += sigchain.o LIB_OBJS += split-index.o LIB_OBJS += stable-qsort.o LIB_OBJS += strbuf.o +LIB_OBJS += strvec.o LIB_OBJS += streaming.o LIB_OBJS += string-list.o LIB_OBJS += sub-process.o @@ -1 +1 @@ -Documentation/RelNotes/2.28.0.txt
\ No newline at end of file +Documentation/RelNotes/2.29.0.txt
\ No newline at end of file diff --git a/add-interactive.c b/add-interactive.c index 29cd2fe020..555c4abf32 100644 --- a/add-interactive.c +++ b/add-interactive.c @@ -935,18 +935,18 @@ static int run_patch(struct add_i_state *s, const struct pathspec *ps, opts->prompt = N_("Patch update"); count = list_and_choose(s, files, opts); if (count > 0) { - struct argv_array args = ARGV_ARRAY_INIT; + struct strvec args = STRVEC_INIT; struct pathspec ps_selected = { 0 }; for (i = 0; i < files->items.nr; i++) if (files->selected[i]) - argv_array_push(&args, - files->items.items[i].string); + strvec_push(&args, + files->items.items[i].string); parse_pathspec(&ps_selected, PATHSPEC_ALL_MAGIC & ~PATHSPEC_LITERAL, - PATHSPEC_LITERAL_PATH, "", args.argv); + PATHSPEC_LITERAL_PATH, "", args.v); res = run_add_p(s->r, ADD_P_ADD, NULL, &ps_selected); - argv_array_clear(&args); + strvec_clear(&args); clear_pathspec(&ps_selected); } @@ -976,18 +976,18 @@ static int run_diff(struct add_i_state *s, const struct pathspec *ps, count = list_and_choose(s, files, opts); opts->flags = 0; if (count > 0) { - struct argv_array args = ARGV_ARRAY_INIT; + struct strvec args = STRVEC_INIT; - argv_array_pushl(&args, "git", "diff", "-p", "--cached", - oid_to_hex(!is_initial ? &oid : - s->r->hash_algo->empty_tree), - "--", NULL); + strvec_pushl(&args, "git", "diff", "-p", "--cached", + oid_to_hex(!is_initial ? &oid : + s->r->hash_algo->empty_tree), + "--", NULL); for (i = 0; i < files->items.nr; i++) if (files->selected[i]) - argv_array_push(&args, - files->items.items[i].string); - res = run_command_v_opt(args.argv, 0); - argv_array_clear(&args); + strvec_push(&args, + files->items.items[i].string); + res = run_command_v_opt(args.v, 0); + strvec_clear(&args); } putchar('\n'); diff --git a/add-patch.c b/add-patch.c index f899389e2c..f67b304a55 100644 --- a/add-patch.c +++ b/add-patch.c @@ -2,7 +2,7 @@ #include "add-interactive.h" #include "strbuf.h" #include "run-command.h" -#include "argv-array.h" +#include "strvec.h" #include "pathspec.h" #include "color.h" #include "diff.h" @@ -286,12 +286,12 @@ static void setup_child_process(struct add_p_state *s, va_start(ap, cp); while ((arg = va_arg(ap, const char *))) - argv_array_push(&cp->args, arg); + strvec_push(&cp->args, arg); va_end(ap); cp->git_cmd = 1; - argv_array_pushf(&cp->env_array, - INDEX_ENVIRONMENT "=%s", s->s.r->index_file); + strvec_pushf(&cp->env_array, + INDEX_ENVIRONMENT "=%s", s->s.r->index_file); } static int parse_range(const char **p, @@ -370,7 +370,7 @@ static int is_octal(const char *p, size_t len) static int parse_diff(struct add_p_state *s, const struct pathspec *ps) { - struct argv_array args = ARGV_ARRAY_INIT; + struct strvec args = STRVEC_INIT; const char *diff_algorithm = s->s.interactive_diff_algorithm; struct strbuf *plain = &s->plain, *colored = NULL; struct child_process cp = CHILD_PROCESS_INIT; @@ -380,32 +380,32 @@ static int parse_diff(struct add_p_state *s, const struct pathspec *ps) struct hunk *hunk = NULL; int res; - argv_array_pushv(&args, s->mode->diff_cmd); + strvec_pushv(&args, s->mode->diff_cmd); if (diff_algorithm) - argv_array_pushf(&args, "--diff-algorithm=%s", diff_algorithm); + strvec_pushf(&args, "--diff-algorithm=%s", diff_algorithm); if (s->revision) { struct object_id oid; - argv_array_push(&args, - /* could be on an unborn branch */ - !strcmp("HEAD", s->revision) && - get_oid("HEAD", &oid) ? - empty_tree_oid_hex() : s->revision); + strvec_push(&args, + /* could be on an unborn branch */ + !strcmp("HEAD", s->revision) && + get_oid("HEAD", &oid) ? + empty_tree_oid_hex() : s->revision); } - color_arg_index = args.argc; + color_arg_index = args.nr; /* Use `--no-color` explicitly, just in case `diff.color = always`. */ - argv_array_pushl(&args, "--no-color", "-p", "--", NULL); + strvec_pushl(&args, "--no-color", "-p", "--", NULL); for (i = 0; i < ps->nr; i++) - argv_array_push(&args, ps->items[i].original); + strvec_push(&args, ps->items[i].original); setup_child_process(s, &cp, NULL); - cp.argv = args.argv; + cp.argv = args.v; res = capture_command(&cp, plain, 0); if (res) { - argv_array_clear(&args); + strvec_clear(&args); return error(_("could not parse diff")); } if (!plain->len) { - argv_array_clear(&args); + strvec_clear(&args); return 0; } strbuf_complete_line(plain); @@ -415,11 +415,11 @@ static int parse_diff(struct add_p_state *s, const struct pathspec *ps) const char *diff_filter = s->s.interactive_diff_filter; setup_child_process(s, &colored_cp, NULL); - xsnprintf((char *)args.argv[color_arg_index], 8, "--color"); - colored_cp.argv = args.argv; + xsnprintf((char *)args.v[color_arg_index], 8, "--color"); + colored_cp.argv = args.v; colored = &s->colored; res = capture_command(&colored_cp, colored, 0); - argv_array_clear(&args); + strvec_clear(&args); if (res) return error(_("could not parse colored diff")); @@ -444,7 +444,7 @@ static int parse_diff(struct add_p_state *s, const struct pathspec *ps) colored_p = colored->buf; colored_pend = colored_p + colored->len; } - argv_array_clear(&args); + strvec_clear(&args); /* parse files and hunks */ p = plain->buf; @@ -1158,7 +1158,7 @@ static int run_apply_check(struct add_p_state *s, setup_child_process(s, &cp, "apply", "--check", NULL); - argv_array_pushv(&cp.args, s->mode->apply_check_args); + strvec_pushv(&cp.args, s->mode->apply_check_args); if (pipe_command(&cp, s->buf.buf, s->buf.len, NULL, 0, NULL, 0)) return error(_("'git apply --cached' failed")); @@ -1203,7 +1203,7 @@ static int edit_hunk_loop(struct add_p_state *s, for (;;) { int res = edit_hunk_manually(s, hunk); if (res == 0) { - /* abandonded */ + /* abandoned */ *hunk = backup; return -1; } @@ -1619,7 +1619,7 @@ soft_increment: s->mode->is_reverse); else { setup_child_process(s, &cp, "apply", NULL); - argv_array_pushv(&cp.args, s->mode->apply_args); + strvec_pushv(&cp.args, s->mode->apply_args); if (pipe_command(&cp, s->buf.buf, s->buf.len, NULL, 0, NULL, 0)) error(_("'git apply' failed")); diff --git a/argv-array.c b/argv-array.c deleted file mode 100644 index 61ef8c0dfd..0000000000 --- a/argv-array.c +++ /dev/null @@ -1,109 +0,0 @@ -#include "cache.h" -#include "argv-array.h" -#include "strbuf.h" - -const char *empty_argv[] = { NULL }; - -void argv_array_init(struct argv_array *array) -{ - array->argv = empty_argv; - array->argc = 0; - array->alloc = 0; -} - -static void argv_array_push_nodup(struct argv_array *array, const char *value) -{ - if (array->argv == empty_argv) - array->argv = NULL; - - ALLOC_GROW(array->argv, array->argc + 2, array->alloc); - array->argv[array->argc++] = value; - array->argv[array->argc] = NULL; -} - -const char *argv_array_push(struct argv_array *array, const char *value) -{ - argv_array_push_nodup(array, xstrdup(value)); - return array->argv[array->argc - 1]; -} - -const char *argv_array_pushf(struct argv_array *array, const char *fmt, ...) -{ - va_list ap; - struct strbuf v = STRBUF_INIT; - - va_start(ap, fmt); - strbuf_vaddf(&v, fmt, ap); - va_end(ap); - - argv_array_push_nodup(array, strbuf_detach(&v, NULL)); - return array->argv[array->argc - 1]; -} - -void argv_array_pushl(struct argv_array *array, ...) -{ - va_list ap; - const char *arg; - - va_start(ap, array); - while ((arg = va_arg(ap, const char *))) - argv_array_push(array, arg); - va_end(ap); -} - -void argv_array_pushv(struct argv_array *array, const char **argv) -{ - for (; *argv; argv++) - argv_array_push(array, *argv); -} - -void argv_array_pop(struct argv_array *array) -{ - if (!array->argc) - return; - free((char *)array->argv[array->argc - 1]); - array->argv[array->argc - 1] = NULL; - array->argc--; -} - -void argv_array_split(struct argv_array *array, const char *to_split) -{ - while (isspace(*to_split)) - to_split++; - for (;;) { - const char *p = to_split; - - if (!*p) - break; - - while (*p && !isspace(*p)) - p++; - argv_array_push_nodup(array, xstrndup(to_split, p - to_split)); - - while (isspace(*p)) - p++; - to_split = p; - } -} - -void argv_array_clear(struct argv_array *array) -{ - if (array->argv != empty_argv) { - int i; - for (i = 0; i < array->argc; i++) - free((char *)array->argv[i]); - free(array->argv); - } - argv_array_init(array); -} - -const char **argv_array_detach(struct argv_array *array) -{ - if (array->argv == empty_argv) - return xcalloc(1, sizeof(const char *)); - else { - const char **ret = array->argv; - argv_array_init(array); - return ret; - } -} @@ -11,7 +11,7 @@ #include "log-tree.h" #include "bisect.h" #include "oid-array.h" -#include "argv-array.h" +#include "strvec.h" #include "commit-slab.h" #include "commit-reach.h" #include "object-store.h" @@ -456,7 +456,7 @@ static GIT_PATH_FUNC(git_path_bisect_log, "BISECT_LOG") static GIT_PATH_FUNC(git_path_bisect_terms, "BISECT_TERMS") static GIT_PATH_FUNC(git_path_head_name, "head-name") -static void read_bisect_paths(struct argv_array *array) +static void read_bisect_paths(struct strvec *array) { struct strbuf str = STRBUF_INIT; const char *filename = git_path_bisect_names(); @@ -464,7 +464,7 @@ static void read_bisect_paths(struct argv_array *array) while (strbuf_getline_lf(&str, fp) != EOF) { strbuf_trim(&str); - if (sq_dequote_to_argv_array(str.buf, array)) + if (sq_dequote_to_strvec(str.buf, array)) die(_("Badly quoted content in file '%s': %s"), filename, str.buf); } @@ -632,7 +632,7 @@ static void bisect_rev_setup(struct repository *r, struct rev_info *revs, const char *bad_format, const char *good_format, int read_paths) { - struct argv_array rev_argv = ARGV_ARRAY_INIT; + struct strvec rev_argv = STRVEC_INIT; int i; repo_init_revisions(r, revs, prefix); @@ -640,16 +640,16 @@ static void bisect_rev_setup(struct repository *r, struct rev_info *revs, revs->commit_format = CMIT_FMT_UNSPECIFIED; /* rev_argv.argv[0] will be ignored by setup_revisions */ - argv_array_push(&rev_argv, "bisect_rev_setup"); - argv_array_pushf(&rev_argv, bad_format, oid_to_hex(current_bad_oid)); + strvec_push(&rev_argv, "bisect_rev_setup"); + strvec_pushf(&rev_argv, bad_format, oid_to_hex(current_bad_oid)); for (i = 0; i < good_revs.nr; i++) - argv_array_pushf(&rev_argv, good_format, - oid_to_hex(good_revs.oid + i)); - argv_array_push(&rev_argv, "--"); + strvec_pushf(&rev_argv, good_format, + oid_to_hex(good_revs.oid + i)); + strvec_push(&rev_argv, "--"); if (read_paths) read_bisect_paths(&rev_argv); - setup_revisions(rev_argv.argc, rev_argv.argv, revs, NULL); + setup_revisions(rev_argv.nr, rev_argv.v, revs, NULL); /* XXX leak rev_argv, as "revs" may still be pointing to it */ } @@ -709,7 +709,7 @@ static enum bisect_error bisect_checkout(const struct object_id *bisect_rev, int char bisect_rev_hex[GIT_MAX_HEXSZ + 1]; enum bisect_error res = BISECT_OK; - memcpy(bisect_rev_hex, oid_to_hex(bisect_rev), the_hash_algo->hexsz + 1); + oid_to_hex_r(bisect_rev_hex, bisect_rev); update_ref(NULL, "BISECT_EXPECTED_REV", bisect_rev, NULL, 0, UPDATE_REFS_DIE_ON_ERR); argv_checkout[2] = bisect_rev_hex; @@ -187,7 +187,7 @@ struct bloom_filter *get_bloom_filter(struct repository *r, struct diff_options diffopt; int max_changes = 512; - if (bloom_filters.slab_size == 0) + if (!bloom_filters.slab_size) return NULL; filter = bloom_filter_slab_at(&bloom_filters, c); @@ -195,16 +195,14 @@ struct bloom_filter *get_bloom_filter(struct repository *r, if (!filter->data) { load_commit_graph_info(r, c); if (commit_graph_position(c) != COMMIT_NOT_FROM_GRAPH && - r->objects->commit_graph->chunk_bloom_indexes) { - if (load_bloom_filter_from_graph(r->objects->commit_graph, filter, c)) - return filter; - else - return NULL; - } + r->objects->commit_graph->chunk_bloom_indexes) + load_bloom_filter_from_graph(r->objects->commit_graph, filter, c); } - if (filter->data || !compute_if_not_present) + if (filter->data) return filter; + if (!compute_if_not_present) + return NULL; repo_diff_setup(r, &diffopt); diffopt.flags.recursive = 1; diff --git a/builtin/add.c b/builtin/add.c index 298e0114f9..ab39a60a0d 100644 --- a/builtin/add.c +++ b/builtin/add.c @@ -18,7 +18,7 @@ #include "diffcore.h" #include "revision.h" #include "bulk-checkin.h" -#include "argv-array.h" +#include "strvec.h" #include "submodule.h" #include "add-interactive.h" @@ -188,7 +188,7 @@ int run_add_interactive(const char *revision, const char *patch_mode, const struct pathspec *pathspec) { int status, i; - struct argv_array argv = ARGV_ARRAY_INIT; + struct strvec argv = STRVEC_INIT; int use_builtin_add_i = git_env_bool("GIT_TEST_ADD_I_USE_BUILTIN", -1); @@ -218,18 +218,18 @@ int run_add_interactive(const char *revision, const char *patch_mode, return !!run_add_p(the_repository, mode, revision, pathspec); } - argv_array_push(&argv, "add--interactive"); + strvec_push(&argv, "add--interactive"); if (patch_mode) - argv_array_push(&argv, patch_mode); + strvec_push(&argv, patch_mode); if (revision) - argv_array_push(&argv, revision); - argv_array_push(&argv, "--"); + strvec_push(&argv, revision); + strvec_push(&argv, "--"); for (i = 0; i < pathspec->nr; i++) /* pass original pathspec, to be re-parsed */ - argv_array_push(&argv, pathspec->items[i].original); + strvec_push(&argv, pathspec->items[i].original); - status = run_command_v_opt(argv.argv, RUN_GIT_CMD); - argv_array_clear(&argv); + status = run_command_v_opt(argv.v, RUN_GIT_CMD); + strvec_clear(&argv); return status; } diff --git a/builtin/am.c b/builtin/am.c index 69e50de018..dd4e6c2d9b 100644 --- a/builtin/am.c +++ b/builtin/am.c @@ -116,7 +116,7 @@ struct am_state { int keep; /* enum keep_type */ int message_id; int scissors; /* enum scissors_type */ - struct argv_array git_apply_opts; + struct strvec git_apply_opts; const char *resolvemsg; int committer_date_is_author_date; int ignore_date; @@ -146,7 +146,7 @@ static void am_state_init(struct am_state *state) state->scissors = SCISSORS_UNSET; - argv_array_init(&state->git_apply_opts); + strvec_init(&state->git_apply_opts); if (!git_config_get_bool("commit.gpgsign", &gpgsign)) state->sign_commit = gpgsign ? "" : NULL; @@ -162,7 +162,7 @@ static void am_state_release(struct am_state *state) free(state->author_email); free(state->author_date); free(state->msg); - argv_array_clear(&state->git_apply_opts); + strvec_clear(&state->git_apply_opts); } /** @@ -398,8 +398,8 @@ static void am_load(struct am_state *state) state->scissors = SCISSORS_UNSET; read_state_file(&sb, state, "apply-opt", 1); - argv_array_clear(&state->git_apply_opts); - if (sq_dequote_to_argv_array(sb.buf, &state->git_apply_opts) < 0) + strvec_clear(&state->git_apply_opts); + if (sq_dequote_to_strvec(sb.buf, &state->git_apply_opts) < 0) die(_("could not parse %s"), am_path(state, "apply-opt")); state->rebasing = !!file_exists(am_path(state, "rebasing")); @@ -452,8 +452,8 @@ static int run_post_rewrite_hook(const struct am_state *state) if (!hook) return 0; - argv_array_push(&cp.args, hook); - argv_array_push(&cp.args, "rebase"); + strvec_push(&cp.args, hook); + strvec_push(&cp.args, "rebase"); cp.in = xopen(am_path(state, "rewritten"), O_RDONLY); cp.stdout_to_stderr = 1; @@ -651,16 +651,16 @@ static int split_mail_mbox(struct am_state *state, const char **paths, int ret; cp.git_cmd = 1; - argv_array_push(&cp.args, "mailsplit"); - argv_array_pushf(&cp.args, "-d%d", state->prec); - argv_array_pushf(&cp.args, "-o%s", state->dir); - argv_array_push(&cp.args, "-b"); + strvec_push(&cp.args, "mailsplit"); + strvec_pushf(&cp.args, "-d%d", state->prec); + strvec_pushf(&cp.args, "-o%s", state->dir); + strvec_push(&cp.args, "-b"); if (keep_cr) - argv_array_push(&cp.args, "--keep-cr"); + strvec_push(&cp.args, "--keep-cr"); if (mboxrd) - argv_array_push(&cp.args, "--mboxrd"); - argv_array_push(&cp.args, "--"); - argv_array_pushv(&cp.args, paths); + strvec_push(&cp.args, "--mboxrd"); + strvec_push(&cp.args, "--"); + strvec_pushv(&cp.args, paths); ret = capture_command(&cp, &last, 8); if (ret) @@ -787,7 +787,7 @@ static int split_mail_stgit_series(struct am_state *state, const char **paths, const char *series_dir; char *series_dir_buf; FILE *fp; - struct argv_array patches = ARGV_ARRAY_INIT; + struct strvec patches = STRVEC_INIT; struct strbuf sb = STRBUF_INIT; int ret; @@ -805,16 +805,16 @@ static int split_mail_stgit_series(struct am_state *state, const char **paths, if (*sb.buf == '#') continue; /* skip comment lines */ - argv_array_push(&patches, mkpath("%s/%s", series_dir, sb.buf)); + strvec_push(&patches, mkpath("%s/%s", series_dir, sb.buf)); } fclose(fp); strbuf_release(&sb); free(series_dir_buf); - ret = split_mail_conv(stgit_patch_to_mail, state, patches.argv, keep_cr); + ret = split_mail_conv(stgit_patch_to_mail, state, patches.v, keep_cr); - argv_array_clear(&patches); + strvec_clear(&patches); return ret; } @@ -1002,7 +1002,7 @@ static void am_setup(struct am_state *state, enum patch_format patch_format, } write_state_text(state, "scissors", str); - sq_quote_argv(&sb, state->git_apply_opts.argv); + sq_quote_argv(&sb, state->git_apply_opts.v); write_state_text(state, "apply-opt", sb.buf); if (state->rebasing) @@ -1390,8 +1390,8 @@ static int parse_mail_rebase(struct am_state *state, const char *mail) */ static int run_apply(const struct am_state *state, const char *index_file) { - struct argv_array apply_paths = ARGV_ARRAY_INIT; - struct argv_array apply_opts = ARGV_ARRAY_INIT; + struct strvec apply_paths = STRVEC_INIT; + struct strvec apply_opts = STRVEC_INIT; struct apply_state apply_state; int res, opts_left; int force_apply = 0; @@ -1400,10 +1400,10 @@ static int run_apply(const struct am_state *state, const char *index_file) if (init_apply_state(&apply_state, the_repository, NULL)) BUG("init_apply_state() failed"); - argv_array_push(&apply_opts, "apply"); - argv_array_pushv(&apply_opts, state->git_apply_opts.argv); + strvec_push(&apply_opts, "apply"); + strvec_pushv(&apply_opts, state->git_apply_opts.v); - opts_left = apply_parse_options(apply_opts.argc, apply_opts.argv, + opts_left = apply_parse_options(apply_opts.nr, apply_opts.v, &apply_state, &force_apply, &options, NULL); @@ -1426,12 +1426,12 @@ static int run_apply(const struct am_state *state, const char *index_file) if (check_apply_state(&apply_state, force_apply)) BUG("check_apply_state() failed"); - argv_array_push(&apply_paths, am_path(state, "patch")); + strvec_push(&apply_paths, am_path(state, "patch")); - res = apply_all_patches(&apply_state, apply_paths.argc, apply_paths.argv, options); + res = apply_all_patches(&apply_state, apply_paths.nr, apply_paths.v, options); - argv_array_clear(&apply_paths); - argv_array_clear(&apply_opts); + strvec_clear(&apply_paths); + strvec_clear(&apply_opts); clear_apply_state(&apply_state); if (res) @@ -1454,10 +1454,10 @@ static int build_fake_ancestor(const struct am_state *state, const char *index_f struct child_process cp = CHILD_PROCESS_INIT; cp.git_cmd = 1; - argv_array_push(&cp.args, "apply"); - argv_array_pushv(&cp.args, state->git_apply_opts.argv); - argv_array_pushf(&cp.args, "--build-fake-ancestor=%s", index_file); - argv_array_push(&cp.args, am_path(state, "patch")); + strvec_push(&cp.args, "apply"); + strvec_pushv(&cp.args, state->git_apply_opts.v); + strvec_pushf(&cp.args, "--build-fake-ancestor=%s", index_file); + strvec_push(&cp.args, am_path(state, "patch")); if (run_command(&cp)) return -1; @@ -1676,7 +1676,7 @@ static int do_interactive(struct am_state *state) if (!pager) pager = "cat"; prepare_pager_args(&cp, pager); - argv_array_push(&cp.args, am_path(state, "patch")); + strvec_push(&cp.args, am_path(state, "patch")); run_command(&cp); } } @@ -2346,7 +2346,7 @@ int cmd_am(int argc, const char **argv, const char *prefix) if (state.signoff == SIGNOFF_EXPLICIT) am_append_signoff(&state); } else { - struct argv_array paths = ARGV_ARRAY_INIT; + struct strvec paths = STRVEC_INIT; int i; /* @@ -2371,17 +2371,17 @@ int cmd_am(int argc, const char **argv, const char *prefix) for (i = 0; i < argc; i++) { if (is_absolute_path(argv[i]) || !prefix) - argv_array_push(&paths, argv[i]); + strvec_push(&paths, argv[i]); else - argv_array_push(&paths, mkpath("%s/%s", prefix, argv[i])); + strvec_push(&paths, mkpath("%s/%s", prefix, argv[i])); } - if (state.interactive && !paths.argc) + if (state.interactive && !paths.nr) die(_("interactive mode requires patches on the command line")); - am_setup(&state, patch_format, paths.argv, keep_cr); + am_setup(&state, patch_format, paths.v, keep_cr); - argv_array_clear(&paths); + strvec_clear(&paths); } switch (resume.mode) { diff --git a/builtin/annotate.c b/builtin/annotate.c index da413ae0d1..58ff977a23 100644 --- a/builtin/annotate.c +++ b/builtin/annotate.c @@ -5,18 +5,18 @@ */ #include "git-compat-util.h" #include "builtin.h" -#include "argv-array.h" +#include "strvec.h" int cmd_annotate(int argc, const char **argv, const char *prefix) { - struct argv_array args = ARGV_ARRAY_INIT; + struct strvec args = STRVEC_INIT; int i; - argv_array_pushl(&args, "annotate", "-c", NULL); + strvec_pushl(&args, "annotate", "-c", NULL); for (i = 1; i < argc; i++) { - argv_array_push(&args, argv[i]); + strvec_push(&args, argv[i]); } - return cmd_blame(args.argc, args.argv, prefix); + return cmd_blame(args.nr, args.v, prefix); } diff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c index ec4996282e..d19300687f 100644 --- a/builtin/bisect--helper.c +++ b/builtin/bisect--helper.c @@ -4,7 +4,7 @@ #include "bisect.h" #include "refs.h" #include "dir.h" -#include "argv-array.h" +#include "strvec.h" #include "run-command.h" #include "prompt.h" #include "quote.h" @@ -13,7 +13,6 @@ static GIT_PATH_FUNC(git_path_bisect_terms, "BISECT_TERMS") static GIT_PATH_FUNC(git_path_bisect_expected_rev, "BISECT_EXPECTED_REV") static GIT_PATH_FUNC(git_path_bisect_ancestors_ok, "BISECT_ANCESTORS_OK") static GIT_PATH_FUNC(git_path_bisect_start, "BISECT_START") -static GIT_PATH_FUNC(git_path_bisect_head, "BISECT_HEAD") static GIT_PATH_FUNC(git_path_bisect_log, "BISECT_LOG") static GIT_PATH_FUNC(git_path_head_name, "head-name") static GIT_PATH_FUNC(git_path_bisect_names, "BISECT_NAMES") @@ -164,19 +163,19 @@ static int bisect_reset(const char *commit) strbuf_addstr(&branch, commit); } - if (!file_exists(git_path_bisect_head())) { - struct argv_array argv = ARGV_ARRAY_INIT; + if (!ref_exists("BISECT_HEAD")) { + struct strvec argv = STRVEC_INIT; - argv_array_pushl(&argv, "checkout", branch.buf, "--", NULL); - if (run_command_v_opt(argv.argv, RUN_GIT_CMD)) { + strvec_pushl(&argv, "checkout", branch.buf, "--", NULL); + if (run_command_v_opt(argv.v, RUN_GIT_CMD)) { error(_("could not check out original" " HEAD '%s'. Try 'git bisect" " reset <commit>'."), branch.buf); strbuf_release(&branch); - argv_array_clear(&argv); + strvec_clear(&argv); return -1; } - argv_array_clear(&argv); + strvec_clear(&argv); } strbuf_release(&branch); @@ -526,11 +525,11 @@ static int bisect_start(struct bisect_terms *terms, int no_checkout, strbuf_read_file(&start_head, git_path_bisect_start(), 0); strbuf_trim(&start_head); if (!no_checkout) { - struct argv_array argv = ARGV_ARRAY_INIT; + struct strvec argv = STRVEC_INIT; - argv_array_pushl(&argv, "checkout", start_head.buf, - "--", NULL); - if (run_command_v_opt(argv.argv, RUN_GIT_CMD)) { + strvec_pushl(&argv, "checkout", start_head.buf, + "--", NULL); + if (run_command_v_opt(argv.v, RUN_GIT_CMD)) { res = error(_("checking out '%s' failed." " Try 'git bisect start " "<valid-branch>'."), diff --git a/builtin/bundle.c b/builtin/bundle.c index f049d27a14..ea6948110b 100644 --- a/builtin/bundle.c +++ b/builtin/bundle.c @@ -1,5 +1,5 @@ #include "builtin.h" -#include "argv-array.h" +#include "strvec.h" #include "parse-options.h" #include "cache.h" #include "bundle.h" @@ -59,7 +59,8 @@ static int parse_options_cmd_bundle(int argc, static int cmd_bundle_create(int argc, const char **argv, const char *prefix) { int all_progress_implied = 0; int progress = isatty(STDERR_FILENO); - struct argv_array pack_opts; + struct strvec pack_opts; + int version = -1; struct option options[] = { OPT_SET_INT('q', "quiet", &progress, @@ -71,6 +72,8 @@ static int cmd_bundle_create(int argc, const char **argv, const char *prefix) { OPT_BOOL(0, "all-progress-implied", &all_progress_implied, N_("similar to --all-progress when progress meter is shown")), + OPT_INTEGER(0, "version", &version, + N_("specify bundle format version")), OPT_END() }; const char* bundle_file; @@ -79,19 +82,19 @@ static int cmd_bundle_create(int argc, const char **argv, const char *prefix) { builtin_bundle_create_usage, options, &bundle_file); /* bundle internals use argv[1] as further parameters */ - argv_array_init(&pack_opts); + strvec_init(&pack_opts); if (progress == 0) - argv_array_push(&pack_opts, "--quiet"); + strvec_push(&pack_opts, "--quiet"); else if (progress == 1) - argv_array_push(&pack_opts, "--progress"); + strvec_push(&pack_opts, "--progress"); else if (progress == 2) - argv_array_push(&pack_opts, "--all-progress"); + strvec_push(&pack_opts, "--all-progress"); if (progress && all_progress_implied) - argv_array_push(&pack_opts, "--all-progress-implied"); + strvec_push(&pack_opts, "--all-progress-implied"); if (!startup_info->have_repository) die(_("Need a repository to create a bundle.")); - return !!create_bundle(the_repository, bundle_file, argc, argv, &pack_opts); + return !!create_bundle(the_repository, bundle_file, argc, argv, &pack_opts, version); } static int cmd_bundle_verify(int argc, const char **argv, const char *prefix) { diff --git a/builtin/checkout.c b/builtin/checkout.c index af849c644f..2837195491 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -239,6 +239,8 @@ static int checkout_merged(int pos, const struct checkout *state, int *nr_checko mmbuffer_t result_buf; struct object_id threeway[3]; unsigned mode = 0; + struct ll_merge_options ll_opts; + int renormalize = 0; memset(threeway, 0, sizeof(threeway)); while (pos < active_nr) { @@ -259,13 +261,12 @@ static int checkout_merged(int pos, const struct checkout *state, int *nr_checko read_mmblob(&ours, &threeway[1]); read_mmblob(&theirs, &threeway[2]); - /* - * NEEDSWORK: re-create conflicts from merges with - * merge.renormalize set, too - */ + memset(&ll_opts, 0, sizeof(ll_opts)); + git_config_get_bool("merge.renormalize", &renormalize); + ll_opts.renormalize = renormalize; status = ll_merge(&result_buf, path, &ancestor, "base", &ours, "ours", &theirs, "theirs", - state->istate, NULL); + state->istate, &ll_opts); free(ancestor.ptr); free(ours.ptr); free(theirs.ptr); @@ -771,13 +772,6 @@ static int merge_working_tree(const struct checkout_opts *opts, */ add_files_to_cache(NULL, NULL, 0); - /* - * NEEDSWORK: carrying over local changes - * when branches have different end-of-line - * normalization (or clean+smudge rules) is - * a pain; plumb in an option to set - * o.renormalize? - */ init_merge_options(&o, the_repository); o.verbosity = 0; work = write_in_core_index_as_tree(the_repository); diff --git a/builtin/clone.c b/builtin/clone.c index bef70745c0..b087ee40c2 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -742,9 +742,9 @@ static void update_head(const struct ref *our, const struct ref *remote, static int git_sparse_checkout_init(const char *repo) { - struct argv_array argv = ARGV_ARRAY_INIT; + struct strvec argv = STRVEC_INIT; int result = 0; - argv_array_pushl(&argv, "-C", repo, "sparse-checkout", "init", NULL); + strvec_pushl(&argv, "-C", repo, "sparse-checkout", "init", NULL); /* * We must apply the setting in the current process @@ -752,12 +752,12 @@ static int git_sparse_checkout_init(const char *repo) */ core_apply_sparse_checkout = 1; - if (run_command_v_opt(argv.argv, RUN_GIT_CMD)) { + if (run_command_v_opt(argv.v, RUN_GIT_CMD)) { error(_("failed to initialize sparse-checkout")); result = 1; } - argv_array_clear(&argv); + strvec_clear(&argv); return result; } @@ -819,33 +819,33 @@ static int checkout(int submodule_progress) oid_to_hex(&oid), "1", NULL); if (!err && (option_recurse_submodules.nr > 0)) { - struct argv_array args = ARGV_ARRAY_INIT; - argv_array_pushl(&args, "submodule", "update", "--require-init", "--recursive", NULL); + struct strvec args = STRVEC_INIT; + strvec_pushl(&args, "submodule", "update", "--require-init", "--recursive", NULL); if (option_shallow_submodules == 1) - argv_array_push(&args, "--depth=1"); + strvec_push(&args, "--depth=1"); if (max_jobs != -1) - argv_array_pushf(&args, "--jobs=%d", max_jobs); + strvec_pushf(&args, "--jobs=%d", max_jobs); if (submodule_progress) - argv_array_push(&args, "--progress"); + strvec_push(&args, "--progress"); if (option_verbosity < 0) - argv_array_push(&args, "--quiet"); + strvec_push(&args, "--quiet"); if (option_remote_submodules) { - argv_array_push(&args, "--remote"); - argv_array_push(&args, "--no-fetch"); + strvec_push(&args, "--remote"); + strvec_push(&args, "--no-fetch"); } if (option_single_branch >= 0) - argv_array_push(&args, option_single_branch ? + strvec_push(&args, option_single_branch ? "--single-branch" : "--no-single-branch"); - err = run_command_v_opt(args.argv, RUN_GIT_CMD); - argv_array_clear(&args); + err = run_command_v_opt(args.v, RUN_GIT_CMD); + strvec_clear(&args); } return err; @@ -946,7 +946,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix) int is_bundle = 0, is_local; const char *repo_name, *repo, *work_tree, *git_dir; char *path, *dir, *display_repo = NULL; - int dest_exists; + int dest_exists, real_dest_exists = 0; const struct ref *refs, *remote_head; const struct ref *remote_head_points_at; const struct ref *our_head_points_at; @@ -961,7 +961,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix) int err = 0, complete_refs_before_fetch = 1; int submodule_progress; - struct argv_array ref_prefixes = ARGV_ARRAY_INIT; + struct strvec ref_prefixes = STRVEC_INIT; packet_trace_identity("clone"); argc = parse_options(argc, argv, prefix, builtin_clone_options, @@ -1021,6 +1021,14 @@ int cmd_clone(int argc, const char **argv, const char *prefix) die(_("destination path '%s' already exists and is not " "an empty directory."), dir); + if (real_git_dir) { + real_dest_exists = path_exists(real_git_dir); + if (real_dest_exists && !is_empty_dir(real_git_dir)) + die(_("repository path '%s' already exists and is not " + "an empty directory."), real_git_dir); + } + + strbuf_addf(&reflog_msg, "clone: from %s", display_repo ? display_repo : repo); free(display_repo); @@ -1057,7 +1065,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix) } if (real_git_dir) { - if (path_exists(real_git_dir)) + if (real_dest_exists) junk_git_dir_flags |= REMOVE_DIR_KEEP_TOPLEVEL; junk_git_dir = real_git_dir; } else { @@ -1211,12 +1219,12 @@ int cmd_clone(int argc, const char **argv, const char *prefix) transport->smart_options->check_self_contained_and_connected = 1; - argv_array_push(&ref_prefixes, "HEAD"); + strvec_push(&ref_prefixes, "HEAD"); refspec_ref_prefixes(&remote->fetch, &ref_prefixes); if (option_branch) expand_ref_prefix(&ref_prefixes, option_branch); if (!option_no_tags) - argv_array_push(&ref_prefixes, "refs/tags/"); + strvec_push(&ref_prefixes, "refs/tags/"); refs = transport_get_remote_refs(transport, &ref_prefixes); @@ -1327,6 +1335,6 @@ int cmd_clone(int argc, const char **argv, const char *prefix) strbuf_release(&default_refspec); junk_mode = JUNK_LEAVE_ALL; - argv_array_clear(&ref_prefixes); + strvec_clear(&ref_prefixes); return err; } diff --git a/builtin/commit-graph.c b/builtin/commit-graph.c index 16c9f6101a..523501f217 100644 --- a/builtin/commit-graph.c +++ b/builtin/commit-graph.c @@ -201,6 +201,7 @@ static int graph_write(int argc, const char **argv) }; opts.progress = isatty(2); + opts.enable_changed_paths = -1; split_opts.size_multiple = 2; split_opts.max_commits = 0; split_opts.expire_time = 0; @@ -221,7 +222,9 @@ static int graph_write(int argc, const char **argv) flags |= COMMIT_GRAPH_WRITE_SPLIT; if (opts.progress) flags |= COMMIT_GRAPH_WRITE_PROGRESS; - if (opts.enable_changed_paths || + if (!opts.enable_changed_paths) + flags |= COMMIT_GRAPH_NO_WRITE_BLOOM_FILTERS; + if (opts.enable_changed_paths == 1 || git_env_bool(GIT_TEST_COMMIT_GRAPH_CHANGED_PATHS, 0)) flags |= COMMIT_GRAPH_WRITE_BLOOM_FILTERS; diff --git a/builtin/commit.c b/builtin/commit.c index d1b7396052..69ac78d5e5 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -1005,15 +1005,15 @@ static int prepare_to_commit(const char *index_file, const char *prefix, return 0; if (use_editor) { - struct argv_array env = ARGV_ARRAY_INIT; + struct strvec env = STRVEC_INIT; - argv_array_pushf(&env, "GIT_INDEX_FILE=%s", index_file); - if (launch_editor(git_path_commit_editmsg(), NULL, env.argv)) { + strvec_pushf(&env, "GIT_INDEX_FILE=%s", index_file); + if (launch_editor(git_path_commit_editmsg(), NULL, env.v)) { fprintf(stderr, _("Please supply the message using either -m or -F option.\n")); exit(1); } - argv_array_clear(&env); + strvec_clear(&env); } if (!no_verify && diff --git a/builtin/describe.c b/builtin/describe.c index 21d2cb9e57..7668591d57 100644 --- a/builtin/describe.c +++ b/builtin/describe.c @@ -12,7 +12,7 @@ #include "revision.h" #include "diff.h" #include "hashmap.h" -#include "argv-array.h" +#include "strvec.h" #include "run-command.h" #include "object-store.h" #include "list-objects.h" @@ -501,15 +501,15 @@ static void process_object(struct object *obj, const char *path, void *data) static void describe_blob(struct object_id oid, struct strbuf *dst) { struct rev_info revs; - struct argv_array args = ARGV_ARRAY_INIT; + struct strvec args = STRVEC_INIT; struct process_commit_data pcd = { null_oid, oid, dst, &revs}; - argv_array_pushl(&args, "internal: The first arg is not parsed", - "--objects", "--in-commit-order", "--reverse", "HEAD", - NULL); + strvec_pushl(&args, "internal: The first arg is not parsed", + "--objects", "--in-commit-order", "--reverse", "HEAD", + NULL); repo_init_revisions(the_repository, &revs, NULL); - if (setup_revisions(args.argc, args.argv, &revs, NULL) > 1) + if (setup_revisions(args.nr, args.v, &revs, NULL) > 1) BUG("setup_revisions could not handle all args?"); if (prepare_revision_walk(&revs)) @@ -594,26 +594,26 @@ int cmd_describe(int argc, const char **argv, const char *prefix) if (contains) { struct string_list_item *item; - struct argv_array args; + struct strvec args; - argv_array_init(&args); - argv_array_pushl(&args, "name-rev", - "--peel-tag", "--name-only", "--no-undefined", - NULL); + strvec_init(&args); + strvec_pushl(&args, "name-rev", + "--peel-tag", "--name-only", "--no-undefined", + NULL); if (always) - argv_array_push(&args, "--always"); + strvec_push(&args, "--always"); if (!all) { - argv_array_push(&args, "--tags"); + strvec_push(&args, "--tags"); for_each_string_list_item(item, &patterns) - argv_array_pushf(&args, "--refs=refs/tags/%s", item->string); + strvec_pushf(&args, "--refs=refs/tags/%s", item->string); for_each_string_list_item(item, &exclude_patterns) - argv_array_pushf(&args, "--exclude=refs/tags/%s", item->string); + strvec_pushf(&args, "--exclude=refs/tags/%s", item->string); } if (argc) - argv_array_pushv(&args, argv); + strvec_pushv(&args, argv); else - argv_array_push(&args, "HEAD"); - return cmd_name_rev(args.argc, args.argv, prefix); + strvec_push(&args, "HEAD"); + return cmd_name_rev(args.nr, args.v, prefix); } hashmap_init(&names, commit_name_neq, NULL, 0); @@ -624,7 +624,7 @@ int cmd_describe(int argc, const char **argv, const char *prefix) if (argc == 0) { if (broken) { struct child_process cp = CHILD_PROCESS_INIT; - argv_array_pushv(&cp.args, diff_index_args); + strvec_pushv(&cp.args, diff_index_args); cp.git_cmd = 1; cp.no_stdin = 1; cp.no_stdout = 1; @@ -646,7 +646,7 @@ int cmd_describe(int argc, const char **argv, const char *prefix) } else if (dirty) { struct lock_file index_lock = LOCK_INIT; struct rev_info revs; - struct argv_array args = ARGV_ARRAY_INIT; + struct strvec args = STRVEC_INIT; int fd, result; setup_work_tree(); @@ -658,8 +658,8 @@ int cmd_describe(int argc, const char **argv, const char *prefix) repo_update_index_if_able(the_repository, &index_lock); repo_init_revisions(the_repository, &revs, prefix); - argv_array_pushv(&args, diff_index_args); - if (setup_revisions(args.argc, args.argv, &revs, NULL) != 1) + strvec_pushv(&args, diff_index_args); + if (setup_revisions(args.nr, args.v, &revs, NULL) != 1) BUG("malformed internal diff-index command line"); result = run_diff_index(&revs, 0); diff --git a/builtin/difftool.c b/builtin/difftool.c index c280e682b2..7ac432b881 100644 --- a/builtin/difftool.c +++ b/builtin/difftool.c @@ -18,7 +18,7 @@ #include "run-command.h" #include "exec-cmd.h" #include "parse-options.h" -#include "argv-array.h" +#include "strvec.h" #include "strbuf.h" #include "lockfile.h" #include "object-store.h" @@ -210,10 +210,10 @@ static void changed_files(struct hashmap *result, const char *index_path, strbuf_addf(&index_env, "GIT_INDEX_FILE=%s", index_path); env[0] = index_env.buf; - argv_array_pushl(&update_index.args, - "--git-dir", git_dir, "--work-tree", workdir, - "update-index", "--really-refresh", "-q", - "--unmerged", NULL); + strvec_pushl(&update_index.args, + "--git-dir", git_dir, "--work-tree", workdir, + "update-index", "--really-refresh", "-q", + "--unmerged", NULL); update_index.no_stdin = 1; update_index.no_stdout = 1; update_index.no_stderr = 1; @@ -225,9 +225,9 @@ static void changed_files(struct hashmap *result, const char *index_path, /* Ignore any errors of update-index */ run_command(&update_index); - argv_array_pushl(&diff_files.args, - "--git-dir", git_dir, "--work-tree", workdir, - "diff-files", "--name-only", "-z", NULL); + strvec_pushl(&diff_files.args, + "--git-dir", git_dir, "--work-tree", workdir, + "diff-files", "--name-only", "-z", NULL); diff_files.no_stdin = 1; diff_files.git_cmd = 1; diff_files.use_shell = 0; @@ -393,10 +393,10 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix, child.clean_on_exit = 1; child.dir = prefix; child.out = -1; - argv_array_pushl(&child.args, "diff", "--raw", "--no-abbrev", "-z", - NULL); + strvec_pushl(&child.args, "diff", "--raw", "--no-abbrev", "-z", + NULL); for (i = 0; i < argc; i++) - argv_array_push(&child.args, argv[i]); + strvec_push(&child.args, argv[i]); if (start_command(&child)) die("could not obtain raw diff"); fp = xfdopen(child.out, "r"); @@ -667,7 +667,7 @@ finish: static int run_file_diff(int prompt, const char *prefix, int argc, const char **argv) { - struct argv_array args = ARGV_ARRAY_INIT; + struct strvec args = STRVEC_INIT; const char *env[] = { "GIT_PAGER=", "GIT_EXTERNAL_DIFF=git-difftool--helper", NULL, NULL @@ -680,10 +680,10 @@ static int run_file_diff(int prompt, const char *prefix, env[2] = "GIT_DIFFTOOL_NO_PROMPT=true"; - argv_array_push(&args, "diff"); + strvec_push(&args, "diff"); for (i = 0; i < argc; i++) - argv_array_push(&args, argv[i]); - ret = run_command_v_opt_cd_env(args.argv, RUN_GIT_CMD, prefix, env); + strvec_push(&args, argv[i]); + ret = run_command_v_opt_cd_env(args.v, RUN_GIT_CMD, prefix, env); exit(ret); } diff --git a/builtin/fetch.c b/builtin/fetch.c index 82ac4be8a5..c49f0e9752 100644 --- a/builtin/fetch.c +++ b/builtin/fetch.c @@ -19,7 +19,7 @@ #include "submodule-config.h" #include "submodule.h" #include "connected.h" -#include "argv-array.h" +#include "strvec.h" #include "utf8.h" #include "packfile.h" #include "list-objects-filter-options.h" @@ -1316,7 +1316,7 @@ static int do_fetch(struct transport *transport, int autotags = (transport->remote->fetch_tags == 1); int retcode = 0; const struct ref *remote_refs; - struct argv_array ref_prefixes = ARGV_ARRAY_INIT; + struct strvec ref_prefixes = STRVEC_INIT; int must_list_refs = 1; if (tags == TAGS_DEFAULT) { @@ -1354,8 +1354,8 @@ static int do_fetch(struct transport *transport, if (tags == TAGS_SET || tags == TAGS_DEFAULT) { must_list_refs = 1; - if (ref_prefixes.argc) - argv_array_push(&ref_prefixes, "refs/tags/"); + if (ref_prefixes.nr) + strvec_push(&ref_prefixes, "refs/tags/"); } if (must_list_refs) { @@ -1365,7 +1365,7 @@ static int do_fetch(struct transport *transport, } else remote_refs = NULL; - argv_array_clear(&ref_prefixes); + strvec_clear(&ref_prefixes); ref_map = get_ref_map(transport->remote, remote_refs, rs, tags, &autotags); @@ -1503,34 +1503,34 @@ static int add_remote_or_group(const char *name, struct string_list *list) return 1; } -static void add_options_to_argv(struct argv_array *argv) +static void add_options_to_argv(struct strvec *argv) { if (dry_run) - argv_array_push(argv, "--dry-run"); + strvec_push(argv, "--dry-run"); if (prune != -1) - argv_array_push(argv, prune ? "--prune" : "--no-prune"); + strvec_push(argv, prune ? "--prune" : "--no-prune"); if (prune_tags != -1) - argv_array_push(argv, prune_tags ? "--prune-tags" : "--no-prune-tags"); + strvec_push(argv, prune_tags ? "--prune-tags" : "--no-prune-tags"); if (update_head_ok) - argv_array_push(argv, "--update-head-ok"); + strvec_push(argv, "--update-head-ok"); if (force) - argv_array_push(argv, "--force"); + strvec_push(argv, "--force"); if (keep) - argv_array_push(argv, "--keep"); + strvec_push(argv, "--keep"); if (recurse_submodules == RECURSE_SUBMODULES_ON) - argv_array_push(argv, "--recurse-submodules"); + strvec_push(argv, "--recurse-submodules"); else if (recurse_submodules == RECURSE_SUBMODULES_ON_DEMAND) - argv_array_push(argv, "--recurse-submodules=on-demand"); + strvec_push(argv, "--recurse-submodules=on-demand"); if (tags == TAGS_SET) - argv_array_push(argv, "--tags"); + strvec_push(argv, "--tags"); else if (tags == TAGS_UNSET) - argv_array_push(argv, "--no-tags"); + strvec_push(argv, "--no-tags"); if (verbosity >= 2) - argv_array_push(argv, "-v"); + strvec_push(argv, "-v"); if (verbosity >= 1) - argv_array_push(argv, "-v"); + strvec_push(argv, "-v"); else if (verbosity < 0) - argv_array_push(argv, "-q"); + strvec_push(argv, "-q"); } @@ -1554,8 +1554,8 @@ static int fetch_next_remote(struct child_process *cp, struct strbuf *out, remote = state->remotes->items[state->next++].string; *task_cb = remote; - argv_array_pushv(&cp->args, state->argv); - argv_array_push(&cp->args, remote); + strvec_pushv(&cp->args, state->argv); + strvec_push(&cp->args, remote); cp->git_cmd = 1; if (verbosity >= 0) @@ -1592,7 +1592,7 @@ static int fetch_finished(int result, struct strbuf *out, static int fetch_multiple(struct string_list *list, int max_children) { int i, result = 0; - struct argv_array argv = ARGV_ARRAY_INIT; + struct strvec argv = STRVEC_INIT; if (!append && !dry_run) { int errcode = truncate_fetch_head(); @@ -1600,14 +1600,14 @@ static int fetch_multiple(struct string_list *list, int max_children) return errcode; } - argv_array_pushl(&argv, "fetch", "--append", "--no-auto-gc", - "--no-write-commit-graph", NULL); + strvec_pushl(&argv, "fetch", "--append", "--no-auto-gc", + "--no-write-commit-graph", NULL); add_options_to_argv(&argv); if (max_children != 1 && list->nr != 1) { - struct parallel_fetch_state state = { argv.argv, list, 0, 0 }; + struct parallel_fetch_state state = { argv.v, list, 0, 0 }; - argv_array_push(&argv, "--end-of-options"); + strvec_push(&argv, "--end-of-options"); result = run_processes_parallel_tr2(max_children, &fetch_next_remote, &fetch_failed_to_start, @@ -1620,17 +1620,17 @@ static int fetch_multiple(struct string_list *list, int max_children) } else for (i = 0; i < list->nr; i++) { const char *name = list->items[i].string; - argv_array_push(&argv, name); + strvec_push(&argv, name); if (verbosity >= 0) printf(_("Fetching %s\n"), name); - if (run_command_v_opt(argv.argv, RUN_GIT_CMD)) { + if (run_command_v_opt(argv.v, RUN_GIT_CMD)) { error(_("Could not fetch %s"), name); result = 1; } - argv_array_pop(&argv); + strvec_pop(&argv); } - argv_array_clear(&argv); + strvec_clear(&argv); return !!result; } @@ -1844,7 +1844,7 @@ int cmd_fetch(int argc, const char **argv, const char *prefix) } if (!result && (recurse_submodules != RECURSE_SUBMODULES_OFF)) { - struct argv_array options = ARGV_ARRAY_INIT; + struct strvec options = STRVEC_INIT; int max_children = max_jobs; if (max_children < 0) @@ -1860,7 +1860,7 @@ int cmd_fetch(int argc, const char **argv, const char *prefix) recurse_submodules_default, verbosity < 0, max_children); - argv_array_clear(&options); + strvec_clear(&options); } string_list_clear(&list, 0); diff --git a/builtin/gc.c b/builtin/gc.c index 8e0b9cf41b..aafa0946f5 100644 --- a/builtin/gc.c +++ b/builtin/gc.c @@ -18,7 +18,7 @@ #include "parse-options.h" #include "run-command.h" #include "sigchain.h" -#include "argv-array.h" +#include "strvec.h" #include "commit.h" #include "commit-graph.h" #include "packfile.h" @@ -50,12 +50,12 @@ static const char *prune_worktrees_expire = "3.months.ago"; static unsigned long big_pack_threshold; static unsigned long max_delta_cache_size = DEFAULT_DELTA_CACHE_SIZE; -static struct argv_array pack_refs_cmd = ARGV_ARRAY_INIT; -static struct argv_array reflog = ARGV_ARRAY_INIT; -static struct argv_array repack = ARGV_ARRAY_INIT; -static struct argv_array prune = ARGV_ARRAY_INIT; -static struct argv_array prune_worktrees = ARGV_ARRAY_INIT; -static struct argv_array rerere = ARGV_ARRAY_INIT; +static struct strvec pack_refs_cmd = STRVEC_INIT; +static struct strvec reflog = STRVEC_INIT; +static struct strvec repack = STRVEC_INIT; +static struct strvec prune = STRVEC_INIT; +static struct strvec prune_worktrees = STRVEC_INIT; +static struct strvec rerere = STRVEC_INIT; static struct tempfile *pidfile; static struct lock_file log_lock; @@ -311,18 +311,18 @@ static uint64_t estimate_repack_memory(struct packed_git *pack) static int keep_one_pack(struct string_list_item *item, void *data) { - argv_array_pushf(&repack, "--keep-pack=%s", basename(item->string)); + strvec_pushf(&repack, "--keep-pack=%s", basename(item->string)); return 0; } static void add_repack_all_option(struct string_list *keep_pack) { if (prune_expire && !strcmp(prune_expire, "now")) - argv_array_push(&repack, "-a"); + strvec_push(&repack, "-a"); else { - argv_array_push(&repack, "-A"); + strvec_push(&repack, "-A"); if (prune_expire) - argv_array_pushf(&repack, "--unpack-unreachable=%s", prune_expire); + strvec_pushf(&repack, "--unpack-unreachable=%s", prune_expire); } if (keep_pack) @@ -331,7 +331,7 @@ static void add_repack_all_option(struct string_list *keep_pack) static void add_repack_incremental_option(void) { - argv_array_push(&repack, "--no-write-bitmap-index"); + strvec_push(&repack, "--no-write-bitmap-index"); } static int need_to_gc(void) @@ -514,11 +514,11 @@ static void gc_before_repack(void) if (done++) return; - if (pack_refs && run_command_v_opt(pack_refs_cmd.argv, RUN_GIT_CMD)) - die(FAILED_RUN, pack_refs_cmd.argv[0]); + if (pack_refs && run_command_v_opt(pack_refs_cmd.v, RUN_GIT_CMD)) + die(FAILED_RUN, pack_refs_cmd.v[0]); - if (prune_reflogs && run_command_v_opt(reflog.argv, RUN_GIT_CMD)) - die(FAILED_RUN, reflog.argv[0]); + if (prune_reflogs && run_command_v_opt(reflog.v, RUN_GIT_CMD)) + die(FAILED_RUN, reflog.v[0]); } int cmd_gc(int argc, const char **argv, const char *prefix) @@ -552,12 +552,12 @@ int cmd_gc(int argc, const char **argv, const char *prefix) if (argc == 2 && !strcmp(argv[1], "-h")) usage_with_options(builtin_gc_usage, builtin_gc_options); - argv_array_pushl(&pack_refs_cmd, "pack-refs", "--all", "--prune", NULL); - argv_array_pushl(&reflog, "reflog", "expire", "--all", NULL); - argv_array_pushl(&repack, "repack", "-d", "-l", NULL); - argv_array_pushl(&prune, "prune", "--expire", NULL); - argv_array_pushl(&prune_worktrees, "worktree", "prune", "--expire", NULL); - argv_array_pushl(&rerere, "rerere", "gc", NULL); + strvec_pushl(&pack_refs_cmd, "pack-refs", "--all", "--prune", NULL); + strvec_pushl(&reflog, "reflog", "expire", "--all", NULL); + strvec_pushl(&repack, "repack", "-d", "-l", NULL); + strvec_pushl(&prune, "prune", "--expire", NULL); + strvec_pushl(&prune_worktrees, "worktree", "prune", "--expire", NULL); + strvec_pushl(&rerere, "rerere", "gc", NULL); /* default expiry time, overwritten in gc_config */ gc_config(); @@ -576,14 +576,14 @@ int cmd_gc(int argc, const char **argv, const char *prefix) die(_("failed to parse prune expiry value %s"), prune_expire); if (aggressive) { - argv_array_push(&repack, "-f"); + strvec_push(&repack, "-f"); if (aggressive_depth > 0) - argv_array_pushf(&repack, "--depth=%d", aggressive_depth); + strvec_pushf(&repack, "--depth=%d", aggressive_depth); if (aggressive_window > 0) - argv_array_pushf(&repack, "--window=%d", aggressive_window); + strvec_pushf(&repack, "--window=%d", aggressive_window); } if (quiet) - argv_array_push(&repack, "-q"); + strvec_push(&repack, "-q"); if (auto_gc) { /* @@ -653,29 +653,29 @@ int cmd_gc(int argc, const char **argv, const char *prefix) if (!repository_format_precious_objects) { close_object_store(the_repository->objects); - if (run_command_v_opt(repack.argv, RUN_GIT_CMD)) - die(FAILED_RUN, repack.argv[0]); + if (run_command_v_opt(repack.v, RUN_GIT_CMD)) + die(FAILED_RUN, repack.v[0]); if (prune_expire) { - argv_array_push(&prune, prune_expire); + strvec_push(&prune, prune_expire); if (quiet) - argv_array_push(&prune, "--no-progress"); + strvec_push(&prune, "--no-progress"); if (has_promisor_remote()) - argv_array_push(&prune, - "--exclude-promisor-objects"); - if (run_command_v_opt(prune.argv, RUN_GIT_CMD)) - die(FAILED_RUN, prune.argv[0]); + strvec_push(&prune, + "--exclude-promisor-objects"); + if (run_command_v_opt(prune.v, RUN_GIT_CMD)) + die(FAILED_RUN, prune.v[0]); } } if (prune_worktrees_expire) { - argv_array_push(&prune_worktrees, prune_worktrees_expire); - if (run_command_v_opt(prune_worktrees.argv, RUN_GIT_CMD)) - die(FAILED_RUN, prune_worktrees.argv[0]); + strvec_push(&prune_worktrees, prune_worktrees_expire); + if (run_command_v_opt(prune_worktrees.v, RUN_GIT_CMD)) + die(FAILED_RUN, prune_worktrees.v[0]); } - if (run_command_v_opt(rerere.argv, RUN_GIT_CMD)) - die(FAILED_RUN, rerere.argv[0]); + if (run_command_v_opt(rerere.v, RUN_GIT_CMD)) + die(FAILED_RUN, rerere.v[0]); report_garbage = report_pack_garbage; reprepare_packed_git(the_repository); diff --git a/builtin/grep.c b/builtin/grep.c index a5056f395a..cee9db3477 100644 --- a/builtin/grep.c +++ b/builtin/grep.c @@ -397,7 +397,7 @@ static void run_pager(struct grep_opt *opt, const char *prefix) int i, status; for (i = 0; i < path_list->nr; i++) - argv_array_push(&child.args, path_list->items[i].string); + strvec_push(&child.args, path_list->items[i].string); child.dir = prefix; child.use_shell = 1; @@ -466,7 +466,7 @@ static int grep_submodule(struct grep_opt *opt, struct strbuf base = STRBUF_INIT; obj_read_lock(); - object = parse_object_or_die(oid, oid_to_hex(oid)); + object = parse_object_or_die(oid, NULL); obj_read_unlock(); data = read_object_with_reference(&subrepo, &object->oid, tree_type, diff --git a/builtin/help.c b/builtin/help.c index 299206eb57..bb339f0fc8 100644 --- a/builtin/help.c +++ b/builtin/help.c @@ -579,7 +579,7 @@ int cmd_help(int argc, const char **argv, const char *prefix) } if (show_guides) - list_common_guides_help(); + list_guides_help(); if (show_all || show_guides) { printf("%s\n", _(git_more_info_string)); diff --git a/builtin/init-db.c b/builtin/init-db.c index cee64823cb..f70076d38e 100644 --- a/builtin/init-db.c +++ b/builtin/init-db.c @@ -183,11 +183,6 @@ void initialize_repository_version(int hash_algo) char repo_version_string[10]; int repo_version = GIT_REPO_VERSION; -#ifndef ENABLE_SHA256 - if (hash_algo != GIT_HASH_SHA1) - die(_("The hash algorithm %s is not supported in this build."), hash_algos[hash_algo].name); -#endif - if (hash_algo != GIT_HASH_SHA1) repo_version = GIT_REPO_VERSION_READ; diff --git a/builtin/log.c b/builtin/log.c index d104d5c688..33528fefa9 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -1128,18 +1128,18 @@ do_pp: static int get_notes_refs(struct string_list_item *item, void *arg) { - argv_array_pushf(arg, "--notes=%s", item->string); + strvec_pushf(arg, "--notes=%s", item->string); return 0; } -static void get_notes_args(struct argv_array *arg, struct rev_info *rev) +static void get_notes_args(struct strvec *arg, struct rev_info *rev) { if (!rev->show_notes) { - argv_array_push(arg, "--no-notes"); + strvec_push(arg, "--no-notes"); } else if (rev->notes_opt.use_default_notes > 0 || (rev->notes_opt.use_default_notes == -1 && !rev->notes_opt.extra_notes_refs.nr)) { - argv_array_push(arg, "--notes"); + strvec_push(arg, "--notes"); } else { for_each_string_list(&rev->notes_opt.extra_notes_refs, get_notes_refs, arg); } @@ -1217,7 +1217,7 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout, * can be added later if deemed desirable. */ struct diff_options opts; - struct argv_array other_arg = ARGV_ARRAY_INIT; + struct strvec other_arg = STRVEC_INIT; diff_setup(&opts); opts.file = rev->diffopt.file; opts.use_color = rev->diffopt.use_color; @@ -1226,7 +1226,7 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout, get_notes_args(&other_arg, rev); show_range_diff(rev->rdiff1, rev->rdiff2, rev->creation_factor, 1, &opts, &other_arg); - argv_array_clear(&other_arg); + strvec_clear(&other_arg); } } diff --git a/builtin/ls-remote.c b/builtin/ls-remote.c index 3a4dd12903..ea91679f33 100644 --- a/builtin/ls-remote.c +++ b/builtin/ls-remote.c @@ -45,7 +45,7 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix) int show_symref_target = 0; const char *uploadpack = NULL; const char **pattern = NULL; - struct argv_array ref_prefixes = ARGV_ARRAY_INIT; + struct strvec ref_prefixes = STRVEC_INIT; int i; struct string_list server_options = STRING_LIST_INIT_DUP; @@ -92,9 +92,9 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix) } if (flags & REF_TAGS) - argv_array_push(&ref_prefixes, "refs/tags/"); + strvec_push(&ref_prefixes, "refs/tags/"); if (flags & REF_HEADS) - argv_array_push(&ref_prefixes, "refs/heads/"); + strvec_push(&ref_prefixes, "refs/heads/"); remote = remote_get(dest); if (!remote) { diff --git a/builtin/merge.c b/builtin/merge.c index 7da707bf55..74829a838e 100644 --- a/builtin/merge.c +++ b/builtin/merge.c @@ -72,7 +72,6 @@ static const char **xopts; static size_t xopts_nr, xopts_alloc; static const char *branch; static char *branch_mergeoptions; -static int option_renormalize; static int verbosity; static int allow_rerere_auto; static int abort_current_merge; @@ -621,8 +620,6 @@ static int git_merge_config(const char *k, const char *v, void *cb) return git_config_string(&pull_octopus, k, v); else if (!strcmp(k, "commit.cleanup")) return git_config_string(&cleanup_arg, k, v); - else if (!strcmp(k, "merge.renormalize")) - option_renormalize = git_config_bool(k, v); else if (!strcmp(k, "merge.ff")) { int boolval = git_parse_maybe_bool(v); if (0 <= boolval) { @@ -721,7 +718,6 @@ static int try_merge_strategy(const char *strategy, struct commit_list *common, if (!strcmp(strategy, "subtree")) o.subtree_shift = ""; - o.renormalize = option_renormalize; o.show_rename_progress = show_progress == -1 ? isatty(2) : show_progress; diff --git a/builtin/mv.c b/builtin/mv.c index be15ba7044..7dac714af9 100644 --- a/builtin/mv.c +++ b/builtin/mv.c @@ -132,6 +132,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix) struct stat st; struct string_list src_for_dst = STRING_LIST_INIT_NODUP; struct lock_file lock_file = LOCK_INIT; + struct cache_entry *ce; git_config(git_default_config, NULL); @@ -220,9 +221,11 @@ int cmd_mv(int argc, const char **argv, const char *prefix) } argc += last - first; } - } else if (cache_name_pos(src, length) < 0) + } else if (!(ce = cache_file_exists(src, length, ignore_case))) { bad = _("not under version control"); - else if (lstat(dst, &st) == 0 && + } else if (ce_stage(ce)) { + bad = _("conflicted"); + } else if (lstat(dst, &st) == 0 && (!ignore_case || strcasecmp(src, dst))) { bad = _("destination exists"); if (force) { diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c index 7016b28485..ada47d1a57 100644 --- a/builtin/pack-objects.c +++ b/builtin/pack-objects.c @@ -27,7 +27,7 @@ #include "delta-islands.h" #include "reachable.h" #include "oid-array.h" -#include "argv-array.h" +#include "strvec.h" #include "list.h" #include "packfile.h" #include "object-store.h" @@ -35,6 +35,7 @@ #include "midx.h" #include "trace2.h" #include "shallow.h" +#include "promisor-remote.h" #define IN_PACK(obj) oe_in_pack(&to_pack, obj) #define SIZE(obj) oe_size(&to_pack, obj) @@ -1704,9 +1705,30 @@ static int can_reuse_delta(const struct object_id *base_oid, return 0; } -static void check_object(struct object_entry *entry) +static void prefetch_to_pack(uint32_t object_index_start) { + struct oid_array to_fetch = OID_ARRAY_INIT; + uint32_t i; + + for (i = object_index_start; i < to_pack.nr_objects; i++) { + struct object_entry *entry = to_pack.objects + i; + + if (!oid_object_info_extended(the_repository, + &entry->idx.oid, + NULL, + OBJECT_INFO_FOR_PREFETCH)) + continue; + oid_array_append(&to_fetch, &entry->idx.oid); + } + promisor_remote_get_direct(the_repository, + to_fetch.oid, to_fetch.nr); + oid_array_clear(&to_fetch); +} + +static void check_object(struct object_entry *entry, uint32_t object_index) { unsigned long canonical_size; + enum object_type type; + struct object_info oi = {.typep = &type, .sizep = &canonical_size}; if (IN_PACK(entry)) { struct packed_git *p = IN_PACK(entry); @@ -1840,8 +1862,18 @@ static void check_object(struct object_entry *entry) unuse_pack(&w_curs); } - oe_set_type(entry, - oid_object_info(the_repository, &entry->idx.oid, &canonical_size)); + if (oid_object_info_extended(the_repository, &entry->idx.oid, &oi, + OBJECT_INFO_SKIP_FETCH_OBJECT | OBJECT_INFO_LOOKUP_REPLACE) < 0) { + if (has_promisor_remote()) { + prefetch_to_pack(object_index); + if (oid_object_info_extended(the_repository, &entry->idx.oid, &oi, + OBJECT_INFO_SKIP_FETCH_OBJECT | OBJECT_INFO_LOOKUP_REPLACE) < 0) + type = -1; + } else { + type = -1; + } + } + oe_set_type(entry, type); if (entry->type_valid) { SET_SIZE(entry, canonical_size); } else { @@ -2061,7 +2093,7 @@ static void get_object_details(void) for (i = 0; i < to_pack.nr_objects; i++) { struct object_entry *entry = sorted_by_offset[i]; - check_object(entry); + check_object(entry, i); if (entry->type_valid && oe_size_greater_than(&to_pack, entry, big_file_threshold)) entry->no_try_delta = 1; @@ -3439,7 +3471,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix) int use_internal_rev_list = 0; int shallow = 0; int all_progress_implied = 0; - struct argv_array rp = ARGV_ARRAY_INIT; + struct strvec rp = STRVEC_INIT; int rev_list_unpacked = 0, rev_list_all = 0, rev_list_reflog = 0; int rev_list_index = 0; struct string_list keep_pack_list = STRING_LIST_INIT_NODUP; @@ -3575,36 +3607,36 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix) cache_max_small_delta_size = (1U << OE_Z_DELTA_BITS) - 1; } - argv_array_push(&rp, "pack-objects"); + strvec_push(&rp, "pack-objects"); if (thin) { use_internal_rev_list = 1; - argv_array_push(&rp, shallow + strvec_push(&rp, shallow ? "--objects-edge-aggressive" : "--objects-edge"); } else - argv_array_push(&rp, "--objects"); + strvec_push(&rp, "--objects"); if (rev_list_all) { use_internal_rev_list = 1; - argv_array_push(&rp, "--all"); + strvec_push(&rp, "--all"); } if (rev_list_reflog) { use_internal_rev_list = 1; - argv_array_push(&rp, "--reflog"); + strvec_push(&rp, "--reflog"); } if (rev_list_index) { use_internal_rev_list = 1; - argv_array_push(&rp, "--indexed-objects"); + strvec_push(&rp, "--indexed-objects"); } if (rev_list_unpacked) { use_internal_rev_list = 1; - argv_array_push(&rp, "--unpacked"); + strvec_push(&rp, "--unpacked"); } if (exclude_promisor_objects) { use_internal_rev_list = 1; fetch_if_missing = 0; - argv_array_push(&rp, "--exclude-promisor-objects"); + strvec_push(&rp, "--exclude-promisor-objects"); } if (unpack_unreachable || keep_unreachable || pack_loose_unreachable) use_internal_rev_list = 1; @@ -3666,7 +3698,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix) write_bitmap_index = 0; if (use_delta_islands) - argv_array_push(&rp, "--topo-order"); + strvec_push(&rp, "--topo-order"); if (progress && all_progress_implied) progress = 2; @@ -3704,8 +3736,8 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix) if (!use_internal_rev_list) read_object_list_from_stdin(); else { - get_object_list(rp.argc, rp.argv); - argv_array_clear(&rp); + get_object_list(rp.nr, rp.v); + strvec_clear(&rp); } cleanup_preferred_base(); if (include_tag && nr_result) diff --git a/builtin/pull.c b/builtin/pull.c index 8159c5d7c9..015f6ded0b 100644 --- a/builtin/pull.c +++ b/builtin/pull.c @@ -87,8 +87,8 @@ static char *opt_verify_signatures; static int opt_autostash = -1; static int config_autostash; static int check_trust_level = 1; -static struct argv_array opt_strategies = ARGV_ARRAY_INIT; -static struct argv_array opt_strategy_opts = ARGV_ARRAY_INIT; +static struct strvec opt_strategies = STRVEC_INIT; +static struct strvec opt_strategy_opts = STRVEC_INIT; static char *opt_gpg_sign; static int opt_allow_unrelated_histories; @@ -110,7 +110,7 @@ static char *opt_ipv4; static char *opt_ipv6; static int opt_show_forced_updates = -1; static char *set_upstream; -static struct argv_array opt_fetch = ARGV_ARRAY_INIT; +static struct strvec opt_fetch = STRVEC_INIT; static struct option pull_options[] = { /* Shared options */ @@ -251,25 +251,25 @@ static struct option pull_options[] = { /** * Pushes "-q" or "-v" switches into arr to match the opt_verbosity level. */ -static void argv_push_verbosity(struct argv_array *arr) +static void argv_push_verbosity(struct strvec *arr) { int verbosity; for (verbosity = opt_verbosity; verbosity > 0; verbosity--) - argv_array_push(arr, "-v"); + strvec_push(arr, "-v"); for (verbosity = opt_verbosity; verbosity < 0; verbosity++) - argv_array_push(arr, "-q"); + strvec_push(arr, "-q"); } /** * Pushes "-f" switches into arr to match the opt_force level. */ -static void argv_push_force(struct argv_array *arr) +static void argv_push_force(struct strvec *arr) { int force = opt_force; while (force-- > 0) - argv_array_push(arr, "-f"); + strvec_push(arr, "-f"); } /** @@ -524,75 +524,75 @@ static void parse_repo_refspecs(int argc, const char **argv, const char **repo, */ static int run_fetch(const char *repo, const char **refspecs) { - struct argv_array args = ARGV_ARRAY_INIT; + struct strvec args = STRVEC_INIT; int ret; - argv_array_pushl(&args, "fetch", "--update-head-ok", NULL); + strvec_pushl(&args, "fetch", "--update-head-ok", NULL); /* Shared options */ argv_push_verbosity(&args); if (opt_progress) - argv_array_push(&args, opt_progress); + strvec_push(&args, opt_progress); /* Options passed to git-fetch */ if (opt_all) - argv_array_push(&args, opt_all); + strvec_push(&args, opt_all); if (opt_append) - argv_array_push(&args, opt_append); + strvec_push(&args, opt_append); if (opt_upload_pack) - argv_array_push(&args, opt_upload_pack); + strvec_push(&args, opt_upload_pack); argv_push_force(&args); if (opt_tags) - argv_array_push(&args, opt_tags); + strvec_push(&args, opt_tags); if (opt_prune) - argv_array_push(&args, opt_prune); + strvec_push(&args, opt_prune); if (recurse_submodules != RECURSE_SUBMODULES_DEFAULT) switch (recurse_submodules) { case RECURSE_SUBMODULES_ON: - argv_array_push(&args, "--recurse-submodules=on"); + strvec_push(&args, "--recurse-submodules=on"); break; case RECURSE_SUBMODULES_OFF: - argv_array_push(&args, "--recurse-submodules=no"); + strvec_push(&args, "--recurse-submodules=no"); break; case RECURSE_SUBMODULES_ON_DEMAND: - argv_array_push(&args, "--recurse-submodules=on-demand"); + strvec_push(&args, "--recurse-submodules=on-demand"); break; default: BUG("submodule recursion option not understood"); } if (max_children) - argv_array_push(&args, max_children); + strvec_push(&args, max_children); if (opt_dry_run) - argv_array_push(&args, "--dry-run"); + strvec_push(&args, "--dry-run"); if (opt_keep) - argv_array_push(&args, opt_keep); + strvec_push(&args, opt_keep); if (opt_depth) - argv_array_push(&args, opt_depth); + strvec_push(&args, opt_depth); if (opt_unshallow) - argv_array_push(&args, opt_unshallow); + strvec_push(&args, opt_unshallow); if (opt_update_shallow) - argv_array_push(&args, opt_update_shallow); + strvec_push(&args, opt_update_shallow); if (opt_refmap) - argv_array_push(&args, opt_refmap); + strvec_push(&args, opt_refmap); if (opt_ipv4) - argv_array_push(&args, opt_ipv4); + strvec_push(&args, opt_ipv4); if (opt_ipv6) - argv_array_push(&args, opt_ipv6); + strvec_push(&args, opt_ipv6); if (opt_show_forced_updates > 0) - argv_array_push(&args, "--show-forced-updates"); + strvec_push(&args, "--show-forced-updates"); else if (opt_show_forced_updates == 0) - argv_array_push(&args, "--no-show-forced-updates"); + strvec_push(&args, "--no-show-forced-updates"); if (set_upstream) - argv_array_push(&args, set_upstream); - argv_array_pushv(&args, opt_fetch.argv); + strvec_push(&args, set_upstream); + strvec_pushv(&args, opt_fetch.v); if (repo) { - argv_array_push(&args, repo); - argv_array_pushv(&args, refspecs); + strvec_push(&args, repo); + strvec_pushv(&args, refspecs); } else if (*refspecs) BUG("refspecs without repo?"); - ret = run_command_v_opt(args.argv, RUN_GIT_CMD); - argv_array_clear(&args); + ret = run_command_v_opt(args.v, RUN_GIT_CMD); + strvec_clear(&args); return ret; } @@ -637,8 +637,8 @@ static int rebase_submodules(void) cp.git_cmd = 1; cp.no_stdin = 1; - argv_array_pushl(&cp.args, "submodule", "update", - "--recursive", "--rebase", NULL); + strvec_pushl(&cp.args, "submodule", "update", + "--recursive", "--rebase", NULL); argv_push_verbosity(&cp.args); return run_command(&cp); @@ -650,8 +650,8 @@ static int update_submodules(void) cp.git_cmd = 1; cp.no_stdin = 1; - argv_array_pushl(&cp.args, "submodule", "update", - "--recursive", "--checkout", NULL); + strvec_pushl(&cp.args, "submodule", "update", + "--recursive", "--checkout", NULL); argv_push_verbosity(&cp.args); return run_command(&cp); @@ -663,48 +663,48 @@ static int update_submodules(void) static int run_merge(void) { int ret; - struct argv_array args = ARGV_ARRAY_INIT; + struct strvec args = STRVEC_INIT; - argv_array_pushl(&args, "merge", NULL); + strvec_pushl(&args, "merge", NULL); /* Shared options */ argv_push_verbosity(&args); if (opt_progress) - argv_array_push(&args, opt_progress); + strvec_push(&args, opt_progress); /* Options passed to git-merge */ if (opt_diffstat) - argv_array_push(&args, opt_diffstat); + strvec_push(&args, opt_diffstat); if (opt_log) - argv_array_push(&args, opt_log); + strvec_push(&args, opt_log); if (opt_signoff) - argv_array_push(&args, opt_signoff); + strvec_push(&args, opt_signoff); if (opt_squash) - argv_array_push(&args, opt_squash); + strvec_push(&args, opt_squash); if (opt_commit) - argv_array_push(&args, opt_commit); + strvec_push(&args, opt_commit); if (opt_edit) - argv_array_push(&args, opt_edit); + strvec_push(&args, opt_edit); if (cleanup_arg) - argv_array_pushf(&args, "--cleanup=%s", cleanup_arg); + strvec_pushf(&args, "--cleanup=%s", cleanup_arg); if (opt_ff) - argv_array_push(&args, opt_ff); + strvec_push(&args, opt_ff); if (opt_verify_signatures) - argv_array_push(&args, opt_verify_signatures); - argv_array_pushv(&args, opt_strategies.argv); - argv_array_pushv(&args, opt_strategy_opts.argv); + strvec_push(&args, opt_verify_signatures); + strvec_pushv(&args, opt_strategies.v); + strvec_pushv(&args, opt_strategy_opts.v); if (opt_gpg_sign) - argv_array_push(&args, opt_gpg_sign); + strvec_push(&args, opt_gpg_sign); if (opt_autostash == 0) - argv_array_push(&args, "--no-autostash"); + strvec_push(&args, "--no-autostash"); else if (opt_autostash == 1) - argv_array_push(&args, "--autostash"); + strvec_push(&args, "--autostash"); if (opt_allow_unrelated_histories > 0) - argv_array_push(&args, "--allow-unrelated-histories"); + strvec_push(&args, "--allow-unrelated-histories"); - argv_array_push(&args, "FETCH_HEAD"); - ret = run_command_v_opt(args.argv, RUN_GIT_CMD); - argv_array_clear(&args); + strvec_push(&args, "FETCH_HEAD"); + ret = run_command_v_opt(args.v, RUN_GIT_CMD); + strvec_clear(&args); return ret; } @@ -801,8 +801,8 @@ static int get_rebase_fork_point(struct object_id *fork_point, const char *repo, if (!remote_branch) return -1; - argv_array_pushl(&cp.args, "merge-base", "--fork-point", - remote_branch, curr_branch->name, NULL); + strvec_pushl(&cp.args, "merge-base", "--fork-point", + remote_branch, curr_branch->name, NULL); cp.no_stdin = 1; cp.no_stderr = 1; cp.git_cmd = 1; @@ -862,48 +862,48 @@ static int run_rebase(const struct object_id *curr_head, { int ret; struct object_id oct_merge_base; - struct argv_array args = ARGV_ARRAY_INIT; + struct strvec args = STRVEC_INIT; if (!get_octopus_merge_base(&oct_merge_base, curr_head, merge_head, fork_point)) if (!is_null_oid(fork_point) && oideq(&oct_merge_base, fork_point)) fork_point = NULL; - argv_array_push(&args, "rebase"); + strvec_push(&args, "rebase"); /* Shared options */ argv_push_verbosity(&args); /* Options passed to git-rebase */ if (opt_rebase == REBASE_MERGES) - argv_array_push(&args, "--rebase-merges"); + strvec_push(&args, "--rebase-merges"); else if (opt_rebase == REBASE_PRESERVE) - argv_array_push(&args, "--preserve-merges"); + strvec_push(&args, "--preserve-merges"); else if (opt_rebase == REBASE_INTERACTIVE) - argv_array_push(&args, "--interactive"); + strvec_push(&args, "--interactive"); if (opt_diffstat) - argv_array_push(&args, opt_diffstat); - argv_array_pushv(&args, opt_strategies.argv); - argv_array_pushv(&args, opt_strategy_opts.argv); + strvec_push(&args, opt_diffstat); + strvec_pushv(&args, opt_strategies.v); + strvec_pushv(&args, opt_strategy_opts.v); if (opt_gpg_sign) - argv_array_push(&args, opt_gpg_sign); + strvec_push(&args, opt_gpg_sign); if (opt_autostash == 0) - argv_array_push(&args, "--no-autostash"); + strvec_push(&args, "--no-autostash"); else if (opt_autostash == 1) - argv_array_push(&args, "--autostash"); + strvec_push(&args, "--autostash"); if (opt_verify_signatures && !strcmp(opt_verify_signatures, "--verify-signatures")) warning(_("ignoring --verify-signatures for rebase")); - argv_array_push(&args, "--onto"); - argv_array_push(&args, oid_to_hex(merge_head)); + strvec_push(&args, "--onto"); + strvec_push(&args, oid_to_hex(merge_head)); if (fork_point && !is_null_oid(fork_point)) - argv_array_push(&args, oid_to_hex(fork_point)); + strvec_push(&args, oid_to_hex(fork_point)); else - argv_array_push(&args, oid_to_hex(merge_head)); + strvec_push(&args, oid_to_hex(merge_head)); - ret = run_command_v_opt(args.argv, RUN_GIT_CMD); - argv_array_clear(&args); + ret = run_command_v_opt(args.v, RUN_GIT_CMD); + strvec_clear(&args); return ret; } diff --git a/builtin/range-diff.c b/builtin/range-diff.c index d8a4670629..24c4162f74 100644 --- a/builtin/range-diff.c +++ b/builtin/range-diff.c @@ -15,7 +15,7 @@ int cmd_range_diff(int argc, const char **argv, const char *prefix) { int creation_factor = RANGE_DIFF_CREATION_FACTOR_DEFAULT; struct diff_options diffopt = { NULL }; - struct argv_array other_arg = ARGV_ARRAY_INIT; + struct strvec other_arg = STRVEC_INIT; int simple_color = -1; struct option range_diff_options[] = { OPT_INTEGER(0, "creation-factor", &creation_factor, @@ -84,7 +84,7 @@ int cmd_range_diff(int argc, const char **argv, const char *prefix) res = show_range_diff(range1.buf, range2.buf, creation_factor, simple_color < 1, &diffopt, &other_arg); - argv_array_clear(&other_arg); + strvec_clear(&other_arg); strbuf_release(&range1); strbuf_release(&range2); diff --git a/builtin/rebase.c b/builtin/rebase.c index 37ba76ac3d..dadb52fa92 100644 --- a/builtin/rebase.c +++ b/builtin/rebase.c @@ -8,7 +8,7 @@ #include "builtin.h" #include "run-command.h" #include "exec-cmd.h" -#include "argv-array.h" +#include "strvec.h" #include "dir.h" #include "packfile.h" #include "refs.h" @@ -84,7 +84,7 @@ struct rebase_options { REBASE_FORCE = 1<<3, REBASE_INTERACTIVE_EXPLICIT = 1<<4, } flags; - struct argv_array git_am_opts; + struct strvec git_am_opts; const char *action; int signoff; int allow_rerere_autoupdate; @@ -108,7 +108,7 @@ struct rebase_options { .keep_empty = 1, \ .default_backend = "merge", \ .flags = REBASE_NO_QUIET, \ - .git_am_opts = ARGV_ARRAY_INIT, \ + .git_am_opts = STRVEC_INIT, \ .git_format_patch_opt = STRBUF_INIT \ } @@ -323,7 +323,7 @@ static int do_interactive_rebase(struct rebase_options *opts, unsigned flags) int ret; const char *head_hash = NULL; char *revisions = NULL, *shortrevisions = NULL; - struct argv_array make_script_args = ARGV_ARRAY_INIT; + struct strvec make_script_args = STRVEC_INIT; struct todo_list todo_list = TODO_LIST_INIT; struct replay_opts replay = get_replay_opts(opts); struct string_list commands = STRING_LIST_INIT_DUP; @@ -345,13 +345,13 @@ static int do_interactive_rebase(struct rebase_options *opts, unsigned flags) write_file(path_squash_onto(), "%s\n", oid_to_hex(opts->squash_onto)); - argv_array_pushl(&make_script_args, "", revisions, NULL); + strvec_pushl(&make_script_args, "", revisions, NULL); if (opts->restrict_revision) - argv_array_pushf(&make_script_args, "^%s", - oid_to_hex(&opts->restrict_revision->object.oid)); + strvec_pushf(&make_script_args, "^%s", + oid_to_hex(&opts->restrict_revision->object.oid)); ret = sequencer_make_script(the_repository, &todo_list.buf, - make_script_args.argc, make_script_args.argv, + make_script_args.nr, make_script_args.v, flags); if (ret) @@ -372,7 +372,7 @@ static int do_interactive_rebase(struct rebase_options *opts, unsigned flags) free(revisions); free(shortrevisions); todo_list_release(&todo_list); - argv_array_clear(&make_script_args); + strvec_clear(&make_script_args); return ret; } @@ -420,7 +420,7 @@ static int run_sequencer_rebase(struct rebase_options *opts, struct child_process cmd = CHILD_PROCESS_INIT; cmd.git_cmd = 1; - argv_array_pushl(&cmd.args, "show", "REBASE_HEAD", "--", NULL); + strvec_pushl(&cmd.args, "show", "REBASE_HEAD", "--", NULL); ret = run_command(&cmd); break; @@ -811,13 +811,13 @@ static int run_am(struct rebase_options *opts) char *rebased_patches; am.git_cmd = 1; - argv_array_push(&am.args, "am"); + strvec_push(&am.args, "am"); if (opts->action && !strcmp("continue", opts->action)) { - argv_array_push(&am.args, "--resolved"); - argv_array_pushf(&am.args, "--resolvemsg=%s", resolvemsg); + strvec_push(&am.args, "--resolved"); + strvec_pushf(&am.args, "--resolvemsg=%s", resolvemsg); if (opts->gpg_sign_opt) - argv_array_push(&am.args, opts->gpg_sign_opt); + strvec_push(&am.args, opts->gpg_sign_opt); status = run_command(&am); if (status) return status; @@ -825,8 +825,8 @@ static int run_am(struct rebase_options *opts) return move_to_original_branch(opts); } if (opts->action && !strcmp("skip", opts->action)) { - argv_array_push(&am.args, "--skip"); - argv_array_pushf(&am.args, "--resolvemsg=%s", resolvemsg); + strvec_push(&am.args, "--skip"); + strvec_pushf(&am.args, "--resolvemsg=%s", resolvemsg); status = run_command(&am); if (status) return status; @@ -834,7 +834,7 @@ static int run_am(struct rebase_options *opts) return move_to_original_branch(opts); } if (opts->action && !strcmp("show-current-patch", opts->action)) { - argv_array_push(&am.args, "--show-current-patch"); + strvec_push(&am.args, "--show-current-patch"); return run_command(&am); } @@ -852,29 +852,29 @@ static int run_am(struct rebase_options *opts) status = error_errno(_("could not open '%s' for writing"), rebased_patches); free(rebased_patches); - argv_array_clear(&am.args); + strvec_clear(&am.args); return status; } format_patch.git_cmd = 1; - argv_array_pushl(&format_patch.args, "format-patch", "-k", "--stdout", - "--full-index", "--cherry-pick", "--right-only", - "--src-prefix=a/", "--dst-prefix=b/", "--no-renames", - "--no-cover-letter", "--pretty=mboxrd", "--topo-order", - "--no-base", NULL); + strvec_pushl(&format_patch.args, "format-patch", "-k", "--stdout", + "--full-index", "--cherry-pick", "--right-only", + "--src-prefix=a/", "--dst-prefix=b/", "--no-renames", + "--no-cover-letter", "--pretty=mboxrd", "--topo-order", + "--no-base", NULL); if (opts->git_format_patch_opt.len) - argv_array_split(&format_patch.args, - opts->git_format_patch_opt.buf); - argv_array_push(&format_patch.args, revisions.buf); + strvec_split(&format_patch.args, + opts->git_format_patch_opt.buf); + strvec_push(&format_patch.args, revisions.buf); if (opts->restrict_revision) - argv_array_pushf(&format_patch.args, "^%s", - oid_to_hex(&opts->restrict_revision->object.oid)); + strvec_pushf(&format_patch.args, "^%s", + oid_to_hex(&opts->restrict_revision->object.oid)); status = run_command(&format_patch); if (status) { unlink(rebased_patches); free(rebased_patches); - argv_array_clear(&am.args); + strvec_clear(&am.args); reset_head(the_repository, &opts->orig_head, "checkout", opts->head_name, 0, @@ -896,20 +896,20 @@ static int run_am(struct rebase_options *opts) status = error_errno(_("could not open '%s' for reading"), rebased_patches); free(rebased_patches); - argv_array_clear(&am.args); + strvec_clear(&am.args); return status; } - argv_array_pushv(&am.args, opts->git_am_opts.argv); - argv_array_push(&am.args, "--rebasing"); - argv_array_pushf(&am.args, "--resolvemsg=%s", resolvemsg); - argv_array_push(&am.args, "--patch-format=mboxrd"); + strvec_pushv(&am.args, opts->git_am_opts.v); + strvec_push(&am.args, "--rebasing"); + strvec_pushf(&am.args, "--resolvemsg=%s", resolvemsg); + strvec_push(&am.args, "--patch-format=mboxrd"); if (opts->allow_rerere_autoupdate == RERERE_AUTOUPDATE) - argv_array_push(&am.args, "--rerere-autoupdate"); + strvec_push(&am.args, "--rerere-autoupdate"); else if (opts->allow_rerere_autoupdate == RERERE_NOAUTOUPDATE) - argv_array_push(&am.args, "--no-rerere-autoupdate"); + strvec_push(&am.args, "--no-rerere-autoupdate"); if (opts->gpg_sign_opt) - argv_array_push(&am.args, opts->gpg_sign_opt); + strvec_push(&am.args, opts->gpg_sign_opt); status = run_command(&am); unlink(rebased_patches); free(rebased_patches); @@ -969,7 +969,7 @@ static int run_specific_rebase(struct rebase_options *opts, enum action action) add_var(&script_snippet, "revisions", opts->revisions); add_var(&script_snippet, "restrict_revision", opts->restrict_revision ? oid_to_hex(&opts->restrict_revision->object.oid) : NULL); - sq_quote_argv_pretty(&buf, opts->git_am_opts.argv); + sq_quote_argv_pretty(&buf, opts->git_am_opts.v); add_var(&script_snippet, "git_am_opt", buf.buf); strbuf_release(&buf); add_var(&script_snippet, "verbose", @@ -1625,8 +1625,8 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) allow_preemptive_ff = 0; } - for (i = 0; i < options.git_am_opts.argc; i++) { - const char *option = options.git_am_opts.argv[i], *p; + for (i = 0; i < options.git_am_opts.nr; i++) { + const char *option = options.git_am_opts.v[i], *p; if (!strcmp(option, "--committer-date-is-author-date") || !strcmp(option, "--ignore-date") || !strcmp(option, "--whitespace=fix") || @@ -1649,7 +1649,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) exit(1); if (!(options.flags & REBASE_NO_QUIET)) - argv_array_push(&options.git_am_opts, "-q"); + strvec_push(&options.git_am_opts, "-q"); if (options.empty != EMPTY_UNSPECIFIED) imply_merge(&options, "--empty"); @@ -1721,10 +1721,10 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) if (isatty(2) && options.flags & REBASE_NO_QUIET) strbuf_addstr(&options.git_format_patch_opt, " --progress"); - if (options.git_am_opts.argc || options.type == REBASE_APPLY) { + if (options.git_am_opts.nr || options.type == REBASE_APPLY) { /* all am options except -q are compatible only with --apply */ - for (i = options.git_am_opts.argc - 1; i >= 0; i--) - if (strcmp(options.git_am_opts.argv[i], "-q")) + for (i = options.git_am_opts.nr - 1; i >= 0; i--) + if (strcmp(options.git_am_opts.v[i], "-q")) break; if (i >= 0) { @@ -1776,7 +1776,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) if (options.type == REBASE_PRESERVE_MERGES) die("cannot combine '--signoff' with " "'--preserve-merges'"); - argv_array_push(&options.git_am_opts, "--signoff"); + strvec_push(&options.git_am_opts, "--signoff"); options.flags |= REBASE_FORCE; } diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c index d43663bb0a..439f29d6c7 100644 --- a/builtin/receive-pack.c +++ b/builtin/receive-pack.c @@ -15,7 +15,7 @@ #include "string-list.h" #include "oid-array.h" #include "connected.h" -#include "argv-array.h" +#include "strvec.h" #include "version.h" #include "tag.h" #include "gpg-interface.h" @@ -667,25 +667,25 @@ static void prepare_push_cert_sha1(struct child_process *proc) nonce_status = check_nonce(push_cert.buf, bogs); } if (!is_null_oid(&push_cert_oid)) { - argv_array_pushf(&proc->env_array, "GIT_PUSH_CERT=%s", - oid_to_hex(&push_cert_oid)); - argv_array_pushf(&proc->env_array, "GIT_PUSH_CERT_SIGNER=%s", - sigcheck.signer ? sigcheck.signer : ""); - argv_array_pushf(&proc->env_array, "GIT_PUSH_CERT_KEY=%s", - sigcheck.key ? sigcheck.key : ""); - argv_array_pushf(&proc->env_array, "GIT_PUSH_CERT_STATUS=%c", - sigcheck.result); + strvec_pushf(&proc->env_array, "GIT_PUSH_CERT=%s", + oid_to_hex(&push_cert_oid)); + strvec_pushf(&proc->env_array, "GIT_PUSH_CERT_SIGNER=%s", + sigcheck.signer ? sigcheck.signer : ""); + strvec_pushf(&proc->env_array, "GIT_PUSH_CERT_KEY=%s", + sigcheck.key ? sigcheck.key : ""); + strvec_pushf(&proc->env_array, "GIT_PUSH_CERT_STATUS=%c", + sigcheck.result); if (push_cert_nonce) { - argv_array_pushf(&proc->env_array, - "GIT_PUSH_CERT_NONCE=%s", - push_cert_nonce); - argv_array_pushf(&proc->env_array, - "GIT_PUSH_CERT_NONCE_STATUS=%s", - nonce_status); + strvec_pushf(&proc->env_array, + "GIT_PUSH_CERT_NONCE=%s", + push_cert_nonce); + strvec_pushf(&proc->env_array, + "GIT_PUSH_CERT_NONCE_STATUS=%s", + nonce_status); if (nonce_status == NONCE_SLOP) - argv_array_pushf(&proc->env_array, - "GIT_PUSH_CERT_NONCE_SLOP=%ld", - nonce_stamp_slop); + strvec_pushf(&proc->env_array, + "GIT_PUSH_CERT_NONCE_SLOP=%ld", + nonce_stamp_slop); } } } @@ -720,16 +720,16 @@ static int run_and_feed_hook(const char *hook_name, feed_fn feed, if (feed_state->push_options) { int i; for (i = 0; i < feed_state->push_options->nr; i++) - argv_array_pushf(&proc.env_array, - "GIT_PUSH_OPTION_%d=%s", i, - feed_state->push_options->items[i].string); - argv_array_pushf(&proc.env_array, "GIT_PUSH_OPTION_COUNT=%d", - feed_state->push_options->nr); + strvec_pushf(&proc.env_array, + "GIT_PUSH_OPTION_%d=%s", i, + feed_state->push_options->items[i].string); + strvec_pushf(&proc.env_array, "GIT_PUSH_OPTION_COUNT=%d", + feed_state->push_options->nr); } else - argv_array_pushf(&proc.env_array, "GIT_PUSH_OPTION_COUNT"); + strvec_pushf(&proc.env_array, "GIT_PUSH_OPTION_COUNT"); if (tmp_objdir) - argv_array_pushv(&proc.env_array, tmp_objdir_env(tmp_objdir)); + strvec_pushv(&proc.env_array, tmp_objdir_env(tmp_objdir)); if (use_sideband) { memset(&muxer, 0, sizeof(muxer)); @@ -931,7 +931,7 @@ static int head_has_history(void) } static const char *push_to_deploy(unsigned char *sha1, - struct argv_array *env, + struct strvec *env, const char *work_tree) { const char *update_refresh[] = { @@ -950,7 +950,7 @@ static const char *push_to_deploy(unsigned char *sha1, struct child_process child = CHILD_PROCESS_INIT; child.argv = update_refresh; - child.env = env->argv; + child.env = env->v; child.dir = work_tree; child.no_stdin = 1; child.stdout_to_stderr = 1; @@ -961,7 +961,7 @@ static const char *push_to_deploy(unsigned char *sha1, /* run_command() does not clean up completely; reinitialize */ child_process_init(&child); child.argv = diff_files; - child.env = env->argv; + child.env = env->v; child.dir = work_tree; child.no_stdin = 1; child.stdout_to_stderr = 1; @@ -974,7 +974,7 @@ static const char *push_to_deploy(unsigned char *sha1, child_process_init(&child); child.argv = diff_index; - child.env = env->argv; + child.env = env->v; child.no_stdin = 1; child.no_stdout = 1; child.stdout_to_stderr = 0; @@ -985,7 +985,7 @@ static const char *push_to_deploy(unsigned char *sha1, read_tree[3] = hash_to_hex(sha1); child_process_init(&child); child.argv = read_tree; - child.env = env->argv; + child.env = env->v; child.dir = work_tree; child.no_stdin = 1; child.no_stdout = 1; @@ -1000,11 +1000,11 @@ static const char *push_to_deploy(unsigned char *sha1, static const char *push_to_checkout_hook = "push-to-checkout"; static const char *push_to_checkout(unsigned char *hash, - struct argv_array *env, + struct strvec *env, const char *work_tree) { - argv_array_pushf(env, "GIT_WORK_TREE=%s", absolute_path(work_tree)); - if (run_hook_le(env->argv, push_to_checkout_hook, + strvec_pushf(env, "GIT_WORK_TREE=%s", absolute_path(work_tree)); + if (run_hook_le(env->v, push_to_checkout_hook, hash_to_hex(hash), NULL)) return "push-to-checkout hook declined"; else @@ -1014,7 +1014,7 @@ static const char *push_to_checkout(unsigned char *hash, static const char *update_worktree(unsigned char *sha1, const struct worktree *worktree) { const char *retval, *work_tree, *git_dir = NULL; - struct argv_array env = ARGV_ARRAY_INIT; + struct strvec env = STRVEC_INIT; if (worktree && worktree->path) work_tree = worktree->path; @@ -1030,14 +1030,14 @@ static const char *update_worktree(unsigned char *sha1, const struct worktree *w if (!git_dir) git_dir = get_git_dir(); - argv_array_pushf(&env, "GIT_DIR=%s", absolute_path(git_dir)); + strvec_pushf(&env, "GIT_DIR=%s", absolute_path(git_dir)); if (!find_hook(push_to_checkout_hook)) retval = push_to_deploy(sha1, &env, work_tree); else retval = push_to_checkout(sha1, &env, work_tree); - argv_array_clear(&env); + strvec_clear(&env); return retval; } @@ -1205,11 +1205,11 @@ static void run_update_post_hook(struct command *commands) for (cmd = commands; cmd; cmd = cmd->next) { if (cmd->error_string || cmd->did_not_exist) continue; - if (!proc.args.argc) - argv_array_push(&proc.args, hook); - argv_array_push(&proc.args, cmd->ref_name); + if (!proc.args.nr) + strvec_push(&proc.args, hook); + strvec_push(&proc.args, cmd->ref_name); } - if (!proc.args.argc) + if (!proc.args.nr) return; proc.no_stdin = 1; @@ -1715,10 +1715,10 @@ static const char *parse_pack_header(struct pack_header *hdr) static const char *pack_lockfile; -static void push_header_arg(struct argv_array *args, struct pack_header *hdr) +static void push_header_arg(struct strvec *args, struct pack_header *hdr) { - argv_array_pushf(args, "--pack_header=%"PRIu32",%"PRIu32, - ntohl(hdr->hdr_version), ntohl(hdr->hdr_entries)); + strvec_pushf(args, "--pack_header=%"PRIu32",%"PRIu32, + ntohl(hdr->hdr_version), ntohl(hdr->hdr_entries)); } static const char *unpack(int err_fd, struct shallow_info *si) @@ -1742,8 +1742,8 @@ static const char *unpack(int err_fd, struct shallow_info *si) if (si->nr_ours || si->nr_theirs) { alt_shallow_file = setup_temporary_shallow(si->shallow); - argv_array_push(&child.args, "--shallow-file"); - argv_array_push(&child.args, alt_shallow_file); + strvec_push(&child.args, "--shallow-file"); + strvec_push(&child.args, alt_shallow_file); } tmp_objdir = tmp_objdir_create(); @@ -1762,16 +1762,16 @@ static const char *unpack(int err_fd, struct shallow_info *si) tmp_objdir_add_as_alternate(tmp_objdir); if (ntohl(hdr.hdr_entries) < unpack_limit) { - argv_array_push(&child.args, "unpack-objects"); + strvec_push(&child.args, "unpack-objects"); push_header_arg(&child.args, &hdr); if (quiet) - argv_array_push(&child.args, "-q"); + strvec_push(&child.args, "-q"); if (fsck_objects) - argv_array_pushf(&child.args, "--strict%s", - fsck_msg_types.buf); + strvec_pushf(&child.args, "--strict%s", + fsck_msg_types.buf); if (max_input_size) - argv_array_pushf(&child.args, "--max-input-size=%"PRIuMAX, - (uintmax_t)max_input_size); + strvec_pushf(&child.args, "--max-input-size=%"PRIuMAX, + (uintmax_t)max_input_size); child.no_stdout = 1; child.err = err_fd; child.git_cmd = 1; @@ -1781,28 +1781,28 @@ static const char *unpack(int err_fd, struct shallow_info *si) } else { char hostname[HOST_NAME_MAX + 1]; - argv_array_pushl(&child.args, "index-pack", "--stdin", NULL); + strvec_pushl(&child.args, "index-pack", "--stdin", NULL); push_header_arg(&child.args, &hdr); if (xgethostname(hostname, sizeof(hostname))) xsnprintf(hostname, sizeof(hostname), "localhost"); - argv_array_pushf(&child.args, - "--keep=receive-pack %"PRIuMAX" on %s", - (uintmax_t)getpid(), - hostname); + strvec_pushf(&child.args, + "--keep=receive-pack %"PRIuMAX" on %s", + (uintmax_t)getpid(), + hostname); if (!quiet && err_fd) - argv_array_push(&child.args, "--show-resolving-progress"); + strvec_push(&child.args, "--show-resolving-progress"); if (use_sideband) - argv_array_push(&child.args, "--report-end-of-input"); + strvec_push(&child.args, "--report-end-of-input"); if (fsck_objects) - argv_array_pushf(&child.args, "--strict%s", - fsck_msg_types.buf); + strvec_pushf(&child.args, "--strict%s", + fsck_msg_types.buf); if (!reject_thin) - argv_array_push(&child.args, "--fix-thin"); + strvec_push(&child.args, "--fix-thin"); if (max_input_size) - argv_array_pushf(&child.args, "--max-input-size=%"PRIuMAX, - (uintmax_t)max_input_size); + strvec_pushf(&child.args, "--max-input-size=%"PRIuMAX, + (uintmax_t)max_input_size); child.out = -1; child.err = err_fd; child.git_cmd = 1; diff --git a/builtin/remote-ext.c b/builtin/remote-ext.c index 6a9127a33c..fd3538d4f0 100644 --- a/builtin/remote-ext.c +++ b/builtin/remote-ext.c @@ -117,12 +117,12 @@ static char *strip_escapes(const char *str, const char *service, } } -static void parse_argv(struct argv_array *out, const char *arg, const char *service) +static void parse_argv(struct strvec *out, const char *arg, const char *service) { while (*arg) { char *expanded = strip_escapes(arg, service, &arg); if (expanded) - argv_array_push(out, expanded); + strvec_push(out, expanded); free(expanded); } } diff --git a/builtin/remote.c b/builtin/remote.c index e8377994e5..c8240e9fcd 100644 --- a/builtin/remote.c +++ b/builtin/remote.c @@ -10,7 +10,7 @@ #include "refs.h" #include "refspec.h" #include "object-store.h" -#include "argv-array.h" +#include "strvec.h" #include "commit-reach.h" static const char * const builtin_remote_usage[] = { @@ -1451,35 +1451,35 @@ static int update(int argc, const char **argv) N_("prune remotes after fetching")), OPT_END() }; - struct argv_array fetch_argv = ARGV_ARRAY_INIT; + struct strvec fetch_argv = STRVEC_INIT; int default_defined = 0; int retval; argc = parse_options(argc, argv, NULL, options, builtin_remote_update_usage, PARSE_OPT_KEEP_ARGV0); - argv_array_push(&fetch_argv, "fetch"); + strvec_push(&fetch_argv, "fetch"); if (prune != -1) - argv_array_push(&fetch_argv, prune ? "--prune" : "--no-prune"); + strvec_push(&fetch_argv, prune ? "--prune" : "--no-prune"); if (verbose) - argv_array_push(&fetch_argv, "-v"); - argv_array_push(&fetch_argv, "--multiple"); + strvec_push(&fetch_argv, "-v"); + strvec_push(&fetch_argv, "--multiple"); if (argc < 2) - argv_array_push(&fetch_argv, "default"); + strvec_push(&fetch_argv, "default"); for (i = 1; i < argc; i++) - argv_array_push(&fetch_argv, argv[i]); + strvec_push(&fetch_argv, argv[i]); - if (strcmp(fetch_argv.argv[fetch_argv.argc-1], "default") == 0) { + if (strcmp(fetch_argv.v[fetch_argv.nr-1], "default") == 0) { git_config(get_remote_default, &default_defined); if (!default_defined) { - argv_array_pop(&fetch_argv); - argv_array_push(&fetch_argv, "--all"); + strvec_pop(&fetch_argv); + strvec_push(&fetch_argv, "--all"); } } - retval = run_command_v_opt(fetch_argv.argv, RUN_GIT_CMD); - argv_array_clear(&fetch_argv); + retval = run_command_v_opt(fetch_argv.v, RUN_GIT_CMD); + strvec_clear(&fetch_argv); return retval; } diff --git a/builtin/repack.c b/builtin/repack.c index df287739d9..04c5ceaf7e 100644 --- a/builtin/repack.c +++ b/builtin/repack.c @@ -7,7 +7,7 @@ #include "sigchain.h" #include "strbuf.h" #include "string-list.h" -#include "argv-array.h" +#include "strvec.h" #include "midx.h" #include "packfile.h" #include "prune-packed.h" @@ -153,28 +153,28 @@ struct pack_objects_args { static void prepare_pack_objects(struct child_process *cmd, const struct pack_objects_args *args) { - argv_array_push(&cmd->args, "pack-objects"); + strvec_push(&cmd->args, "pack-objects"); if (args->window) - argv_array_pushf(&cmd->args, "--window=%s", args->window); + strvec_pushf(&cmd->args, "--window=%s", args->window); if (args->window_memory) - argv_array_pushf(&cmd->args, "--window-memory=%s", args->window_memory); + strvec_pushf(&cmd->args, "--window-memory=%s", args->window_memory); if (args->depth) - argv_array_pushf(&cmd->args, "--depth=%s", args->depth); + strvec_pushf(&cmd->args, "--depth=%s", args->depth); if (args->threads) - argv_array_pushf(&cmd->args, "--threads=%s", args->threads); + strvec_pushf(&cmd->args, "--threads=%s", args->threads); if (args->max_pack_size) - argv_array_pushf(&cmd->args, "--max-pack-size=%s", args->max_pack_size); + strvec_pushf(&cmd->args, "--max-pack-size=%s", args->max_pack_size); if (args->no_reuse_delta) - argv_array_pushf(&cmd->args, "--no-reuse-delta"); + strvec_pushf(&cmd->args, "--no-reuse-delta"); if (args->no_reuse_object) - argv_array_pushf(&cmd->args, "--no-reuse-object"); + strvec_pushf(&cmd->args, "--no-reuse-object"); if (args->local) - argv_array_push(&cmd->args, "--local"); + strvec_push(&cmd->args, "--local"); if (args->quiet) - argv_array_push(&cmd->args, "--quiet"); + strvec_push(&cmd->args, "--quiet"); if (delta_base_offset) - argv_array_push(&cmd->args, "--delta-base-offset"); - argv_array_push(&cmd->args, packtmp); + strvec_push(&cmd->args, "--delta-base-offset"); + strvec_push(&cmd->args, packtmp); cmd->git_cmd = 1; cmd->out = -1; } @@ -361,24 +361,24 @@ int cmd_repack(int argc, const char **argv, const char *prefix) prepare_pack_objects(&cmd, &po_args); - argv_array_push(&cmd.args, "--keep-true-parents"); + strvec_push(&cmd.args, "--keep-true-parents"); if (!pack_kept_objects) - argv_array_push(&cmd.args, "--honor-pack-keep"); + strvec_push(&cmd.args, "--honor-pack-keep"); for (i = 0; i < keep_pack_list.nr; i++) - argv_array_pushf(&cmd.args, "--keep-pack=%s", - keep_pack_list.items[i].string); - argv_array_push(&cmd.args, "--non-empty"); - argv_array_push(&cmd.args, "--all"); - argv_array_push(&cmd.args, "--reflog"); - argv_array_push(&cmd.args, "--indexed-objects"); + strvec_pushf(&cmd.args, "--keep-pack=%s", + keep_pack_list.items[i].string); + strvec_push(&cmd.args, "--non-empty"); + strvec_push(&cmd.args, "--all"); + strvec_push(&cmd.args, "--reflog"); + strvec_push(&cmd.args, "--indexed-objects"); if (has_promisor_remote()) - argv_array_push(&cmd.args, "--exclude-promisor-objects"); + strvec_push(&cmd.args, "--exclude-promisor-objects"); if (write_bitmaps > 0) - argv_array_push(&cmd.args, "--write-bitmap-index"); + strvec_push(&cmd.args, "--write-bitmap-index"); else if (write_bitmaps < 0) - argv_array_push(&cmd.args, "--write-bitmap-index-quiet"); + strvec_push(&cmd.args, "--write-bitmap-index-quiet"); if (use_delta_islands) - argv_array_push(&cmd.args, "--delta-islands"); + strvec_push(&cmd.args, "--delta-islands"); if (pack_everything & ALL_INTO_ONE) { get_non_kept_pack_filenames(&existing_packs, &keep_pack_list); @@ -387,23 +387,23 @@ int cmd_repack(int argc, const char **argv, const char *prefix) if (existing_packs.nr && delete_redundant) { if (unpack_unreachable) { - argv_array_pushf(&cmd.args, - "--unpack-unreachable=%s", - unpack_unreachable); - argv_array_push(&cmd.env_array, "GIT_REF_PARANOIA=1"); + strvec_pushf(&cmd.args, + "--unpack-unreachable=%s", + unpack_unreachable); + strvec_push(&cmd.env_array, "GIT_REF_PARANOIA=1"); } else if (pack_everything & LOOSEN_UNREACHABLE) { - argv_array_push(&cmd.args, - "--unpack-unreachable"); + strvec_push(&cmd.args, + "--unpack-unreachable"); } else if (keep_unreachable) { - argv_array_push(&cmd.args, "--keep-unreachable"); - argv_array_push(&cmd.args, "--pack-loose-unreachable"); + strvec_push(&cmd.args, "--keep-unreachable"); + strvec_push(&cmd.args, "--pack-loose-unreachable"); } else { - argv_array_push(&cmd.env_array, "GIT_REF_PARANOIA=1"); + strvec_push(&cmd.env_array, "GIT_REF_PARANOIA=1"); } } } else { - argv_array_push(&cmd.args, "--unpacked"); - argv_array_push(&cmd.args, "--incremental"); + strvec_push(&cmd.args, "--unpacked"); + strvec_push(&cmd.args, "--incremental"); } cmd.no_stdin = 1; diff --git a/builtin/replace.c b/builtin/replace.c index b36d17a657..cd48765911 100644 --- a/builtin/replace.c +++ b/builtin/replace.c @@ -228,13 +228,13 @@ static int export_object(const struct object_id *oid, enum object_type type, if (fd < 0) return error_errno(_("unable to open %s for writing"), filename); - argv_array_push(&cmd.args, "--no-replace-objects"); - argv_array_push(&cmd.args, "cat-file"); + strvec_push(&cmd.args, "--no-replace-objects"); + strvec_push(&cmd.args, "cat-file"); if (raw) - argv_array_push(&cmd.args, type_name(type)); + strvec_push(&cmd.args, type_name(type)); else - argv_array_push(&cmd.args, "-p"); - argv_array_push(&cmd.args, oid_to_hex(oid)); + strvec_push(&cmd.args, "-p"); + strvec_push(&cmd.args, oid_to_hex(oid)); cmd.git_cmd = 1; cmd.out = fd; @@ -502,7 +502,7 @@ static int convert_graft_file(int force) const char *graft_file = get_graft_file(the_repository); FILE *fp = fopen_or_warn(graft_file, "r"); struct strbuf buf = STRBUF_INIT, err = STRBUF_INIT; - struct argv_array args = ARGV_ARRAY_INIT; + struct strvec args = STRVEC_INIT; if (!fp) return -1; @@ -512,10 +512,10 @@ static int convert_graft_file(int force) if (*buf.buf == '#') continue; - argv_array_split(&args, buf.buf); - if (args.argc && create_graft(args.argc, args.argv, force, 1)) + strvec_split(&args, buf.buf); + if (args.nr && create_graft(args.nr, args.v, force, 1)) strbuf_addf(&err, "\n\t%s", buf.buf); - argv_array_clear(&args); + strvec_clear(&args); } fclose(fp); diff --git a/builtin/show-branch.c b/builtin/show-branch.c index 7e52ee9126..7eae5f3801 100644 --- a/builtin/show-branch.c +++ b/builtin/show-branch.c @@ -4,7 +4,7 @@ #include "refs.h" #include "builtin.h" #include "color.h" -#include "argv-array.h" +#include "strvec.h" #include "parse-options.h" #include "dir.h" #include "commit-slab.h" @@ -20,7 +20,7 @@ static const char* show_branch_usage[] = { static int showbranch_use_color = -1; -static struct argv_array default_args = ARGV_ARRAY_INIT; +static struct strvec default_args = STRVEC_INIT; /* * TODO: convert this use of commit->object.flags to commit-slab @@ -561,9 +561,9 @@ static int git_show_branch_config(const char *var, const char *value, void *cb) * default_arg is now passed to parse_options(), so we need to * mimic the real argv a bit better. */ - if (!default_args.argc) - argv_array_push(&default_args, "show-branch"); - argv_array_push(&default_args, value); + if (!default_args.nr) + strvec_push(&default_args, "show-branch"); + strvec_push(&default_args, value); return 0; } @@ -684,9 +684,9 @@ int cmd_show_branch(int ac, const char **av, const char *prefix) git_config(git_show_branch_config, NULL); /* If nothing is specified, try the default first */ - if (ac == 1 && default_args.argc) { - ac = default_args.argc; - av = default_args.argv; + if (ac == 1 && default_args.nr) { + ac = default_args.nr; + av = default_args.v; } ac = parse_options(ac, av, prefix, builtin_show_branch_options, diff --git a/builtin/stash.c b/builtin/stash.c index 0c52a3b849..10d87630cd 100644 --- a/builtin/stash.c +++ b/builtin/stash.c @@ -7,7 +7,7 @@ #include "cache-tree.h" #include "unpack-trees.h" #include "merge-recursive.h" -#include "argv-array.h" +#include "strvec.h" #include "run-command.h" #include "dir.h" #include "rerere.h" @@ -277,8 +277,8 @@ static int diff_tree_binary(struct strbuf *out, struct object_id *w_commit) * however it should be done together with apply_cached. */ cp.git_cmd = 1; - argv_array_pushl(&cp.args, "diff-tree", "--binary", NULL); - argv_array_pushf(&cp.args, "%s^2^..%s^2", w_commit_hex, w_commit_hex); + strvec_pushl(&cp.args, "diff-tree", "--binary", NULL); + strvec_pushf(&cp.args, "%s^2^..%s^2", w_commit_hex, w_commit_hex); return pipe_command(&cp, NULL, 0, out, 0, NULL, 0); } @@ -293,7 +293,7 @@ static int apply_cached(struct strbuf *out) * buffer. */ cp.git_cmd = 1; - argv_array_pushl(&cp.args, "apply", "--cached", NULL); + strvec_pushl(&cp.args, "apply", "--cached", NULL); return pipe_command(&cp, out->buf, out->len, NULL, 0, NULL, 0); } @@ -306,7 +306,7 @@ static int reset_head(void) * API for resetting. */ cp.git_cmd = 1; - argv_array_push(&cp.args, "reset"); + strvec_push(&cp.args, "reset"); return run_command(&cp); } @@ -335,9 +335,9 @@ static int get_newly_staged(struct strbuf *out, struct object_id *c_tree) * converted together with update_index. */ cp.git_cmd = 1; - argv_array_pushl(&cp.args, "diff-index", "--cached", "--name-only", - "--diff-filter=A", NULL); - argv_array_push(&cp.args, c_tree_hex); + strvec_pushl(&cp.args, "diff-index", "--cached", "--name-only", + "--diff-filter=A", NULL); + strvec_push(&cp.args, c_tree_hex); return pipe_command(&cp, NULL, 0, out, 0, NULL, 0); } @@ -350,7 +350,7 @@ static int update_index(struct strbuf *out) * function exposed in order to remove this forking. */ cp.git_cmd = 1; - argv_array_pushl(&cp.args, "update-index", "--add", "--stdin", NULL); + strvec_pushl(&cp.args, "update-index", "--add", "--stdin", NULL); return pipe_command(&cp, out->buf, out->len, NULL, 0, NULL, 0); } @@ -365,10 +365,10 @@ static int restore_untracked(struct object_id *u_tree) * run_command to fork processes that will not interfere. */ cp.git_cmd = 1; - argv_array_push(&cp.args, "read-tree"); - argv_array_push(&cp.args, oid_to_hex(u_tree)); - argv_array_pushf(&cp.env_array, "GIT_INDEX_FILE=%s", - stash_index_path.buf); + strvec_push(&cp.args, "read-tree"); + strvec_push(&cp.args, oid_to_hex(u_tree)); + strvec_pushf(&cp.env_array, "GIT_INDEX_FILE=%s", + stash_index_path.buf); if (run_command(&cp)) { remove_path(stash_index_path.buf); return -1; @@ -376,9 +376,9 @@ static int restore_untracked(struct object_id *u_tree) child_process_init(&cp); cp.git_cmd = 1; - argv_array_pushl(&cp.args, "checkout-index", "--all", NULL); - argv_array_pushf(&cp.env_array, "GIT_INDEX_FILE=%s", - stash_index_path.buf); + strvec_pushl(&cp.args, "checkout-index", "--all", NULL); + strvec_pushf(&cp.env_array, "GIT_INDEX_FILE=%s", + stash_index_path.buf); res = run_command(&cp); remove_path(stash_index_path.buf); @@ -499,11 +499,11 @@ static int do_apply_stash(const char *prefix, struct stash_info *info, */ cp.git_cmd = 1; cp.dir = prefix; - argv_array_pushf(&cp.env_array, GIT_WORK_TREE_ENVIRONMENT"=%s", - absolute_path(get_git_work_tree())); - argv_array_pushf(&cp.env_array, GIT_DIR_ENVIRONMENT"=%s", - absolute_path(get_git_dir())); - argv_array_push(&cp.args, "status"); + strvec_pushf(&cp.env_array, GIT_WORK_TREE_ENVIRONMENT"=%s", + absolute_path(get_git_work_tree())); + strvec_pushf(&cp.env_array, GIT_DIR_ENVIRONMENT"=%s", + absolute_path(get_git_dir())); + strvec_push(&cp.args, "status"); run_command(&cp); } @@ -546,9 +546,9 @@ static int do_drop_stash(struct stash_info *info, int quiet) */ cp_reflog.git_cmd = 1; - argv_array_pushl(&cp_reflog.args, "reflog", "delete", "--updateref", - "--rewrite", NULL); - argv_array_push(&cp_reflog.args, info->revision.buf); + strvec_pushl(&cp_reflog.args, "reflog", "delete", "--updateref", + "--rewrite", NULL); + strvec_push(&cp_reflog.args, info->revision.buf); ret = run_command(&cp_reflog); if (!ret) { if (!quiet) @@ -566,8 +566,8 @@ static int do_drop_stash(struct stash_info *info, int quiet) cp.git_cmd = 1; /* Even though --quiet is specified, rev-parse still outputs the hash */ cp.no_stdout = 1; - argv_array_pushl(&cp.args, "rev-parse", "--verify", "--quiet", NULL); - argv_array_pushf(&cp.args, "%s@{0}", ref_stash); + strvec_pushl(&cp.args, "rev-parse", "--verify", "--quiet", NULL); + strvec_pushf(&cp.args, "%s@{0}", ref_stash); ret = run_command(&cp); /* do_clear_stash if we just dropped the last stash entry */ @@ -663,9 +663,9 @@ static int branch_stash(int argc, const char **argv, const char *prefix) return -1; cp.git_cmd = 1; - argv_array_pushl(&cp.args, "checkout", "-b", NULL); - argv_array_push(&cp.args, branch); - argv_array_push(&cp.args, oid_to_hex(&info.b_commit)); + strvec_pushl(&cp.args, "checkout", "-b", NULL); + strvec_push(&cp.args, branch); + strvec_push(&cp.args, oid_to_hex(&info.b_commit)); ret = run_command(&cp); if (!ret) ret = do_apply_stash(prefix, &info, 1, 0); @@ -692,11 +692,11 @@ static int list_stash(int argc, const char **argv, const char *prefix) return 0; cp.git_cmd = 1; - argv_array_pushl(&cp.args, "log", "--format=%gd: %gs", "-g", - "--first-parent", "-m", NULL); - argv_array_pushv(&cp.args, argv); - argv_array_push(&cp.args, ref_stash); - argv_array_push(&cp.args, "--"); + strvec_pushl(&cp.args, "log", "--format=%gd: %gs", "-g", + "--first-parent", "-m", NULL); + strvec_pushv(&cp.args, argv); + strvec_push(&cp.args, ref_stash); + strvec_push(&cp.args, "--"); return run_command(&cp); } @@ -727,8 +727,8 @@ static int show_stash(int argc, const char **argv, const char *prefix) int ret = 0; struct stash_info info; struct rev_info rev; - struct argv_array stash_args = ARGV_ARRAY_INIT; - struct argv_array revision_args = ARGV_ARRAY_INIT; + struct strvec stash_args = STRVEC_INIT; + struct strvec revision_args = STRVEC_INIT; struct option options[] = { OPT_END() }; @@ -737,16 +737,16 @@ static int show_stash(int argc, const char **argv, const char *prefix) git_config(git_diff_ui_config, NULL); init_revisions(&rev, prefix); - argv_array_push(&revision_args, argv[0]); + strvec_push(&revision_args, argv[0]); for (i = 1; i < argc; i++) { if (argv[i][0] != '-') - argv_array_push(&stash_args, argv[i]); + strvec_push(&stash_args, argv[i]); else - argv_array_push(&revision_args, argv[i]); + strvec_push(&revision_args, argv[i]); } - ret = get_stash_info(&info, stash_args.argc, stash_args.argv); - argv_array_clear(&stash_args); + ret = get_stash_info(&info, stash_args.nr, stash_args.v); + strvec_clear(&stash_args); if (ret) return -1; @@ -754,7 +754,7 @@ static int show_stash(int argc, const char **argv, const char *prefix) * The config settings are applied only if there are not passed * any options. */ - if (revision_args.argc == 1) { + if (revision_args.nr == 1) { if (show_stat) rev.diffopt.output_format = DIFF_FORMAT_DIFFSTAT; @@ -767,7 +767,7 @@ static int show_stash(int argc, const char **argv, const char *prefix) } } - argc = setup_revisions(revision_args.argc, revision_args.argv, &rev, NULL); + argc = setup_revisions(revision_args.nr, revision_args.v, &rev, NULL); if (argc > 1) { free_stash_info(&info); usage_with_options(git_stash_show_usage, options); @@ -842,12 +842,12 @@ static int store_stash(int argc, const char **argv, const char *prefix) return do_store_stash(&obj, stash_msg, quiet); } -static void add_pathspecs(struct argv_array *args, +static void add_pathspecs(struct strvec *args, const struct pathspec *ps) { int i; for (i = 0; i < ps->nr; i++) - argv_array_push(args, ps->items[i].original); + strvec_push(args, ps->items[i].original); } /* @@ -960,9 +960,9 @@ static int save_untracked_files(struct stash_info *info, struct strbuf *msg, struct index_state istate = { NULL }; cp_upd_index.git_cmd = 1; - argv_array_pushl(&cp_upd_index.args, "update-index", "-z", "--add", - "--remove", "--stdin", NULL); - argv_array_pushf(&cp_upd_index.env_array, "GIT_INDEX_FILE=%s", + strvec_pushl(&cp_upd_index.args, "update-index", "-z", "--add", + "--remove", "--stdin", NULL); + strvec_pushf(&cp_upd_index.env_array, "GIT_INDEX_FILE=%s", stash_index_path.buf); strbuf_addf(&untracked_msg, "untracked files on %s\n", msg->buf); @@ -1003,9 +1003,9 @@ static int stash_patch(struct stash_info *info, const struct pathspec *ps, remove_path(stash_index_path.buf); cp_read_tree.git_cmd = 1; - argv_array_pushl(&cp_read_tree.args, "read-tree", "HEAD", NULL); - argv_array_pushf(&cp_read_tree.env_array, "GIT_INDEX_FILE=%s", - stash_index_path.buf); + strvec_pushl(&cp_read_tree.args, "read-tree", "HEAD", NULL); + strvec_pushf(&cp_read_tree.env_array, "GIT_INDEX_FILE=%s", + stash_index_path.buf); if (run_command(&cp_read_tree)) { ret = -1; goto done; @@ -1034,8 +1034,8 @@ static int stash_patch(struct stash_info *info, const struct pathspec *ps, } cp_diff_tree.git_cmd = 1; - argv_array_pushl(&cp_diff_tree.args, "diff-tree", "-p", "-U1", "HEAD", - oid_to_hex(&info->w_tree), "--", NULL); + strvec_pushl(&cp_diff_tree.args, "diff-tree", "-p", "-U1", "HEAD", + oid_to_hex(&info->w_tree), "--", NULL); if (pipe_command(&cp_diff_tree, NULL, 0, out_patch, 0, NULL, 0)) { ret = -1; goto done; @@ -1088,11 +1088,11 @@ static int stash_working_tree(struct stash_info *info, const struct pathspec *ps } cp_upd_index.git_cmd = 1; - argv_array_pushl(&cp_upd_index.args, "update-index", - "--ignore-skip-worktree-entries", - "-z", "--add", "--remove", "--stdin", NULL); - argv_array_pushf(&cp_upd_index.env_array, "GIT_INDEX_FILE=%s", - stash_index_path.buf); + strvec_pushl(&cp_upd_index.args, "update-index", + "--ignore-skip-worktree-entries", + "-z", "--add", "--remove", "--stdin", NULL); + strvec_pushf(&cp_upd_index.env_array, "GIT_INDEX_FILE=%s", + stash_index_path.buf); if (pipe_command(&cp_upd_index, diff_output.buf, diff_output.len, NULL, 0, NULL, 0)) { @@ -1342,10 +1342,10 @@ static int do_push_stash(const struct pathspec *ps, const char *stash_msg, int q struct child_process cp = CHILD_PROCESS_INIT; cp.git_cmd = 1; - argv_array_pushl(&cp.args, "clean", "--force", - "--quiet", "-d", NULL); + strvec_pushl(&cp.args, "clean", "--force", + "--quiet", "-d", NULL); if (include_untracked == INCLUDE_ALL_FILES) - argv_array_push(&cp.args, "-x"); + strvec_push(&cp.args, "-x"); if (run_command(&cp)) { ret = -1; goto done; @@ -1359,12 +1359,12 @@ static int do_push_stash(const struct pathspec *ps, const char *stash_msg, int q struct strbuf out = STRBUF_INIT; cp_add.git_cmd = 1; - argv_array_push(&cp_add.args, "add"); + strvec_push(&cp_add.args, "add"); if (!include_untracked) - argv_array_push(&cp_add.args, "-u"); + strvec_push(&cp_add.args, "-u"); if (include_untracked == INCLUDE_ALL_FILES) - argv_array_push(&cp_add.args, "--force"); - argv_array_push(&cp_add.args, "--"); + strvec_push(&cp_add.args, "--force"); + strvec_push(&cp_add.args, "--"); add_pathspecs(&cp_add.args, ps); if (run_command(&cp_add)) { ret = -1; @@ -1372,9 +1372,9 @@ static int do_push_stash(const struct pathspec *ps, const char *stash_msg, int q } cp_diff.git_cmd = 1; - argv_array_pushl(&cp_diff.args, "diff-index", "-p", - "--cached", "--binary", "HEAD", "--", - NULL); + strvec_pushl(&cp_diff.args, "diff-index", "-p", + "--cached", "--binary", "HEAD", "--", + NULL); add_pathspecs(&cp_diff.args, ps); if (pipe_command(&cp_diff, NULL, 0, &out, 0, NULL, 0)) { ret = -1; @@ -1382,8 +1382,8 @@ static int do_push_stash(const struct pathspec *ps, const char *stash_msg, int q } cp_apply.git_cmd = 1; - argv_array_pushl(&cp_apply.args, "apply", "--index", - "-R", NULL); + strvec_pushl(&cp_apply.args, "apply", "--index", + "-R", NULL); if (pipe_command(&cp_apply, out.buf, out.len, NULL, 0, NULL, 0)) { ret = -1; @@ -1392,8 +1392,8 @@ static int do_push_stash(const struct pathspec *ps, const char *stash_msg, int q } else { struct child_process cp = CHILD_PROCESS_INIT; cp.git_cmd = 1; - argv_array_pushl(&cp.args, "reset", "--hard", "-q", - "--no-recurse-submodules", NULL); + strvec_pushl(&cp.args, "reset", "--hard", "-q", + "--no-recurse-submodules", NULL); if (run_command(&cp)) { ret = -1; goto done; @@ -1404,10 +1404,10 @@ static int do_push_stash(const struct pathspec *ps, const char *stash_msg, int q struct child_process cp = CHILD_PROCESS_INIT; cp.git_cmd = 1; - argv_array_pushl(&cp.args, "checkout", "--no-overlay", - oid_to_hex(&info.i_tree), "--", NULL); + strvec_pushl(&cp.args, "checkout", "--no-overlay", + oid_to_hex(&info.i_tree), "--", NULL); if (!ps->nr) - argv_array_push(&cp.args, ":/"); + strvec_push(&cp.args, ":/"); else add_pathspecs(&cp.args, ps); if (run_command(&cp)) { @@ -1420,7 +1420,7 @@ static int do_push_stash(const struct pathspec *ps, const char *stash_msg, int q struct child_process cp = CHILD_PROCESS_INIT; cp.git_cmd = 1; - argv_array_pushl(&cp.args, "apply", "-R", NULL); + strvec_pushl(&cp.args, "apply", "-R", NULL); if (pipe_command(&cp, patch.buf, patch.len, NULL, 0, NULL, 0)) { if (!quiet) @@ -1434,7 +1434,7 @@ static int do_push_stash(const struct pathspec *ps, const char *stash_msg, int q struct child_process cp = CHILD_PROCESS_INIT; cp.git_cmd = 1; - argv_array_pushl(&cp.args, "reset", "-q", "--", NULL); + strvec_pushl(&cp.args, "reset", "-q", "--", NULL); add_pathspecs(&cp.args, ps); if (run_command(&cp)) { ret = -1; @@ -1560,7 +1560,7 @@ int cmd_stash(int argc, const char **argv, const char *prefix) { pid_t pid = getpid(); const char *index_file; - struct argv_array args = ARGV_ARRAY_INIT; + struct strvec args = STRVEC_INIT; struct option options[] = { OPT_END() @@ -1609,7 +1609,7 @@ int cmd_stash(int argc, const char **argv, const char *prefix) git_stash_usage, options); /* Assume 'stash push' */ - argv_array_push(&args, "push"); - argv_array_pushv(&args, argv); - return !!push_stash(args.argc, args.argv, prefix, 1); + strvec_push(&args, "push"); + strvec_pushv(&args, argv); + return !!push_stash(args.nr, args.v, prefix, 1); } diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index a1c75607c7..df135abbf1 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -294,9 +294,9 @@ static char *compute_rev_name(const char *sub_path, const char* object_id) cp.git_cmd = 1; cp.no_stderr = 1; - argv_array_push(&cp.args, "describe"); - argv_array_pushv(&cp.args, *d); - argv_array_push(&cp.args, object_id); + strvec_push(&cp.args, "describe"); + strvec_pushv(&cp.args, *d); + strvec_push(&cp.args, object_id); if (!capture_command(&cp, &sb, 0)) { strbuf_strip_suffix(&sb, "\n"); @@ -495,12 +495,12 @@ static void runcommand_in_submodule_cb(const struct cache_entry *list_item, char *toplevel = xgetcwd(); struct strbuf sb = STRBUF_INIT; - argv_array_pushf(&cp.env_array, "name=%s", sub->name); - argv_array_pushf(&cp.env_array, "sm_path=%s", path); - argv_array_pushf(&cp.env_array, "displaypath=%s", displaypath); - argv_array_pushf(&cp.env_array, "sha1=%s", - oid_to_hex(ce_oid)); - argv_array_pushf(&cp.env_array, "toplevel=%s", toplevel); + strvec_pushf(&cp.env_array, "name=%s", sub->name); + strvec_pushf(&cp.env_array, "sm_path=%s", path); + strvec_pushf(&cp.env_array, "displaypath=%s", displaypath); + strvec_pushf(&cp.env_array, "sha1=%s", + oid_to_hex(ce_oid)); + strvec_pushf(&cp.env_array, "toplevel=%s", toplevel); /* * Since the path variable was accessible from the script @@ -509,15 +509,15 @@ static void runcommand_in_submodule_cb(const struct cache_entry *list_item, * on windows. And since environment variables are * case-insensitive in windows, it interferes with the * existing PATH variable. Hence, to avoid that, we expose - * path via the args argv_array and not via env_array. + * path via the args strvec and not via env_array. */ sq_quote_buf(&sb, path); - argv_array_pushf(&cp.args, "path=%s; %s", - sb.buf, info->argv[0]); + strvec_pushf(&cp.args, "path=%s; %s", + sb.buf, info->argv[0]); strbuf_release(&sb); free(toplevel); } else { - argv_array_pushv(&cp.args, info->argv); + strvec_pushv(&cp.args, info->argv); } if (!info->quiet) @@ -534,16 +534,16 @@ static void runcommand_in_submodule_cb(const struct cache_entry *list_item, cpr.dir = path; prepare_submodule_repo_env(&cpr.env_array); - argv_array_pushl(&cpr.args, "--super-prefix", NULL); - argv_array_pushf(&cpr.args, "%s/", displaypath); - argv_array_pushl(&cpr.args, "submodule--helper", "foreach", "--recursive", - NULL); + strvec_pushl(&cpr.args, "--super-prefix", NULL); + strvec_pushf(&cpr.args, "%s/", displaypath); + strvec_pushl(&cpr.args, "submodule--helper", "foreach", "--recursive", + NULL); if (info->quiet) - argv_array_push(&cpr.args, "--quiet"); + strvec_push(&cpr.args, "--quiet"); - argv_array_push(&cpr.args, "--"); - argv_array_pushv(&cpr.args, info->argv); + strvec_push(&cpr.args, "--"); + strvec_pushv(&cpr.args, info->argv); if (run_command(&cpr)) die(_("run_command returned non-zero status while " @@ -779,7 +779,7 @@ static void status_submodule(const char *path, const struct object_id *ce_oid, unsigned int flags) { char *displaypath; - struct argv_array diff_files_args = ARGV_ARRAY_INIT; + struct strvec diff_files_args = STRVEC_INIT; struct rev_info rev; int diff_files_result; struct strbuf buf = STRBUF_INIT; @@ -809,17 +809,17 @@ static void status_submodule(const char *path, const struct object_id *ce_oid, } strbuf_release(&buf); - argv_array_pushl(&diff_files_args, "diff-files", - "--ignore-submodules=dirty", "--quiet", "--", - path, NULL); + strvec_pushl(&diff_files_args, "diff-files", + "--ignore-submodules=dirty", "--quiet", "--", + path, NULL); git_config(git_diff_basic_config, NULL); repo_init_revisions(the_repository, &rev, NULL); rev.abbrev = 0; - diff_files_args.argc = setup_revisions(diff_files_args.argc, - diff_files_args.argv, - &rev, NULL); + diff_files_args.nr = setup_revisions(diff_files_args.nr, + diff_files_args.v, + &rev, NULL); diff_files_result = run_diff_files(&rev, 0); if (!diff_result_code(&rev.diffopt, diff_files_result)) { @@ -849,23 +849,23 @@ static void status_submodule(const char *path, const struct object_id *ce_oid, cpr.dir = path; prepare_submodule_repo_env(&cpr.env_array); - argv_array_push(&cpr.args, "--super-prefix"); - argv_array_pushf(&cpr.args, "%s/", displaypath); - argv_array_pushl(&cpr.args, "submodule--helper", "status", - "--recursive", NULL); + strvec_push(&cpr.args, "--super-prefix"); + strvec_pushf(&cpr.args, "%s/", displaypath); + strvec_pushl(&cpr.args, "submodule--helper", "status", + "--recursive", NULL); if (flags & OPT_CACHED) - argv_array_push(&cpr.args, "--cached"); + strvec_push(&cpr.args, "--cached"); if (flags & OPT_QUIET) - argv_array_push(&cpr.args, "--quiet"); + strvec_push(&cpr.args, "--quiet"); if (run_command(&cpr)) die(_("failed to recurse into submodule '%s'"), path); } cleanup: - argv_array_clear(&diff_files_args); + strvec_clear(&diff_files_args); free(displaypath); } @@ -995,8 +995,8 @@ static void sync_submodule(const char *path, const char *prefix, prepare_submodule_repo_env(&cp.env_array); cp.git_cmd = 1; cp.dir = path; - argv_array_pushl(&cp.args, "submodule--helper", - "print-default-remote", NULL); + strvec_pushl(&cp.args, "submodule--helper", + "print-default-remote", NULL); strbuf_reset(&sb); if (capture_command(&cp, &sb, 0)) @@ -1021,13 +1021,13 @@ static void sync_submodule(const char *path, const char *prefix, cpr.dir = path; prepare_submodule_repo_env(&cpr.env_array); - argv_array_push(&cpr.args, "--super-prefix"); - argv_array_pushf(&cpr.args, "%s/", displaypath); - argv_array_pushl(&cpr.args, "submodule--helper", "sync", - "--recursive", NULL); + strvec_push(&cpr.args, "--super-prefix"); + strvec_pushf(&cpr.args, "%s/", displaypath); + strvec_pushl(&cpr.args, "submodule--helper", "sync", + "--recursive", NULL); if (flags & OPT_QUIET) - argv_array_push(&cpr.args, "--quiet"); + strvec_push(&cpr.args, "--quiet"); if (run_command(&cpr)) die(_("failed to recurse into submodule '%s'"), @@ -1127,8 +1127,8 @@ static void deinit_submodule(const char *path, const char *prefix, if (!(flags & OPT_FORCE)) { struct child_process cp_rm = CHILD_PROCESS_INIT; cp_rm.git_cmd = 1; - argv_array_pushl(&cp_rm.args, "rm", "-qn", - path, NULL); + strvec_pushl(&cp_rm.args, "rm", "-qn", + path, NULL); if (run_command(&cp_rm)) die(_("Submodule work tree '%s' contains local " @@ -1156,8 +1156,8 @@ static void deinit_submodule(const char *path, const char *prefix, displaypath); cp_config.git_cmd = 1; - argv_array_pushl(&cp_config.args, "config", "--get-regexp", NULL); - argv_array_pushf(&cp_config.args, "submodule.%s\\.", sub->name); + strvec_pushl(&cp_config.args, "config", "--get-regexp", NULL); + strvec_pushf(&cp_config.args, "submodule.%s\\.", sub->name); /* remove the .git/config entries (unless the user already did it) */ if (!capture_command(&cp_config, &sb_config, 0) && sb_config.len) { @@ -1239,32 +1239,32 @@ static int clone_submodule(const char *path, const char *gitdir, const char *url { struct child_process cp = CHILD_PROCESS_INIT; - argv_array_push(&cp.args, "clone"); - argv_array_push(&cp.args, "--no-checkout"); + strvec_push(&cp.args, "clone"); + strvec_push(&cp.args, "--no-checkout"); if (quiet) - argv_array_push(&cp.args, "--quiet"); + strvec_push(&cp.args, "--quiet"); if (progress) - argv_array_push(&cp.args, "--progress"); + strvec_push(&cp.args, "--progress"); if (depth && *depth) - argv_array_pushl(&cp.args, "--depth", depth, NULL); + strvec_pushl(&cp.args, "--depth", depth, NULL); if (reference->nr) { struct string_list_item *item; for_each_string_list_item(item, reference) - argv_array_pushl(&cp.args, "--reference", - item->string, NULL); + strvec_pushl(&cp.args, "--reference", + item->string, NULL); } if (dissociate) - argv_array_push(&cp.args, "--dissociate"); + strvec_push(&cp.args, "--dissociate"); if (gitdir && *gitdir) - argv_array_pushl(&cp.args, "--separate-git-dir", gitdir, NULL); + strvec_pushl(&cp.args, "--separate-git-dir", gitdir, NULL); if (single_branch >= 0) - argv_array_push(&cp.args, single_branch ? + strvec_push(&cp.args, single_branch ? "--single-branch" : "--no-single-branch"); - argv_array_push(&cp.args, "--"); - argv_array_push(&cp.args, url); - argv_array_push(&cp.args, path); + strvec_push(&cp.args, "--"); + strvec_push(&cp.args, url); + strvec_push(&cp.args, path); cp.git_cmd = 1; prepare_submodule_repo_env(&cp.env_array); @@ -1717,32 +1717,32 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce, child->no_stdin = 1; child->stdout_to_stderr = 1; child->err = -1; - argv_array_push(&child->args, "submodule--helper"); - argv_array_push(&child->args, "clone"); + strvec_push(&child->args, "submodule--helper"); + strvec_push(&child->args, "clone"); if (suc->progress) - argv_array_push(&child->args, "--progress"); + strvec_push(&child->args, "--progress"); if (suc->quiet) - argv_array_push(&child->args, "--quiet"); + strvec_push(&child->args, "--quiet"); if (suc->prefix) - argv_array_pushl(&child->args, "--prefix", suc->prefix, NULL); + strvec_pushl(&child->args, "--prefix", suc->prefix, NULL); if (suc->recommend_shallow && sub->recommend_shallow == 1) - argv_array_push(&child->args, "--depth=1"); + strvec_push(&child->args, "--depth=1"); if (suc->require_init) - argv_array_push(&child->args, "--require-init"); - argv_array_pushl(&child->args, "--path", sub->path, NULL); - argv_array_pushl(&child->args, "--name", sub->name, NULL); - argv_array_pushl(&child->args, "--url", url, NULL); + strvec_push(&child->args, "--require-init"); + strvec_pushl(&child->args, "--path", sub->path, NULL); + strvec_pushl(&child->args, "--name", sub->name, NULL); + strvec_pushl(&child->args, "--url", url, NULL); if (suc->references.nr) { struct string_list_item *item; for_each_string_list_item(item, &suc->references) - argv_array_pushl(&child->args, "--reference", item->string, NULL); + strvec_pushl(&child->args, "--reference", item->string, NULL); } if (suc->dissociate) - argv_array_push(&child->args, "--dissociate"); + strvec_push(&child->args, "--dissociate"); if (suc->depth) - argv_array_push(&child->args, suc->depth); + strvec_push(&child->args, suc->depth); if (suc->single_branch >= 0) - argv_array_push(&child->args, suc->single_branch ? + strvec_push(&child->args, suc->single_branch ? "--single-branch" : "--no-single-branch"); diff --git a/builtin/update-ref.c b/builtin/update-ref.c index b74dd9a69d..8a2df4459c 100644 --- a/builtin/update-ref.c +++ b/builtin/update-ref.c @@ -4,7 +4,7 @@ #include "builtin.h" #include "parse-options.h" #include "quote.h" -#include "argv-array.h" +#include "strvec.h" static const char * const git_update_ref_usage[] = { N_("git update-ref [<options>] -d <refname> [<old-val>]"), diff --git a/builtin/upload-archive.c b/builtin/upload-archive.c index 018879737a..24654b4c9b 100644 --- a/builtin/upload-archive.c +++ b/builtin/upload-archive.c @@ -7,7 +7,7 @@ #include "pkt-line.h" #include "sideband.h" #include "run-command.h" -#include "argv-array.h" +#include "strvec.h" static const char upload_archive_usage[] = "git upload-archive <repo>"; @@ -19,7 +19,7 @@ static const char deadchild[] = int cmd_upload_archive_writer(int argc, const char **argv, const char *prefix) { - struct argv_array sent_argv = ARGV_ARRAY_INIT; + struct strvec sent_argv = STRVEC_INIT; const char *arg_cmd = "argument "; if (argc != 2 || !strcmp(argv[1], "-h")) @@ -31,21 +31,21 @@ int cmd_upload_archive_writer(int argc, const char **argv, const char *prefix) init_archivers(); /* put received options in sent_argv[] */ - argv_array_push(&sent_argv, "git-upload-archive"); + strvec_push(&sent_argv, "git-upload-archive"); for (;;) { char *buf = packet_read_line(0, NULL); if (!buf) break; /* got a flush */ - if (sent_argv.argc > MAX_ARGS) + if (sent_argv.nr > MAX_ARGS) die("Too many options (>%d)", MAX_ARGS - 1); if (!starts_with(buf, arg_cmd)) die("'argument' token or flush expected"); - argv_array_push(&sent_argv, buf + strlen(arg_cmd)); + strvec_push(&sent_argv, buf + strlen(arg_cmd)); } /* parse all options sent by the client */ - return write_archive(sent_argv.argc, sent_argv.argv, prefix, + return write_archive(sent_argv.nr, sent_argv.v, prefix, the_repository, NULL, 1); } diff --git a/builtin/verify-pack.c b/builtin/verify-pack.c index c2a1a5c504..05c5213594 100644 --- a/builtin/verify-pack.c +++ b/builtin/verify-pack.c @@ -7,21 +7,26 @@ #define VERIFY_PACK_VERBOSE 01 #define VERIFY_PACK_STAT_ONLY 02 -static int verify_one_pack(const char *path, unsigned int flags) +static int verify_one_pack(const char *path, unsigned int flags, const char *hash_algo) { struct child_process index_pack = CHILD_PROCESS_INIT; - const char *argv[] = {"index-pack", NULL, NULL, NULL }; + struct strvec *argv = &index_pack.args; struct strbuf arg = STRBUF_INIT; int verbose = flags & VERIFY_PACK_VERBOSE; int stat_only = flags & VERIFY_PACK_STAT_ONLY; int err; + strvec_push(argv, "index-pack"); + if (stat_only) - argv[1] = "--verify-stat-only"; + strvec_push(argv, "--verify-stat-only"); else if (verbose) - argv[1] = "--verify-stat"; + strvec_push(argv, "--verify-stat"); else - argv[1] = "--verify"; + strvec_push(argv, "--verify"); + + if (hash_algo) + strvec_pushf(argv, "--object-format=%s", hash_algo); /* * In addition to "foo.pack" we accept "foo.idx" and "foo"; @@ -31,9 +36,8 @@ static int verify_one_pack(const char *path, unsigned int flags) if (strbuf_strip_suffix(&arg, ".idx") || !ends_with(arg.buf, ".pack")) strbuf_addstr(&arg, ".pack"); - argv[2] = arg.buf; + strvec_push(argv, arg.buf); - index_pack.argv = argv; index_pack.git_cmd = 1; err = run_command(&index_pack); @@ -60,12 +64,15 @@ int cmd_verify_pack(int argc, const char **argv, const char *prefix) { int err = 0; unsigned int flags = 0; + const char *object_format = NULL; int i; const struct option verify_pack_options[] = { OPT_BIT('v', "verbose", &flags, N_("verbose"), VERIFY_PACK_VERBOSE), OPT_BIT('s', "stat-only", &flags, N_("show statistics only"), VERIFY_PACK_STAT_ONLY), + OPT_STRING(0, "object-format", &object_format, N_("hash"), + N_("specify the hash algorithm to use")), OPT_END() }; @@ -75,7 +82,7 @@ int cmd_verify_pack(int argc, const char **argv, const char *prefix) if (argc < 1) usage_with_options(verify_pack_usage, verify_pack_options); for (i = 0; i < argc; i++) { - if (verify_one_pack(argv[i], flags)) + if (verify_one_pack(argv[i], flags, object_format)) err = 1; } diff --git a/builtin/worktree.c b/builtin/worktree.c index f0cbdef718..378f332b5d 100644 --- a/builtin/worktree.c +++ b/builtin/worktree.c @@ -4,7 +4,7 @@ #include "builtin.h" #include "dir.h" #include "parse-options.h" -#include "argv-array.h" +#include "strvec.h" #include "branch.h" #include "refs.h" #include "run-command.h" @@ -316,7 +316,7 @@ static int add_worktree(const char *path, const char *refname, struct strbuf sb = STRBUF_INIT, realpath = STRBUF_INIT; const char *name; struct child_process cp = CHILD_PROCESS_INIT; - struct argv_array child_env = ARGV_ARRAY_INIT; + struct strvec child_env = STRVEC_INIT; unsigned int counter = 0; int len, ret; struct strbuf symref = STRBUF_INIT; @@ -408,32 +408,32 @@ static int add_worktree(const char *path, const char *refname, strbuf_addf(&sb, "%s/commondir", sb_repo.buf); write_file(sb.buf, "../.."); - argv_array_pushf(&child_env, "%s=%s", GIT_DIR_ENVIRONMENT, sb_git.buf); - argv_array_pushf(&child_env, "%s=%s", GIT_WORK_TREE_ENVIRONMENT, path); + strvec_pushf(&child_env, "%s=%s", GIT_DIR_ENVIRONMENT, sb_git.buf); + strvec_pushf(&child_env, "%s=%s", GIT_WORK_TREE_ENVIRONMENT, path); cp.git_cmd = 1; if (!is_branch) - argv_array_pushl(&cp.args, "update-ref", "HEAD", - oid_to_hex(&commit->object.oid), NULL); + strvec_pushl(&cp.args, "update-ref", "HEAD", + oid_to_hex(&commit->object.oid), NULL); else { - argv_array_pushl(&cp.args, "symbolic-ref", "HEAD", - symref.buf, NULL); + strvec_pushl(&cp.args, "symbolic-ref", "HEAD", + symref.buf, NULL); if (opts->quiet) - argv_array_push(&cp.args, "--quiet"); + strvec_push(&cp.args, "--quiet"); } - cp.env = child_env.argv; + cp.env = child_env.v; ret = run_command(&cp); if (ret) goto done; if (opts->checkout) { cp.argv = NULL; - argv_array_clear(&cp.args); - argv_array_pushl(&cp.args, "reset", "--hard", "--no-recurse-submodules", NULL); + strvec_clear(&cp.args); + strvec_pushl(&cp.args, "reset", "--hard", "--no-recurse-submodules", NULL); if (opts->quiet) - argv_array_push(&cp.args, "--quiet"); - cp.env = child_env.argv; + strvec_push(&cp.args, "--quiet"); + cp.env = child_env.v; ret = run_command(&cp); if (ret) goto done; @@ -465,15 +465,15 @@ done: cp.env = env; cp.argv = NULL; cp.trace2_hook_name = "post-checkout"; - argv_array_pushl(&cp.args, absolute_path(hook), - oid_to_hex(&null_oid), - oid_to_hex(&commit->object.oid), - "1", NULL); + strvec_pushl(&cp.args, absolute_path(hook), + oid_to_hex(&null_oid), + oid_to_hex(&commit->object.oid), + "1", NULL); ret = run_command(&cp); } } - argv_array_clear(&child_env); + strvec_clear(&child_env); strbuf_release(&sb); strbuf_release(&symref); strbuf_release(&sb_repo); @@ -619,15 +619,15 @@ static int add(int ac, const char **av, const char *prefix) if (new_branch) { struct child_process cp = CHILD_PROCESS_INIT; cp.git_cmd = 1; - argv_array_push(&cp.args, "branch"); + strvec_push(&cp.args, "branch"); if (new_branch_force) - argv_array_push(&cp.args, "--force"); + strvec_push(&cp.args, "--force"); if (opts.quiet) - argv_array_push(&cp.args, "--quiet"); - argv_array_push(&cp.args, new_branch); - argv_array_push(&cp.args, branch); + strvec_push(&cp.args, "--quiet"); + strvec_push(&cp.args, new_branch); + strvec_push(&cp.args, branch); if (opt_track) - argv_array_push(&cp.args, opt_track); + strvec_push(&cp.args, opt_track); if (run_command(&cp)) return -1; branch = new_branch; @@ -924,7 +924,7 @@ static int move_worktree(int ac, const char **av, const char *prefix) static void check_clean_worktree(struct worktree *wt, const char *original_path) { - struct argv_array child_env = ARGV_ARRAY_INIT; + struct strvec child_env = STRVEC_INIT; struct child_process cp; char buf[1]; int ret; @@ -935,15 +935,15 @@ static void check_clean_worktree(struct worktree *wt, */ validate_no_submodules(wt); - argv_array_pushf(&child_env, "%s=%s/.git", - GIT_DIR_ENVIRONMENT, wt->path); - argv_array_pushf(&child_env, "%s=%s", - GIT_WORK_TREE_ENVIRONMENT, wt->path); + strvec_pushf(&child_env, "%s=%s/.git", + GIT_DIR_ENVIRONMENT, wt->path); + strvec_pushf(&child_env, "%s=%s", + GIT_WORK_TREE_ENVIRONMENT, wt->path); memset(&cp, 0, sizeof(cp)); - argv_array_pushl(&cp.args, "status", - "--porcelain", "--ignore-submodules=none", - NULL); - cp.env = child_env.argv; + strvec_pushl(&cp.args, "status", + "--porcelain", "--ignore-submodules=none", + NULL); + cp.env = child_env.v; cp.git_cmd = 1; cp.dir = wt->path; cp.out = -1; @@ -10,9 +10,18 @@ #include "list-objects.h" #include "run-command.h" #include "refs.h" -#include "argv-array.h" +#include "strvec.h" -static const char bundle_signature[] = "# v2 git bundle\n"; + +static const char v2_bundle_signature[] = "# v2 git bundle\n"; +static const char v3_bundle_signature[] = "# v3 git bundle\n"; +static struct { + int version; + const char *signature; +} bundle_sigs[] = { + { 2, v2_bundle_signature }, + { 3, v3_bundle_signature }, +}; static void add_to_ref_list(const struct object_id *oid, const char *name, struct ref_list *list) @@ -23,15 +32,30 @@ static void add_to_ref_list(const struct object_id *oid, const char *name, list->nr++; } -static const struct git_hash_algo *detect_hash_algo(struct strbuf *buf) +static int parse_capability(struct bundle_header *header, const char *capability) +{ + const char *arg; + if (skip_prefix(capability, "object-format=", &arg)) { + int algo = hash_algo_by_name(arg); + if (algo == GIT_HASH_UNKNOWN) + return error(_("unrecognized bundle hash algorithm: %s"), arg); + header->hash_algo = &hash_algos[algo]; + return 0; + } + return error(_("unknown capability '%s'"), capability); +} + +static int parse_bundle_signature(struct bundle_header *header, const char *line) { - size_t len = strcspn(buf->buf, " \n"); - int algo; + int i; - algo = hash_algo_by_length(len / 2); - if (algo == GIT_HASH_UNKNOWN) - return NULL; - return &hash_algos[algo]; + for (i = 0; i < ARRAY_SIZE(bundle_sigs); i++) { + if (!strcmp(line, bundle_sigs[i].signature)) { + header->version = bundle_sigs[i].version; + return 0; + } + } + return -1; } static int parse_bundle_header(int fd, struct bundle_header *header, @@ -42,14 +66,16 @@ static int parse_bundle_header(int fd, struct bundle_header *header, /* The bundle header begins with the signature */ if (strbuf_getwholeline_fd(&buf, fd, '\n') || - strcmp(buf.buf, bundle_signature)) { + parse_bundle_signature(header, buf.buf)) { if (report_path) - error(_("'%s' does not look like a v2 bundle file"), + error(_("'%s' does not look like a v2 or v3 bundle file"), report_path); status = -1; goto abort; } + header->hash_algo = the_hash_algo; + /* The bundle header ends with an empty line */ while (!strbuf_getwholeline_fd(&buf, fd, '\n') && buf.len && buf.buf[0] != '\n') { @@ -57,19 +83,19 @@ static int parse_bundle_header(int fd, struct bundle_header *header, int is_prereq = 0; const char *p; - if (*buf.buf == '-') { - is_prereq = 1; - strbuf_remove(&buf, 0, 1); - } strbuf_rtrim(&buf); - if (!header->hash_algo) { - header->hash_algo = detect_hash_algo(&buf); - if (!header->hash_algo) { - error(_("unknown hash algorithm length")); + if (header->version == 3 && *buf.buf == '@') { + if (parse_capability(header, buf.buf + 1)) { status = -1; break; } + continue; + } + + if (*buf.buf == '-') { + is_prereq = 1; + strbuf_remove(&buf, 0, 1); } /* @@ -269,16 +295,16 @@ out: /* Write the pack data to bundle_fd */ -static int write_pack_data(int bundle_fd, struct rev_info *revs, struct argv_array *pack_options) +static int write_pack_data(int bundle_fd, struct rev_info *revs, struct strvec *pack_options) { struct child_process pack_objects = CHILD_PROCESS_INIT; int i; - argv_array_pushl(&pack_objects.args, - "pack-objects", - "--stdout", "--thin", "--delta-base-offset", - NULL); - argv_array_pushv(&pack_objects.args, pack_options->argv); + strvec_pushl(&pack_objects.args, + "pack-objects", + "--stdout", "--thin", "--delta-base-offset", + NULL); + strvec_pushv(&pack_objects.args, pack_options->v); pack_objects.in = -1; pack_objects.out = bundle_fd; pack_objects.git_cmd = 1; @@ -321,11 +347,11 @@ static int compute_and_write_prerequisites(int bundle_fd, FILE *rls_fout; int i; - argv_array_pushl(&rls.args, - "rev-list", "--boundary", "--pretty=oneline", - NULL); + strvec_pushl(&rls.args, + "rev-list", "--boundary", "--pretty=oneline", + NULL); for (i = 1; i < argc; i++) - argv_array_push(&rls.args, argv[i]); + strvec_push(&rls.args, argv[i]); rls.out = -1; rls.git_cmd = 1; if (start_command(&rls)) @@ -449,13 +475,14 @@ static int write_bundle_refs(int bundle_fd, struct rev_info *revs) } int create_bundle(struct repository *r, const char *path, - int argc, const char **argv, struct argv_array *pack_options) + int argc, const char **argv, struct strvec *pack_options, int version) { struct lock_file lock = LOCK_INIT; int bundle_fd = -1; int bundle_to_stdout; int ref_count = 0; struct rev_info revs; + int min_version = the_hash_algo == &hash_algos[GIT_HASH_SHA1] ? 2 : 3; bundle_to_stdout = !strcmp(path, "-"); if (bundle_to_stdout) @@ -464,8 +491,22 @@ int create_bundle(struct repository *r, const char *path, bundle_fd = hold_lock_file_for_update(&lock, path, LOCK_DIE_ON_ERROR); - /* write signature */ - write_or_die(bundle_fd, bundle_signature, strlen(bundle_signature)); + if (version == -1) + version = min_version; + + if (version < 2 || version > 3) { + die(_("unsupported bundle version %d"), version); + } else if (version < min_version) { + die(_("cannot write bundle version %d with algorithm %s"), version, the_hash_algo->name); + } else if (version == 2) { + write_or_die(bundle_fd, v2_bundle_signature, strlen(v2_bundle_signature)); + } else { + const char *capability = "@object-format="; + write_or_die(bundle_fd, v3_bundle_signature, strlen(v3_bundle_signature)); + write_or_die(bundle_fd, capability, strlen(capability)); + write_or_die(bundle_fd, the_hash_algo->name, strlen(the_hash_algo->name)); + write_or_die(bundle_fd, "\n", 1); + } /* init revs to list objects for pack-objects later */ save_commit_buffer = 0; @@ -1,7 +1,7 @@ #ifndef BUNDLE_H #define BUNDLE_H -#include "argv-array.h" +#include "strvec.h" #include "cache.h" struct ref_list { @@ -13,6 +13,7 @@ struct ref_list { }; struct bundle_header { + unsigned version; struct ref_list prerequisites; struct ref_list references; const struct git_hash_algo *hash_algo; @@ -21,7 +22,8 @@ struct bundle_header { int is_bundle(const char *path, int quiet); int read_bundle_header(const char *path, struct bundle_header *header); int create_bundle(struct repository *r, const char *path, - int argc, const char **argv, struct argv_array *pack_options); + int argc, const char **argv, struct strvec *pack_options, + int version); int verify_bundle(struct repository *r, struct bundle_header *header, int verbose); #define BUNDLE_VERBOSE 1 int unbundle(struct repository *r, struct bundle_header *header, @@ -1044,6 +1044,7 @@ struct repository_format { int hash_algo; char *work_tree; struct string_list unknown_extensions; + struct string_list v1_only_extensions; }; /* @@ -1057,6 +1058,7 @@ struct repository_format { .is_bare = -1, \ .hash_algo = GIT_HASH_SHA1, \ .unknown_extensions = STRING_LIST_INIT_DUP, \ + .v1_only_extensions = STRING_LIST_INIT_DUP, \ } /* @@ -184,9 +184,9 @@ linux-clang|linux-gcc) if [ "$jobname" = linux-gcc ] then export CC=gcc-8 - MAKEFLAGS="$MAKEFLAGS PYTHON_PATH=$(which python3)" + MAKEFLAGS="$MAKEFLAGS PYTHON_PATH=/usr/bin/python3" else - MAKEFLAGS="$MAKEFLAGS PYTHON_PATH=$(which python2)" + MAKEFLAGS="$MAKEFLAGS PYTHON_PATH=/usr/bin/python2" fi export GIT_TEST_HTTPD=true diff --git a/ci/run-build-and-tests.sh b/ci/run-build-and-tests.sh index 17e25aade9..6c27b886b8 100755 --- a/ci/run-build-and-tests.sh +++ b/ci/run-build-and-tests.sh @@ -24,6 +24,12 @@ linux-gcc) export GIT_TEST_ADD_I_USE_BUILTIN=1 make test ;; +linux-clang) + export GIT_TEST_DEFAULT_HASH=sha1 + make test + export GIT_TEST_DEFAULT_HASH=sha256 + make test + ;; linux-gcc-4.8) # Don't run the tests; we only care about whether Git can be # built with GCC 4.8, as it errors out on some undesired (C99) @@ -107,7 +107,7 @@ static void display_plain(const struct string_list *list, printf("%s%s%s", indent, list->items[i].string, nl); } -/* Print a cell to stdout with all necessary leading/traling space */ +/* Print a cell to stdout with all necessary leading/trailing space */ static int display_cell(struct column_data *data, int initial_width, const char *empty_cell, int x, int y) { @@ -358,7 +358,7 @@ static struct child_process column_process = CHILD_PROCESS_INIT; int run_column_filter(int colopts, const struct column_options *opts) { - struct argv_array *argv; + struct strvec *argv; if (fd_out != -1) return -1; @@ -366,14 +366,14 @@ int run_column_filter(int colopts, const struct column_options *opts) child_process_init(&column_process); argv = &column_process.args; - argv_array_push(argv, "column"); - argv_array_pushf(argv, "--raw-mode=%d", colopts); + strvec_push(argv, "column"); + strvec_pushf(argv, "--raw-mode=%d", colopts); if (opts && opts->width) - argv_array_pushf(argv, "--width=%d", opts->width); + strvec_pushf(argv, "--width=%d", opts->width); if (opts && opts->indent) - argv_array_pushf(argv, "--indent=%s", opts->indent); + strvec_pushf(argv, "--indent=%s", opts->indent); if (opts && opts->padding) - argv_array_pushf(argv, "--padding=%d", opts->padding); + strvec_pushf(argv, "--padding=%d", opts->padding); fflush(stdout); column_process.in = -1; diff --git a/command-list.txt b/command-list.txt index 89aa60cde7..e5901f2213 100644 --- a/command-list.txt +++ b/command-list.txt @@ -195,6 +195,7 @@ git-write-tree plumbingmanipulators gitattributes guide gitcli guide gitcore-tutorial guide +gitcredentials guide gitcvs-migration guide gitdiffcore guide giteveryday guide @@ -204,6 +205,7 @@ githooks guide gitignore guide gitmodules guide gitnamespaces guide +gitremote-helpers guide gitrepository-layout guide gitrevisions guide gitsubmodules guide diff --git a/commit-graph.c b/commit-graph.c index 1af68c297d..e51c91dd5b 100644 --- a/commit-graph.c +++ b/commit-graph.c @@ -1,7 +1,5 @@ -#include "cache.h" -#include "config.h" -#include "dir.h" #include "git-compat-util.h" +#include "config.h" #include "lockfile.h" #include "pack.h" #include "packfile.h" @@ -19,6 +17,8 @@ #include "bloom.h" #include "commit-slab.h" #include "shallow.h" +#include "json-writer.h" +#include "trace2.h" void git_test_write_commit_graph_or_die(void) { @@ -285,8 +285,7 @@ struct commit_graph *parse_commit_graph(void *graph_map, size_t graph_size) const unsigned char *data, *chunk_lookup; uint32_t i; struct commit_graph *graph; - uint64_t last_chunk_offset; - uint32_t last_chunk_id; + uint64_t next_chunk_offset; uint32_t graph_signature; unsigned char graph_version, hash_version; @@ -326,24 +325,26 @@ struct commit_graph *parse_commit_graph(void *graph_map, size_t graph_size) graph->data = graph_map; graph->data_len = graph_size; - last_chunk_id = 0; - last_chunk_offset = 8; + if (graph_size < GRAPH_HEADER_SIZE + + (graph->num_chunks + 1) * GRAPH_CHUNKLOOKUP_WIDTH + + GRAPH_FANOUT_SIZE + the_hash_algo->rawsz) { + error(_("commit-graph file is too small to hold %u chunks"), + graph->num_chunks); + free(graph); + return NULL; + } + chunk_lookup = data + 8; + next_chunk_offset = get_be64(chunk_lookup + 4); for (i = 0; i < graph->num_chunks; i++) { uint32_t chunk_id; - uint64_t chunk_offset; + uint64_t chunk_offset = next_chunk_offset; int chunk_repeated = 0; - if (data + graph_size - chunk_lookup < - GRAPH_CHUNKLOOKUP_WIDTH) { - error(_("commit-graph chunk lookup table entry missing; file may be incomplete")); - goto free_and_return; - } - chunk_id = get_be32(chunk_lookup + 0); - chunk_offset = get_be64(chunk_lookup + 4); chunk_lookup += GRAPH_CHUNKLOOKUP_WIDTH; + next_chunk_offset = get_be64(chunk_lookup + 4); if (chunk_offset > graph_size - the_hash_algo->rawsz) { error(_("commit-graph improper chunk offset %08x%08x"), (uint32_t)(chunk_offset >> 32), @@ -362,8 +363,11 @@ struct commit_graph *parse_commit_graph(void *graph_map, size_t graph_size) case GRAPH_CHUNKID_OIDLOOKUP: if (graph->chunk_oid_lookup) chunk_repeated = 1; - else + else { graph->chunk_oid_lookup = data + chunk_offset; + graph->num_commits = (next_chunk_offset - chunk_offset) + / graph->hash_len; + } break; case GRAPH_CHUNKID_DATA: @@ -417,15 +421,6 @@ struct commit_graph *parse_commit_graph(void *graph_map, size_t graph_size) error(_("commit-graph chunk id %08x appears multiple times"), chunk_id); goto free_and_return; } - - if (last_chunk_id == GRAPH_CHUNKID_OIDLOOKUP) - { - graph->num_commits = (chunk_offset - last_chunk_offset) - / graph->hash_len; - } - - last_chunk_id = chunk_id; - last_chunk_offset = chunk_offset; } if (graph->chunk_bloom_indexes && graph->chunk_bloom_data) { @@ -624,10 +619,6 @@ static int prepare_commit_graph(struct repository *r) return !!r->objects->commit_graph; r->objects->commit_graph_attempted = 1; - if (git_env_bool(GIT_TEST_COMMIT_GRAPH_DIE_ON_LOAD, 0)) - die("dying as requested by the '%s' variable on commit-graph load!", - GIT_TEST_COMMIT_GRAPH_DIE_ON_LOAD); - prepare_repo_settings(r); if (!git_env_bool(GIT_TEST_COMMIT_GRAPH, 0) && @@ -856,6 +847,14 @@ static int parse_commit_in_graph_one(struct repository *r, int parse_commit_in_graph(struct repository *r, struct commit *item) { + static int checked_env = 0; + + if (!checked_env && + git_env_bool(GIT_TEST_COMMIT_GRAPH_DIE_ON_PARSE, 0)) + die("dying as requested by the '%s' variable on commit-graph parse!", + GIT_TEST_COMMIT_GRAPH_DIE_ON_PARSE); + checked_env = 1; + if (!prepare_commit_graph(r)) return 0; return parse_commit_in_graph_one(r, r->objects->commit_graph, item); @@ -948,10 +947,11 @@ struct write_commit_graph_context { const struct split_commit_graph_opts *split_opts; size_t total_bloom_filter_data_size; + const struct bloom_filter_settings *bloom_settings; }; -static void write_graph_chunk_fanout(struct hashfile *f, - struct write_commit_graph_context *ctx) +static int write_graph_chunk_fanout(struct hashfile *f, + struct write_commit_graph_context *ctx) { int i, count = 0; struct commit **list = ctx->commits.list; @@ -972,17 +972,21 @@ static void write_graph_chunk_fanout(struct hashfile *f, hashwrite_be32(f, count); } + + return 0; } -static void write_graph_chunk_oids(struct hashfile *f, int hash_len, - struct write_commit_graph_context *ctx) +static int write_graph_chunk_oids(struct hashfile *f, + struct write_commit_graph_context *ctx) { struct commit **list = ctx->commits.list; int count; for (count = 0; count < ctx->commits.nr; count++, list++) { display_progress(ctx->progress, ++ctx->progress_cnt); - hashwrite(f, (*list)->object.oid.hash, (int)hash_len); + hashwrite(f, (*list)->object.oid.hash, the_hash_algo->rawsz); } + + return 0; } static const unsigned char *commit_to_sha1(size_t index, void *table) @@ -991,8 +995,8 @@ static const unsigned char *commit_to_sha1(size_t index, void *table) return commits[index]->object.oid.hash; } -static void write_graph_chunk_data(struct hashfile *f, int hash_len, - struct write_commit_graph_context *ctx) +static int write_graph_chunk_data(struct hashfile *f, + struct write_commit_graph_context *ctx) { struct commit **list = ctx->commits.list; struct commit **last = ctx->commits.list + ctx->commits.nr; @@ -1009,7 +1013,7 @@ static void write_graph_chunk_data(struct hashfile *f, int hash_len, die(_("unable to parse commit %s"), oid_to_hex(&(*list)->object.oid)); tree = get_commit_tree_oid(*list); - hashwrite(f, tree->hash, hash_len); + hashwrite(f, tree->hash, the_hash_algo->rawsz); parent = (*list)->parents; @@ -1089,10 +1093,12 @@ static void write_graph_chunk_data(struct hashfile *f, int hash_len, list++; } + + return 0; } -static void write_graph_chunk_extra_edges(struct hashfile *f, - struct write_commit_graph_context *ctx) +static int write_graph_chunk_extra_edges(struct hashfile *f, + struct write_commit_graph_context *ctx) { struct commit **list = ctx->commits.list; struct commit **last = ctx->commits.list + ctx->commits.nr; @@ -1141,10 +1147,12 @@ static void write_graph_chunk_extra_edges(struct hashfile *f, list++; } + + return 0; } -static void write_graph_chunk_bloom_indexes(struct hashfile *f, - struct write_commit_graph_context *ctx) +static int write_graph_chunk_bloom_indexes(struct hashfile *f, + struct write_commit_graph_context *ctx) { struct commit **list = ctx->commits.list; struct commit **last = ctx->commits.list + ctx->commits.nr; @@ -1152,30 +1160,54 @@ static void write_graph_chunk_bloom_indexes(struct hashfile *f, while (list < last) { struct bloom_filter *filter = get_bloom_filter(ctx->r, *list, 0); - cur_pos += filter->len; + size_t len = filter ? filter->len : 0; + cur_pos += len; display_progress(ctx->progress, ++ctx->progress_cnt); hashwrite_be32(f, cur_pos); list++; } + + return 0; } -static void write_graph_chunk_bloom_data(struct hashfile *f, - struct write_commit_graph_context *ctx, - const struct bloom_filter_settings *settings) +static void trace2_bloom_filter_settings(struct write_commit_graph_context *ctx) +{ + struct json_writer jw = JSON_WRITER_INIT; + + jw_object_begin(&jw, 0); + jw_object_intmax(&jw, "hash_version", ctx->bloom_settings->hash_version); + jw_object_intmax(&jw, "num_hashes", ctx->bloom_settings->num_hashes); + jw_object_intmax(&jw, "bits_per_entry", ctx->bloom_settings->bits_per_entry); + jw_end(&jw); + + trace2_data_json("bloom", ctx->r, "settings", &jw); + + jw_release(&jw); +} + +static int write_graph_chunk_bloom_data(struct hashfile *f, + struct write_commit_graph_context *ctx) { struct commit **list = ctx->commits.list; struct commit **last = ctx->commits.list + ctx->commits.nr; - hashwrite_be32(f, settings->hash_version); - hashwrite_be32(f, settings->num_hashes); - hashwrite_be32(f, settings->bits_per_entry); + trace2_bloom_filter_settings(ctx); + + hashwrite_be32(f, ctx->bloom_settings->hash_version); + hashwrite_be32(f, ctx->bloom_settings->num_hashes); + hashwrite_be32(f, ctx->bloom_settings->bits_per_entry); while (list < last) { struct bloom_filter *filter = get_bloom_filter(ctx->r, *list, 0); + size_t len = filter ? filter->len : 0; + display_progress(ctx->progress, ++ctx->progress_cnt); - hashwrite(f, filter->data, filter->len * sizeof(unsigned char)); + if (len) + hashwrite(f, filter->data, len * sizeof(unsigned char)); list++; } + + return 0; } static int oid_compare(const void *_a, const void *_b) @@ -1586,19 +1618,36 @@ static int write_graph_chunk_base(struct hashfile *f, return 0; } +typedef int (*chunk_write_fn)(struct hashfile *f, + struct write_commit_graph_context *ctx); + +struct chunk_info { + uint32_t id; + uint64_t size; + chunk_write_fn write_fn; +}; + static int write_commit_graph_file(struct write_commit_graph_context *ctx) { uint32_t i; int fd; struct hashfile *f; struct lock_file lk = LOCK_INIT; - uint32_t chunk_ids[MAX_NUM_CHUNKS + 1]; - uint64_t chunk_offsets[MAX_NUM_CHUNKS + 1]; + struct chunk_info chunks[MAX_NUM_CHUNKS + 1]; const unsigned hashsz = the_hash_algo->rawsz; struct strbuf progress_title = STRBUF_INIT; int num_chunks = 3; + uint64_t chunk_offset; struct object_id file_hash; - const struct bloom_filter_settings bloom_settings = DEFAULT_BLOOM_FILTER_SETTINGS; + struct bloom_filter_settings bloom_settings = DEFAULT_BLOOM_FILTER_SETTINGS; + + if (!ctx->bloom_settings) { + bloom_settings.bits_per_entry = git_env_ulong("GIT_TEST_BLOOM_SETTINGS_BITS_PER_ENTRY", + bloom_settings.bits_per_entry); + bloom_settings.num_hashes = git_env_ulong("GIT_TEST_BLOOM_SETTINGS_NUM_HASHES", + bloom_settings.num_hashes); + ctx->bloom_settings = &bloom_settings; + } if (ctx->split) { struct strbuf tmp_file = STRBUF_INIT; @@ -1644,51 +1693,41 @@ static int write_commit_graph_file(struct write_commit_graph_context *ctx) f = hashfd(lk.tempfile->fd, lk.tempfile->filename.buf); } - chunk_ids[0] = GRAPH_CHUNKID_OIDFANOUT; - chunk_ids[1] = GRAPH_CHUNKID_OIDLOOKUP; - chunk_ids[2] = GRAPH_CHUNKID_DATA; + chunks[0].id = GRAPH_CHUNKID_OIDFANOUT; + chunks[0].size = GRAPH_FANOUT_SIZE; + chunks[0].write_fn = write_graph_chunk_fanout; + chunks[1].id = GRAPH_CHUNKID_OIDLOOKUP; + chunks[1].size = hashsz * ctx->commits.nr; + chunks[1].write_fn = write_graph_chunk_oids; + chunks[2].id = GRAPH_CHUNKID_DATA; + chunks[2].size = (hashsz + 16) * ctx->commits.nr; + chunks[2].write_fn = write_graph_chunk_data; if (ctx->num_extra_edges) { - chunk_ids[num_chunks] = GRAPH_CHUNKID_EXTRAEDGES; + chunks[num_chunks].id = GRAPH_CHUNKID_EXTRAEDGES; + chunks[num_chunks].size = 4 * ctx->num_extra_edges; + chunks[num_chunks].write_fn = write_graph_chunk_extra_edges; num_chunks++; } if (ctx->changed_paths) { - chunk_ids[num_chunks] = GRAPH_CHUNKID_BLOOMINDEXES; + chunks[num_chunks].id = GRAPH_CHUNKID_BLOOMINDEXES; + chunks[num_chunks].size = sizeof(uint32_t) * ctx->commits.nr; + chunks[num_chunks].write_fn = write_graph_chunk_bloom_indexes; num_chunks++; - chunk_ids[num_chunks] = GRAPH_CHUNKID_BLOOMDATA; + chunks[num_chunks].id = GRAPH_CHUNKID_BLOOMDATA; + chunks[num_chunks].size = sizeof(uint32_t) * 3 + + ctx->total_bloom_filter_data_size; + chunks[num_chunks].write_fn = write_graph_chunk_bloom_data; num_chunks++; } if (ctx->num_commit_graphs_after > 1) { - chunk_ids[num_chunks] = GRAPH_CHUNKID_BASE; + chunks[num_chunks].id = GRAPH_CHUNKID_BASE; + chunks[num_chunks].size = hashsz * (ctx->num_commit_graphs_after - 1); + chunks[num_chunks].write_fn = write_graph_chunk_base; num_chunks++; } - chunk_ids[num_chunks] = 0; - - chunk_offsets[0] = 8 + (num_chunks + 1) * GRAPH_CHUNKLOOKUP_WIDTH; - chunk_offsets[1] = chunk_offsets[0] + GRAPH_FANOUT_SIZE; - chunk_offsets[2] = chunk_offsets[1] + hashsz * ctx->commits.nr; - chunk_offsets[3] = chunk_offsets[2] + (hashsz + 16) * ctx->commits.nr; - - num_chunks = 3; - if (ctx->num_extra_edges) { - chunk_offsets[num_chunks + 1] = chunk_offsets[num_chunks] + - 4 * ctx->num_extra_edges; - num_chunks++; - } - if (ctx->changed_paths) { - chunk_offsets[num_chunks + 1] = chunk_offsets[num_chunks] + - sizeof(uint32_t) * ctx->commits.nr; - num_chunks++; - - chunk_offsets[num_chunks + 1] = chunk_offsets[num_chunks] + - sizeof(uint32_t) * 3 + ctx->total_bloom_filter_data_size; - num_chunks++; - } - if (ctx->num_commit_graphs_after > 1) { - chunk_offsets[num_chunks + 1] = chunk_offsets[num_chunks] + - hashsz * (ctx->num_commit_graphs_after - 1); - num_chunks++; - } + chunks[num_chunks].id = 0; + chunks[num_chunks].size = 0; hashwrite_be32(f, GRAPH_SIGNATURE); @@ -1697,13 +1736,16 @@ static int write_commit_graph_file(struct write_commit_graph_context *ctx) hashwrite_u8(f, num_chunks); hashwrite_u8(f, ctx->num_commit_graphs_after - 1); + chunk_offset = 8 + (num_chunks + 1) * GRAPH_CHUNKLOOKUP_WIDTH; for (i = 0; i <= num_chunks; i++) { uint32_t chunk_write[3]; - chunk_write[0] = htonl(chunk_ids[i]); - chunk_write[1] = htonl(chunk_offsets[i] >> 32); - chunk_write[2] = htonl(chunk_offsets[i] & 0xffffffff); + chunk_write[0] = htonl(chunks[i].id); + chunk_write[1] = htonl(chunk_offset >> 32); + chunk_write[2] = htonl(chunk_offset & 0xffffffff); hashwrite(f, chunk_write, 12); + + chunk_offset += chunks[i].size; } if (ctx->report_progress) { @@ -1716,19 +1758,19 @@ static int write_commit_graph_file(struct write_commit_graph_context *ctx) progress_title.buf, num_chunks * ctx->commits.nr); } - write_graph_chunk_fanout(f, ctx); - write_graph_chunk_oids(f, hashsz, ctx); - write_graph_chunk_data(f, hashsz, ctx); - if (ctx->num_extra_edges) - write_graph_chunk_extra_edges(f, ctx); - if (ctx->changed_paths) { - write_graph_chunk_bloom_indexes(f, ctx); - write_graph_chunk_bloom_data(f, ctx, &bloom_settings); - } - if (ctx->num_commit_graphs_after > 1 && - write_graph_chunk_base(f, ctx)) { - return -1; + + for (i = 0; i < num_chunks; i++) { + uint64_t start_offset = f->total + f->offset; + + if (chunks[i].write_fn(f, ctx)) + return -1; + + if (f->total + f->offset != start_offset + chunks[i].size) + BUG("expected to write %"PRId64" bytes to chunk %"PRIx32", but wrote %"PRId64" instead", + chunks[i].size, chunks[i].id, + f->total + f->offset - start_offset); } + stop_progress(&ctx->progress); strbuf_release(&progress_title); @@ -2062,9 +2104,23 @@ int write_commit_graph(struct object_directory *odb, ctx->report_progress = flags & COMMIT_GRAPH_WRITE_PROGRESS ? 1 : 0; ctx->split = flags & COMMIT_GRAPH_WRITE_SPLIT ? 1 : 0; ctx->split_opts = split_opts; - ctx->changed_paths = flags & COMMIT_GRAPH_WRITE_BLOOM_FILTERS ? 1 : 0; ctx->total_bloom_filter_data_size = 0; + if (flags & COMMIT_GRAPH_WRITE_BLOOM_FILTERS) + ctx->changed_paths = 1; + if (!(flags & COMMIT_GRAPH_NO_WRITE_BLOOM_FILTERS)) { + struct commit_graph *g; + prepare_commit_graph_one(ctx->r, ctx->odb); + + g = ctx->r->objects->commit_graph; + + /* We have changed-paths already. Keep them in the next graph */ + if (g && g->chunk_bloom_data) { + ctx->changed_paths = 1; + ctx->bloom_settings = g->bloom_filter_settings; + } + } + if (ctx->split) { struct commit_graph *g; prepare_commit_graph(ctx->r); diff --git a/commit-graph.h b/commit-graph.h index 28f89cdf3e..09a97030dc 100644 --- a/commit-graph.h +++ b/commit-graph.h @@ -2,14 +2,11 @@ #define COMMIT_GRAPH_H #include "git-compat-util.h" -#include "repository.h" -#include "string-list.h" -#include "cache.h" #include "object-store.h" #include "oidset.h" #define GIT_TEST_COMMIT_GRAPH "GIT_TEST_COMMIT_GRAPH" -#define GIT_TEST_COMMIT_GRAPH_DIE_ON_LOAD "GIT_TEST_COMMIT_GRAPH_DIE_ON_LOAD" +#define GIT_TEST_COMMIT_GRAPH_DIE_ON_PARSE "GIT_TEST_COMMIT_GRAPH_DIE_ON_PARSE" #define GIT_TEST_COMMIT_GRAPH_CHANGED_PATHS "GIT_TEST_COMMIT_GRAPH_CHANGED_PATHS" /* @@ -23,6 +20,9 @@ void git_test_write_commit_graph_or_die(void); struct commit; struct bloom_filter_settings; +struct repository; +struct raw_object_store; +struct string_list; char *get_commit_graph_filename(struct object_directory *odb); int open_commit_graph(const char *graph_file, int *fd, struct stat *st); @@ -92,6 +92,7 @@ enum commit_graph_write_flags { COMMIT_GRAPH_WRITE_PROGRESS = (1 << 1), COMMIT_GRAPH_WRITE_SPLIT = (1 << 2), COMMIT_GRAPH_WRITE_BLOOM_FILTERS = (1 << 3), + COMMIT_GRAPH_NO_WRITE_BLOOM_FILTERS = (1 << 4), }; enum commit_graph_split_flags { diff --git a/commit-slab-decl.h b/commit-slab-decl.h index bfbed1516a..98de2c970c 100644 --- a/commit-slab-decl.h +++ b/commit-slab-decl.h @@ -32,6 +32,7 @@ struct slabname { \ void init_ ##slabname## _with_stride(struct slabname *s, unsigned stride); \ void init_ ##slabname(struct slabname *s); \ void clear_ ##slabname(struct slabname *s); \ +void deep_clear_ ##slabname(struct slabname *s, void (*free_fn)(elemtype *ptr)); \ elemtype *slabname## _at_peek(struct slabname *s, const struct commit *c, int add_if_missing); \ elemtype *slabname## _at(struct slabname *s, const struct commit *c); \ elemtype *slabname## _peek(struct slabname *s, const struct commit *c) diff --git a/commit-slab-impl.h b/commit-slab-impl.h index 5c0eb91a5d..557738df27 100644 --- a/commit-slab-impl.h +++ b/commit-slab-impl.h @@ -38,6 +38,19 @@ scope void clear_ ##slabname(struct slabname *s) \ FREE_AND_NULL(s->slab); \ } \ \ +scope void deep_clear_ ##slabname(struct slabname *s, void (*free_fn)(elemtype *)) \ +{ \ + unsigned int i; \ + for (i = 0; i < s->slab_count; i++) { \ + unsigned int j; \ + if (!s->slab[i]) \ + continue; \ + for (j = 0; j < s->slab_size; j++) \ + free_fn(&s->slab[i][j * s->stride]); \ + } \ + clear_ ##slabname(s); \ +} \ + \ scope elemtype *slabname## _at_peek(struct slabname *s, \ const struct commit *c, \ int add_if_missing) \ diff --git a/commit-slab.h b/commit-slab.h index 05b3f2804e..8e72a30536 100644 --- a/commit-slab.h +++ b/commit-slab.h @@ -47,6 +47,16 @@ * * Call this function before the slab falls out of scope to avoid * leaking memory. + * + * - void deep_clear_indegree(struct indegree *, void (*free_fn)(int*)) + * + * Empties the slab, similar to clear_indegree(), but in addition it + * calls the given 'free_fn' for each slab entry to release any + * additional memory that might be owned by the entry (but not the + * entry itself!). + * Note that 'free_fn' might be called even for entries for which no + * indegree_at() call has been made; in this case 'free_fn' is invoked + * with a pointer to a zero-initialized location. */ #define define_commit_slab(slabname, elemtype) \ @@ -1630,22 +1630,22 @@ size_t ignore_non_trailer(const char *buf, size_t len) int run_commit_hook(int editor_is_used, const char *index_file, const char *name, ...) { - struct argv_array hook_env = ARGV_ARRAY_INIT; + struct strvec hook_env = STRVEC_INIT; va_list args; int ret; - argv_array_pushf(&hook_env, "GIT_INDEX_FILE=%s", index_file); + strvec_pushf(&hook_env, "GIT_INDEX_FILE=%s", index_file); /* * Let the hook know that no editor will be launched. */ if (!editor_is_used) - argv_array_push(&hook_env, "GIT_EDITOR=:"); + strvec_push(&hook_env, "GIT_EDITOR=:"); va_start(args, name); - ret = run_hook_ve(hook_env.argv,name, args); + ret = run_hook_ve(hook_env.v, name, args); va_end(args); - argv_array_clear(&hook_env); + strvec_clear(&hook_env); return ret; } diff --git a/compat/mingw.c b/compat/mingw.c index 8ee0b6408e..4454b3e67b 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -18,8 +18,8 @@ void open_in_gdb(void) static struct child_process cp = CHILD_PROCESS_INIT; extern char *_pgmptr; - argv_array_pushl(&cp.args, "mintty", "gdb", NULL); - argv_array_pushf(&cp.args, "--pid=%d", getpid()); + strvec_pushl(&cp.args, "mintty", "gdb", NULL); + strvec_pushf(&cp.args, "--pid=%d", getpid()); cp.clean_on_exit = 1; if (start_command(&cp) < 0) die_errno("Could not start gdb"); diff --git a/compat/terminal.c b/compat/terminal.c index 35bca03d14..43b73ddc75 100644 --- a/compat/terminal.c +++ b/compat/terminal.c @@ -86,9 +86,9 @@ static void restore_term(void) if (stty_restore.nr == 0) return; - argv_array_push(&cp.args, "stty"); + strvec_push(&cp.args, "stty"); for (i = 0; i < stty_restore.nr; i++) - argv_array_push(&cp.args, stty_restore.items[i].string); + strvec_push(&cp.args, stty_restore.items[i].string); run_command(&cp); string_list_clear(&stty_restore, 0); return; @@ -107,25 +107,25 @@ static int disable_bits(DWORD bits) if (use_stty) { struct child_process cp = CHILD_PROCESS_INIT; - argv_array_push(&cp.args, "stty"); + strvec_push(&cp.args, "stty"); if (bits & ENABLE_LINE_INPUT) { string_list_append(&stty_restore, "icanon"); - argv_array_push(&cp.args, "-icanon"); + strvec_push(&cp.args, "-icanon"); } if (bits & ENABLE_ECHO_INPUT) { string_list_append(&stty_restore, "echo"); - argv_array_push(&cp.args, "-echo"); + strvec_push(&cp.args, "-echo"); } if (bits & ENABLE_PROCESSED_INPUT) { string_list_append(&stty_restore, "-ignbrk"); string_list_append(&stty_restore, "intr"); string_list_append(&stty_restore, "^c"); - argv_array_push(&cp.args, "ignbrk"); - argv_array_push(&cp.args, "intr"); - argv_array_push(&cp.args, ""); + strvec_push(&cp.args, "ignbrk"); + strvec_push(&cp.args, "intr"); + strvec_push(&cp.args, ""); } if (run_command(&cp) == 0) @@ -273,7 +273,7 @@ static int is_known_escape_sequence(const char *sequence) hashmap_init(&sequences, (hashmap_cmp_fn)sequence_entry_cmp, NULL, 0); - argv_array_pushl(&cp.args, "infocmp", "-L", "-1", NULL); + strvec_pushl(&cp.args, "infocmp", "-L", "-1", NULL); if (pipe_command(&cp, NULL, 0, &buf, 0, NULL, 0)) strbuf_setlen(&buf, 0); @@ -3115,7 +3115,7 @@ static int git_config_copy_or_rename_section_in_file(const char *config_filename } while (fgets(buf, sizeof(buf), config_file)) { - int i; + unsigned i; int length; int is_section = 0; char *output = buf; diff --git a/config.mak.dev b/config.mak.dev index cd4a82a9eb..89b218d11a 100644 --- a/config.mak.dev +++ b/config.mak.dev @@ -16,8 +16,6 @@ DEVELOPER_CFLAGS += -Wstrict-prototypes DEVELOPER_CFLAGS += -Wunused DEVELOPER_CFLAGS += -Wvla -DEVELOPER_CFLAGS += -DENABLE_SHA256 - ifndef COMPILER_FEATURES COMPILER_FEATURES := $(shell ./detect-compiler $(CC)) endif @@ -17,7 +17,7 @@ #include "alias.h" static char *server_capabilities_v1; -static struct argv_array server_capabilities_v2 = ARGV_ARRAY_INIT; +static struct strvec server_capabilities_v2 = STRVEC_INIT; static const char *next_server_feature_value(const char *feature, int *len, int *offset); static int check_ref(const char *name, unsigned int flags) @@ -70,9 +70,9 @@ int server_supports_v2(const char *c, int die_on_error) { int i; - for (i = 0; i < server_capabilities_v2.argc; i++) { + for (i = 0; i < server_capabilities_v2.nr; i++) { const char *out; - if (skip_prefix(server_capabilities_v2.argv[i], c, &out) && + if (skip_prefix(server_capabilities_v2.v[i], c, &out) && (!*out || *out == '=')) return 1; } @@ -87,9 +87,9 @@ int server_feature_v2(const char *c, const char **v) { int i; - for (i = 0; i < server_capabilities_v2.argc; i++) { + for (i = 0; i < server_capabilities_v2.nr; i++) { const char *out; - if (skip_prefix(server_capabilities_v2.argv[i], c, &out) && + if (skip_prefix(server_capabilities_v2.v[i], c, &out) && (*out == '=')) { *v = out + 1; return 1; @@ -103,9 +103,9 @@ int server_supports_feature(const char *c, const char *feature, { int i; - for (i = 0; i < server_capabilities_v2.argc; i++) { + for (i = 0; i < server_capabilities_v2.nr; i++) { const char *out; - if (skip_prefix(server_capabilities_v2.argv[i], c, &out) && + if (skip_prefix(server_capabilities_v2.v[i], c, &out) && (!*out || *(out++) == '=')) { if (parse_feature_request(out, feature)) return 1; @@ -123,7 +123,7 @@ int server_supports_feature(const char *c, const char *feature, static void process_capabilities_v2(struct packet_reader *reader) { while (packet_reader_read(reader) == PACKET_READ_NORMAL) - argv_array_push(&server_capabilities_v2, reader->line); + strvec_push(&server_capabilities_v2, reader->line); if (reader->status != PACKET_READ_FLUSH) die(_("expected flush after capabilities")); @@ -453,7 +453,7 @@ void check_stateless_delimiter(int stateless_rpc, struct ref **get_remote_refs(int fd_out, struct packet_reader *reader, struct ref **list, int for_push, - const struct argv_array *ref_prefixes, + const struct strvec *ref_prefixes, const struct string_list *server_options, int stateless_rpc) { @@ -488,9 +488,9 @@ struct ref **get_remote_refs(int fd_out, struct packet_reader *reader, if (!for_push) packet_write_fmt(fd_out, "peel\n"); packet_write_fmt(fd_out, "symrefs\n"); - for (i = 0; ref_prefixes && i < ref_prefixes->argc; i++) { + for (i = 0; ref_prefixes && i < ref_prefixes->nr; i++) { packet_write_fmt(fd_out, "ref-prefix %s\n", - ref_prefixes->argv[i]); + ref_prefixes->v[i]); } packet_flush(fd_out); @@ -944,9 +944,9 @@ static struct child_process *git_proxy_connect(int fd[2], char *host) proxy = xmalloc(sizeof(*proxy)); child_process_init(proxy); - argv_array_push(&proxy->args, git_proxy_command); - argv_array_push(&proxy->args, host); - argv_array_push(&proxy->args, port); + strvec_push(&proxy->args, git_proxy_command); + strvec_push(&proxy->args, host); + strvec_push(&proxy->args, port); proxy->in = -1; proxy->out = -1; if (start_command(proxy)) @@ -1199,16 +1199,16 @@ static struct child_process *git_connect_git(int fd[2], char *hostandport, * Append the appropriate environment variables to `env` and options to * `args` for running ssh in Git's SSH-tunneled transport. */ -static void push_ssh_options(struct argv_array *args, struct argv_array *env, +static void push_ssh_options(struct strvec *args, struct strvec *env, enum ssh_variant variant, const char *port, enum protocol_version version, int flags) { if (variant == VARIANT_SSH && version > 0) { - argv_array_push(args, "-o"); - argv_array_push(args, "SendEnv=" GIT_PROTOCOL_ENVIRONMENT); - argv_array_pushf(env, GIT_PROTOCOL_ENVIRONMENT "=version=%d", - version); + strvec_push(args, "-o"); + strvec_push(args, "SendEnv=" GIT_PROTOCOL_ENVIRONMENT); + strvec_pushf(env, GIT_PROTOCOL_ENVIRONMENT "=version=%d", + version); } if (flags & CONNECT_IPV4) { @@ -1221,7 +1221,7 @@ static void push_ssh_options(struct argv_array *args, struct argv_array *env, case VARIANT_PLINK: case VARIANT_PUTTY: case VARIANT_TORTOISEPLINK: - argv_array_push(args, "-4"); + strvec_push(args, "-4"); } } else if (flags & CONNECT_IPV6) { switch (variant) { @@ -1233,12 +1233,12 @@ static void push_ssh_options(struct argv_array *args, struct argv_array *env, case VARIANT_PLINK: case VARIANT_PUTTY: case VARIANT_TORTOISEPLINK: - argv_array_push(args, "-6"); + strvec_push(args, "-6"); } } if (variant == VARIANT_TORTOISEPLINK) - argv_array_push(args, "-batch"); + strvec_push(args, "-batch"); if (port) { switch (variant) { @@ -1247,15 +1247,15 @@ static void push_ssh_options(struct argv_array *args, struct argv_array *env, case VARIANT_SIMPLE: die(_("ssh variant 'simple' does not support setting port")); case VARIANT_SSH: - argv_array_push(args, "-p"); + strvec_push(args, "-p"); break; case VARIANT_PLINK: case VARIANT_PUTTY: case VARIANT_TORTOISEPLINK: - argv_array_push(args, "-P"); + strvec_push(args, "-P"); } - argv_array_push(args, port); + strvec_push(args, port); } } @@ -1293,18 +1293,18 @@ static void fill_ssh_args(struct child_process *conn, const char *ssh_host, detect.use_shell = conn->use_shell; detect.no_stdin = detect.no_stdout = detect.no_stderr = 1; - argv_array_push(&detect.args, ssh); - argv_array_push(&detect.args, "-G"); + strvec_push(&detect.args, ssh); + strvec_push(&detect.args, "-G"); push_ssh_options(&detect.args, &detect.env_array, VARIANT_SSH, port, version, flags); - argv_array_push(&detect.args, ssh_host); + strvec_push(&detect.args, ssh_host); variant = run_command(&detect) ? VARIANT_SIMPLE : VARIANT_SSH; } - argv_array_push(&conn->args, ssh); + strvec_push(&conn->args, ssh); push_ssh_options(&conn->args, &conn->env_array, variant, port, version, flags); - argv_array_push(&conn->args, ssh_host); + strvec_push(&conn->args, ssh_host); } /* @@ -1365,7 +1365,7 @@ struct child_process *git_connect(int fd[2], const char *url, /* remove repo-local variables from the environment */ for (var = local_repo_env; *var; var++) - argv_array_push(&conn->env_array, *var); + strvec_push(&conn->env_array, *var); conn->use_shell = 1; conn->in = conn->out = -1; @@ -1397,11 +1397,12 @@ struct child_process *git_connect(int fd[2], const char *url, transport_check_allowed("file"); conn->trace2_child_class = "transport/file"; if (version > 0) { - argv_array_pushf(&conn->env_array, GIT_PROTOCOL_ENVIRONMENT "=version=%d", - version); + strvec_pushf(&conn->env_array, + GIT_PROTOCOL_ENVIRONMENT "=version=%d", + version); } } - argv_array_push(&conn->args, cmd.buf); + strvec_push(&conn->args, cmd.buf); if (start_command(conn)) die(_("unable to fork")); diff --git a/connected.c b/connected.c index 937b4bae38..21c1ebe9fb 100644 --- a/connected.c +++ b/connected.c @@ -90,23 +90,23 @@ promisor_pack_found: no_promisor_pack_found: if (opt->shallow_file) { - argv_array_push(&rev_list.args, "--shallow-file"); - argv_array_push(&rev_list.args, opt->shallow_file); + strvec_push(&rev_list.args, "--shallow-file"); + strvec_push(&rev_list.args, opt->shallow_file); } - argv_array_push(&rev_list.args,"rev-list"); - argv_array_push(&rev_list.args, "--objects"); - argv_array_push(&rev_list.args, "--stdin"); + strvec_push(&rev_list.args,"rev-list"); + strvec_push(&rev_list.args, "--objects"); + strvec_push(&rev_list.args, "--stdin"); if (has_promisor_remote()) - argv_array_push(&rev_list.args, "--exclude-promisor-objects"); + strvec_push(&rev_list.args, "--exclude-promisor-objects"); if (!opt->is_deepening_fetch) { - argv_array_push(&rev_list.args, "--not"); - argv_array_push(&rev_list.args, "--all"); + strvec_push(&rev_list.args, "--not"); + strvec_push(&rev_list.args, "--all"); } - argv_array_push(&rev_list.args, "--quiet"); - argv_array_push(&rev_list.args, "--alternate-refs"); + strvec_push(&rev_list.args, "--quiet"); + strvec_push(&rev_list.args, "--alternate-refs"); if (opt->progress) - argv_array_pushf(&rev_list.args, "--progress=%s", - _("Checking connectivity")); + strvec_pushf(&rev_list.args, "--progress=%s", + _("Checking connectivity")); rev_list.git_cmd = 1; rev_list.env = opt->env; diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index ee468ea3b0..0fdb5da83b 100644 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -2907,6 +2907,14 @@ _git_show () __gitcomp "$__git_diff_submodule_formats" "" "${cur##--submodule=}" return ;; + --color-moved=*) + __gitcomp "$__git_color_moved_opts" "" "${cur##--color-moved=}" + return + ;; + --color-moved-ws=*) + __gitcomp "$__git_color_moved_ws_opts" "" "${cur##--color-moved-ws=}" + return + ;; --*) __gitcomp "--pretty= --format= --abbrev-commit --no-abbrev-commit --oneline --show-signature --patch diff --git a/contrib/subtree/t/t7900-subtree.sh b/contrib/subtree/t/t7900-subtree.sh index 53d7accf94..57ff4b25c1 100755 --- a/contrib/subtree/t/t7900-subtree.sh +++ b/contrib/subtree/t/t7900-subtree.sh @@ -196,8 +196,7 @@ test_expect_success 'merge new subproj history into sub dir/ with --prefix' ' cd "$subtree_test_count" && git fetch ./"sub proj" master && git subtree merge --prefix="sub dir" FETCH_HEAD && - check_equal "$(last_commit_message)" \ - "Merge commit '\''$(git rev-parse FETCH_HEAD)'\'' into master" + check_equal "$(last_commit_message)" "Merge commit '\''$(git rev-parse FETCH_HEAD)'\''" ) ' @@ -274,8 +273,7 @@ test_expect_success 'merge new subproj history into subdir/ with a slash appende cd "$test_count" && git fetch ./subproj master && git subtree merge --prefix=subdir/ FETCH_HEAD && - check_equal "$(last_commit_message)" \ - "Merge commit '\''$(git rev-parse FETCH_HEAD)'\'' into master" + check_equal "$(last_commit_message)" "Merge commit '\''$(git rev-parse FETCH_HEAD)'\''" ) ' @@ -296,7 +296,7 @@ static const char *path_ok(const char *directory, struct hostinfo *hi) return NULL; /* Fallthrough. Deny by default */ } -typedef int (*daemon_service_fn)(const struct argv_array *env); +typedef int (*daemon_service_fn)(const struct strvec *env); struct daemon_service { const char *name; const char *config_name; @@ -377,7 +377,7 @@ error_return: } static int run_service(const char *dir, struct daemon_service *service, - struct hostinfo *hi, const struct argv_array *env) + struct hostinfo *hi, const struct strvec *env) { const char *path; int enabled = service->enabled; @@ -462,7 +462,7 @@ static void copy_to_log(int fd) static int run_service_command(struct child_process *cld) { - argv_array_push(&cld->args, "."); + strvec_push(&cld->args, "."); cld->git_cmd = 1; cld->err = -1; if (start_command(cld)) @@ -476,33 +476,33 @@ static int run_service_command(struct child_process *cld) return finish_command(cld); } -static int upload_pack(const struct argv_array *env) +static int upload_pack(const struct strvec *env) { struct child_process cld = CHILD_PROCESS_INIT; - argv_array_pushl(&cld.args, "upload-pack", "--strict", NULL); - argv_array_pushf(&cld.args, "--timeout=%u", timeout); + strvec_pushl(&cld.args, "upload-pack", "--strict", NULL); + strvec_pushf(&cld.args, "--timeout=%u", timeout); - argv_array_pushv(&cld.env_array, env->argv); + strvec_pushv(&cld.env_array, env->v); return run_service_command(&cld); } -static int upload_archive(const struct argv_array *env) +static int upload_archive(const struct strvec *env) { struct child_process cld = CHILD_PROCESS_INIT; - argv_array_push(&cld.args, "upload-archive"); + strvec_push(&cld.args, "upload-archive"); - argv_array_pushv(&cld.env_array, env->argv); + strvec_pushv(&cld.env_array, env->v); return run_service_command(&cld); } -static int receive_pack(const struct argv_array *env) +static int receive_pack(const struct strvec *env) { struct child_process cld = CHILD_PROCESS_INIT; - argv_array_push(&cld.args, "receive-pack"); + strvec_push(&cld.args, "receive-pack"); - argv_array_pushv(&cld.env_array, env->argv); + strvec_pushv(&cld.env_array, env->v); return run_service_command(&cld); } @@ -633,7 +633,7 @@ static char *parse_host_arg(struct hostinfo *hi, char *extra_args, int buflen) return extra_args; } -static void parse_extra_args(struct hostinfo *hi, struct argv_array *env, +static void parse_extra_args(struct hostinfo *hi, struct strvec *env, char *extra_args, int buflen) { const char *end = extra_args + buflen; @@ -664,8 +664,8 @@ static void parse_extra_args(struct hostinfo *hi, struct argv_array *env, if (git_protocol.len > 0) { loginfo("Extended attribute \"protocol\": %s", git_protocol.buf); - argv_array_pushf(env, GIT_PROTOCOL_ENVIRONMENT "=%s", - git_protocol.buf); + strvec_pushf(env, GIT_PROTOCOL_ENVIRONMENT "=%s", + git_protocol.buf); } strbuf_release(&git_protocol); } @@ -761,7 +761,7 @@ static int execute(void) int pktlen, len, i; char *addr = getenv("REMOTE_ADDR"), *port = getenv("REMOTE_PORT"); struct hostinfo hi; - struct argv_array env = ARGV_ARRAY_INIT; + struct strvec env = STRVEC_INIT; hostinfo_init(&hi); @@ -794,13 +794,13 @@ static int execute(void) */ int rc = run_service(arg, s, &hi, &env); hostinfo_clear(&hi); - argv_array_clear(&env); + strvec_clear(&env); return rc; } } hostinfo_clear(&hi); - argv_array_clear(&env); + strvec_clear(&env); logerror("Protocol error: '%s'", line); return -1; } @@ -893,7 +893,7 @@ static void check_dead_children(void) cradle = &blanket->next; } -static struct argv_array cld_argv = ARGV_ARRAY_INIT; +static struct strvec cld_argv = STRVEC_INIT; static void handle(int incoming, struct sockaddr *addr, socklen_t addrlen) { struct child_process cld = CHILD_PROCESS_INIT; @@ -913,21 +913,21 @@ static void handle(int incoming, struct sockaddr *addr, socklen_t addrlen) char buf[128] = ""; struct sockaddr_in *sin_addr = (void *) addr; inet_ntop(addr->sa_family, &sin_addr->sin_addr, buf, sizeof(buf)); - argv_array_pushf(&cld.env_array, "REMOTE_ADDR=%s", buf); - argv_array_pushf(&cld.env_array, "REMOTE_PORT=%d", - ntohs(sin_addr->sin_port)); + strvec_pushf(&cld.env_array, "REMOTE_ADDR=%s", buf); + strvec_pushf(&cld.env_array, "REMOTE_PORT=%d", + ntohs(sin_addr->sin_port)); #ifndef NO_IPV6 } else if (addr->sa_family == AF_INET6) { char buf[128] = ""; struct sockaddr_in6 *sin6_addr = (void *) addr; inet_ntop(AF_INET6, &sin6_addr->sin6_addr, buf, sizeof(buf)); - argv_array_pushf(&cld.env_array, "REMOTE_ADDR=[%s]", buf); - argv_array_pushf(&cld.env_array, "REMOTE_PORT=%d", - ntohs(sin6_addr->sin6_port)); + strvec_pushf(&cld.env_array, "REMOTE_ADDR=[%s]", buf); + strvec_pushf(&cld.env_array, "REMOTE_PORT=%d", + ntohs(sin6_addr->sin6_port)); #endif } - cld.argv = cld_argv.argv; + cld.argv = cld_argv.v; cld.in = incoming; cld.out = dup(incoming); @@ -1476,10 +1476,10 @@ int cmd_main(int argc, const char **argv) write_file(pid_file, "%"PRIuMAX, (uintmax_t) getpid()); /* prepare argv for serving-processes */ - argv_array_push(&cld_argv, argv[0]); /* git-daemon */ - argv_array_push(&cld_argv, "--serve"); + strvec_push(&cld_argv, argv[0]); /* git-daemon */ + strvec_push(&cld_argv, "--serve"); for (i = 1; i < argc; ++i) - argv_array_push(&cld_argv, argv[i]); + strvec_push(&cld_argv, argv[i]); return serve(&listen_addr, listen_port, cred); } @@ -20,7 +20,7 @@ #include "hashmap.h" #include "ll-merge.h" #include "string-list.h" -#include "argv-array.h" +#include "strvec.h" #include "graph.h" #include "packfile.h" #include "parse-options.h" @@ -4192,14 +4192,14 @@ static struct diff_tempfile *prepare_temp_file(struct repository *r, } static void add_external_diff_name(struct repository *r, - struct argv_array *argv, + struct strvec *argv, const char *name, struct diff_filespec *df) { struct diff_tempfile *temp = prepare_temp_file(r, name, df); - argv_array_push(argv, temp->name); - argv_array_push(argv, temp->hex); - argv_array_push(argv, temp->mode); + strvec_push(argv, temp->name); + strvec_push(argv, temp->hex); + strvec_push(argv, temp->mode); } /* An external diff command takes: @@ -4216,12 +4216,12 @@ static void run_external_diff(const char *pgm, const char *xfrm_msg, struct diff_options *o) { - struct argv_array argv = ARGV_ARRAY_INIT; - struct argv_array env = ARGV_ARRAY_INIT; + struct strvec argv = STRVEC_INIT; + struct strvec env = STRVEC_INIT; struct diff_queue_struct *q = &diff_queued_diff; - argv_array_push(&argv, pgm); - argv_array_push(&argv, name); + strvec_push(&argv, pgm); + strvec_push(&argv, name); if (one && two) { add_external_diff_name(o->repo, &argv, name, one); @@ -4229,22 +4229,22 @@ static void run_external_diff(const char *pgm, add_external_diff_name(o->repo, &argv, name, two); else { add_external_diff_name(o->repo, &argv, other, two); - argv_array_push(&argv, other); - argv_array_push(&argv, xfrm_msg); + strvec_push(&argv, other); + strvec_push(&argv, xfrm_msg); } } - argv_array_pushf(&env, "GIT_DIFF_PATH_COUNTER=%d", ++o->diff_path_counter); - argv_array_pushf(&env, "GIT_DIFF_PATH_TOTAL=%d", q->nr); + strvec_pushf(&env, "GIT_DIFF_PATH_COUNTER=%d", ++o->diff_path_counter); + strvec_pushf(&env, "GIT_DIFF_PATH_TOTAL=%d", q->nr); diff_free_filespec_data(one); diff_free_filespec_data(two); - if (run_command_v_opt_cd_env(argv.argv, RUN_USING_SHELL, NULL, env.argv)) + if (run_command_v_opt_cd_env(argv.v, RUN_USING_SHELL, NULL, env.v)) die(_("external diff died, stopping at %s"), name); remove_tempfile(); - argv_array_clear(&argv); - argv_array_clear(&env); + strvec_clear(&argv); + strvec_clear(&env); } static int similarity_index(struct diff_filepair *p) @@ -431,11 +431,11 @@ struct combine_diff_path *diff_tree_paths( struct combine_diff_path *p, const struct object_id *oid, const struct object_id **parents_oid, int nparent, struct strbuf *base, struct diff_options *opt); -int diff_tree_oid(const struct object_id *old_oid, - const struct object_id *new_oid, - const char *base, struct diff_options *opt); -int diff_root_tree_oid(const struct object_id *new_oid, const char *base, - struct diff_options *opt); +void diff_tree_oid(const struct object_id *old_oid, + const struct object_id *new_oid, + const char *base, struct diff_options *opt); +void diff_root_tree_oid(const struct object_id *new_oid, const char *base, + struct diff_options *opt); struct combine_diff_path { struct combine_diff_path *next; @@ -2209,13 +2209,13 @@ static enum path_treatment treat_path(struct dir_struct *dir, baselen, excluded, pathspec); case DT_REG: case DT_LNK: - if (excluded) - return path_excluded; if (pathspec && !match_pathspec(istate, pathspec, path->buf, path->len, 0 /* prefix */, NULL /* seen */, 0 /* is_dir */)) return path_none; + if (excluded) + return path_excluded; return path_untracked; } } diff --git a/environment.c b/environment.c index aaca0e91ac..52e0c979ba 100644 --- a/environment.c +++ b/environment.c @@ -14,7 +14,7 @@ #include "refs.h" #include "fmt-merge-msg.h" #include "commit.h" -#include "argv-array.h" +#include "strvec.h" #include "object-store.h" #include "chdir-notify.h" #include "shallow.h" @@ -156,15 +156,15 @@ static char *expand_namespace(const char *raw_namespace) * Wrapper of getenv() that returns a strdup value. This value is kept * in argv to be freed later. */ -static const char *getenv_safe(struct argv_array *argv, const char *name) +static const char *getenv_safe(struct strvec *argv, const char *name) { const char *value = getenv(name); if (!value) return NULL; - argv_array_push(argv, value); - return argv->argv[argv->argc - 1]; + strvec_push(argv, value); + return argv->v[argv->nr - 1]; } void setup_git_env(const char *git_dir) @@ -172,7 +172,7 @@ void setup_git_env(const char *git_dir) const char *shallow_file; const char *replace_ref_base; struct set_gitdir_args args = { NULL }; - struct argv_array to_free = ARGV_ARRAY_INIT; + struct strvec to_free = STRVEC_INIT; args.commondir = getenv_safe(&to_free, GIT_COMMON_DIR_ENVIRONMENT); args.object_dir = getenv_safe(&to_free, DB_ENVIRONMENT); @@ -180,7 +180,7 @@ void setup_git_env(const char *git_dir) args.index_file = getenv_safe(&to_free, INDEX_ENVIRONMENT); args.alternate_db = getenv_safe(&to_free, ALTERNATE_DB_ENVIRONMENT); repo_set_gitdir(the_repository, git_dir, &args); - argv_array_clear(&to_free); + strvec_clear(&to_free); if (getenv(NO_REPLACE_OBJECTS_ENVIRONMENT)) read_replace_refs = 0; diff --git a/exec-cmd.c b/exec-cmd.c index 7deeab3039..eeb2ee52b8 100644 --- a/exec-cmd.c +++ b/exec-cmd.c @@ -1,7 +1,7 @@ #include "cache.h" #include "exec-cmd.h" #include "quote.h" -#include "argv-array.h" +#include "strvec.h" #if defined(RUNTIME_PREFIX) @@ -320,26 +320,26 @@ void setup_path(void) strbuf_release(&new_path); } -const char **prepare_git_cmd(struct argv_array *out, const char **argv) +const char **prepare_git_cmd(struct strvec *out, const char **argv) { - argv_array_push(out, "git"); - argv_array_pushv(out, argv); - return out->argv; + strvec_push(out, "git"); + strvec_pushv(out, argv); + return out->v; } int execv_git_cmd(const char **argv) { - struct argv_array nargv = ARGV_ARRAY_INIT; + struct strvec nargv = STRVEC_INIT; prepare_git_cmd(&nargv, argv); - trace_argv_printf(nargv.argv, "trace: exec:"); + trace_argv_printf(nargv.v, "trace: exec:"); /* execvp() can only ever return if it fails */ - sane_execvp("git", (char **)nargv.argv); + sane_execvp("git", (char **)nargv.v); trace_printf("trace: exec failed: %s\n", strerror(errno)); - argv_array_clear(&nargv); + strvec_clear(&nargv); return -1; } diff --git a/exec-cmd.h b/exec-cmd.h index 8cd1df28d3..330b41d54d 100644 --- a/exec-cmd.h +++ b/exec-cmd.h @@ -1,13 +1,13 @@ #ifndef GIT_EXEC_CMD_H #define GIT_EXEC_CMD_H -struct argv_array; +struct strvec; void git_set_exec_path(const char *exec_path); void git_resolve_executable_dir(const char *path); const char *git_exec_path(void); void setup_path(void); -const char **prepare_git_cmd(struct argv_array *out, const char **argv); +const char **prepare_git_cmd(struct strvec *out, const char **argv); int execv_git_cmd(const char **argv); /* NULL terminated */ LAST_ARG_MUST_BE_NULL int execl_git_cmd(const char *cmd, ...); diff --git a/fast-import.c b/fast-import.c index 0dfa14dc8c..ce47794db6 100644 --- a/fast-import.c +++ b/fast-import.c @@ -843,9 +843,9 @@ static int loosen_small_pack(const struct packed_git *p) unpack.in = p->pack_fd; unpack.git_cmd = 1; unpack.stdout_to_stderr = 1; - argv_array_push(&unpack.args, "unpack-objects"); + strvec_push(&unpack.args, "unpack-objects"); if (!show_stats) - argv_array_push(&unpack.args, "-q"); + strvec_push(&unpack.args, "-q"); return run_command(&unpack); } diff --git a/fetch-pack.c b/fetch-pack.c index 80fb3bd899..7f20eca4f8 100644 --- a/fetch-pack.c +++ b/fetch-pack.c @@ -835,30 +835,30 @@ static int get_pack(struct fetch_pack_args *args, } if (alternate_shallow_file) { - argv_array_push(&cmd.args, "--shallow-file"); - argv_array_push(&cmd.args, alternate_shallow_file); + strvec_push(&cmd.args, "--shallow-file"); + strvec_push(&cmd.args, alternate_shallow_file); } if (do_keep || args->from_promisor) { if (pack_lockfiles) cmd.out = -1; cmd_name = "index-pack"; - argv_array_push(&cmd.args, cmd_name); - argv_array_push(&cmd.args, "--stdin"); + strvec_push(&cmd.args, cmd_name); + strvec_push(&cmd.args, "--stdin"); if (!args->quiet && !args->no_progress) - argv_array_push(&cmd.args, "-v"); + strvec_push(&cmd.args, "-v"); if (args->use_thin_pack) - argv_array_push(&cmd.args, "--fix-thin"); + strvec_push(&cmd.args, "--fix-thin"); if (do_keep && (args->lock_pack || unpack_limit)) { char hostname[HOST_NAME_MAX + 1]; if (xgethostname(hostname, sizeof(hostname))) xsnprintf(hostname, sizeof(hostname), "localhost"); - argv_array_pushf(&cmd.args, - "--keep=fetch-pack %"PRIuMAX " on %s", - (uintmax_t)getpid(), hostname); + strvec_pushf(&cmd.args, + "--keep=fetch-pack %"PRIuMAX " on %s", + (uintmax_t)getpid(), hostname); } if (only_packfile && args->check_self_contained_and_connected) - argv_array_push(&cmd.args, "--check-self-contained-and-connected"); + strvec_push(&cmd.args, "--check-self-contained-and-connected"); else /* * We cannot perform any connectivity checks because @@ -873,19 +873,19 @@ static int get_pack(struct fetch_pack_args *args, * us. */ if (!(do_keep && pack_lockfiles) && args->from_promisor) - argv_array_push(&cmd.args, "--promisor"); + strvec_push(&cmd.args, "--promisor"); } else { cmd_name = "unpack-objects"; - argv_array_push(&cmd.args, cmd_name); + strvec_push(&cmd.args, cmd_name); if (args->quiet || args->no_progress) - argv_array_push(&cmd.args, "-q"); + strvec_push(&cmd.args, "-q"); args->check_self_contained_and_connected = 0; } if (pass_header) - argv_array_pushf(&cmd.args, "--pack_header=%"PRIu32",%"PRIu32, - ntohl(header.hdr_version), + strvec_pushf(&cmd.args, "--pack_header=%"PRIu32",%"PRIu32, + ntohl(header.hdr_version), ntohl(header.hdr_entries)); if (fetch_fsck_objects >= 0 ? fetch_fsck_objects @@ -898,10 +898,10 @@ static int get_pack(struct fetch_pack_args *args, * checks both broken objects and links, but we only * want to check for broken objects. */ - argv_array_push(&cmd.args, "--fsck-objects"); + strvec_push(&cmd.args, "--fsck-objects"); else - argv_array_pushf(&cmd.args, "--strict%s", - fsck_msg_types.buf); + strvec_pushf(&cmd.args, "--strict%s", + fsck_msg_types.buf); } cmd.in = demux.out; @@ -1652,11 +1652,11 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args, const char *uri = packfile_uris.items[i].string + the_hash_algo->hexsz + 1; - argv_array_push(&cmd.args, "http-fetch"); - argv_array_pushf(&cmd.args, "--packfile=%.*s", - (int) the_hash_algo->hexsz, - packfile_uris.items[i].string); - argv_array_push(&cmd.args, uri); + strvec_push(&cmd.args, "http-fetch"); + strvec_pushf(&cmd.args, "--packfile=%.*s", + (int) the_hash_algo->hexsz, + packfile_uris.items[i].string); + strvec_push(&cmd.args, uri); cmd.git_cmd = 1; cmd.no_stdin = 1; cmd.out = -1; diff --git a/fmt-merge-msg.c b/fmt-merge-msg.c index cfb8ff2f33..bd22e1ea88 100644 --- a/fmt-merge-msg.c +++ b/fmt-merge-msg.c @@ -10,6 +10,8 @@ #include "commit-reach.h" static int use_branch_desc; +static int suppress_dest_pattern_seen; +static struct string_list suppress_dest_patterns = STRING_LIST_INIT_DUP; int fmt_merge_msg_config(const char *key, const char *value, void *cb) { @@ -22,6 +24,14 @@ int fmt_merge_msg_config(const char *key, const char *value, void *cb) merge_log_config = DEFAULT_MERGE_LOG_LEN; } else if (!strcmp(key, "merge.branchdesc")) { use_branch_desc = git_config_bool(key, value); + } else if (!strcmp(key, "merge.suppressdest")) { + if (!value) + return config_error_nonbool(key); + if (!*value) + string_list_clear(&suppress_dest_patterns, 0); + else + string_list_append(&suppress_dest_patterns, value); + suppress_dest_pattern_seen = 1; } else { return git_default_config(key, value, cb); } @@ -403,6 +413,24 @@ static void shortlog(const char *name, string_list_clear(&subjects, 0); } +/* + * See if dest_branch matches with any glob pattern on the + * suppress_dest_patterns list. + * + * We may want to also allow negative matches e.g. ":!glob" like we do + * for pathspec, but for now, let's keep it simple and stupid. + */ +static int dest_suppressed(const char *dest_branch) +{ + struct string_list_item *item; + + for_each_string_list_item(item, &suppress_dest_patterns) { + if (!wildmatch(item->string, dest_branch, WM_PATHNAME)) + return 1; + } + return 0; +} + static void fmt_merge_msg_title(struct strbuf *out, const char *current_branch) { @@ -451,7 +479,9 @@ static void fmt_merge_msg_title(struct strbuf *out, strbuf_addf(out, " of %s", srcs.items[i].string); } - strbuf_addf(out, " into %s\n", current_branch); + if (!dest_suppressed(current_branch)) + strbuf_addf(out, " into %s", current_branch); + strbuf_addch(out, '\n'); } static void fmt_tag_signature(struct strbuf *tagbuf, @@ -596,6 +626,9 @@ int fmt_merge_msg(struct strbuf *in, struct strbuf *out, void *current_branch_to_free; struct merge_parents merge_parents; + if (!suppress_dest_pattern_seen) + string_list_append(&suppress_dest_patterns, "master"); + memset(&merge_parents, 0, sizeof(merge_parents)); /* get current branch */ diff --git a/fsmonitor.c b/fsmonitor.c index 932bd9012d..ca031c3abb 100644 --- a/fsmonitor.c +++ b/fsmonitor.c @@ -146,9 +146,9 @@ static int query_fsmonitor(int version, const char *last_update, struct strbuf * if (!core_fsmonitor) return -1; - argv_array_push(&cp.args, core_fsmonitor); - argv_array_pushf(&cp.args, "%d", version); - argv_array_pushf(&cp.args, "%s", last_update); + strvec_push(&cp.args, core_fsmonitor); + strvec_pushf(&cp.args, "%d", version); + strvec_pushf(&cp.args, "%s", last_update); cp.use_shell = 1; cp.dir = get_git_work_tree(); @@ -217,7 +217,7 @@ void refresh_fsmonitor(struct index_state *istate) * Need to use a char * variable because static * analysis was suggesting to use strbuf_addbuf * but we don't want to copy the entire strbuf - * only the the chars up to the first NUL + * only the chars up to the first NUL */ buf = query_result.buf; strbuf_addstr(&last_update_token, buf); diff --git a/git-bisect.sh b/git-bisect.sh index 08a6ed57dd..f03fbb18f0 100755 --- a/git-bisect.sh +++ b/git-bisect.sh @@ -41,7 +41,7 @@ TERM_GOOD=good bisect_head() { - if test -f "$GIT_DIR/BISECT_HEAD" + if git rev-parse --verify -q BISECT_HEAD > /dev/null then echo BISECT_HEAD else @@ -153,7 +153,7 @@ bisect_next() { git bisect--helper --bisect-next-check $TERM_GOOD $TERM_BAD $TERM_GOOD|| exit # Perform all bisection computation, display and checkout - git bisect--helper --next-all $(test -f "$GIT_DIR/BISECT_HEAD" && echo --no-checkout) + git bisect--helper --next-all $(git rev-parse --verify -q BISECT_HEAD > /dev/null && echo --no-checkout) res=$? # Check if we should exit because bisection is finished @@ -349,10 +349,10 @@ static int handle_alias(int *argcp, const char ***argv) child.clean_on_exit = 1; child.wait_after_clean = 1; child.trace2_child_class = "shell_alias"; - argv_array_push(&child.args, alias_string + 1); - argv_array_pushv(&child.args, (*argv) + 1); + strvec_push(&child.args, alias_string + 1); + strvec_pushv(&child.args, (*argv) + 1); - trace2_cmd_alias(alias_command, child.args.argv); + trace2_cmd_alias(alias_command, child.args.v); trace2_cmd_list_config(); trace2_cmd_list_env_vars(); trace2_cmd_name("_run_shell_alias_"); @@ -646,7 +646,7 @@ static void strip_extension(const char **argv) static void handle_builtin(int argc, const char **argv) { - struct argv_array args = ARGV_ARRAY_INIT; + struct strvec args = STRVEC_INIT; const char *cmd; struct cmd_struct *builtin; @@ -661,19 +661,19 @@ static void handle_builtin(int argc, const char **argv) argv[0] = cmd = "help"; for (i = 0; i < argc; i++) { - argv_array_push(&args, argv[i]); + strvec_push(&args, argv[i]); if (!i) - argv_array_push(&args, "--exclude-guides"); + strvec_push(&args, "--exclude-guides"); } argc++; - argv = args.argv; + argv = args.v; } builtin = get_builtin(cmd); if (builtin) exit(run_builtin(builtin, argc, argv)); - argv_array_clear(&args); + strvec_clear(&args); } static void execv_dashed_external(const char **argv) @@ -688,8 +688,8 @@ static void execv_dashed_external(const char **argv) use_pager = check_pager_config(argv[0]); commit_pager_choice(); - argv_array_pushf(&cmd.args, "git-%s", argv[0]); - argv_array_pushv(&cmd.args, argv + 1); + strvec_pushf(&cmd.args, "git-%s", argv[0]); + strvec_pushv(&cmd.args, argv + 1); cmd.clean_on_exit = 1; cmd.wait_after_clean = 1; cmd.silent_exec_failure = 1; @@ -701,7 +701,7 @@ static void execv_dashed_external(const char **argv) * The code in run_command() logs trace2 child_start/child_exit * events, so we do not need to report exec/exec_result events here. */ - trace_argv_printf(cmd.args.argv, "trace: exec:"); + trace_argv_printf(cmd.args.v, "trace: exec:"); /* * If we fail because the command is not found, it is @@ -741,7 +741,7 @@ static int run_argv(int *argcp, const char ***argv) if (!done_alias) handle_builtin(*argcp, *argv); else if (get_builtin(**argv)) { - struct argv_array args = ARGV_ARRAY_INIT; + struct strvec args = STRVEC_INIT; int i; /* @@ -758,17 +758,17 @@ static int run_argv(int *argcp, const char ***argv) commit_pager_choice(); - argv_array_push(&args, "git"); + strvec_push(&args, "git"); for (i = 0; i < *argcp; i++) - argv_array_push(&args, (*argv)[i]); + strvec_push(&args, (*argv)[i]); - trace_argv_printf(args.argv, "trace: exec:"); + trace_argv_printf(args.v, "trace: exec:"); /* * if we fail because the command is not found, it is * OK to return. Otherwise, we just pass along the status code. */ - i = run_command_v_opt_tr2(args.argv, RUN_SILENT_EXEC_FAILURE | + i = run_command_v_opt_tr2(args.v, RUN_SILENT_EXEC_FAILURE | RUN_CLEAN_ON_EXIT | RUN_WAIT_AFTER_CLEAN, "git_alias"); if (i >= 0 || errno != ENOENT) exit(i); diff --git a/gpg-interface.c b/gpg-interface.c index 2d538bcd6e..b499270836 100644 --- a/gpg-interface.c +++ b/gpg-interface.c @@ -282,12 +282,12 @@ static int verify_signed_buffer(const char *payload, size_t payload_size, if (!fmt) BUG("bad signature '%s'", signature); - argv_array_push(&gpg.args, fmt->program); - argv_array_pushv(&gpg.args, fmt->verify_args); - argv_array_pushl(&gpg.args, - "--status-fd=1", - "--verify", temp->filename.buf, "-", - NULL); + strvec_push(&gpg.args, fmt->program); + strvec_pushv(&gpg.args, fmt->verify_args); + strvec_pushl(&gpg.args, + "--status-fd=1", + "--verify", temp->filename.buf, "-", + NULL); if (!gpg_status) gpg_status = &buf; @@ -434,11 +434,11 @@ int sign_buffer(struct strbuf *buffer, struct strbuf *signature, const char *sig size_t i, j, bottom; struct strbuf gpg_status = STRBUF_INIT; - argv_array_pushl(&gpg.args, - use_format->program, - "--status-fd=2", - "-bsau", signing_key, - NULL); + strvec_pushl(&gpg.args, + use_format->program, + "--status-fd=2", + "-bsau", signing_key, + NULL); bottom = signature->len; @@ -4,7 +4,7 @@ #include "color.h" #include "graph.h" #include "revision.h" -#include "argv-array.h" +#include "strvec.h" /* Internal API */ @@ -82,7 +82,7 @@ static void graph_show_line_prefix(const struct diff_options *diffopt) static const char **column_colors; static unsigned short column_colors_max; -static void parse_graph_colors_config(struct argv_array *colors, const char *string) +static void parse_graph_colors_config(struct strvec *colors, const char *string) { const char *end, *start; @@ -93,13 +93,13 @@ static void parse_graph_colors_config(struct argv_array *colors, const char *str char color[COLOR_MAXLEN]; if (!color_parse_mem(start, comma - start, color)) - argv_array_push(colors, color); + strvec_push(colors, color); else warning(_("ignore invalid color '%.*s' in log.graphColors"), (int)(comma - start), start); start = comma + 1; } - argv_array_push(colors, GIT_COLOR_RESET); + strvec_push(colors, GIT_COLOR_RESET); } void graph_set_column_colors(const char **colors, unsigned short colors_max) @@ -350,13 +350,13 @@ struct git_graph *graph_init(struct rev_info *opt) graph_set_column_colors(column_colors_ansi, column_colors_ansi_max); } else { - static struct argv_array custom_colors = ARGV_ARRAY_INIT; - argv_array_clear(&custom_colors); + static struct strvec custom_colors = STRVEC_INIT; + strvec_clear(&custom_colors); parse_graph_colors_config(&custom_colors, string); free(string); /* graph_set_column_colors takes a max-index, not a count */ - graph_set_column_colors(custom_colors.argv, - custom_colors.argc - 1); + graph_set_column_colors(custom_colors.v, + custom_colors.nr - 1); } } @@ -1817,7 +1817,7 @@ static int grep_source_1(struct grep_opt *opt, struct grep_source *gs, int colle * We might set up the shared textconv cache data here, which * is not thread-safe. Also, get_oid_with_context() and * parse_object() might be internally called. As they are not - * currenty thread-safe and might be racy with object reading, + * currently thread-safe and might be racy with object reading, * obj_read_lock() must be called. */ grep_attr_lock(); @@ -168,7 +168,7 @@ struct hashmap_entry { * argument `keydata`, respectively. Otherwise, `keydata` is NULL. * * When it is too expensive to allocate a user entry (either because it is - * large or varialbe sized, such that it is not on the stack), then the + * large or variable sized, such that it is not on the stack), then the * relevant data to check for equality should be passed via `keydata`. * In this case `key` can be a stripped down version of the user key data * or even just a hashmap_entry having the correct hash. @@ -397,10 +397,10 @@ void list_cmds_by_config(struct string_list *list) } } -void list_common_guides_help(void) +void list_guides_help(void) { struct category_description catdesc[] = { - { CAT_guide, N_("The common Git guides are:") }, + { CAT_guide, N_("The Git concept guides are:") }, { 0, NULL } }; print_cmd_by_category(catdesc, NULL); @@ -21,7 +21,7 @@ static inline void mput_char(char c, unsigned int num) void list_common_cmds_help(void); void list_all_cmds_help(void); -void list_common_guides_help(void); +void list_guides_help(void); void list_all_main_cmds(struct string_list *list); void list_all_other_cmds(struct string_list *list); diff --git a/http-backend.c b/http-backend.c index ec3144b444..a03b4bae22 100644 --- a/http-backend.c +++ b/http-backend.c @@ -9,7 +9,7 @@ #include "run-command.h" #include "string-list.h" #include "url.h" -#include "argv-array.h" +#include "strvec.h" #include "packfile.h" #include "object-store.h" #include "protocol.h" @@ -477,10 +477,10 @@ static void run_service(const char **argv, int buffer_input) host = "(none)"; if (!getenv("GIT_COMMITTER_NAME")) - argv_array_pushf(&cld.env_array, "GIT_COMMITTER_NAME=%s", user); + strvec_pushf(&cld.env_array, "GIT_COMMITTER_NAME=%s", user); if (!getenv("GIT_COMMITTER_EMAIL")) - argv_array_pushf(&cld.env_array, - "GIT_COMMITTER_EMAIL=%s@http.%s", user, host); + strvec_pushf(&cld.env_array, + "GIT_COMMITTER_EMAIL=%s@http.%s", user, host); cld.argv = argv; if (buffer_input || gzipped_request || req_len >= 0) diff --git a/http-fetch.c b/http-fetch.c index 1df376e745..c4ccc5fea9 100644 --- a/http-fetch.c +++ b/http-fetch.c @@ -84,8 +84,11 @@ int cmd_main(int argc, const char **argv) int get_verbosely = 0; int get_recover = 0; int packfile = 0; + int nongit; struct object_id packfile_hash; + setup_git_directory_gently(&nongit); + while (arg < argc && argv[arg][0] == '-') { const char *p; @@ -115,7 +118,8 @@ int cmd_main(int argc, const char **argv) if (argc != arg + 2 - (commits_on_stdin || packfile)) usage(http_fetch_usage); - setup_git_directory(); + if (nongit) + die(_("not a git repository")); git_config(git_default_config, NULL); diff --git a/http-push.c b/http-push.c index 1ff1883cdd..6a4a43e07f 100644 --- a/http-push.c +++ b/http-push.c @@ -11,7 +11,7 @@ #include "remote.h" #include "list-objects.h" #include "sigchain.h" -#include "argv-array.h" +#include "strvec.h" #include "packfile.h" #include "object-store.h" #include "commit-reach.h" @@ -1846,7 +1846,7 @@ int cmd_main(int argc, const char **argv) new_refs = 0; for (ref = remote_refs; ref; ref = ref->next) { - struct argv_array commit_argv = ARGV_ARRAY_INIT; + struct strvec commit_argv = STRVEC_INIT; if (!ref->peer_ref) continue; @@ -1924,14 +1924,14 @@ int cmd_main(int argc, const char **argv) } /* Set up revision info for this refspec */ - argv_array_push(&commit_argv, ""); /* ignored */ - argv_array_push(&commit_argv, "--objects"); - argv_array_push(&commit_argv, oid_to_hex(&ref->new_oid)); + strvec_push(&commit_argv, ""); /* ignored */ + strvec_push(&commit_argv, "--objects"); + strvec_push(&commit_argv, oid_to_hex(&ref->new_oid)); if (!push_all && !is_null_oid(&ref->old_oid)) - argv_array_pushf(&commit_argv, "^%s", - oid_to_hex(&ref->old_oid)); + strvec_pushf(&commit_argv, "^%s", + oid_to_hex(&ref->old_oid)); repo_init_revisions(the_repository, &revs, setup_git_directory()); - setup_revisions(commit_argv.argc, commit_argv.argv, &revs, NULL); + setup_revisions(commit_argv.nr, commit_argv.v, &revs, NULL); revs.edge_hint = 0; /* just in case */ /* Generate a list of objects that need to be pushed */ @@ -1961,7 +1961,7 @@ int cmd_main(int argc, const char **argv) printf("%s %s\n", !rc ? "ok" : "error", ref->name); unlock_remote(ref_lock); check_locks(); - argv_array_clear(&commit_argv); + strvec_clear(&commit_argv); } /* Update remote server info if appropriate */ @@ -2270,13 +2270,13 @@ int finish_http_pack_request(struct http_pack_request *preq) tmpfile_fd = xopen(preq->tmpfile.buf, O_RDONLY); - argv_array_push(&ip.args, "index-pack"); - argv_array_push(&ip.args, "--stdin"); + strvec_push(&ip.args, "index-pack"); + strvec_push(&ip.args, "--stdin"); ip.git_cmd = 1; ip.in = tmpfile_fd; if (preq->generate_keep) { - argv_array_pushf(&ip.args, "--keep=git %"PRIuMAX, - (uintmax_t)getpid()); + strvec_pushf(&ip.args, "--keep=git %"PRIuMAX, + (uintmax_t)getpid()); ip.out = 0; } else { ip.no_stdout = 1; diff --git a/imap-send.c b/imap-send.c index 52737546f3..5764dd812c 100644 --- a/imap-send.c +++ b/imap-send.c @@ -976,7 +976,7 @@ static struct imap_store *imap_open_store(struct imap_server_conf *srvc, char *f imap_info("Starting tunnel '%s'... ", srvc->tunnel); - argv_array_push(&tunnel.args, srvc->tunnel); + strvec_push(&tunnel.args, srvc->tunnel); tunnel.use_shell = 1; tunnel.in = -1; tunnel.out = -1; diff --git a/line-log.c b/line-log.c index c53692834d..bf73ea95ac 100644 --- a/line-log.c +++ b/line-log.c @@ -14,7 +14,7 @@ #include "graph.h" #include "userdiff.h" #include "line-log.h" -#include "argv-array.h" +#include "strvec.h" #include "bloom.h" static void range_set_grow(struct range_set *rs, size_t extra) @@ -758,12 +758,12 @@ static void parse_pathspec_from_ranges(struct pathspec *pathspec, struct line_log_data *range) { struct line_log_data *r; - struct argv_array array = ARGV_ARRAY_INIT; + struct strvec array = STRVEC_INIT; const char **paths; for (r = range; r; r = r->next) - argv_array_push(&array, r->path); - paths = argv_array_detach(&array); + strvec_push(&array, r->path); + paths = strvec_detach(&array); parse_pathspec(pathspec, 0, PATHSPEC_PREFER_FULL, "", paths); /* strings are now owned by pathspec */ diff --git a/list-objects-filter-options.c b/list-objects-filter-options.c index 3553ad7b0a..3667766f29 100644 --- a/list-objects-filter-options.c +++ b/list-objects-filter-options.c @@ -2,7 +2,7 @@ #include "commit.h" #include "config.h" #include "revision.h" -#include "argv-array.h" +#include "strvec.h" #include "list-objects.h" #include "list-objects-filter.h" #include "list-objects-filter-options.h" @@ -2,7 +2,7 @@ #include "repository.h" #include "refs.h" #include "remote.h" -#include "argv-array.h" +#include "strvec.h" #include "ls-refs.h" #include "pkt-line.h" #include "config.h" @@ -11,15 +11,15 @@ * Check if one of the prefixes is a prefix of the ref. * If no prefixes were provided, all refs match. */ -static int ref_match(const struct argv_array *prefixes, const char *refname) +static int ref_match(const struct strvec *prefixes, const char *refname) { int i; - if (!prefixes->argc) + if (!prefixes->nr) return 1; /* no restriction */ - for (i = 0; i < prefixes->argc; i++) { - const char *prefix = prefixes->argv[i]; + for (i = 0; i < prefixes->nr; i++) { + const char *prefix = prefixes->v[i]; if (starts_with(refname, prefix)) return 1; @@ -31,7 +31,7 @@ static int ref_match(const struct argv_array *prefixes, const char *refname) struct ls_refs_data { unsigned peel; unsigned symrefs; - struct argv_array prefixes; + struct strvec prefixes; }; static int send_ref(const char *refname, const struct object_id *oid, @@ -84,7 +84,7 @@ static int ls_refs_config(const char *var, const char *value, void *data) return parse_hide_refs_config(var, value, "uploadpack"); } -int ls_refs(struct repository *r, struct argv_array *keys, +int ls_refs(struct repository *r, struct strvec *keys, struct packet_reader *request) { struct ls_refs_data data; @@ -102,7 +102,7 @@ int ls_refs(struct repository *r, struct argv_array *keys, else if (!strcmp("symrefs", arg)) data.symrefs = 1; else if (skip_prefix(arg, "ref-prefix ", &out)) - argv_array_push(&data.prefixes, out); + strvec_push(&data.prefixes, out); } if (request->status != PACKET_READ_FLUSH) @@ -111,6 +111,6 @@ int ls_refs(struct repository *r, struct argv_array *keys, head_ref_namespaced(send_ref, &data); for_each_namespaced_ref(send_ref, &data); packet_flush(1); - argv_array_clear(&data.prefixes); + strvec_clear(&data.prefixes); return 0; } @@ -2,9 +2,9 @@ #define LS_REFS_H struct repository; -struct argv_array; +struct strvec; struct packet_reader; -int ls_refs(struct repository *r, struct argv_array *keys, +int ls_refs(struct repository *r, struct strvec *keys, struct packet_reader *request); #endif /* LS_REFS_H */ diff --git a/merge-recursive.c b/merge-recursive.c index 36948eafb7..d0214335a7 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -3529,8 +3529,9 @@ static struct commit_list *reverse_commit_list(struct commit_list *list) } /* - * Merge the commits h1 and h2, return the resulting virtual - * commit object and a flag indicating the cleanness of the merge. + * Merge the commits h1 and h2, returning a flag (int) indicating the + * cleanness of the merge. Also, if opt->priv->call_depth, create a + * virtual commit and write its location to *result. */ static int merge_recursive_internal(struct merge_options *opt, struct commit *h1, @@ -3791,9 +3792,12 @@ int merge_recursive_generic(struct merge_options *opt, static void merge_recursive_config(struct merge_options *opt) { char *value = NULL; + int renormalize = 0; git_config_get_int("merge.verbosity", &opt->verbosity); git_config_get_int("diff.renamelimit", &opt->rename_limit); git_config_get_int("merge.renamelimit", &opt->rename_limit); + git_config_get_bool("merge.renormalize", &renormalize); + opt->renormalize = renormalize; if (!git_config_get_string("diff.renames", &value)) { opt->detect_renames = git_config_rename("diff.renames", value); free(value); diff --git a/merge-recursive.h b/merge-recursive.h index 978847e672..0795a1d3ec 100644 --- a/merge-recursive.h +++ b/merge-recursive.h @@ -69,9 +69,8 @@ int parse_merge_opt(struct merge_options *opt, const char *s); * * Outputs: * - See RETURN VALUES above - * - No commit is created * - opt->repo->index has the new index - * - $GIT_INDEX_FILE is not updated + * - new index NOT written to disk * - The working tree is updated with results of the merge */ int merge_trees(struct merge_options *opt, @@ -81,7 +80,7 @@ int merge_trees(struct merge_options *opt, /* * merge_recursive is like merge_trees() but with recursive ancestor - * consolidation and, if the commit is clean, creation of a commit. + * consolidation. * * NOTE: empirically, about a decade ago it was determined that with more * than two merge bases, optimal behavior was found when the @@ -91,9 +90,9 @@ int merge_trees(struct merge_options *opt, * * Outputs: * - See RETURN VALUES above - * - If merge is clean, a commit is created and its address written to *result + * - *result is treated as scratch space for temporary recursive merges * - opt->repo->index has the new index - * - $GIT_INDEX_FILE is not updated + * - new index NOT written to disk * - The working tree is updated with results of the merge */ int merge_recursive(struct merge_options *opt, @@ -109,9 +108,9 @@ int merge_recursive(struct merge_options *opt, * * Outputs: * - See RETURN VALUES above - * - If merge is clean, a commit is created and its address written to *result + * - *result is treated as scratch space for temporary recursive merges * - opt->repo->index has the new index - * - $GIT_INDEX_FILE is updated + * - new index also written to $GIT_INDEX_FILE on disk * - The working tree is updated with results of the merge */ int merge_recursive_generic(struct merge_options *opt, @@ -19,22 +19,22 @@ int try_merge_command(struct repository *r, const char **xopts, struct commit_list *common, const char *head_arg, struct commit_list *remotes) { - struct argv_array args = ARGV_ARRAY_INIT; + struct strvec args = STRVEC_INIT; int i, ret; struct commit_list *j; - argv_array_pushf(&args, "merge-%s", strategy); + strvec_pushf(&args, "merge-%s", strategy); for (i = 0; i < xopts_nr; i++) - argv_array_pushf(&args, "--%s", xopts[i]); + strvec_pushf(&args, "--%s", xopts[i]); for (j = common; j; j = j->next) - argv_array_push(&args, merge_argument(j->item)); - argv_array_push(&args, "--"); - argv_array_push(&args, head_arg); + strvec_push(&args, merge_argument(j->item)); + strvec_push(&args, "--"); + strvec_push(&args, head_arg); for (j = remotes; j; j = j->next) - argv_array_push(&args, merge_argument(j->item)); + strvec_push(&args, merge_argument(j->item)); - ret = run_command_v_opt(args.argv, RUN_GIT_CMD); - argv_array_clear(&args); + ret = run_command_v_opt(args.v, RUN_GIT_CMD); + strvec_clear(&args); discard_index(r->index); if (repo_read_index(r) < 0) @@ -1408,21 +1408,21 @@ int midx_repack(struct repository *r, const char *object_dir, size_t batch_size, repo_config_get_bool(r, "repack.usedeltabaseoffset", &delta_base_offset); repo_config_get_bool(r, "repack.usedeltaislands", &use_delta_islands); - argv_array_push(&cmd.args, "pack-objects"); + strvec_push(&cmd.args, "pack-objects"); strbuf_addstr(&base_name, object_dir); strbuf_addstr(&base_name, "/pack/pack"); - argv_array_push(&cmd.args, base_name.buf); + strvec_push(&cmd.args, base_name.buf); if (delta_base_offset) - argv_array_push(&cmd.args, "--delta-base-offset"); + strvec_push(&cmd.args, "--delta-base-offset"); if (use_delta_islands) - argv_array_push(&cmd.args, "--delta-islands"); + strvec_push(&cmd.args, "--delta-islands"); if (flags & MIDX_PROGRESS) - argv_array_push(&cmd.args, "--progress"); + strvec_push(&cmd.args, "--progress"); else - argv_array_push(&cmd.args, "-q"); + strvec_push(&cmd.args, "-q"); strbuf_release(&base_name); diff --git a/pack-write.c b/pack-write.c index f0017beb9d..685d327d80 100644 --- a/pack-write.c +++ b/pack-write.c @@ -38,9 +38,8 @@ static int need_large_offset(off_t offset, const struct pack_idx_option *opts) } /* - * On entry *sha1 contains the pack content SHA1 hash, on exit it is - * the SHA1 hash of sorted object names. The objects array passed in - * will be sorted by SHA1 on exit. + * The *sha1 contains the pack content SHA1 hash. + * The objects array passed in will be sorted by SHA1 on exit. */ const char *write_idx_file(const char *index_name, struct pack_idx_entry **objects, int nr_objects, const struct pack_idx_option *opts, @@ -68,7 +68,7 @@ const char *git_pager(int stdout_is_tty) return pager; } -static void setup_pager_env(struct argv_array *env) +static void setup_pager_env(struct strvec *env) { const char **argv; int i; @@ -88,7 +88,7 @@ static void setup_pager_env(struct argv_array *env) *cp = '\0'; if (!getenv(argv[i])) { *cp = '='; - argv_array_push(env, argv[i]); + strvec_push(env, argv[i]); } } free(pager_env); @@ -97,7 +97,7 @@ static void setup_pager_env(struct argv_array *env) void prepare_pager_args(struct child_process *pager_process, const char *pager) { - argv_array_push(&pager_process->args, pager); + strvec_push(&pager_process->args, pager); pager_process->use_shell = 1; setup_pager_env(&pager_process->env_array); pager_process->trace2_child_class = "pager"; @@ -126,7 +126,7 @@ void setup_pager(void) /* spawn the pager */ prepare_pager_args(&pager_process, pager); pager_process.in = -1; - argv_array_push(&pager_process.env_array, "GIT_PAGER_IN_USE"); + strvec_push(&pager_process.env_array, "GIT_PAGER_IN_USE"); if (start_command(&pager_process)) return; diff --git a/parse-options-cb.c b/parse-options-cb.c index 86cd393013..d9d3b0819f 100644 --- a/parse-options-cb.c +++ b/parse-options-cb.c @@ -4,7 +4,7 @@ #include "commit.h" #include "color.h" #include "string-list.h" -#include "argv-array.h" +#include "strvec.h" #include "oid-array.h" /*----- some often used options -----*/ @@ -275,19 +275,19 @@ int parse_opt_passthru(const struct option *opt, const char *arg, int unset) /** * For an option opt, recreate the command-line option, appending it to - * opt->value which must be a argv_array. This is useful when we need to pass + * opt->value which must be a strvec. This is useful when we need to pass * the command-line option, which can be specified multiple times, to another * command. */ int parse_opt_passthru_argv(const struct option *opt, const char *arg, int unset) { static struct strbuf sb = STRBUF_INIT; - struct argv_array *opt_value = opt->value; + struct strvec *opt_value = opt->value; if (recreate_opt(&sb, opt, arg, unset) < 0) return -1; - argv_array_push(opt_value, sb.buf); + strvec_push(opt_value, sb.buf); return 0; } diff --git a/pathspec.c b/pathspec.c index 8243e06eab..7a229d8d22 100644 --- a/pathspec.c +++ b/pathspec.c @@ -3,7 +3,7 @@ #include "dir.h" #include "pathspec.h" #include "attr.h" -#include "argv-array.h" +#include "strvec.h" #include "quote.h" /* @@ -624,7 +624,7 @@ void parse_pathspec_file(struct pathspec *pathspec, unsigned magic_mask, unsigned flags, const char *prefix, const char *file, int nul_term_line) { - struct argv_array parsed_file = ARGV_ARRAY_INIT; + struct strvec parsed_file = STRVEC_INIT; strbuf_getline_fn getline_fn = nul_term_line ? strbuf_getline_nul : strbuf_getline; struct strbuf buf = STRBUF_INIT; @@ -643,7 +643,7 @@ void parse_pathspec_file(struct pathspec *pathspec, unsigned magic_mask, die(_("line is badly quoted: %s"), buf.buf); strbuf_swap(&buf, &unquoted); } - argv_array_push(&parsed_file, buf.buf); + strvec_push(&parsed_file, buf.buf); strbuf_reset(&buf); } @@ -652,8 +652,8 @@ void parse_pathspec_file(struct pathspec *pathspec, unsigned magic_mask, if (in != stdin) fclose(in); - parse_pathspec(pathspec, magic_mask, flags, prefix, parsed_file.argv); - argv_array_clear(&parsed_file); + parse_pathspec(pathspec, magic_mask, flags, prefix, parsed_file.v); + strvec_clear(&parsed_file); } void copy_pathspec(struct pathspec *dst, const struct pathspec *src) @@ -1,6 +1,6 @@ #include "cache.h" #include "quote.h" -#include "argv-array.h" +#include "strvec.h" int quote_path_fully = 1; @@ -172,7 +172,7 @@ char *sq_dequote(char *arg) static int sq_dequote_to_argv_internal(char *arg, const char ***argv, int *nr, int *alloc, - struct argv_array *array) + struct strvec *array) { char *next = arg; @@ -187,7 +187,7 @@ static int sq_dequote_to_argv_internal(char *arg, (*argv)[(*nr)++] = dequoted; } if (array) - argv_array_push(array, dequoted); + strvec_push(array, dequoted); } while (next); return 0; @@ -198,7 +198,7 @@ int sq_dequote_to_argv(char *arg, const char ***argv, int *nr, int *alloc) return sq_dequote_to_argv_internal(arg, argv, nr, alloc, NULL); } -int sq_dequote_to_argv_array(char *arg, struct argv_array *array) +int sq_dequote_to_strvec(char *arg, struct strvec *array) { return sq_dequote_to_argv_internal(arg, NULL, NULL, NULL, array); } @@ -56,12 +56,12 @@ char *sq_dequote(char *); int sq_dequote_to_argv(char *arg, const char ***argv, int *nr, int *alloc); /* - * Same as above, but store the unquoted strings in an argv_array. We will - * still modify arg in place, but unlike sq_dequote_to_argv, the argv_array + * Same as above, but store the unquoted strings in a strvec. We will + * still modify arg in place, but unlike sq_dequote_to_argv, the strvec * will duplicate and take ownership of the strings. */ -struct argv_array; -int sq_dequote_to_argv_array(char *arg, struct argv_array *); +struct strvec; +int sq_dequote_to_strvec(char *arg, struct strvec *); int unquote_c_style(struct strbuf *, const char *quoted, const char **endp); size_t quote_c_style(const char *name, struct strbuf *, FILE *, int no_dq); diff --git a/range-diff.c b/range-diff.c index 40af086281..24dc435e48 100644 --- a/range-diff.c +++ b/range-diff.c @@ -2,7 +2,7 @@ #include "range-diff.h" #include "string-list.h" #include "run-command.h" -#include "argv-array.h" +#include "strvec.h" #include "hashmap.h" #include "xdiff-interface.h" #include "linear-assignment.h" @@ -41,7 +41,7 @@ static size_t find_end_of_line(char *buffer, unsigned long size) * as struct object_id (will need to be free()d). */ static int read_patches(const char *range, struct string_list *list, - const struct argv_array *other_arg) + const struct strvec *other_arg) { struct child_process cp = CHILD_PROCESS_INIT; struct strbuf buf = STRBUF_INIT, contents = STRBUF_INIT; @@ -51,24 +51,24 @@ static int read_patches(const char *range, struct string_list *list, int offset, len; size_t size; - argv_array_pushl(&cp.args, "log", "--no-color", "-p", "--no-merges", - "--reverse", "--date-order", "--decorate=no", - "--no-prefix", - /* - * Choose indicators that are not used anywhere - * else in diffs, but still look reasonable - * (e.g. will not be confusing when debugging) - */ - "--output-indicator-new=>", - "--output-indicator-old=<", - "--output-indicator-context=#", - "--no-abbrev-commit", - "--pretty=medium", - "--notes", - NULL); + strvec_pushl(&cp.args, "log", "--no-color", "-p", "--no-merges", + "--reverse", "--date-order", "--decorate=no", + "--no-prefix", + /* + * Choose indicators that are not used anywhere + * else in diffs, but still look reasonable + * (e.g. will not be confusing when debugging) + */ + "--output-indicator-new=>", + "--output-indicator-old=<", + "--output-indicator-context=#", + "--no-abbrev-commit", + "--pretty=medium", + "--notes", + NULL); if (other_arg) - argv_array_pushv(&cp.args, other_arg->argv); - argv_array_push(&cp.args, range); + strvec_pushv(&cp.args, other_arg->v); + strvec_push(&cp.args, range); cp.out = -1; cp.no_stdin = 1; cp.git_cmd = 1; @@ -523,7 +523,7 @@ static struct strbuf *output_prefix_cb(struct diff_options *opt, void *data) int show_range_diff(const char *range1, const char *range2, int creation_factor, int dual_color, const struct diff_options *diffopt, - const struct argv_array *other_arg) + const struct strvec *other_arg) { int res = 0; diff --git a/range-diff.h b/range-diff.h index e11976dc81..583ced2e8e 100644 --- a/range-diff.h +++ b/range-diff.h @@ -2,7 +2,7 @@ #define RANGE_DIFF_H #include "diff.h" -#include "argv-array.h" +#include "strvec.h" #define RANGE_DIFF_CREATION_FACTOR_DEFAULT 60 @@ -14,6 +14,6 @@ int show_range_diff(const char *range1, const char *range2, int creation_factor, int dual_color, const struct diff_options *diffopt, - const struct argv_array *other_arg); + const struct strvec *other_arg); #endif diff --git a/read-cache.c b/read-cache.c index aa427c5c17..8ed1c29b54 100644 --- a/read-cache.c +++ b/read-cache.c @@ -1171,20 +1171,6 @@ static int has_dir_name(struct index_state *istate, return retval; } - if (istate->cache_nr > 0 && - ce_namelen(istate->cache[istate->cache_nr - 1]) > len) { - /* - * The directory prefix lines up with part of - * a longer file or directory name, but sorts - * after it, so this sub-directory cannot - * collide with a file. - * - * last: xxx/yy-file (because '-' sorts before '/') - * this: xxx/yy/abc - */ - return retval; - } - /* * This is a possible collision. Fall through and * let the regular search code handle it. diff --git a/ref-filter.c b/ref-filter.c index 8447cb09be..ba85869755 100644 --- a/ref-filter.c +++ b/ref-filter.c @@ -22,7 +22,7 @@ #include "commit-reach.h" #include "worktree.h" #include "hashmap.h" -#include "argv-array.h" +#include "strvec.h" static struct ref_msg { const char *gone; @@ -127,7 +127,8 @@ static struct used_atom { unsigned int nobracket : 1, push : 1, push_remote : 1; } remote_ref; struct { - enum { C_BARE, C_BODY, C_BODY_DEP, C_LINES, C_SIG, C_SUB, C_TRAILERS } option; + enum { C_BARE, C_BODY, C_BODY_DEP, C_LENGTH, + C_LINES, C_SIG, C_SUB, C_TRAILERS } option; struct process_trailer_options trailer_opts; unsigned int nlines; } contents; @@ -338,6 +339,8 @@ static int contents_atom_parser(const struct ref_format *format, struct used_ato atom->u.contents.option = C_BARE; else if (!strcmp(arg, "body")) atom->u.contents.option = C_BODY; + else if (!strcmp(arg, "size")) + atom->u.contents.option = C_LENGTH; else if (!strcmp(arg, "signature")) atom->u.contents.option = C_SIG; else if (!strcmp(arg, "subject")) @@ -1253,6 +1256,8 @@ static void grab_sub_body_contents(struct atom_value *val, int deref, void *buf) v->s = copy_subject(subpos, sublen); else if (atom->u.contents.option == C_BODY_DEP) v->s = xmemdupz(bodypos, bodylen); + else if (atom->u.contents.option == C_LENGTH) + v->s = xstrfmt("%"PRIuMAX, (uintmax_t)strlen(subpos)); else if (atom->u.contents.option == C_BODY) v->s = xmemdupz(bodypos, nonsiglen); else if (atom->u.contents.option == C_SIG) @@ -1914,15 +1919,15 @@ static void find_longest_prefixes_1(struct string_list *out, static void find_longest_prefixes(struct string_list *out, const char **patterns) { - struct argv_array sorted = ARGV_ARRAY_INIT; + struct strvec sorted = STRVEC_INIT; struct strbuf prefix = STRBUF_INIT; - argv_array_pushv(&sorted, patterns); - QSORT(sorted.argv, sorted.argc, qsort_strcmp); + strvec_pushv(&sorted, patterns); + QSORT(sorted.v, sorted.nr, qsort_strcmp); - find_longest_prefixes_1(out, &prefix, sorted.argv, sorted.argc); + find_longest_prefixes_1(out, &prefix, sorted.v, sorted.nr); - argv_array_clear(&sorted); + strvec_clear(&sorted); strbuf_release(&prefix); } @@ -1980,7 +1985,7 @@ static int for_each_fullref_in_pattern(struct ref_filter *filter, * of oids. If the given ref is a tag, check if the given tag points * at one of the oids in the given oid array. * NEEDSWORK: - * 1. Only a single level of inderection is obtained, we might want to + * 1. Only a single level of indirection is obtained, we might want to * change this to account for multiple levels (e.g. annotated tags * pointing to annotated tags pointing to a commit.) * 2. As the refs are cached we might know what refname peels to without @@ -15,7 +15,7 @@ #include "tag.h" #include "submodule.h" #include "worktree.h" -#include "argv-array.h" +#include "strvec.h" #include "repository.h" #include "sigchain.h" @@ -553,13 +553,13 @@ int refname_match(const char *abbrev_name, const char *full_name) * Given a 'prefix' expand it by the rules in 'ref_rev_parse_rules' and add * the results to 'prefixes' */ -void expand_ref_prefix(struct argv_array *prefixes, const char *prefix) +void expand_ref_prefix(struct strvec *prefixes, const char *prefix) { const char **p; int len = strlen(prefix); for (p = ref_rev_parse_rules; *p; p++) - argv_array_pushf(prefixes, *p, len, prefix); + strvec_pushf(prefixes, *p, len, prefix); } char *repo_default_branch_name(struct repository *r) @@ -902,12 +902,11 @@ int delete_ref(const char *msg, const char *refname, old_oid, flags); } -void copy_reflog_msg(struct strbuf *sb, const char *msg) +static void copy_reflog_msg(struct strbuf *sb, const char *msg) { char c; int wasspace = 1; - strbuf_addch(sb, '\t'); while ((c = *msg++)) { if (wasspace && isspace(c)) continue; @@ -919,6 +918,15 @@ void copy_reflog_msg(struct strbuf *sb, const char *msg) strbuf_rtrim(sb); } +static char *normalize_reflog_message(const char *msg) +{ + struct strbuf sb = STRBUF_INIT; + + if (msg && *msg) + copy_reflog_msg(&sb, msg); + return strbuf_detach(&sb, NULL); +} + int should_autocreate_reflog(const char *refname) { switch (log_all_ref_updates) { @@ -1124,7 +1132,7 @@ struct ref_update *ref_transaction_add_update( oidcpy(&update->new_oid, new_oid); if (flags & REF_HAVE_OLD) oidcpy(&update->old_oid, old_oid); - update->msg = xstrdup_or_null(msg); + update->msg = normalize_reflog_message(msg); return update; } @@ -1983,9 +1991,14 @@ int refs_create_symref(struct ref_store *refs, const char *refs_heads_master, const char *logmsg) { - return refs->be->create_symref(refs, ref_target, - refs_heads_master, - logmsg); + char *msg; + int retval; + + msg = normalize_reflog_message(logmsg); + retval = refs->be->create_symref(refs, ref_target, refs_heads_master, + msg); + free(msg); + return retval; } int create_symref(const char *ref_target, const char *refs_heads_master, @@ -2037,7 +2050,7 @@ static int run_transaction_hook(struct ref_transaction *transaction, return ret; } - argv_array_pushl(&proc.args, hook, state, NULL); + strvec_pushl(&proc.args, hook, state, NULL); proc.in = -1; proc.stdout_to_stderr = 1; proc.trace2_hook_name = "reference-transaction"; @@ -2370,10 +2383,16 @@ int initial_ref_transaction_commit(struct ref_transaction *transaction, return refs->be->initial_transaction_commit(refs, transaction, err); } -int refs_delete_refs(struct ref_store *refs, const char *msg, +int refs_delete_refs(struct ref_store *refs, const char *logmsg, struct string_list *refnames, unsigned int flags) { - return refs->be->delete_refs(refs, msg, refnames, flags); + char *msg; + int retval; + + msg = normalize_reflog_message(logmsg); + retval = refs->be->delete_refs(refs, msg, refnames, flags); + free(msg); + return retval; } int delete_refs(const char *msg, struct string_list *refnames, @@ -2385,7 +2404,13 @@ int delete_refs(const char *msg, struct string_list *refnames, int refs_rename_ref(struct ref_store *refs, const char *oldref, const char *newref, const char *logmsg) { - return refs->be->rename_ref(refs, oldref, newref, logmsg); + char *msg; + int retval; + + msg = normalize_reflog_message(logmsg); + retval = refs->be->rename_ref(refs, oldref, newref, msg); + free(msg); + return retval; } int rename_ref(const char *oldref, const char *newref, const char *logmsg) @@ -2396,7 +2421,13 @@ int rename_ref(const char *oldref, const char *newref, const char *logmsg) int refs_copy_existing_ref(struct ref_store *refs, const char *oldref, const char *newref, const char *logmsg) { - return refs->be->copy_ref(refs, oldref, newref, logmsg); + char *msg; + int retval; + + msg = normalize_reflog_message(logmsg); + retval = refs->be->copy_ref(refs, oldref, newref, msg); + free(msg); + return retval; } int copy_existing_ref(const char *oldref, const char *newref, const char *logmsg) @@ -145,8 +145,8 @@ int refname_match(const char *abbrev_name, const char *full_name); * Given a 'prefix' expand it by the rules in 'ref_rev_parse_rules' and add * the results to 'prefixes' */ -struct argv_array; -void expand_ref_prefix(struct argv_array *prefixes, const char *prefix); +struct strvec; +void expand_ref_prefix(struct strvec *prefixes, const char *prefix); int expand_ref(struct repository *r, const char *str, int len, struct object_id *oid, char **ref); int repo_dwim_ref(struct repository *r, const char *str, int len, struct object_id *oid, char **ref); diff --git a/refs/files-backend.c b/refs/files-backend.c index 6516c7bc8c..985631f33e 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -1628,8 +1628,10 @@ static int log_ref_write_fd(int fd, const struct object_id *old_oid, int ret = 0; strbuf_addf(&sb, "%s %s %s", oid_to_hex(old_oid), oid_to_hex(new_oid), committer); - if (msg && *msg) - copy_reflog_msg(&sb, msg); + if (msg && *msg) { + strbuf_addch(&sb, '\t'); + strbuf_addstr(&sb, msg); + } strbuf_addch(&sb, '\n'); if (write_in_full(fd, sb.buf, sb.len) < 0) ret = -1; diff --git a/refs/refs-internal.h b/refs/refs-internal.h index 4271362d26..357359a0be 100644 --- a/refs/refs-internal.h +++ b/refs/refs-internal.h @@ -96,12 +96,6 @@ enum peel_status { */ enum peel_status peel_object(const struct object_id *name, struct object_id *oid); -/* - * Copy the reflog message msg to sb while cleaning up the whitespaces. - * Especially, convert LF to space, because reflog file is one line per entry. - */ -void copy_reflog_msg(struct strbuf *sb, const char *msg); - /** * Information needed for a single ref update. Set new_oid to the new * value or to null_oid to delete the ref. To check the old value @@ -1,5 +1,5 @@ #include "cache.h" -#include "argv-array.h" +#include "strvec.h" #include "refs.h" #include "refspec.h" @@ -202,7 +202,7 @@ int valid_fetch_refspec(const char *fetch_refspec_str) } void refspec_ref_prefixes(const struct refspec *rs, - struct argv_array *ref_prefixes) + struct strvec *ref_prefixes) { int i; for (i = 0; i < rs->nr; i++) { @@ -221,9 +221,9 @@ void refspec_ref_prefixes(const struct refspec *rs, if (prefix) { if (item->pattern) { const char *glob = strchr(prefix, '*'); - argv_array_pushf(ref_prefixes, "%.*s", - (int)(glob - prefix), - prefix); + strvec_pushf(ref_prefixes, "%.*s", + (int)(glob - prefix), + prefix); } else { expand_ref_prefix(ref_prefixes, prefix); } @@ -60,12 +60,12 @@ void refspec_clear(struct refspec *rs); int valid_fetch_refspec(const char *refspec); -struct argv_array; +struct strvec; /* * Determine what <prefix> values to pass to the peer in ref-prefix lines * (see Documentation/technical/protocol-v2.txt). */ void refspec_ref_prefixes(const struct refspec *rs, - struct argv_array *ref_prefixes); + struct strvec *ref_prefixes); #endif /* REFSPEC_H */ diff --git a/remote-curl.c b/remote-curl.c index 5cbc6e5002..62b3a45cde 100644 --- a/remote-curl.c +++ b/remote-curl.c @@ -10,7 +10,7 @@ #include "pkt-line.h" #include "string-list.h" #include "sideband.h" -#include "argv-array.h" +#include "strvec.h" #include "credential.h" #include "oid-array.h" #include "send-pack.h" @@ -121,7 +121,11 @@ static int set_option(const char *name, const char *value) } else if (!strcmp(name, "cas")) { struct strbuf val = STRBUF_INIT; - strbuf_addf(&val, "--" CAS_OPT_NAME "=%s", value); + strbuf_addstr(&val, "--force-with-lease="); + if (*value != '"') + strbuf_addstr(&val, value); + else if (unquote_c_style(&val, value, NULL)) + return -1; string_list_append(&cas_options, val.buf); strbuf_release(&val); return 0; @@ -1141,41 +1145,41 @@ static int fetch_git(struct discovery *heads, struct rpc_state rpc; struct strbuf preamble = STRBUF_INIT; int i, err; - struct argv_array args = ARGV_ARRAY_INIT; + struct strvec args = STRVEC_INIT; struct strbuf rpc_result = STRBUF_INIT; - argv_array_pushl(&args, "fetch-pack", "--stateless-rpc", - "--stdin", "--lock-pack", NULL); + strvec_pushl(&args, "fetch-pack", "--stateless-rpc", + "--stdin", "--lock-pack", NULL); if (options.followtags) - argv_array_push(&args, "--include-tag"); + strvec_push(&args, "--include-tag"); if (options.thin) - argv_array_push(&args, "--thin"); + strvec_push(&args, "--thin"); if (options.verbosity >= 3) - argv_array_pushl(&args, "-v", "-v", NULL); + strvec_pushl(&args, "-v", "-v", NULL); if (options.check_self_contained_and_connected) - argv_array_push(&args, "--check-self-contained-and-connected"); + strvec_push(&args, "--check-self-contained-and-connected"); if (options.cloning) - argv_array_push(&args, "--cloning"); + strvec_push(&args, "--cloning"); if (options.update_shallow) - argv_array_push(&args, "--update-shallow"); + strvec_push(&args, "--update-shallow"); if (!options.progress) - argv_array_push(&args, "--no-progress"); + strvec_push(&args, "--no-progress"); if (options.depth) - argv_array_pushf(&args, "--depth=%lu", options.depth); + strvec_pushf(&args, "--depth=%lu", options.depth); if (options.deepen_since) - argv_array_pushf(&args, "--shallow-since=%s", options.deepen_since); + strvec_pushf(&args, "--shallow-since=%s", options.deepen_since); for (i = 0; i < options.deepen_not.nr; i++) - argv_array_pushf(&args, "--shallow-exclude=%s", - options.deepen_not.items[i].string); + strvec_pushf(&args, "--shallow-exclude=%s", + options.deepen_not.items[i].string); if (options.deepen_relative && options.depth) - argv_array_push(&args, "--deepen-relative"); + strvec_push(&args, "--deepen-relative"); if (options.from_promisor) - argv_array_push(&args, "--from-promisor"); + strvec_push(&args, "--from-promisor"); if (options.no_dependents) - argv_array_push(&args, "--no-dependents"); + strvec_push(&args, "--no-dependents"); if (options.filter) - argv_array_pushf(&args, "--filter=%s", options.filter); - argv_array_push(&args, url.buf); + strvec_pushf(&args, "--filter=%s", options.filter); + strvec_push(&args, url.buf); for (i = 0; i < nr_heads; i++) { struct ref *ref = to_fetch[i]; @@ -1190,12 +1194,12 @@ static int fetch_git(struct discovery *heads, rpc.service_name = "git-upload-pack", rpc.gzip_request = 1; - err = rpc_service(&rpc, heads, args.argv, &preamble, &rpc_result); + err = rpc_service(&rpc, heads, args.v, &preamble, &rpc_result); if (rpc_result.len) write_or_die(1, rpc_result.buf, rpc_result.len); strbuf_release(&rpc_result); strbuf_release(&preamble); - argv_array_clear(&args); + strvec_clear(&args); return err; } @@ -1267,15 +1271,15 @@ static int push_dav(int nr_spec, const char **specs) size_t i; child.git_cmd = 1; - argv_array_push(&child.args, "http-push"); - argv_array_push(&child.args, "--helper-status"); + strvec_push(&child.args, "http-push"); + strvec_push(&child.args, "--helper-status"); if (options.dry_run) - argv_array_push(&child.args, "--dry-run"); + strvec_push(&child.args, "--dry-run"); if (options.verbosity > 1) - argv_array_push(&child.args, "--verbose"); - argv_array_push(&child.args, url.buf); + strvec_push(&child.args, "--verbose"); + strvec_push(&child.args, url.buf); for (i = 0; i < nr_spec; i++) - argv_array_push(&child.args, specs[i]); + strvec_push(&child.args, specs[i]); if (run_command(&child)) die(_("git-http-push failed")); @@ -1286,38 +1290,38 @@ static int push_git(struct discovery *heads, int nr_spec, const char **specs) { struct rpc_state rpc; int i, err; - struct argv_array args; + struct strvec args; struct string_list_item *cas_option; struct strbuf preamble = STRBUF_INIT; struct strbuf rpc_result = STRBUF_INIT; - argv_array_init(&args); - argv_array_pushl(&args, "send-pack", "--stateless-rpc", "--helper-status", - NULL); + strvec_init(&args); + strvec_pushl(&args, "send-pack", "--stateless-rpc", "--helper-status", + NULL); if (options.thin) - argv_array_push(&args, "--thin"); + strvec_push(&args, "--thin"); if (options.dry_run) - argv_array_push(&args, "--dry-run"); + strvec_push(&args, "--dry-run"); if (options.push_cert == SEND_PACK_PUSH_CERT_ALWAYS) - argv_array_push(&args, "--signed=yes"); + strvec_push(&args, "--signed=yes"); else if (options.push_cert == SEND_PACK_PUSH_CERT_IF_ASKED) - argv_array_push(&args, "--signed=if-asked"); + strvec_push(&args, "--signed=if-asked"); if (options.atomic) - argv_array_push(&args, "--atomic"); + strvec_push(&args, "--atomic"); if (options.verbosity == 0) - argv_array_push(&args, "--quiet"); + strvec_push(&args, "--quiet"); else if (options.verbosity > 1) - argv_array_push(&args, "--verbose"); + strvec_push(&args, "--verbose"); for (i = 0; i < options.push_options.nr; i++) - argv_array_pushf(&args, "--push-option=%s", - options.push_options.items[i].string); - argv_array_push(&args, options.progress ? "--progress" : "--no-progress"); + strvec_pushf(&args, "--push-option=%s", + options.push_options.items[i].string); + strvec_push(&args, options.progress ? "--progress" : "--no-progress"); for_each_string_list_item(cas_option, &cas_options) - argv_array_push(&args, cas_option->string); - argv_array_push(&args, url.buf); + strvec_push(&args, cas_option->string); + strvec_push(&args, url.buf); - argv_array_push(&args, "--stdin"); + strvec_push(&args, "--stdin"); for (i = 0; i < nr_spec; i++) packet_buf_write(&preamble, "%s\n", specs[i]); packet_buf_flush(&preamble); @@ -1325,12 +1329,12 @@ static int push_git(struct discovery *heads, int nr_spec, const char **specs) memset(&rpc, 0, sizeof(rpc)); rpc.service_name = "git-receive-pack", - err = rpc_service(&rpc, heads, args.argv, &preamble, &rpc_result); + err = rpc_service(&rpc, heads, args.v, &preamble, &rpc_result); if (rpc_result.len) write_or_die(1, rpc_result.buf, rpc_result.len); strbuf_release(&rpc_result); strbuf_release(&preamble); - argv_array_clear(&args); + strvec_clear(&args); return err; } @@ -1349,13 +1353,13 @@ static int push(int nr_spec, const char **specs) static void parse_push(struct strbuf *buf) { - struct argv_array specs = ARGV_ARRAY_INIT; + struct strvec specs = STRVEC_INIT; int ret; do { const char *arg; if (skip_prefix(buf->buf, "push ", &arg)) - argv_array_push(&specs, arg); + strvec_push(&specs, arg); else die(_("http transport does not support %s"), buf->buf); @@ -1366,7 +1370,7 @@ static void parse_push(struct strbuf *buf) break; } while (1); - ret = push(specs.argc, specs.argv); + ret = push(specs.nr, specs.v); printf("\n"); fflush(stdout); @@ -1374,7 +1378,7 @@ static void parse_push(struct strbuf *buf) exit(128); /* error already reported */ free_specs: - argv_array_clear(&specs); + strvec_clear(&specs); } static int stateless_connect(const char *service_name) diff --git a/remote-testsvn.c b/remote-testsvn.c index cde39b94fb..636b2b62a6 100644 --- a/remote-testsvn.c +++ b/remote-testsvn.c @@ -8,7 +8,7 @@ #include "run-command.h" #include "vcs-svn/svndump.h" #include "notes.h" -#include "argv-array.h" +#include "strvec.h" static const char *url; static int dump_from_file; @@ -198,10 +198,10 @@ static int cmd_import(const char *line) die_errno("Couldn't open svn dump file %s.", url); } else { svndump_proc.out = -1; - argv_array_push(&svndump_proc.args, command); - argv_array_push(&svndump_proc.args, "dump"); - argv_array_push(&svndump_proc.args, url); - argv_array_pushf(&svndump_proc.args, "-r%u:HEAD", startrev); + strvec_push(&svndump_proc.args, command); + strvec_push(&svndump_proc.args, "dump"); + strvec_push(&svndump_proc.args, url); + strvec_pushf(&svndump_proc.args, "-r%u:HEAD", startrev); code = start_command(&svndump_proc); if (code) @@ -11,7 +11,7 @@ #include "tag.h" #include "string-list.h" #include "mergesort.h" -#include "argv-array.h" +#include "strvec.h" #include "commit-reach.h" #include "advice.h" @@ -1885,7 +1885,7 @@ static int stat_branch_pair(const char *branch_name, const char *base, struct object_id oid; struct commit *ours, *theirs; struct rev_info revs; - struct argv_array argv = ARGV_ARRAY_INIT; + struct strvec argv = STRVEC_INIT; /* Cannot stat if what we used to build on no longer exists */ if (read_ref(base, &oid)) @@ -1911,15 +1911,15 @@ static int stat_branch_pair(const char *branch_name, const char *base, BUG("stat_branch_pair: invalid abf '%d'", abf); /* Run "rev-list --left-right ours...theirs" internally... */ - argv_array_push(&argv, ""); /* ignored */ - argv_array_push(&argv, "--left-right"); - argv_array_pushf(&argv, "%s...%s", - oid_to_hex(&ours->object.oid), - oid_to_hex(&theirs->object.oid)); - argv_array_push(&argv, "--"); + strvec_push(&argv, ""); /* ignored */ + strvec_push(&argv, "--left-right"); + strvec_pushf(&argv, "%s...%s", + oid_to_hex(&ours->object.oid), + oid_to_hex(&theirs->object.oid)); + strvec_push(&argv, "--"); repo_init_revisions(the_repository, &revs, NULL); - setup_revisions(argv.argc, argv.argv, &revs, NULL); + setup_revisions(argv.nr, argv.v, &revs, NULL); if (prepare_revision_walk(&revs)) die(_("revision walk setup failed")); @@ -1938,7 +1938,7 @@ static int stat_branch_pair(const char *branch_name, const char *base, clear_commit_marks(ours, ALL_REV_FLAGS); clear_commit_marks(theirs, ALL_REV_FLAGS); - argv_array_clear(&argv); + strvec_clear(&argv); return 1; } @@ -168,7 +168,7 @@ void free_refs(struct ref *ref); struct oid_array; struct packet_reader; -struct argv_array; +struct strvec; struct string_list; struct ref **get_remote_heads(struct packet_reader *reader, struct ref **list, unsigned int flags, @@ -178,7 +178,7 @@ struct ref **get_remote_heads(struct packet_reader *reader, /* Used for protocol v2 in order to retrieve refs from a remote */ struct ref **get_remote_refs(int fd_out, struct packet_reader *reader, struct ref **list, int for_push, - const struct argv_array *ref_prefixes, + const struct strvec *ref_prefixes, const struct string_list *server_options, int stateless_rpc); diff --git a/repository.c b/repository.c index 6f7f6f002b..a4174ddb06 100644 --- a/repository.c +++ b/repository.c @@ -89,10 +89,6 @@ void repo_set_gitdir(struct repository *repo, void repo_set_hash_algo(struct repository *repo, int hash_algo) { repo->hash_algo = &hash_algos[hash_algo]; -#ifndef ENABLE_SHA256 - if (hash_algo != GIT_HASH_SHA1) - die(_("The hash algorithm %s is not supported in this build."), repo->hash_algo->name); -#endif } /* diff --git a/revision.c b/revision.c index 6aa7f4f567..3dcf689341 100644 --- a/revision.c +++ b/revision.c @@ -23,7 +23,7 @@ #include "bisect.h" #include "packfile.h" #include "worktree.h" -#include "argv-array.h" +#include "strvec.h" #include "commit-reach.h" #include "commit-graph.h" #include "prio-queue.h" @@ -633,7 +633,6 @@ static unsigned int count_bloom_filter_maybe; static unsigned int count_bloom_filter_definitely_not; static unsigned int count_bloom_filter_false_positive; static unsigned int count_bloom_filter_not_present; -static unsigned int count_bloom_filter_length_zero; static void trace2_bloom_filter_statistics_atexit(void) { @@ -641,7 +640,6 @@ static void trace2_bloom_filter_statistics_atexit(void) jw_object_begin(&jw, 0); jw_object_intmax(&jw, "filter_not_present", count_bloom_filter_not_present); - jw_object_intmax(&jw, "zero_length_filter", count_bloom_filter_length_zero); jw_object_intmax(&jw, "maybe", count_bloom_filter_maybe); jw_object_intmax(&jw, "definitely_not", count_bloom_filter_definitely_not); jw_object_intmax(&jw, "false_positive", count_bloom_filter_false_positive); @@ -670,9 +668,9 @@ static void prepare_to_use_bloom_filter(struct rev_info *revs) { struct pathspec_item *pi; char *path_alloc = NULL; - const char *path; - int last_index; - int len; + const char *path, *p; + size_t len; + int path_component_nr = 1; if (!revs->commits) return; @@ -693,20 +691,48 @@ static void prepare_to_use_bloom_filter(struct rev_info *revs) return; pi = &revs->pruning.pathspec.items[0]; - last_index = pi->len - 1; /* remove single trailing slash from path, if needed */ - if (pi->match[last_index] == '/') { - path_alloc = xstrdup(pi->match); - path_alloc[last_index] = '\0'; - path = path_alloc; + if (pi->len > 0 && pi->match[pi->len - 1] == '/') { + path_alloc = xmemdupz(pi->match, pi->len - 1); + path = path_alloc; } else - path = pi->match; + path = pi->match; len = strlen(path); + if (!len) { + revs->bloom_filter_settings = NULL; + free(path_alloc); + return; + } + + p = path; + while (*p) { + /* + * At this point, the path is normalized to use Unix-style + * path separators. This is required due to how the + * changed-path Bloom filters store the paths. + */ + if (*p == '/') + path_component_nr++; + p++; + } + + revs->bloom_keys_nr = path_component_nr; + ALLOC_ARRAY(revs->bloom_keys, revs->bloom_keys_nr); - revs->bloom_key = xmalloc(sizeof(struct bloom_key)); - fill_bloom_key(path, len, revs->bloom_key, revs->bloom_filter_settings); + fill_bloom_key(path, len, &revs->bloom_keys[0], + revs->bloom_filter_settings); + path_component_nr = 1; + + p = path + len - 1; + while (p > path) { + if (*p == '/') + fill_bloom_key(path, p - path, + &revs->bloom_keys[path_component_nr++], + revs->bloom_filter_settings); + p--; + } if (trace2_is_enabled() && !bloom_filter_atexit_registered) { atexit(trace2_bloom_filter_statistics_atexit); @@ -720,7 +746,7 @@ static int check_maybe_different_in_bloom_filter(struct rev_info *revs, struct commit *commit) { struct bloom_filter *filter; - int result; + int result = 1, j; if (!revs->repo->objects->commit_graph) return -1; @@ -735,15 +761,12 @@ static int check_maybe_different_in_bloom_filter(struct rev_info *revs, return -1; } - if (!filter->len) { - count_bloom_filter_length_zero++; - return -1; + for (j = 0; result && j < revs->bloom_keys_nr; j++) { + result = bloom_filter_contains(filter, + &revs->bloom_keys[j], + revs->bloom_filter_settings); } - result = bloom_filter_contains(filter, - revs->bloom_key, - revs->bloom_filter_settings); - if (result) count_bloom_filter_maybe++; else @@ -782,7 +805,7 @@ static int rev_compare_tree(struct rev_info *revs, return REV_TREE_SAME; } - if (revs->bloom_key && !nth_parent) { + if (revs->bloom_keys_nr && !nth_parent) { bloom_ret = check_maybe_different_in_bloom_filter(revs, commit); if (bloom_ret == 0) @@ -791,9 +814,7 @@ static int rev_compare_tree(struct rev_info *revs, tree_difference = REV_TREE_SAME; revs->pruning.flags.has_changes = 0; - if (diff_tree_oid(&t1->object.oid, &t2->object.oid, "", - &revs->pruning) < 0) - return REV_TREE_DIFFERENT; + diff_tree_oid(&t1->object.oid, &t2->object.oid, "", &revs->pruning); if (!nth_parent) if (bloom_ret == 1 && tree_difference == REV_TREE_SAME) @@ -804,7 +825,6 @@ static int rev_compare_tree(struct rev_info *revs, static int rev_same_tree_as_empty(struct rev_info *revs, struct commit *commit) { - int retval; struct tree *t1 = get_commit_tree(commit); if (!t1) @@ -812,9 +832,9 @@ static int rev_same_tree_as_empty(struct rev_info *revs, struct commit *commit) tree_difference = REV_TREE_SAME; revs->pruning.flags.has_changes = 0; - retval = diff_tree_oid(NULL, &t1->object.oid, "", &revs->pruning); + diff_tree_oid(NULL, &t1->object.oid, "", &revs->pruning); - return retval >= 0 && (tree_difference == REV_TREE_SAME); + return tree_difference == REV_TREE_SAME; } struct treesame_state { @@ -2073,14 +2093,14 @@ int handle_revision_arg(const char *arg_, struct rev_info *revs, int flags, unsi } static void read_pathspec_from_stdin(struct strbuf *sb, - struct argv_array *prune) + struct strvec *prune) { while (strbuf_getline(sb, stdin) != EOF) - argv_array_push(prune, sb->buf); + strvec_push(prune, sb->buf); } static void read_revisions_from_stdin(struct rev_info *revs, - struct argv_array *prune) + struct strvec *prune) { struct strbuf sb; int seen_dashdash = 0; @@ -2315,7 +2335,7 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg } else if (!strcmp(arg, "--unpacked")) { revs->unpacked = 1; } else if (starts_with(arg, "--unpacked=")) { - die("--unpacked=<packfile> no longer supported."); + die(_("--unpacked=<packfile> no longer supported")); } else if (!strcmp(arg, "-r")) { revs->diff = 1; revs->diffopt.flags.recursive = 1; @@ -2675,7 +2695,7 @@ static void NORETURN diagnose_missing_default(const char *def) int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct setup_revision_opt *opt) { int i, flags, left, seen_dashdash, got_rev_arg = 0, revarg_opt; - struct argv_array prune_data = ARGV_ARRAY_INIT; + struct strvec prune_data = STRVEC_INIT; const char *submodule = NULL; int seen_end_of_options = 0; @@ -2694,7 +2714,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s argv[i] = NULL; argc = i; if (argv[i + 1]) - argv_array_pushv(&prune_data, argv + i + 1); + strvec_pushv(&prune_data, argv + i + 1); seen_dashdash = 1; break; } @@ -2760,14 +2780,14 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s for (j = i; j < argc; j++) verify_filename(revs->prefix, argv[j], j == i); - argv_array_pushv(&prune_data, argv + i); + strvec_pushv(&prune_data, argv + i); break; } else got_rev_arg = 1; } - if (prune_data.argc) { + if (prune_data.nr) { /* * If we need to introduce the magic "a lone ':' means no * pathspec whatsoever", here is the place to do so. @@ -2783,9 +2803,9 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s * } */ parse_pathspec(&revs->prune_data, 0, 0, - revs->prefix, prune_data.argv); + revs->prefix, prune_data.v); } - argv_array_clear(&prune_data); + strvec_clear(&prune_data); if (revs->def == NULL) revs->def = opt ? opt->def : NULL; diff --git a/revision.h b/revision.h index f412ae85eb..889216c2d8 100644 --- a/revision.h +++ b/revision.h @@ -301,8 +301,10 @@ struct rev_info { struct topo_walk_info *topo_walk_info; /* Commit graph bloom filter fields */ - /* The bloom filter key for the pathspec */ - struct bloom_key *bloom_key; + /* The bloom filter key(s) for the pathspec */ + struct bloom_key *bloom_keys; + int bloom_keys_nr; + /* * The bloom filter settings used to generate the key. * This is loaded from the commit-graph being used. diff --git a/run-command.c b/run-command.c index a735e380a9..cc9c3296ba 100644 --- a/run-command.c +++ b/run-command.c @@ -2,7 +2,7 @@ #include "run-command.h" #include "exec-cmd.h" #include "sigchain.h" -#include "argv-array.h" +#include "strvec.h" #include "thread-utils.h" #include "strbuf.h" #include "string-list.h" @@ -11,14 +11,14 @@ void child_process_init(struct child_process *child) { memset(child, 0, sizeof(*child)); - argv_array_init(&child->args); - argv_array_init(&child->env_array); + strvec_init(&child->args); + strvec_init(&child->env_array); } void child_process_clear(struct child_process *child) { - argv_array_clear(&child->args); - argv_array_clear(&child->env_array); + strvec_clear(&child->args); + strvec_clear(&child->env_array); } struct child_to_clean { @@ -263,31 +263,31 @@ int sane_execvp(const char *file, char * const argv[]) return -1; } -static const char **prepare_shell_cmd(struct argv_array *out, const char **argv) +static const char **prepare_shell_cmd(struct strvec *out, const char **argv) { if (!argv[0]) BUG("shell command is empty"); if (strcspn(argv[0], "|&;<>()$`\\\"' \t\n*?[#~=%") != strlen(argv[0])) { #ifndef GIT_WINDOWS_NATIVE - argv_array_push(out, SHELL_PATH); + strvec_push(out, SHELL_PATH); #else - argv_array_push(out, "sh"); + strvec_push(out, "sh"); #endif - argv_array_push(out, "-c"); + strvec_push(out, "-c"); /* * If we have no extra arguments, we do not even need to * bother with the "$@" magic. */ if (!argv[1]) - argv_array_push(out, argv[0]); + strvec_push(out, argv[0]); else - argv_array_pushf(out, "%s \"$@\"", argv[0]); + strvec_pushf(out, "%s \"$@\"", argv[0]); } - argv_array_pushv(out, argv); - return out->argv; + strvec_pushv(out, argv); + return out->v; } #ifndef GIT_WINDOWS_NATIVE @@ -401,7 +401,7 @@ static void child_err_spew(struct child_process *cmd, struct child_err *cerr) set_error_routine(old_errfn); } -static int prepare_cmd(struct argv_array *out, const struct child_process *cmd) +static int prepare_cmd(struct strvec *out, const struct child_process *cmd) { if (!cmd->argv[0]) BUG("command is empty"); @@ -410,14 +410,14 @@ static int prepare_cmd(struct argv_array *out, const struct child_process *cmd) * Add SHELL_PATH so in the event exec fails with ENOEXEC we can * attempt to interpret the command with 'sh'. */ - argv_array_push(out, SHELL_PATH); + strvec_push(out, SHELL_PATH); if (cmd->git_cmd) { prepare_git_cmd(out, cmd->argv); } else if (cmd->use_shell) { prepare_shell_cmd(out, cmd->argv); } else { - argv_array_pushv(out, cmd->argv); + strvec_pushv(out, cmd->argv); } /* @@ -426,13 +426,13 @@ static int prepare_cmd(struct argv_array *out, const struct child_process *cmd) * there are dir separator characters, we have exec attempt to invoke * the command directly. */ - if (!has_dir_sep(out->argv[1])) { - char *program = locate_in_PATH(out->argv[1]); + if (!has_dir_sep(out->v[1])) { + char *program = locate_in_PATH(out->v[1]); if (program) { - free((char *)out->argv[1]); - out->argv[1] = program; + free((char *)out->v[1]); + out->v[1] = program; } else { - argv_array_clear(out); + strvec_clear(out); errno = ENOENT; return -1; } @@ -672,9 +672,9 @@ int start_command(struct child_process *cmd) char *str; if (!cmd->argv) - cmd->argv = cmd->args.argv; + cmd->argv = cmd->args.v; if (!cmd->env) - cmd->env = cmd->env_array.argv; + cmd->env = cmd->env_array.v; /* * In case of errors we must keep the promise to close FDs @@ -742,7 +742,7 @@ fail_pipe: int notify_pipe[2]; int null_fd = -1; char **childenv; - struct argv_array argv = ARGV_ARRAY_INIT; + struct strvec argv = STRVEC_INIT; struct child_err cerr; struct atfork_state as; @@ -846,10 +846,10 @@ fail_pipe: * be used in the event exec failed with ENOEXEC at which point * we will try to interpret the command using 'sh'. */ - execve(argv.argv[1], (char *const *) argv.argv + 1, + execve(argv.v[1], (char *const *) argv.v + 1, (char *const *) childenv); if (errno == ENOEXEC) - execve(argv.argv[0], (char *const *) argv.argv, + execve(argv.v[0], (char *const *) argv.v, (char *const *) childenv); if (errno == ENOENT) { @@ -888,7 +888,7 @@ fail_pipe: if (null_fd >= 0) close(null_fd); - argv_array_clear(&argv); + strvec_clear(&argv); free(childenv); } end_of_spawn: @@ -897,7 +897,7 @@ end_of_spawn: { int fhin = 0, fhout = 1, fherr = 2; const char **sargv = cmd->argv; - struct argv_array nargv = ARGV_ARRAY_INIT; + struct strvec nargv = STRVEC_INIT; if (cmd->no_stdin) fhin = open("/dev/null", O_RDWR); @@ -935,7 +935,7 @@ end_of_spawn: if (cmd->clean_on_exit && cmd->pid >= 0) mark_child_for_cleanup(cmd->pid, cmd); - argv_array_clear(&nargv); + strvec_clear(&nargv); cmd->argv = sargv; if (fhin != 0) close(fhin); @@ -1352,9 +1352,9 @@ int run_hook_ve(const char *const *env, const char *name, va_list args) if (!p) return 0; - argv_array_push(&hook.args, p); + strvec_push(&hook.args, p); while ((p = va_arg(args, const char *))) - argv_array_push(&hook.args, p); + strvec_push(&hook.args, p); hook.env = env; hook.no_stdin = 1; hook.stdout_to_stderr = 1; @@ -1868,13 +1868,13 @@ int run_processes_parallel_tr2(int n, get_next_task_fn get_next_task, int run_auto_gc(int quiet) { - struct argv_array argv_gc_auto = ARGV_ARRAY_INIT; + struct strvec argv_gc_auto = STRVEC_INIT; int status; - argv_array_pushl(&argv_gc_auto, "gc", "--auto", NULL); + strvec_pushl(&argv_gc_auto, "gc", "--auto", NULL); if (quiet) - argv_array_push(&argv_gc_auto, "--quiet"); - status = run_command_v_opt(argv_gc_auto.argv, RUN_GIT_CMD); - argv_array_clear(&argv_gc_auto); + strvec_push(&argv_gc_auto, "--quiet"); + status = run_command_v_opt(argv_gc_auto.v, RUN_GIT_CMD); + strvec_clear(&argv_gc_auto); return status; } diff --git a/run-command.h b/run-command.h index ef3071a565..8b9bfaef16 100644 --- a/run-command.h +++ b/run-command.h @@ -3,7 +3,7 @@ #include "thread-utils.h" -#include "argv-array.h" +#include "strvec.h" /** * The run-command API offers a versatile tool to run sub-processes with @@ -52,15 +52,15 @@ struct child_process { * Note that the ownership of the memory pointed to by .argv stays with the * caller, but it should survive until `finish_command` completes. If the * .argv member is NULL, `start_command` will point it at the .args - * `argv_array` (so you may use one or the other, but you must use exactly + * `strvec` (so you may use one or the other, but you must use exactly * one). The memory in .args will be cleaned up automatically during * `finish_command` (or during `start_command` when it is unsuccessful). * */ const char **argv; - struct argv_array args; - struct argv_array env_array; + struct strvec args; + struct strvec env_array; pid_t pid; int trace2_child_id; @@ -107,7 +107,7 @@ struct child_process { * variable that will be removed from the child process's environment. * * If the .env member is NULL, `start_command` will point it at the - * .env_array `argv_array` (so you may use one or the other, but not both). + * .env_array `strvec` (so you may use one or the other, but not both). * The memory in .env_array will be cleaned up automatically during * `finish_command` (or during `start_command` when it is unsuccessful). */ @@ -134,7 +134,7 @@ struct child_process { void *clean_on_exit_handler_cbdata; }; -#define CHILD_PROCESS_INIT { NULL, ARGV_ARRAY_INIT, ARGV_ARRAY_INIT } +#define CHILD_PROCESS_INIT { NULL, STRVEC_INIT, STRVEC_INIT } /** * The functions: child_process_init, start_command, finish_command, diff --git a/send-pack.c b/send-pack.c index d671ab5d05..632f1580ca 100644 --- a/send-pack.c +++ b/send-pack.c @@ -68,20 +68,20 @@ static int pack_objects(int fd, struct ref *refs, struct oid_array *extra, struc int i; int rc; - argv_array_push(&po.args, "pack-objects"); - argv_array_push(&po.args, "--all-progress-implied"); - argv_array_push(&po.args, "--revs"); - argv_array_push(&po.args, "--stdout"); + strvec_push(&po.args, "pack-objects"); + strvec_push(&po.args, "--all-progress-implied"); + strvec_push(&po.args, "--revs"); + strvec_push(&po.args, "--stdout"); if (args->use_thin_pack) - argv_array_push(&po.args, "--thin"); + strvec_push(&po.args, "--thin"); if (args->use_ofs_delta) - argv_array_push(&po.args, "--delta-base-offset"); + strvec_push(&po.args, "--delta-base-offset"); if (args->quiet || !args->progress) - argv_array_push(&po.args, "-q"); + strvec_push(&po.args, "-q"); if (args->progress) - argv_array_push(&po.args, "--progress"); + strvec_push(&po.args, "--progress"); if (is_repository_shallow(the_repository)) - argv_array_push(&po.args, "--shallow"); + strvec_push(&po.args, "--shallow"); po.in = -1; po.out = args->stateless_rpc ? -1 : fd; po.git_cmd = 1; diff --git a/sequencer.c b/sequencer.c index fd7701c88a..cc3f8fa88e 100644 --- a/sequencer.c +++ b/sequencer.c @@ -16,7 +16,7 @@ #include "rerere.h" #include "merge-recursive.h" #include "refs.h" -#include "argv-array.h" +#include "strvec.h" #include "quote.h" #include "trailer.h" #include "log-tree.h" @@ -830,10 +830,10 @@ finish: /* * Read a GIT_AUTHOR_NAME, GIT_AUTHOR_EMAIL AND GIT_AUTHOR_DATE from a - * file with shell quoting into struct argv_array. Returns -1 on + * file with shell quoting into struct strvec. Returns -1 on * error, 0 otherwise. */ -static int read_env_script(struct argv_array *env) +static int read_env_script(struct strvec *env) { char *name, *email, *date; @@ -841,9 +841,9 @@ static int read_env_script(struct argv_array *env) &name, &email, &date, 0)) return -1; - argv_array_pushf(env, "GIT_AUTHOR_NAME=%s", name); - argv_array_pushf(env, "GIT_AUTHOR_EMAIL=%s", email); - argv_array_pushf(env, "GIT_AUTHOR_DATE=%s", date); + strvec_pushf(env, "GIT_AUTHOR_NAME=%s", name); + strvec_pushf(env, "GIT_AUTHOR_EMAIL=%s", email); + strvec_pushf(env, "GIT_AUTHOR_DATE=%s", date); free(name); free(email); free(date); @@ -929,34 +929,34 @@ static int run_git_commit(struct repository *r, gpg_opt, gpg_opt); } - argv_array_push(&cmd.args, "commit"); + strvec_push(&cmd.args, "commit"); if (!(flags & VERIFY_MSG)) - argv_array_push(&cmd.args, "-n"); + strvec_push(&cmd.args, "-n"); if ((flags & AMEND_MSG)) - argv_array_push(&cmd.args, "--amend"); + strvec_push(&cmd.args, "--amend"); if (opts->gpg_sign) - argv_array_pushf(&cmd.args, "-S%s", opts->gpg_sign); + strvec_pushf(&cmd.args, "-S%s", opts->gpg_sign); else - argv_array_push(&cmd.args, "--no-gpg-sign"); + strvec_push(&cmd.args, "--no-gpg-sign"); if (defmsg) - argv_array_pushl(&cmd.args, "-F", defmsg, NULL); + strvec_pushl(&cmd.args, "-F", defmsg, NULL); else if (!(flags & EDIT_MSG)) - argv_array_pushl(&cmd.args, "-C", "HEAD", NULL); + strvec_pushl(&cmd.args, "-C", "HEAD", NULL); if ((flags & CLEANUP_MSG)) - argv_array_push(&cmd.args, "--cleanup=strip"); + strvec_push(&cmd.args, "--cleanup=strip"); if ((flags & EDIT_MSG)) - argv_array_push(&cmd.args, "-e"); + strvec_push(&cmd.args, "-e"); else if (!(flags & CLEANUP_MSG) && !opts->signoff && !opts->record_origin && !opts->explicit_cleanup) - argv_array_push(&cmd.args, "--cleanup=verbatim"); + strvec_push(&cmd.args, "--cleanup=verbatim"); if ((flags & ALLOW_EMPTY)) - argv_array_push(&cmd.args, "--allow-empty"); + strvec_push(&cmd.args, "--allow-empty"); if (!(flags & EDIT_MSG)) - argv_array_push(&cmd.args, "--allow-empty-message"); + strvec_push(&cmd.args, "--allow-empty-message"); if (is_rebase_i(opts) && !(flags & EDIT_MSG)) return run_command_silent_on_success(&cmd); @@ -2754,15 +2754,15 @@ static int rollback_is_safe(void) static int reset_merge(const struct object_id *oid) { int ret; - struct argv_array argv = ARGV_ARRAY_INIT; + struct strvec argv = STRVEC_INIT; - argv_array_pushl(&argv, "reset", "--merge", NULL); + strvec_pushl(&argv, "reset", "--merge", NULL); if (!is_null_oid(oid)) - argv_array_push(&argv, oid_to_hex(oid)); + strvec_push(&argv, oid_to_hex(oid)); - ret = run_command_v_opt(argv.argv, RUN_GIT_CMD); - argv_array_clear(&argv); + ret = run_command_v_opt(argv.v, RUN_GIT_CMD); + strvec_clear(&argv); return ret; } @@ -3125,17 +3125,17 @@ static int error_failed_squash(struct repository *r, static int do_exec(struct repository *r, const char *command_line) { - struct argv_array child_env = ARGV_ARRAY_INIT; + struct strvec child_env = STRVEC_INIT; const char *child_argv[] = { NULL, NULL }; int dirty, status; fprintf(stderr, _("Executing: %s\n"), command_line); child_argv[0] = command_line; - argv_array_pushf(&child_env, "GIT_DIR=%s", absolute_path(get_git_dir())); - argv_array_pushf(&child_env, "GIT_WORK_TREE=%s", - absolute_path(get_git_work_tree())); + strvec_pushf(&child_env, "GIT_DIR=%s", absolute_path(get_git_dir())); + strvec_pushf(&child_env, "GIT_WORK_TREE=%s", + absolute_path(get_git_work_tree())); status = run_command_v_opt_cd_env(child_argv, RUN_USING_SHELL, NULL, - child_env.argv); + child_env.v); /* force re-reading of the cache */ if (discard_index(r->index) < 0 || repo_read_index(r) < 0) @@ -3165,7 +3165,7 @@ static int do_exec(struct repository *r, const char *command_line) status = 1; } - argv_array_clear(&child_env); + strvec_clear(&child_env); return status; } @@ -3544,29 +3544,29 @@ static int do_merge(struct repository *r, } cmd.git_cmd = 1; - argv_array_push(&cmd.args, "merge"); - argv_array_push(&cmd.args, "-s"); + strvec_push(&cmd.args, "merge"); + strvec_push(&cmd.args, "-s"); if (!strategy) - argv_array_push(&cmd.args, "octopus"); + strvec_push(&cmd.args, "octopus"); else { - argv_array_push(&cmd.args, strategy); + strvec_push(&cmd.args, strategy); for (k = 0; k < opts->xopts_nr; k++) - argv_array_pushf(&cmd.args, - "-X%s", opts->xopts[k]); + strvec_pushf(&cmd.args, + "-X%s", opts->xopts[k]); } - argv_array_push(&cmd.args, "--no-edit"); - argv_array_push(&cmd.args, "--no-ff"); - argv_array_push(&cmd.args, "--no-log"); - argv_array_push(&cmd.args, "--no-stat"); - argv_array_push(&cmd.args, "-F"); - argv_array_push(&cmd.args, git_path_merge_msg(r)); + strvec_push(&cmd.args, "--no-edit"); + strvec_push(&cmd.args, "--no-ff"); + strvec_push(&cmd.args, "--no-log"); + strvec_push(&cmd.args, "--no-stat"); + strvec_push(&cmd.args, "-F"); + strvec_push(&cmd.args, git_path_merge_msg(r)); if (opts->gpg_sign) - argv_array_push(&cmd.args, opts->gpg_sign); + strvec_push(&cmd.args, opts->gpg_sign); /* Add the tips to be merged */ for (j = to_merge; j; j = j->next) - argv_array_push(&cmd.args, - oid_to_hex(&j->item->object.oid)); + strvec_push(&cmd.args, + oid_to_hex(&j->item->object.oid)); strbuf_release(&ref_name); unlink(git_path_cherry_pick_head(r)); @@ -3694,8 +3694,8 @@ void create_autostash(struct repository *r, const char *path, struct child_process stash = CHILD_PROCESS_INIT; struct object_id oid; - argv_array_pushl(&stash.args, - "stash", "create", "autostash", NULL); + strvec_pushl(&stash.args, + "stash", "create", "autostash", NULL); stash.git_cmd = 1; stash.no_stdin = 1; strbuf_reset(&buf); @@ -3734,9 +3734,9 @@ static int apply_save_autostash_oid(const char *stash_oid, int attempt_apply) child.git_cmd = 1; child.no_stdout = 1; child.no_stderr = 1; - argv_array_push(&child.args, "stash"); - argv_array_push(&child.args, "apply"); - argv_array_push(&child.args, stash_oid); + strvec_push(&child.args, "stash"); + strvec_push(&child.args, "apply"); + strvec_push(&child.args, stash_oid); ret = run_command(&child); } @@ -3746,12 +3746,12 @@ static int apply_save_autostash_oid(const char *stash_oid, int attempt_apply) struct child_process store = CHILD_PROCESS_INIT; store.git_cmd = 1; - argv_array_push(&store.args, "stash"); - argv_array_push(&store.args, "store"); - argv_array_push(&store.args, "-m"); - argv_array_push(&store.args, "autostash"); - argv_array_push(&store.args, "-q"); - argv_array_push(&store.args, stash_oid); + strvec_push(&store.args, "stash"); + strvec_push(&store.args, "store"); + strvec_push(&store.args, "-m"); + strvec_push(&store.args, "autostash"); + strvec_push(&store.args, "-q"); + strvec_push(&store.args, stash_oid); if (run_command(&store)) ret = error(_("cannot store %s"), stash_oid); else @@ -3831,9 +3831,9 @@ static int run_git_checkout(struct repository *r, struct replay_opts *opts, cmd.git_cmd = 1; - argv_array_push(&cmd.args, "checkout"); - argv_array_push(&cmd.args, commit); - argv_array_pushf(&cmd.env_array, GIT_REFLOG_ACTION "=%s", action); + strvec_push(&cmd.args, "checkout"); + strvec_push(&cmd.args, commit); + strvec_pushf(&cmd.env_array, GIT_REFLOG_ACTION "=%s", action); if (opts->verbose) ret = run_command(&cmd); @@ -4157,9 +4157,9 @@ cleanup_head_ref: child.in = open(rebase_path_rewritten_list(), O_RDONLY); child.git_cmd = 1; - argv_array_push(&child.args, "notes"); - argv_array_push(&child.args, "copy"); - argv_array_push(&child.args, "--for-rewrite=rebase"); + strvec_push(&child.args, "notes"); + strvec_push(&child.args, "copy"); + strvec_push(&child.args, "--for-rewrite=rebase"); /* we don't care if this copying failed */ run_command(&child); @@ -4170,8 +4170,8 @@ cleanup_head_ref: O_RDONLY); hook.stdout_to_stderr = 1; hook.trace2_hook_name = "post-rewrite"; - argv_array_push(&hook.args, post_rewrite_hook); - argv_array_push(&hook.args, "rebase"); + strvec_push(&hook.args, post_rewrite_hook); + strvec_push(&hook.args, "rebase"); /* we don't care if this hook failed */ run_command(&hook); } @@ -3,7 +3,7 @@ #include "config.h" #include "pkt-line.h" #include "version.h" -#include "argv-array.h" +#include "strvec.h" #include "ls-refs.h" #include "serve.h" #include "upload-pack.h" @@ -56,7 +56,7 @@ struct protocol_capability { * This field should be NULL for capabilities which are not commands. */ int (*command)(struct repository *r, - struct argv_array *keys, + struct strvec *keys, struct packet_reader *request); }; @@ -142,13 +142,13 @@ static int is_command(const char *key, struct protocol_capability **command) return 0; } -int has_capability(const struct argv_array *keys, const char *capability, +int has_capability(const struct strvec *keys, const char *capability, const char **value) { int i; - for (i = 0; i < keys->argc; i++) { + for (i = 0; i < keys->nr; i++) { const char *out; - if (skip_prefix(keys->argv[i], capability, &out) && + if (skip_prefix(keys->v[i], capability, &out) && (!*out || *out == '=')) { if (value) { if (*out == '=') @@ -162,7 +162,7 @@ int has_capability(const struct argv_array *keys, const char *capability, return 0; } -static void check_algorithm(struct repository *r, struct argv_array *keys) +static void check_algorithm(struct repository *r, struct strvec *keys) { int client = GIT_HASH_SHA1, server = hash_algo_by_ptr(r->hash_algo); const char *algo_name; @@ -187,7 +187,7 @@ static int process_request(void) { enum request_state state = PROCESS_REQUEST_KEYS; struct packet_reader reader; - struct argv_array keys = ARGV_ARRAY_INIT; + struct strvec keys = STRVEC_INIT; struct protocol_capability *command = NULL; packet_reader_init(&reader, 0, NULL, 0, @@ -211,7 +211,7 @@ static int process_request(void) /* collect request; a sequence of keys and values */ if (is_command(reader.line, &command) || is_valid_capability(reader.line)) - argv_array_push(&keys, reader.line); + strvec_push(&keys, reader.line); else die("unknown capability '%s'", reader.line); @@ -223,7 +223,7 @@ static int process_request(void) * If no command and no keys were given then the client * wanted to terminate the connection. */ - if (!keys.argc) + if (!keys.nr) return 1; /* @@ -254,7 +254,7 @@ static int process_request(void) command->command(the_repository, &keys, &reader); - argv_array_clear(&keys); + strvec_clear(&keys); return 0; } @@ -1,8 +1,8 @@ #ifndef SERVE_H #define SERVE_H -struct argv_array; -int has_capability(const struct argv_array *keys, const char *capability, +struct strvec; +int has_capability(const struct strvec *keys, const char *capability, const char **value); struct serve_options { @@ -447,6 +447,63 @@ static int read_worktree_config(const char *var, const char *value, void *vdata) return 0; } +enum extension_result { + EXTENSION_ERROR = -1, /* compatible with error(), etc */ + EXTENSION_UNKNOWN = 0, + EXTENSION_OK = 1 +}; + +/* + * Do not add new extensions to this function. It handles extensions which are + * respected even in v0-format repositories for historical compatibility. + */ +static enum extension_result handle_extension_v0(const char *var, + const char *value, + const char *ext, + struct repository_format *data) +{ + if (!strcmp(ext, "noop")) { + return EXTENSION_OK; + } else if (!strcmp(ext, "preciousobjects")) { + data->precious_objects = git_config_bool(var, value); + return EXTENSION_OK; + } else if (!strcmp(ext, "partialclone")) { + if (!value) + return config_error_nonbool(var); + data->partial_clone = xstrdup(value); + return EXTENSION_OK; + } else if (!strcmp(ext, "worktreeconfig")) { + data->worktree_config = git_config_bool(var, value); + return EXTENSION_OK; + } + + return EXTENSION_UNKNOWN; +} + +/* + * Record any new extensions in this function. + */ +static enum extension_result handle_extension(const char *var, + const char *value, + const char *ext, + struct repository_format *data) +{ + if (!strcmp(ext, "noop-v1")) { + return EXTENSION_OK; + } else if (!strcmp(ext, "objectformat")) { + int format; + + if (!value) + return config_error_nonbool(var); + format = hash_algo_by_name(value); + if (format == GIT_HASH_UNKNOWN) + return error("invalid value for 'extensions.objectformat'"); + data->hash_algo = format; + return EXTENSION_OK; + } + return EXTENSION_UNKNOWN; +} + static int check_repo_format(const char *var, const char *value, void *vdata) { struct repository_format *data = vdata; @@ -455,23 +512,25 @@ static int check_repo_format(const char *var, const char *value, void *vdata) if (strcmp(var, "core.repositoryformatversion") == 0) data->version = git_config_int(var, value); else if (skip_prefix(var, "extensions.", &ext)) { - /* - * record any known extensions here; otherwise, - * we fall through to recording it as unknown, and - * check_repository_format will complain - */ - if (!strcmp(ext, "noop")) - ; - else if (!strcmp(ext, "preciousobjects")) - data->precious_objects = git_config_bool(var, value); - else if (!strcmp(ext, "partialclone")) { - if (!value) - return config_error_nonbool(var); - data->partial_clone = xstrdup(value); - } else if (!strcmp(ext, "worktreeconfig")) - data->worktree_config = git_config_bool(var, value); - else + switch (handle_extension_v0(var, value, ext, data)) { + case EXTENSION_ERROR: + return -1; + case EXTENSION_OK: + return 0; + case EXTENSION_UNKNOWN: + break; + } + + switch (handle_extension(var, value, ext, data)) { + case EXTENSION_ERROR: + return -1; + case EXTENSION_OK: + string_list_append(&data->v1_only_extensions, ext); + return 0; + case EXTENSION_UNKNOWN: string_list_append(&data->unknown_extensions, ext); + return 0; + } } return read_worktree_config(var, value, vdata); @@ -510,6 +569,7 @@ static int check_repository_format_gently(const char *gitdir, struct repository_ set_repository_format_partial_clone(candidate->partial_clone); repository_format_worktree_config = candidate->worktree_config; string_list_clear(&candidate->unknown_extensions, 0); + string_list_clear(&candidate->v1_only_extensions, 0); if (repository_format_worktree_config) { /* @@ -588,6 +648,7 @@ int read_repository_format(struct repository_format *format, const char *path) void clear_repository_format(struct repository_format *format) { string_list_clear(&format->unknown_extensions, 0); + string_list_clear(&format->v1_only_extensions, 0); free(format->work_tree); free(format->partial_clone); init_repository_format(format); @@ -613,6 +674,18 @@ int verify_repository_format(const struct repository_format *format, return -1; } + if (format->version == 0 && format->v1_only_extensions.nr) { + int i; + + strbuf_addstr(err, + _("repo version is 0, but v1-only extensions found:")); + + for (i = 0; i < format->v1_only_extensions.nr; i++) + strbuf_addf(err, "\n\t%s", + format->v1_only_extensions.items[i].string); + return -1; + } + return 0; } diff --git a/sha1-file.c b/sha1-file.c index ccd34dd9e8..8904559da2 100644 --- a/sha1-file.c +++ b/sha1-file.c @@ -763,18 +763,18 @@ static void fill_alternate_refs_command(struct child_process *cmd, if (!git_config_get_value("core.alternateRefsCommand", &value)) { cmd->use_shell = 1; - argv_array_push(&cmd->args, value); - argv_array_push(&cmd->args, repo_path); + strvec_push(&cmd->args, value); + strvec_push(&cmd->args, repo_path); } else { cmd->git_cmd = 1; - argv_array_pushf(&cmd->args, "--git-dir=%s", repo_path); - argv_array_push(&cmd->args, "for-each-ref"); - argv_array_push(&cmd->args, "--format=%(objectname)"); + strvec_pushf(&cmd->args, "--git-dir=%s", repo_path); + strvec_push(&cmd->args, "for-each-ref"); + strvec_push(&cmd->args, "--format=%(objectname)"); if (!git_config_get_value("core.alternateRefsPrefixes", &value)) { - argv_array_push(&cmd->args, "--"); - argv_array_split(&cmd->args, value); + strvec_push(&cmd->args, "--"); + strvec_split(&cmd->args, value); } } @@ -1600,7 +1600,8 @@ int pretend_object_file(void *buf, unsigned long len, enum object_type type, struct cached_object *co; hash_object_file(the_hash_algo, buf, len, type_name(type), oid); - if (has_object_file(oid) || find_cached_object(oid)) + if (has_object_file_with_flags(oid, OBJECT_INFO_QUICK | OBJECT_INFO_SKIP_FETCH_OBJECT) || + find_cached_object(oid)) return 0; ALLOC_GROW(cached_objects, cached_object_nr + 1, cached_object_alloc); co = &cached_objects[cached_object_nr++]; @@ -110,6 +110,10 @@ void rollback_shallow_file(struct repository *r, struct shallow_lock *lk) * supports a "valid" flag. */ define_commit_slab(commit_depth, int *); +static void free_depth_in_slab(int **ptr) +{ + FREE_AND_NULL(*ptr); +} struct commit_list *get_shallow_commits(struct object_array *heads, int depth, int shallow_flag, int not_shallow_flag) { @@ -176,15 +180,7 @@ struct commit_list *get_shallow_commits(struct object_array *heads, int depth, } } } - for (i = 0; i < depths.slab_count; i++) { - int j; - - if (!depths.slab[i]) - continue; - for (j = 0; j < depths.slab_size; j++) - free(depths.slab[i][j]); - } - clear_commit_depth(&depths); + deep_clear_commit_depth(&depths, free_depth_in_slab); return result; } diff --git a/strvec.c b/strvec.c new file mode 100644 index 0000000000..21dce0a7a4 --- /dev/null +++ b/strvec.c @@ -0,0 +1,109 @@ +#include "cache.h" +#include "strvec.h" +#include "strbuf.h" + +const char *empty_strvec[] = { NULL }; + +void strvec_init(struct strvec *array) +{ + array->v = empty_strvec; + array->nr = 0; + array->alloc = 0; +} + +static void strvec_push_nodup(struct strvec *array, const char *value) +{ + if (array->v == empty_strvec) + array->v = NULL; + + ALLOC_GROW(array->v, array->nr + 2, array->alloc); + array->v[array->nr++] = value; + array->v[array->nr] = NULL; +} + +const char *strvec_push(struct strvec *array, const char *value) +{ + strvec_push_nodup(array, xstrdup(value)); + return array->v[array->nr - 1]; +} + +const char *strvec_pushf(struct strvec *array, const char *fmt, ...) +{ + va_list ap; + struct strbuf v = STRBUF_INIT; + + va_start(ap, fmt); + strbuf_vaddf(&v, fmt, ap); + va_end(ap); + + strvec_push_nodup(array, strbuf_detach(&v, NULL)); + return array->v[array->nr - 1]; +} + +void strvec_pushl(struct strvec *array, ...) +{ + va_list ap; + const char *arg; + + va_start(ap, array); + while ((arg = va_arg(ap, const char *))) + strvec_push(array, arg); + va_end(ap); +} + +void strvec_pushv(struct strvec *array, const char **items) +{ + for (; *items; items++) + strvec_push(array, *items); +} + +void strvec_pop(struct strvec *array) +{ + if (!array->nr) + return; + free((char *)array->v[array->nr - 1]); + array->v[array->nr - 1] = NULL; + array->nr--; +} + +void strvec_split(struct strvec *array, const char *to_split) +{ + while (isspace(*to_split)) + to_split++; + for (;;) { + const char *p = to_split; + + if (!*p) + break; + + while (*p && !isspace(*p)) + p++; + strvec_push_nodup(array, xstrndup(to_split, p - to_split)); + + while (isspace(*p)) + p++; + to_split = p; + } +} + +void strvec_clear(struct strvec *array) +{ + if (array->v != empty_strvec) { + int i; + for (i = 0; i < array->nr; i++) + free((char *)array->v[i]); + free(array->v); + } + strvec_init(array); +} + +const char **strvec_detach(struct strvec *array) +{ + if (array->v == empty_strvec) + return xcalloc(1, sizeof(const char *)); + else { + const char **ret = array->v; + strvec_init(array); + return ret; + } +} diff --git a/argv-array.h b/strvec.h index a7d3b10707..fdcad75b45 100644 --- a/argv-array.h +++ b/strvec.h @@ -1,11 +1,11 @@ -#ifndef ARGV_ARRAY_H -#define ARGV_ARRAY_H +#ifndef STRVEC_H +#define STRVEC_H /** - * The argv-array API allows one to dynamically build and store - * NULL-terminated lists. An argv-array maintains the invariant that the - * `argv` member always points to a non-NULL array, and that the array is - * always NULL-terminated at the element pointed to by `argv[argc]`. This + * The strvec API allows one to dynamically build and store + * NULL-terminated arrays of strings. A strvec maintains the invariant that the + * `items` member always points to a non-NULL array, and that the array is + * always NULL-terminated at the element pointed to by `items[nr]`. This * makes the result suitable for passing to functions expecting to receive * argv from main(). * @@ -14,42 +14,42 @@ * it contains an item structure with a `util` field that is not compatible * with the traditional argv interface. * - * Each `argv_array` manages its own memory. Any strings pushed into the - * array are duplicated, and all memory is freed by argv_array_clear(). + * Each `strvec` manages its own memory. Any strings pushed into the + * array are duplicated, and all memory is freed by strvec_clear(). */ -extern const char *empty_argv[]; +extern const char *empty_strvec[]; /** * A single array. This should be initialized by assignment from - * `ARGV_ARRAY_INIT`, or by calling `argv_array_init`. The `argv` - * member contains the actual array; the `argc` member contains the + * `STRVEC_INIT`, or by calling `strvec_init`. The `items` + * member contains the actual array; the `nr` member contains the * number of elements in the array, not including the terminating * NULL. */ -struct argv_array { - const char **argv; - int argc; +struct strvec { + const char **v; + int nr; int alloc; }; -#define ARGV_ARRAY_INIT { empty_argv, 0, 0 } +#define STRVEC_INIT { empty_strvec, 0, 0 } /** * Initialize an array. This is no different than assigning from - * `ARGV_ARRAY_INIT`. + * `STRVEC_INIT`. */ -void argv_array_init(struct argv_array *); +void strvec_init(struct strvec *); /* Push a copy of a string onto the end of the array. */ -const char *argv_array_push(struct argv_array *, const char *); +const char *strvec_push(struct strvec *, const char *); /** * Format a string and push it onto the end of the array. This is a - * convenience wrapper combining `strbuf_addf` and `argv_array_push`. + * convenience wrapper combining `strbuf_addf` and `strvec_push`. */ __attribute__((format (printf,2,3))) -const char *argv_array_pushf(struct argv_array *, const char *fmt, ...); +const char *strvec_pushf(struct strvec *, const char *fmt, ...); /** * Push a list of strings onto the end of the array. The arguments @@ -57,33 +57,33 @@ const char *argv_array_pushf(struct argv_array *, const char *fmt, ...); * argument. */ LAST_ARG_MUST_BE_NULL -void argv_array_pushl(struct argv_array *, ...); +void strvec_pushl(struct strvec *, ...); /* Push a null-terminated array of strings onto the end of the array. */ -void argv_array_pushv(struct argv_array *, const char **); +void strvec_pushv(struct strvec *, const char **); /** * Remove the final element from the array. If there are no * elements in the array, do nothing. */ -void argv_array_pop(struct argv_array *); +void strvec_pop(struct strvec *); /* Splits by whitespace; does not handle quoted arguments! */ -void argv_array_split(struct argv_array *, const char *); +void strvec_split(struct strvec *, const char *); /** * Free all memory associated with the array and return it to the * initial, empty state. */ -void argv_array_clear(struct argv_array *); +void strvec_clear(struct strvec *); /** - * Disconnect the `argv` member from the `argv_array` struct and + * Disconnect the `items` member from the `strvec` struct and * return it. The caller is responsible for freeing the memory used * by the array, and by the strings it references. After detaching, - * the `argv_array` is in a reinitialized state and can be pushed + * the `strvec` is in a reinitialized state and can be pushed * into again. */ -const char **argv_array_detach(struct argv_array *); +const char **strvec_detach(struct strvec *); -#endif /* ARGV_ARRAY_H */ +#endif /* STRVEC_H */ diff --git a/sub-process.c b/sub-process.c index 1b1af9dcbd..dfa790d3ff 100644 --- a/sub-process.c +++ b/sub-process.c @@ -84,7 +84,7 @@ int subprocess_start(struct hashmap *hashmap, struct subprocess_entry *entry, co process = &entry->process; child_process_init(process); - argv_array_push(&process->args, cmd); + strvec_push(&process->args, cmd); process->use_shell = 1; process->in = -1; process->out = -1; diff --git a/submodule.c b/submodule.c index e2ef5698c8..a52b93a87f 100644 --- a/submodule.c +++ b/submodule.c @@ -13,7 +13,7 @@ #include "refs.h" #include "string-list.h" #include "oid-array.h" -#include "argv-array.h" +#include "strvec.h" #include "blob.h" #include "thread-utils.h" #include "quote.h" @@ -262,17 +262,17 @@ int is_submodule_active(struct repository *repo, const char *path) sl = repo_config_get_value_multi(repo, "submodule.active"); if (sl) { struct pathspec ps; - struct argv_array args = ARGV_ARRAY_INIT; + struct strvec args = STRVEC_INIT; const struct string_list_item *item; for_each_string_list_item(item, sl) { - argv_array_push(&args, item->string); + strvec_push(&args, item->string); } - parse_pathspec(&ps, 0, 0, NULL, args.argv); + parse_pathspec(&ps, 0, 0, NULL, args.v); ret = match_pathspec(repo->index, &ps, path, strlen(path), 0, NULL, 1); - argv_array_clear(&args); + strvec_clear(&args); clear_pathspec(&ps); return ret; } @@ -481,27 +481,27 @@ static void print_submodule_summary(struct repository *r, struct rev_info *rev, strbuf_release(&sb); } -static void prepare_submodule_repo_env_no_git_dir(struct argv_array *out) +static void prepare_submodule_repo_env_no_git_dir(struct strvec *out) { const char * const *var; for (var = local_repo_env; *var; var++) { if (strcmp(*var, CONFIG_DATA_ENVIRONMENT)) - argv_array_push(out, *var); + strvec_push(out, *var); } } -void prepare_submodule_repo_env(struct argv_array *out) +void prepare_submodule_repo_env(struct strvec *out) { prepare_submodule_repo_env_no_git_dir(out); - argv_array_pushf(out, "%s=%s", GIT_DIR_ENVIRONMENT, - DEFAULT_GIT_DIR_ENVIRONMENT); + strvec_pushf(out, "%s=%s", GIT_DIR_ENVIRONMENT, + DEFAULT_GIT_DIR_ENVIRONMENT); } -static void prepare_submodule_repo_env_in_gitdir(struct argv_array *out) +static void prepare_submodule_repo_env_in_gitdir(struct strvec *out) { prepare_submodule_repo_env_no_git_dir(out); - argv_array_pushf(out, "%s=.", GIT_DIR_ENVIRONMENT); + strvec_pushf(out, "%s=.", GIT_DIR_ENVIRONMENT); } /* @@ -681,22 +681,22 @@ void show_submodule_inline_diff(struct diff_options *o, const char *path, cp.no_stdin = 1; /* TODO: other options may need to be passed here. */ - argv_array_pushl(&cp.args, "diff", "--submodule=diff", NULL); - argv_array_pushf(&cp.args, "--color=%s", want_color(o->use_color) ? + strvec_pushl(&cp.args, "diff", "--submodule=diff", NULL); + strvec_pushf(&cp.args, "--color=%s", want_color(o->use_color) ? "always" : "never"); if (o->flags.reverse_diff) { - argv_array_pushf(&cp.args, "--src-prefix=%s%s/", - o->b_prefix, path); - argv_array_pushf(&cp.args, "--dst-prefix=%s%s/", - o->a_prefix, path); + strvec_pushf(&cp.args, "--src-prefix=%s%s/", + o->b_prefix, path); + strvec_pushf(&cp.args, "--dst-prefix=%s%s/", + o->a_prefix, path); } else { - argv_array_pushf(&cp.args, "--src-prefix=%s%s/", - o->a_prefix, path); - argv_array_pushf(&cp.args, "--dst-prefix=%s%s/", - o->b_prefix, path); + strvec_pushf(&cp.args, "--src-prefix=%s%s/", + o->a_prefix, path); + strvec_pushf(&cp.args, "--dst-prefix=%s%s/", + o->b_prefix, path); } - argv_array_push(&cp.args, oid_to_hex(old_oid)); + strvec_push(&cp.args, oid_to_hex(old_oid)); /* * If the submodule has modified content, we will diff against the * work tree, under the assumption that the user has asked for the @@ -704,7 +704,7 @@ void show_submodule_inline_diff(struct diff_options *o, const char *path, * haven't yet been committed to the submodule yet. */ if (!(dirty_submodule & DIRTY_SUBMODULE_MODIFIED)) - argv_array_push(&cp.args, oid_to_hex(new_oid)); + strvec_push(&cp.args, oid_to_hex(new_oid)); prepare_submodule_repo_env(&cp.env_array); if (start_command(&cp)) @@ -836,13 +836,13 @@ static void collect_changed_submodules_cb(struct diff_queue_struct *q, */ static void collect_changed_submodules(struct repository *r, struct string_list *changed, - struct argv_array *argv) + struct strvec *argv) { struct rev_info rev; const struct commit *commit; repo_init_revisions(r, &rev, NULL); - setup_revisions(argv->argc, argv->argv, &rev, NULL); + setup_revisions(argv->nr, argv->v, &rev, NULL); if (prepare_revision_walk(&rev)) die(_("revision walk setup failed")); @@ -879,8 +879,8 @@ static int has_remote(const char *refname, const struct object_id *oid, static int append_oid_to_argv(const struct object_id *oid, void *data) { - struct argv_array *argv = data; - argv_array_push(argv, oid_to_hex(oid)); + struct strvec *argv = data; + strvec_push(argv, oid_to_hex(oid)); return 0; } @@ -941,9 +941,9 @@ static int submodule_has_commits(struct repository *r, struct child_process cp = CHILD_PROCESS_INIT; struct strbuf out = STRBUF_INIT; - argv_array_pushl(&cp.args, "rev-list", "-n", "1", NULL); + strvec_pushl(&cp.args, "rev-list", "-n", "1", NULL); oid_array_for_each_unique(commits, append_oid_to_argv, &cp.args); - argv_array_pushl(&cp.args, "--not", "--all", NULL); + strvec_pushl(&cp.args, "--not", "--all", NULL); prepare_submodule_repo_env(&cp.env_array); cp.git_cmd = 1; @@ -982,9 +982,9 @@ static int submodule_needs_pushing(struct repository *r, struct strbuf buf = STRBUF_INIT; int needs_pushing = 0; - argv_array_push(&cp.args, "rev-list"); + strvec_push(&cp.args, "rev-list"); oid_array_for_each_unique(commits, append_oid_to_argv, &cp.args); - argv_array_pushl(&cp.args, "--not", "--remotes", "-n", "1" , NULL); + strvec_pushl(&cp.args, "--not", "--remotes", "-n", "1" , NULL); prepare_submodule_repo_env(&cp.env_array); cp.git_cmd = 1; @@ -1012,13 +1012,13 @@ int find_unpushed_submodules(struct repository *r, { struct string_list submodules = STRING_LIST_INIT_DUP; struct string_list_item *name; - struct argv_array argv = ARGV_ARRAY_INIT; + struct strvec argv = STRVEC_INIT; - /* argv.argv[0] will be ignored by setup_revisions */ - argv_array_push(&argv, "find_unpushed_submodules"); + /* argv.v[0] will be ignored by setup_revisions */ + strvec_push(&argv, "find_unpushed_submodules"); oid_array_for_each_unique(commits, append_oid_to_argv, &argv); - argv_array_push(&argv, "--not"); - argv_array_pushf(&argv, "--remotes=%s", remotes_name); + strvec_push(&argv, "--not"); + strvec_pushf(&argv, "--remotes=%s", remotes_name); collect_changed_submodules(r, &submodules, &argv); @@ -1041,7 +1041,7 @@ int find_unpushed_submodules(struct repository *r, } free_submodules_oids(&submodules); - argv_array_clear(&argv); + strvec_clear(&argv); return needs_pushing->nr; } @@ -1054,22 +1054,22 @@ static int push_submodule(const char *path, { if (for_each_remote_ref_submodule(path, has_remote, NULL) > 0) { struct child_process cp = CHILD_PROCESS_INIT; - argv_array_push(&cp.args, "push"); + strvec_push(&cp.args, "push"); if (dry_run) - argv_array_push(&cp.args, "--dry-run"); + strvec_push(&cp.args, "--dry-run"); if (push_options && push_options->nr) { const struct string_list_item *item; for_each_string_list_item(item, push_options) - argv_array_pushf(&cp.args, "--push-option=%s", - item->string); + strvec_pushf(&cp.args, "--push-option=%s", + item->string); } if (remote->origin != REMOTE_UNCONFIGURED) { int i; - argv_array_push(&cp.args, remote->name); + strvec_push(&cp.args, remote->name); for (i = 0; i < rs->raw_nr; i++) - argv_array_push(&cp.args, rs->raw[i]); + strvec_push(&cp.args, rs->raw[i]); } prepare_submodule_repo_env(&cp.env_array); @@ -1095,13 +1095,13 @@ static void submodule_push_check(const char *path, const char *head, struct child_process cp = CHILD_PROCESS_INIT; int i; - argv_array_push(&cp.args, "submodule--helper"); - argv_array_push(&cp.args, "push-check"); - argv_array_push(&cp.args, head); - argv_array_push(&cp.args, remote->name); + strvec_push(&cp.args, "submodule--helper"); + strvec_push(&cp.args, "push-check"); + strvec_push(&cp.args, head); + strvec_push(&cp.args, remote->name); for (i = 0; i < rs->raw_nr; i++) - argv_array_push(&cp.args, rs->raw[i]); + strvec_push(&cp.args, rs->raw[i]); prepare_submodule_repo_env(&cp.env_array); cp.git_cmd = 1; @@ -1189,17 +1189,17 @@ void check_for_new_submodule_commits(struct object_id *oid) static void calculate_changed_submodule_paths(struct repository *r, struct string_list *changed_submodule_names) { - struct argv_array argv = ARGV_ARRAY_INIT; + struct strvec argv = STRVEC_INIT; struct string_list_item *name; /* No need to check if there are no submodules configured */ if (!submodule_from_path(r, NULL, NULL)) return; - argv_array_push(&argv, "--"); /* argv[0] program name */ + strvec_push(&argv, "--"); /* argv[0] program name */ oid_array_for_each_unique(&ref_tips_after_fetch, append_oid_to_argv, &argv); - argv_array_push(&argv, "--not"); + strvec_push(&argv, "--not"); oid_array_for_each_unique(&ref_tips_before_fetch, append_oid_to_argv, &argv); @@ -1231,7 +1231,7 @@ static void calculate_changed_submodule_paths(struct repository *r, string_list_remove_empty_items(changed_submodule_names, 1); - argv_array_clear(&argv); + strvec_clear(&argv); oid_array_clear(&ref_tips_before_fetch); oid_array_clear(&ref_tips_after_fetch); initialized_fetch_ref_tips = 0; @@ -1242,24 +1242,24 @@ int submodule_touches_in_range(struct repository *r, struct object_id *incl_oid) { struct string_list subs = STRING_LIST_INIT_DUP; - struct argv_array args = ARGV_ARRAY_INIT; + struct strvec args = STRVEC_INIT; int ret; /* No need to check if there are no submodules configured */ if (!submodule_from_path(r, NULL, NULL)) return 0; - argv_array_push(&args, "--"); /* args[0] program name */ - argv_array_push(&args, oid_to_hex(incl_oid)); + strvec_push(&args, "--"); /* args[0] program name */ + strvec_push(&args, oid_to_hex(incl_oid)); if (!is_null_oid(excl_oid)) { - argv_array_push(&args, "--not"); - argv_array_push(&args, oid_to_hex(excl_oid)); + strvec_push(&args, "--not"); + strvec_push(&args, oid_to_hex(excl_oid)); } collect_changed_submodules(r, &subs, &args); ret = subs.nr; - argv_array_clear(&args); + strvec_clear(&args); free_submodules_oids(&subs); return ret; @@ -1267,7 +1267,7 @@ int submodule_touches_in_range(struct repository *r, struct submodule_parallel_fetch { int count; - struct argv_array args; + struct strvec args; struct repository *r; const char *prefix; int command_line_option; @@ -1283,7 +1283,7 @@ struct submodule_parallel_fetch { struct strbuf submodules_with_errors; }; -#define SPF_INIT {0, ARGV_ARRAY_INIT, NULL, NULL, 0, 0, 0, 0, \ +#define SPF_INIT {0, STRVEC_INIT, NULL, NULL, 0, 0, 0, 0, \ STRING_LIST_INIT_DUP, \ NULL, 0, 0, STRBUF_INIT} @@ -1452,15 +1452,15 @@ static int get_next_submodule(struct child_process *cp, if (!spf->quiet) strbuf_addf(err, _("Fetching submodule %s%s\n"), spf->prefix, ce->name); - argv_array_init(&cp->args); - argv_array_pushv(&cp->args, spf->args.argv); - argv_array_push(&cp->args, default_argv); - argv_array_push(&cp->args, "--submodule-prefix"); + strvec_init(&cp->args); + strvec_pushv(&cp->args, spf->args.v); + strvec_push(&cp->args, default_argv); + strvec_push(&cp->args, "--submodule-prefix"); strbuf_addf(&submodule_prefix, "%s%s/", spf->prefix, task->sub->path); - argv_array_push(&cp->args, submodule_prefix.buf); + strvec_push(&cp->args, submodule_prefix.buf); spf->count++; *task_cb = task; @@ -1500,14 +1500,14 @@ static int get_next_submodule(struct child_process *cp, cp->git_cmd = 1; cp->dir = task->repo->gitdir; - argv_array_init(&cp->args); - argv_array_pushv(&cp->args, spf->args.argv); - argv_array_push(&cp->args, "on-demand"); - argv_array_push(&cp->args, "--submodule-prefix"); - argv_array_push(&cp->args, submodule_prefix.buf); + strvec_init(&cp->args); + strvec_pushv(&cp->args, spf->args.v); + strvec_push(&cp->args, "on-demand"); + strvec_push(&cp->args, "--submodule-prefix"); + strvec_push(&cp->args, submodule_prefix.buf); /* NEEDSWORK: have get_default_remote from submodule--helper */ - argv_array_push(&cp->args, "origin"); + strvec_push(&cp->args, "origin"); oid_array_for_each_unique(task->commits, append_oid_to_argv, &cp->args); @@ -1598,7 +1598,7 @@ out: } int fetch_populated_submodules(struct repository *r, - const struct argv_array *options, + const struct strvec *options, const char *prefix, int command_line_option, int default_option, int quiet, int max_parallel_jobs) @@ -1618,10 +1618,10 @@ int fetch_populated_submodules(struct repository *r, if (repo_read_index(r) < 0) die(_("index file corrupt")); - argv_array_push(&spf.args, "fetch"); - for (i = 0; i < options->argc; i++) - argv_array_push(&spf.args, options->argv[i]); - argv_array_push(&spf.args, "--recurse-submodules-default"); + strvec_push(&spf.args, "fetch"); + for (i = 0; i < options->nr; i++) + strvec_push(&spf.args, options->v[i]); + strvec_push(&spf.args, "--recurse-submodules-default"); /* default value, "--submodule-prefix" and its value are added later */ calculate_changed_submodule_paths(r, &spf.changed_submodule_names); @@ -1638,7 +1638,7 @@ int fetch_populated_submodules(struct repository *r, spf.submodules_with_errors.buf); - argv_array_clear(&spf.args); + strvec_clear(&spf.args); out: free_submodules_oids(&spf.changed_submodule_names); return spf.result; @@ -1666,9 +1666,9 @@ unsigned is_submodule_modified(const char *path, int ignore_untracked) } strbuf_reset(&buf); - argv_array_pushl(&cp.args, "status", "--porcelain=2", NULL); + strvec_pushl(&cp.args, "status", "--porcelain=2", NULL); if (ignore_untracked) - argv_array_push(&cp.args, "-uno"); + strvec_push(&cp.args, "-uno"); prepare_submodule_repo_env(&cp.env_array); cp.git_cmd = 1; @@ -1779,16 +1779,16 @@ int bad_to_remove_submodule(const char *path, unsigned flags) if (!submodule_uses_gitfile(path)) return 1; - argv_array_pushl(&cp.args, "status", "--porcelain", - "--ignore-submodules=none", NULL); + strvec_pushl(&cp.args, "status", "--porcelain", + "--ignore-submodules=none", NULL); if (flags & SUBMODULE_REMOVAL_IGNORE_UNTRACKED) - argv_array_push(&cp.args, "-uno"); + strvec_push(&cp.args, "-uno"); else - argv_array_push(&cp.args, "-uall"); + strvec_push(&cp.args, "-uall"); if (!(flags & SUBMODULE_REMOVAL_IGNORE_IGNORED_UNTRACKED)) - argv_array_push(&cp.args, "--ignored"); + strvec_push(&cp.args, "--ignored"); prepare_submodule_repo_env(&cp.env_array); cp.git_cmd = 1; @@ -1846,8 +1846,8 @@ static int submodule_has_dirty_index(const struct submodule *sub) prepare_submodule_repo_env(&cp.env_array); cp.git_cmd = 1; - argv_array_pushl(&cp.args, "diff-index", "--quiet", - "--cached", "HEAD", NULL); + strvec_pushl(&cp.args, "diff-index", "--quiet", + "--cached", "HEAD", NULL); cp.no_stdin = 1; cp.no_stdout = 1; cp.dir = sub->path; @@ -1866,11 +1866,11 @@ static void submodule_reset_index(const char *path) cp.no_stdin = 1; cp.dir = path; - argv_array_pushf(&cp.args, "--super-prefix=%s%s/", - get_super_prefix_or_empty(), path); - argv_array_pushl(&cp.args, "read-tree", "-u", "--reset", NULL); + strvec_pushf(&cp.args, "--super-prefix=%s%s/", + get_super_prefix_or_empty(), path); + strvec_pushl(&cp.args, "read-tree", "-u", "--reset", NULL); - argv_array_push(&cp.args, empty_tree_oid_hex()); + strvec_push(&cp.args, empty_tree_oid_hex()); if (run_command(&cp)) die(_("could not reset submodule index")); @@ -1947,24 +1947,24 @@ int submodule_move_head(const char *path, cp.no_stdin = 1; cp.dir = path; - argv_array_pushf(&cp.args, "--super-prefix=%s%s/", - get_super_prefix_or_empty(), path); - argv_array_pushl(&cp.args, "read-tree", "--recurse-submodules", NULL); + strvec_pushf(&cp.args, "--super-prefix=%s%s/", + get_super_prefix_or_empty(), path); + strvec_pushl(&cp.args, "read-tree", "--recurse-submodules", NULL); if (flags & SUBMODULE_MOVE_HEAD_DRY_RUN) - argv_array_push(&cp.args, "-n"); + strvec_push(&cp.args, "-n"); else - argv_array_push(&cp.args, "-u"); + strvec_push(&cp.args, "-u"); if (flags & SUBMODULE_MOVE_HEAD_FORCE) - argv_array_push(&cp.args, "--reset"); + strvec_push(&cp.args, "--reset"); else - argv_array_push(&cp.args, "-m"); + strvec_push(&cp.args, "-m"); if (!(flags & SUBMODULE_MOVE_HEAD_FORCE)) - argv_array_push(&cp.args, old_head ? old_head : empty_tree_oid_hex()); + strvec_push(&cp.args, old_head ? old_head : empty_tree_oid_hex()); - argv_array_push(&cp.args, new_head ? new_head : empty_tree_oid_hex()); + strvec_push(&cp.args, new_head ? new_head : empty_tree_oid_hex()); if (run_command(&cp)) { ret = error(_("Submodule '%s' could not be updated."), path); @@ -1980,8 +1980,8 @@ int submodule_move_head(const char *path, cp.dir = path; prepare_submodule_repo_env(&cp.env_array); - argv_array_pushl(&cp.args, "update-ref", "HEAD", - "--no-deref", new_head, NULL); + strvec_pushl(&cp.args, "update-ref", "HEAD", + "--no-deref", new_head, NULL); if (run_command(&cp)) { ret = -1; @@ -2157,9 +2157,9 @@ void absorb_git_dir_into_superproject(const char *path, cp.dir = path; cp.git_cmd = 1; cp.no_stdin = 1; - argv_array_pushl(&cp.args, "--super-prefix", sb.buf, - "submodule--helper", - "absorb-git-dirs", NULL); + strvec_pushl(&cp.args, "--super-prefix", sb.buf, + "submodule--helper", + "absorb-git-dirs", NULL); prepare_submodule_repo_env(&cp.env_array); if (run_command(&cp)) die(_("could not recurse into submodule '%s'"), path); @@ -2194,11 +2194,11 @@ int get_superproject_working_tree(struct strbuf *buf) strbuf_release(&one_up); prepare_submodule_repo_env(&cp.env_array); - argv_array_pop(&cp.env_array); + strvec_pop(&cp.env_array); - argv_array_pushl(&cp.args, "--literal-pathspecs", "-C", "..", - "ls-files", "-z", "--stage", "--full-name", "--", - subpath, NULL); + strvec_pushl(&cp.args, "--literal-pathspecs", "-C", "..", + "ls-files", "-z", "--stage", "--full-name", "--", + subpath, NULL); strbuf_reset(&sb); cp.no_stdin = 1; diff --git a/submodule.h b/submodule.h index 4dad649f94..9ce85c03fe 100644 --- a/submodule.h +++ b/submodule.h @@ -1,7 +1,7 @@ #ifndef SUBMODULE_H #define SUBMODULE_H -struct argv_array; +struct strvec; struct cache_entry; struct diff_options; struct index_state; @@ -84,7 +84,7 @@ int should_update_submodules(void); const struct submodule *submodule_from_ce(const struct cache_entry *ce); void check_for_new_submodule_commits(struct object_id *oid); int fetch_populated_submodules(struct repository *r, - const struct argv_array *options, + const struct strvec *options, const char *prefix, int command_line_option, int default_option, @@ -143,7 +143,7 @@ void submodule_unset_core_worktree(const struct submodule *sub); * a submodule by clearing any repo-specific environment variables, but * retaining any config in the environment. */ -void prepare_submodule_repo_env(struct argv_array *out); +void prepare_submodule_repo_env(struct strvec *out); #define ABSORB_GITDIR_RECURSE_SUBMODULES (1<<0) void absorb_git_dir_into_superproject(const char *path, diff --git a/t/helper/test-bloom.c b/t/helper/test-bloom.c index f0aa80b98e..5e77d56f59 100644 --- a/t/helper/test-bloom.c +++ b/t/helper/test-bloom.c @@ -50,6 +50,8 @@ static const char *bloom_usage = "\n" int cmd__bloom(int argc, const char **argv) { + setup_git_directory(); + if (argc < 2) usage(bloom_usage); diff --git a/t/helper/test-run-command.c b/t/helper/test-run-command.c index 1646aa25d8..7ae03dc712 100644 --- a/t/helper/test-run-command.c +++ b/t/helper/test-run-command.c @@ -12,7 +12,7 @@ #include "git-compat-util.h" #include "cache.h" #include "run-command.h" -#include "argv-array.h" +#include "strvec.h" #include "strbuf.h" #include "parse-options.h" #include "string-list.h" @@ -31,7 +31,7 @@ static int parallel_next(struct child_process *cp, if (number_callbacks >= 4) return 0; - argv_array_pushv(&cp->args, d->argv); + strvec_pushv(&cp->args, d->argv); strbuf_addstr(err, "preloaded output of a child\n"); number_callbacks++; return 1; @@ -72,19 +72,19 @@ static int next_test(struct child_process *cp, struct strbuf *err, void *cb, return 0; test = suite->tests.items[suite->next++].string; - argv_array_pushl(&cp->args, "sh", test, NULL); + strvec_pushl(&cp->args, "sh", test, NULL); if (suite->quiet) - argv_array_push(&cp->args, "--quiet"); + strvec_push(&cp->args, "--quiet"); if (suite->immediate) - argv_array_push(&cp->args, "-i"); + strvec_push(&cp->args, "-i"); if (suite->verbose) - argv_array_push(&cp->args, "-v"); + strvec_push(&cp->args, "-v"); if (suite->verbose_log) - argv_array_push(&cp->args, "-V"); + strvec_push(&cp->args, "-V"); if (suite->trace) - argv_array_push(&cp->args, "-x"); + strvec_push(&cp->args, "-x"); if (suite->write_junit_xml) - argv_array_push(&cp->args, "--write-junit-xml"); + strvec_push(&cp->args, "--write-junit-xml"); strbuf_addf(err, "Output of '%s':\n", test); *task_cb = (void *)test; @@ -220,7 +220,7 @@ static int quote_stress_test(int argc, const char **argv) char special[] = ".?*\\^_\"'`{}()[]<>@~&+:;$%"; // \t\r\n\a"; int i, j, k, trials = 100, skip = 0, msys2 = 0; struct strbuf out = STRBUF_INIT; - struct argv_array args = ARGV_ARRAY_INIT; + struct strvec args = STRVEC_INIT; struct option options[] = { OPT_INTEGER('n', "trials", &trials, "Number of trials"), OPT_INTEGER('s', "skip", &skip, "Skip <n> trials"), @@ -241,20 +241,20 @@ static int quote_stress_test(int argc, const char **argv) size_t arg_count, arg_offset; int ret = 0; - argv_array_clear(&args); + strvec_clear(&args); if (msys2) - argv_array_pushl(&args, "sh", "-c", - "printf %s\\\\0 \"$@\"", "skip", NULL); + strvec_pushl(&args, "sh", "-c", + "printf %s\\\\0 \"$@\"", "skip", NULL); else - argv_array_pushl(&args, "test-tool", "run-command", - "quote-echo", NULL); - arg_offset = args.argc; + strvec_pushl(&args, "test-tool", "run-command", + "quote-echo", NULL); + arg_offset = args.nr; if (argc > 0) { trials = 1; arg_count = argc; for (j = 0; j < arg_count; j++) - argv_array_push(&args, argv[j]); + strvec_push(&args, argv[j]); } else { arg_count = 1 + (my_random() % 5); for (j = 0; j < arg_count; j++) { @@ -268,20 +268,20 @@ static int quote_stress_test(int argc, const char **argv) ARRAY_SIZE(special)]; buf[arg_len] = '\0'; - argv_array_push(&args, buf); + strvec_push(&args, buf); } } if (i < skip) continue; - cp.argv = args.argv; + cp.argv = args.v; strbuf_reset(&out); if (pipe_command(&cp, NULL, 0, &out, 0, NULL, 0) < 0) return error("Failed to spawn child process"); for (j = 0, k = 0; j < arg_count; j++) { - const char *arg = args.argv[j + arg_offset]; + const char *arg = args.v[j + arg_offset]; if (strcmp(arg, out.buf + k)) ret = error("incorrectly quoted arg: '%s', " @@ -298,10 +298,10 @@ static int quote_stress_test(int argc, const char **argv) fprintf(stderr, "Trial #%d failed. Arguments:\n", i); for (j = 0; j < arg_count; j++) fprintf(stderr, "arg #%d: '%s'\n", - (int)j, args.argv[j + arg_offset]); + (int)j, args.v[j + arg_offset]); strbuf_release(&out); - argv_array_clear(&args); + strvec_clear(&args); return ret; } @@ -311,7 +311,7 @@ static int quote_stress_test(int argc, const char **argv) } strbuf_release(&out); - argv_array_clear(&args); + strvec_clear(&args); return 0; } @@ -338,8 +338,8 @@ static int inherit_handle(const char *argv0) xsnprintf(path, sizeof(path), "out-XXXXXX"); tmp = xmkstemp(path); - argv_array_pushl(&cp.args, - "test-tool", argv0, "inherited-handle-child", NULL); + strvec_pushl(&cp.args, + "test-tool", argv0, "inherited-handle-child", NULL); cp.in = -1; cp.no_stdout = cp.no_stderr = 1; if (start_command(&cp) < 0) @@ -391,7 +391,7 @@ int cmd__run_command(int argc, const char **argv) while (!strcmp(argv[1], "env")) { if (!argv[2]) die("env specifier without a value"); - argv_array_push(&proc.env_array, argv[2]); + strvec_push(&proc.env_array, argv[2]); argv += 2; argc -= 2; } diff --git a/t/helper/test-trace2.c b/t/helper/test-trace2.c index 197819c872..823f33ceff 100644 --- a/t/helper/test-trace2.c +++ b/t/helper/test-trace2.c @@ -1,6 +1,6 @@ #include "test-tool.h" #include "cache.h" -#include "argv-array.h" +#include "strvec.h" #include "run-command.h" #include "exec-cmd.h" #include "config.h" diff --git a/t/lib-pack.sh b/t/lib-pack.sh index f3463170b3..bb8938ccbe 100644 --- a/t/lib-pack.sh +++ b/t/lib-pack.sh @@ -35,8 +35,6 @@ pack_header () { # have hardcoded some well-known objects. See the case statements below for the # complete list. pack_obj () { - test_oid_init - case "$1" in # empty blob $EMPTY_BLOB) @@ -93,6 +91,14 @@ pack_obj () { ;; esac ;; + # blob containing "\3\326" + 471819e8c52bf11513f100b2810a8aa0622d5cd3d1c913758a071dd4b3bad8fe) + case "$2" in + '') + printf '\062\170\234\143\276\006\000\000\336\000\332' + return + ;; + esac esac # If it's not a delta, we can convince pack-objects to generate a pack @@ -113,7 +119,6 @@ pack_obj () { # Compute and append pack trailer to "$1" pack_trailer () { - test_oid_init && test-tool $(test_oid algo) -b <"$1" >trailer.tmp && cat trailer.tmp >>"$1" && rm -f trailer.tmp diff --git a/t/lib-submodule-update.sh b/t/lib-submodule-update.sh index 07c822c8ff..87a759149f 100644 --- a/t/lib-submodule-update.sh +++ b/t/lib-submodule-update.sh @@ -196,7 +196,6 @@ test_git_directory_exists () { # the submodule repo if it doesn't exist and configures the most problematic # settings for diff.ignoreSubmodules. prolog () { - test_oid_init && (test -d submodule_update_repo || create_lib_submodule_repo) && test_config_global diff.ignoreSubmodules all && test_config diff.ignoreSubmodules all diff --git a/t/lib-t6000.sh b/t/lib-t6000.sh index b0ed4767e3..fba6778ca3 100644 --- a/t/lib-t6000.sh +++ b/t/lib-t6000.sh @@ -1,7 +1,5 @@ : included from 6002 and others -mkdir -p .git/refs/tags - >sed.script # Answer the sha1 has associated with the tag. The tag must exist under refs/tags @@ -26,7 +24,8 @@ save_tag () { _tag=$1 test -n "$_tag" || error "usage: save_tag tag commit-args ..." shift 1 - "$@" >".git/refs/tags/$_tag" + + git update-ref "refs/tags/$_tag" $("$@") echo "s/$(tag $_tag)/$_tag/g" >sed.script.tmp cat sed.script >>sed.script.tmp diff --git a/t/t0000-basic.sh b/t/t0000-basic.sh index 2ff176cd5d..923281af93 100755 --- a/t/t0000-basic.sh +++ b/t/t0000-basic.sh @@ -891,10 +891,6 @@ test_expect_success 'test_atexit is run' " test_path_is_missing also-clean-atexit " -test_expect_success 'test_oid setup' ' - test_oid_init -' - test_expect_success 'test_oid provides sane info by default' ' test_oid zero >actual && grep "^00*\$" actual && @@ -928,6 +924,17 @@ test_expect_success 'test_oid can look up data for SHA-256' ' test "$hexsz" -eq 64 ' +test_expect_success 'test_oid can look up data for a specified algorithm' ' + rawsz="$(test_oid --hash=sha1 rawsz)" && + hexsz="$(test_oid --hash=sha1 hexsz)" && + test "$rawsz" -eq 20 && + test "$hexsz" -eq 40 && + rawsz="$(test_oid --hash=sha256 rawsz)" && + hexsz="$(test_oid --hash=sha256 hexsz)" && + test "$rawsz" -eq 32 && + test "$hexsz" -eq 64 +' + test_expect_success 'test_bool_env' ' ( sane_unset envvar && @@ -1271,4 +1278,22 @@ test_expect_success 'very long name in the index handled sanely' ' test $len = 4098 ' +test_expect_success 'test_must_fail on a failing git command' ' + test_must_fail git notacommand +' + +test_expect_success 'test_must_fail on a failing git command with env' ' + test_must_fail env var1=a var2=b git notacommand +' + +test_expect_success 'test_must_fail rejects a non-git command' ' + ! test_must_fail grep ^$ notafile 2>err && + grep -F "test_must_fail: only '"'"'git'"'"' is allowed" err +' + +test_expect_success 'test_must_fail rejects a non-git command with env' ' + ! test_must_fail env var1=a var2=b grep ^$ notafile 2>err && + grep -F "test_must_fail: only '"'"'git'"'"' is allowed" err +' + test_done diff --git a/t/t0001-init.sh b/t/t0001-init.sh index 6d2467995e..d71d4c7238 100755 --- a/t/t0001-init.sh +++ b/t/t0001-init.sh @@ -441,6 +441,39 @@ test_expect_success 're-init from a linked worktree' ' ) ' +test_expect_success 'init honors GIT_DEFAULT_HASH' ' + GIT_DEFAULT_HASH=sha1 git init sha1 && + git -C sha1 rev-parse --show-object-format >actual && + echo sha1 >expected && + test_cmp expected actual && + GIT_DEFAULT_HASH=sha256 git init sha256 && + git -C sha256 rev-parse --show-object-format >actual && + echo sha256 >expected && + test_cmp expected actual +' + +test_expect_success 'init honors --object-format' ' + git init --object-format=sha1 explicit-sha1 && + git -C explicit-sha1 rev-parse --show-object-format >actual && + echo sha1 >expected && + test_cmp expected actual && + git init --object-format=sha256 explicit-sha256 && + git -C explicit-sha256 rev-parse --show-object-format >actual && + echo sha256 >expected && + test_cmp expected actual +' + +test_expect_success 'extensions.objectFormat is not allowed with repo version 0' ' + git init --object-format=sha256 explicit-v0 && + git -C explicit-v0 config core.repositoryformatversion 0 && + test_must_fail git -C explicit-v0 rev-parse --show-object-format +' + +test_expect_success 'init rejects attempts to initialize with different hash' ' + test_must_fail git -C sha1 init --object-format=sha256 && + test_must_fail git -C sha256 init --object-format=sha1 +' + test_expect_success MINGW 'core.hidedotfiles = false' ' git config --global core.hidedotfiles false && rm -rf newdir && diff --git a/t/t0410-partial-clone.sh b/t/t0410-partial-clone.sh index 6aa0f313bd..a5ebdf9ff3 100755 --- a/t/t0410-partial-clone.sh +++ b/t/t0410-partial-clone.sh @@ -42,7 +42,7 @@ test_expect_success 'convert shallow clone to partial clone' ' test_cmp_config -C client 1 core.repositoryformatversion ' -test_expect_success 'convert to partial clone with noop extension' ' +test_expect_success SHA1 'convert to partial clone with noop extension' ' rm -fr server client && test_create_repo server && test_commit -C server my_commit 1 && @@ -53,7 +53,7 @@ test_expect_success 'convert to partial clone with noop extension' ' git -C client fetch --unshallow --filter="blob:none" ' -test_expect_success 'converting to partial clone fails with unrecognized extension' ' +test_expect_success SHA1 'converting to partial clone fails with unrecognized extension' ' rm -fr server client && test_create_repo server && test_commit -C server my_commit 1 && diff --git a/t/t1006-cat-file.sh b/t/t1006-cat-file.sh index 43c4be1e5e..2f501d2dc9 100755 --- a/t/t1006-cat-file.sh +++ b/t/t1006-cat-file.sh @@ -140,8 +140,6 @@ test_expect_success '--batch-check without %(rest) considers whole line' ' test_cmp expect actual ' -test_oid_init - tree_sha1=$(git write-tree) tree_size=$(($(test_oid rawsz) + 13)) tree_pretty_content="100644 blob $hello_sha1 hello" diff --git a/t/t1050-large.sh b/t/t1050-large.sh index 6a56d1ca24..61e89a8071 100755 --- a/t/t1050-large.sh +++ b/t/t1050-large.sh @@ -12,7 +12,6 @@ file_size () { } test_expect_success setup ' - test_oid_init && # clone does not allow us to pass core.bigfilethreshold to # new repos, so set core.bigfilethreshold globally git config --global core.bigfilethreshold 200k && diff --git a/t/t1091-sparse-checkout-builtin.sh b/t/t1091-sparse-checkout-builtin.sh index 7cd45fc139..84acfc48b6 100755 --- a/t/t1091-sparse-checkout-builtin.sh +++ b/t/t1091-sparse-checkout-builtin.sh @@ -369,7 +369,7 @@ test_expect_success 'sparse-checkout (init|set|disable) warns with unmerged stat git clone repo unmerged && cat >input <<-EOF && - 0 0000000000000000000000000000000000000000 folder1/a + 0 $ZERO_OID folder1/a 100644 $(git -C unmerged rev-parse HEAD:folder1/a) 1 folder1/a EOF git -C unmerged update-index --index-info <input && @@ -396,7 +396,7 @@ test_expect_success 'sparse-checkout reapply' ' echo dirty >tweak/deep/deeper2/a && cat >input <<-EOF && - 0 0000000000000000000000000000000000000000 folder1/a + 0 $ZERO_OID folder1/a 100644 $(git -C tweak rev-parse HEAD:folder1/a) 1 folder1/a EOF git -C tweak update-index --index-info <input && diff --git a/t/t1302-repo-version.sh b/t/t1302-repo-version.sh index d60c042ce8..0acabb6d11 100755 --- a/t/t1302-repo-version.sh +++ b/t/t1302-repo-version.sh @@ -87,6 +87,9 @@ allow 1 allow 1 noop abort 1 no-such-extension allow 0 no-such-extension +allow 0 noop +abort 0 noop-v1 +allow 1 noop-v1 EOF test_expect_success 'precious-objects allowed' ' diff --git a/t/t1410-reflog.sh b/t/t1410-reflog.sh index 76d9b744a6..730a43d9dd 100755 --- a/t/t1410-reflog.sh +++ b/t/t1410-reflog.sh @@ -54,7 +54,6 @@ check_dont_have () { } test_expect_success setup ' - test_oid_init && mkdir -p A/B && echo rat >C && echo ox >A/D && diff --git a/t/t1450-fsck.sh b/t/t1450-fsck.sh index 344a2aad82..b17f5c21fb 100755 --- a/t/t1450-fsck.sh +++ b/t/t1450-fsck.sh @@ -9,7 +9,6 @@ test_description='git fsck random collection of tests . ./test-lib.sh test_expect_success setup ' - test_oid_init && git config gc.auto 0 && git config i18n.commitencoding ISO-8859-1 && test_commit A fileA one && @@ -714,7 +713,7 @@ test_expect_success 'fsck fails on corrupt packfile' ' # at least one of which is not zero, so setting the first byte to 0 is # sufficient.) chmod a+w .git/objects/pack/pack-$pack.pack && - printf '\0' | dd of=.git/objects/pack/pack-$pack.pack bs=1 conv=notrunc seek=12 && + printf "\0" | dd of=.git/objects/pack/pack-$pack.pack bs=1 conv=notrunc seek=12 && test_when_finished "rm -f .git/objects/pack/pack-$pack.*" && remove_object $hsh && diff --git a/t/t1500-rev-parse.sh b/t/t1500-rev-parse.sh index 603019b541..408b97d5af 100755 --- a/t/t1500-rev-parse.sh +++ b/t/t1500-rev-parse.sh @@ -59,7 +59,6 @@ test_rev_parse () { ROOT=$(pwd) test_expect_success 'setup' ' - test_oid_init && mkdir -p sub/dir work && cp -R .git repo.git ' diff --git a/t/t1507-rev-parse-upstream.sh b/t/t1507-rev-parse-upstream.sh index f213aa8053..dfc0d96d8a 100755 --- a/t/t1507-rev-parse-upstream.sh +++ b/t/t1507-rev-parse-upstream.sh @@ -137,7 +137,7 @@ test_expect_success 'merge my-side@{u} records the correct name' ' git branch -t new my-side@{u} && git merge -s ours new@{u} && git show -s --pretty=tformat:%s >actual && - echo "Merge remote-tracking branch ${SQ}origin/side${SQ} into master" >expect && + echo "Merge remote-tracking branch ${SQ}origin/side${SQ}" >expect && test_cmp expect actual ) ' diff --git a/t/t3305-notes-fanout.sh b/t/t3305-notes-fanout.sh index 3b4753e1b4..94c1b02251 100755 --- a/t/t3305-notes-fanout.sh +++ b/t/t3305-notes-fanout.sh @@ -7,7 +7,7 @@ test_description='Test that adding/removing many notes triggers automatic fanout path_has_fanout() { path=$1 && fanout=$2 && - after_last_slash=$((40 - $fanout * 2)) && + after_last_slash=$(($(test_oid hexsz) - $fanout * 2)) && echo $path | grep -q "^\([0-9a-f]\{2\}/\)\{$fanout\}[0-9a-f]\{$after_last_slash\}$" } diff --git a/t/t3308-notes-merge.sh b/t/t3308-notes-merge.sh index 790e292966..d69c84c640 100755 --- a/t/t3308-notes-merge.sh +++ b/t/t3308-notes-merge.sh @@ -22,7 +22,6 @@ test_expect_success setup ' # Copy notes to remote-notes git fetch . refs/notes/*:refs/remote-notes/origin/* && - test_oid_init && test_oid_cache <<-EOF hash4a sha1:5e93d24084d32e1cb61f7070505b9d2530cca987 hash3a sha1:8366731eeee53787d2bdf8fc1eff7d94757e8da0 diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh index 4a7d21f898..9744e88760 100755 --- a/t/t3404-rebase-interactive.sh +++ b/t/t3404-rebase-interactive.sh @@ -1250,7 +1250,7 @@ test_expect_success 'rebase -i error on commits with \ in message' ' test_expect_code 1 grep " emp" error ' -test_expect_success SHA1 'short SHA-1 setup' ' +test_expect_success 'short commit ID setup' ' test_when_finished "git checkout master" && git checkout --orphan collide && git rm -rf . && @@ -1262,23 +1262,54 @@ test_expect_success SHA1 'short SHA-1 setup' ' ) ' -test_expect_success SHA1 'short SHA-1 collide' ' +if test -n "$GIT_TEST_FIND_COLLIDER" +then + author="$(unset test_tick; test_tick; git var GIT_AUTHOR_IDENT)" + committer="$(unset test_tick; test_tick; git var GIT_COMMITTER_IDENT)" + blob="$(git rev-parse collide2:collide)" + from="$(git rev-parse collide1^0)" + repl="commit refs/heads/collider-&\\n" + repl="${repl}author $author\\ncommitter $committer\\n" + repl="${repl}data <<EOF\\ncollide2 &\\nEOF\\n" + repl="${repl}from $from\\nM 100644 $blob collide\\n" + test_seq 1 32768 | sed "s|.*|$repl|" >script && + git fast-import <script && + git pack-refs && + git for-each-ref >refs && + grep "^$(test_oid t3404_collision)" <refs >matches && + cat matches && + test_line_count -gt 2 matches || { + echo "Could not find a collider" >&2 + exit 1 + } +fi + +test_expect_success 'short commit ID collide' ' + test_oid_cache <<-EOF && + # collision-related constants + t3404_collision sha1:6bcd + t3404_collision sha256:0161 + t3404_collider sha1:ac4f2ee + t3404_collider sha256:16697 + EOF test_when_finished "reset_rebase && git checkout master" && git checkout collide && - colliding_sha1=6bcda37 && - test $colliding_sha1 = "$(git rev-parse HEAD | cut -c 1-7)" && + colliding_id=$(test_oid t3404_collision) && + hexsz=$(test_oid hexsz) && + test $colliding_id = "$(git rev-parse HEAD | cut -c 1-4)" && + test_config core.abbrev 4 && ( unset test_tick && test_tick && set_fake_editor && - FAKE_COMMIT_MESSAGE="collide2 ac4f2ee" \ + FAKE_COMMIT_MESSAGE="collide2 $(test_oid t3404_collider)" \ FAKE_LINES="reword 1 break 2" git rebase -i HEAD~2 && - test $colliding_sha1 = "$(git rev-parse HEAD | cut -c 1-7)" && - grep "^pick $colliding_sha1 " \ + test $colliding_id = "$(git rev-parse HEAD | cut -c 1-4)" && + grep "^pick $colliding_id " \ .git/rebase-merge/git-rebase-todo.tmp && - grep "^pick [0-9a-f]\{40\}" \ + grep "^pick [0-9a-f]\{$hexsz\}" \ .git/rebase-merge/git-rebase-todo && - grep "^pick [0-9a-f]\{40\}" \ + grep "^pick [0-9a-f]\{$hexsz\}" \ .git/rebase-merge/git-rebase-todo.backup && git rebase --continue ) && diff --git a/t/t3432-rebase-fast-forward.sh b/t/t3432-rebase-fast-forward.sh index 6f0452c0ea..a29eda87e9 100755 --- a/t/t3432-rebase-fast-forward.sh +++ b/t/t3432-rebase-fast-forward.sh @@ -60,15 +60,16 @@ test_rebase_same_head_ () { fi && oldhead=\$(git rev-parse HEAD) && test_when_finished 'git reset --hard \$oldhead' && - cp .git/logs/HEAD expect && + git reflog HEAD >expect && git rebase$flag $* >stdout && + git reflog HEAD >actual && if test $what = work then old=\$(wc -l <expect) && - test_line_count '-gt' \$old .git/logs/HEAD + test_line_count '-gt' \$old actual elif test $what = noop then - test_cmp expect .git/logs/HEAD + test_cmp expect actual fi && newhead=\$(git rev-parse HEAD) && if test $cmp = same diff --git a/t/t3600-rm.sh b/t/t3600-rm.sh index f2c0168941..efec8d13b6 100755 --- a/t/t3600-rm.sh +++ b/t/t3600-rm.sh @@ -241,7 +241,6 @@ test_expect_success 'refresh index before checking if it is up-to-date' ' ' test_expect_success 'choking "git rm" should not let it die with cruft' ' - test_oid_init && git reset -q --hard && test_when_finished "rm -f .git/index.lock && git reset -q --hard" && i=0 && diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh index 49decbac71..fb73a847cb 100755 --- a/t/t3701-add-interactive.sh +++ b/t/t3701-add-interactive.sh @@ -31,7 +31,16 @@ diff_cmp () { # indicates a dumb terminal, so we set that variable, too. force_color () { - env GIT_PAGER_IN_USE=true TERM=vt100 "$@" + # The first element of $@ may be a shell function, as a result POSIX + # does not guarantee that "one-shot assignment" will not persist after + # the function call. Thus, we prevent these variables from escaping + # this function's context with this subshell. + ( + GIT_PAGER_IN_USE=true && + TERM=vt100 && + export GIT_PAGER_IN_USE TERM && + "$@" + ) } test_expect_success 'setup (initial)' ' @@ -604,7 +613,7 @@ test_expect_success 'detect bogus diffFilter output' ' echo content >test && test_config interactive.diffFilter "sed 1d" && printf y >y && - test_must_fail force_color git add -p <y + force_color test_must_fail git add -p <y ' test_expect_success 'diff.algorithm is passed to `git diff-files`' ' diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh index 64dcc5ec28..d696aa4e52 100755 --- a/t/t3800-mktag.sh +++ b/t/t3800-mktag.sh @@ -23,7 +23,6 @@ check_verify_failure () { # first create a commit, so we have a valid object/type # for the tag. test_expect_success 'setup' ' - test_oid_init && echo Hello >A && git update-index --add A && git commit -m "Initial commit" && diff --git a/t/t4002-diff-basic.sh b/t/t4002-diff-basic.sh index cbcdd10464..6a9f010197 100755 --- a/t/t4002-diff-basic.sh +++ b/t/t4002-diff-basic.sh @@ -10,8 +10,6 @@ test_description='Test diff raw-output. . "$TEST_DIRECTORY"/lib-read-tree-m-3way.sh -test_oid_init - test_oid_cache <<\EOF aa_1 sha1:ccba72ad3888a3520b39efcf780b9ee64167535d aa_1 sha256:9febfbf18197819b2735c45291f138525d2476d59470f98239647544586ba403 diff --git a/t/t4010-diff-pathspec.sh b/t/t4010-diff-pathspec.sh index e5ca359edf..65cc703c65 100755 --- a/t/t4010-diff-pathspec.sh +++ b/t/t4010-diff-pathspec.sh @@ -125,7 +125,9 @@ test_expect_success 'setup submodules' ' test_expect_success 'diff-tree ignores trailing slash on submodule path' ' git diff --name-only HEAD^ HEAD submod >expect && git diff --name-only HEAD^ HEAD submod/ >actual && - test_cmp expect actual + test_cmp expect actual && + git diff --name-only HEAD^ HEAD -- submod/whatever >actual && + test_must_be_empty actual ' test_expect_success 'diff multiple wildcard pathspecs' ' diff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh index 43267d6024..3f60f7d96c 100755 --- a/t/t4013-diff-various.sh +++ b/t/t4013-diff-various.sh @@ -117,12 +117,12 @@ test_expect_success setup ' : <<\EOF ! [initial] Initial - * [master] Merge branch 'side' into master + * [master] Merge branch 'side' ! [rearrange] Rearranged lines in dir/sub ! [side] Side ---- + [rearrange] Rearranged lines in dir/sub - - [master] Merge branch 'side' into master + - [master] Merge branch 'side' * + [side] Side * [master^] Third * [master~2] Second diff --git a/t/t4013/diff.log_--decorate=full_--all b/t/t4013/diff.log_--decorate=full_--all index c56783b985..3f9b872ece 100644 --- a/t/t4013/diff.log_--decorate=full_--all +++ b/t/t4013/diff.log_--decorate=full_--all @@ -31,7 +31,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <author@example.com> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' into master + Merge branch 'side' commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a (refs/heads/side) Author: A U Thor <author@example.com> diff --git a/t/t4013/diff.log_--decorate_--all b/t/t4013/diff.log_--decorate_--all index 1cbdc038f4..f5e20e1e14 100644 --- a/t/t4013/diff.log_--decorate_--all +++ b/t/t4013/diff.log_--decorate_--all @@ -31,7 +31,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <author@example.com> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' into master + Merge branch 'side' commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a (side) Author: A U Thor <author@example.com> diff --git a/t/t4013/diff.log_--patch-with-stat_--summary_master_--_dir_ b/t/t4013/diff.log_--patch-with-stat_--summary_master_--_dir_ index f5b1b6516b..a18f1472a9 100644 --- a/t/t4013/diff.log_--patch-with-stat_--summary_master_--_dir_ +++ b/t/t4013/diff.log_--patch-with-stat_--summary_master_--_dir_ @@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <author@example.com> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' into master + Merge branch 'side' commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a Author: A U Thor <author@example.com> diff --git a/t/t4013/diff.log_--patch-with-stat_master b/t/t4013/diff.log_--patch-with-stat_master index af23803cdc..ae425c4672 100644 --- a/t/t4013/diff.log_--patch-with-stat_master +++ b/t/t4013/diff.log_--patch-with-stat_master @@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <author@example.com> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' into master + Merge branch 'side' commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a Author: A U Thor <author@example.com> diff --git a/t/t4013/diff.log_--patch-with-stat_master_--_dir_ b/t/t4013/diff.log_--patch-with-stat_master_--_dir_ index 814098fbf8..d5207cadf4 100644 --- a/t/t4013/diff.log_--patch-with-stat_master_--_dir_ +++ b/t/t4013/diff.log_--patch-with-stat_master_--_dir_ @@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <author@example.com> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' into master + Merge branch 'side' commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a Author: A U Thor <author@example.com> diff --git a/t/t4013/diff.log_--root_--cc_--patch-with-stat_--summary_master b/t/t4013/diff.log_--root_--cc_--patch-with-stat_--summary_master index b927fe4a98..0fc1e8cd71 100644 --- a/t/t4013/diff.log_--root_--cc_--patch-with-stat_--summary_master +++ b/t/t4013/diff.log_--root_--cc_--patch-with-stat_--summary_master @@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <author@example.com> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' into master + Merge branch 'side' dir/sub | 2 ++ file0 | 3 +++ diff --git a/t/t4013/diff.log_--root_--patch-with-stat_--summary_master b/t/t4013/diff.log_--root_--patch-with-stat_--summary_master index 6db3cea329..dffc09dde9 100644 --- a/t/t4013/diff.log_--root_--patch-with-stat_--summary_master +++ b/t/t4013/diff.log_--root_--patch-with-stat_--summary_master @@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <author@example.com> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' into master + Merge branch 'side' commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a Author: A U Thor <author@example.com> diff --git a/t/t4013/diff.log_--root_--patch-with-stat_master b/t/t4013/diff.log_--root_--patch-with-stat_master index 98e9c320c3..55aa98012d 100644 --- a/t/t4013/diff.log_--root_--patch-with-stat_master +++ b/t/t4013/diff.log_--root_--patch-with-stat_master @@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <author@example.com> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' into master + Merge branch 'side' commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a Author: A U Thor <author@example.com> diff --git a/t/t4013/diff.log_--root_-c_--patch-with-stat_--summary_master b/t/t4013/diff.log_--root_-c_--patch-with-stat_--summary_master index b61b1117ae..019d85f7de 100644 --- a/t/t4013/diff.log_--root_-c_--patch-with-stat_--summary_master +++ b/t/t4013/diff.log_--root_-c_--patch-with-stat_--summary_master @@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <author@example.com> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' into master + Merge branch 'side' dir/sub | 2 ++ file0 | 3 +++ diff --git a/t/t4013/diff.log_--root_-p_master b/t/t4013/diff.log_--root_-p_master index 345bd9e8a9..b42c334439 100644 --- a/t/t4013/diff.log_--root_-p_master +++ b/t/t4013/diff.log_--root_-p_master @@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <author@example.com> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' into master + Merge branch 'side' commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a Author: A U Thor <author@example.com> diff --git a/t/t4013/diff.log_--root_master b/t/t4013/diff.log_--root_master index db56b1fe6b..e8f46159da 100644 --- a/t/t4013/diff.log_--root_master +++ b/t/t4013/diff.log_--root_master @@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <author@example.com> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' into master + Merge branch 'side' commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a Author: A U Thor <author@example.com> diff --git a/t/t4013/diff.log_-m_-p_--first-parent_master b/t/t4013/diff.log_-m_-p_--first-parent_master index bcadb50e26..7a0073f529 100644 --- a/t/t4013/diff.log_-m_-p_--first-parent_master +++ b/t/t4013/diff.log_-m_-p_--first-parent_master @@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <author@example.com> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' into master + Merge branch 'side' diff --git a/dir/sub b/dir/sub index cead32e..992913c 100644 diff --git a/t/t4013/diff.log_-m_-p_master b/t/t4013/diff.log_-m_-p_master index 2acf43a9fb..9ca62a01ed 100644 --- a/t/t4013/diff.log_-m_-p_master +++ b/t/t4013/diff.log_-m_-p_master @@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <author@example.com> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' into master + Merge branch 'side' diff --git a/dir/sub b/dir/sub index cead32e..992913c 100644 @@ -33,7 +33,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <author@example.com> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' into master + Merge branch 'side' diff --git a/dir/sub b/dir/sub index 7289e35..992913c 100644 diff --git a/t/t4013/diff.log_-p_--first-parent_master b/t/t4013/diff.log_-p_--first-parent_master index c6a5876d80..3fc896d424 100644 --- a/t/t4013/diff.log_-p_--first-parent_master +++ b/t/t4013/diff.log_-p_--first-parent_master @@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <author@example.com> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' into master + Merge branch 'side' commit 9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0 Author: A U Thor <author@example.com> diff --git a/t/t4013/diff.log_-p_master b/t/t4013/diff.log_-p_master index 1841cded94..bf1326dc36 100644 --- a/t/t4013/diff.log_-p_master +++ b/t/t4013/diff.log_-p_master @@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <author@example.com> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' into master + Merge branch 'side' commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a Author: A U Thor <author@example.com> diff --git a/t/t4013/diff.log_master b/t/t4013/diff.log_master index f8ec445eb3..a8f6ce5abd 100644 --- a/t/t4013/diff.log_master +++ b/t/t4013/diff.log_master @@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <author@example.com> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' into master + Merge branch 'side' commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a Author: A U Thor <author@example.com> diff --git a/t/t4013/diff.show_--first-parent_master b/t/t4013/diff.show_--first-parent_master index 94548f4598..3dcbe473a0 100644 --- a/t/t4013/diff.show_--first-parent_master +++ b/t/t4013/diff.show_--first-parent_master @@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <author@example.com> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' into master + Merge branch 'side' diff --git a/dir/sub b/dir/sub index cead32e..992913c 100644 diff --git a/t/t4013/diff.show_-c_master b/t/t4013/diff.show_-c_master index 1c46ed64fd..81aba8da96 100644 --- a/t/t4013/diff.show_-c_master +++ b/t/t4013/diff.show_-c_master @@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <author@example.com> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' into master + Merge branch 'side' diff --combined dir/sub index cead32e,7289e35..992913c diff --git a/t/t4013/diff.show_-m_master b/t/t4013/diff.show_-m_master index 7559fc22f8..4ea2ee453d 100644 --- a/t/t4013/diff.show_-m_master +++ b/t/t4013/diff.show_-m_master @@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <author@example.com> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' into master + Merge branch 'side' diff --git a/dir/sub b/dir/sub index cead32e..992913c 100644 @@ -33,7 +33,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <author@example.com> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' into master + Merge branch 'side' diff --git a/dir/sub b/dir/sub index 7289e35..992913c 100644 diff --git a/t/t4013/diff.show_master b/t/t4013/diff.show_master index 57091c5d90..fb08ce0e46 100644 --- a/t/t4013/diff.show_master +++ b/t/t4013/diff.show_master @@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <author@example.com> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' into master + Merge branch 'side' diff --cc dir/sub index cead32e,7289e35..992913c diff --git a/t/t4013/diff.whatchanged_--root_--cc_--patch-with-stat_--summary_master b/t/t4013/diff.whatchanged_--root_--cc_--patch-with-stat_--summary_master index 5f13a71bb5..30aae7817b 100644 --- a/t/t4013/diff.whatchanged_--root_--cc_--patch-with-stat_--summary_master +++ b/t/t4013/diff.whatchanged_--root_--cc_--patch-with-stat_--summary_master @@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <author@example.com> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' into master + Merge branch 'side' dir/sub | 2 ++ file0 | 3 +++ diff --git a/t/t4013/diff.whatchanged_--root_-c_--patch-with-stat_--summary_master b/t/t4013/diff.whatchanged_--root_-c_--patch-with-stat_--summary_master index 8acb88267b..d1d32bd34c 100644 --- a/t/t4013/diff.whatchanged_--root_-c_--patch-with-stat_--summary_master +++ b/t/t4013/diff.whatchanged_--root_-c_--patch-with-stat_--summary_master @@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <author@example.com> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' into master + Merge branch 'side' dir/sub | 2 ++ file0 | 3 +++ diff --git a/t/t4027-diff-submodule.sh b/t/t4027-diff-submodule.sh index e29deaf4a5..d7145ccca4 100755 --- a/t/t4027-diff-submodule.sh +++ b/t/t4027-diff-submodule.sh @@ -6,7 +6,6 @@ test_description='difference in submodules' . "$TEST_DIRECTORY"/diff-lib.sh test_expect_success setup ' - test_oid_init && test_tick && test_create_repo sub && ( diff --git a/t/t4134-apply-submodule.sh b/t/t4134-apply-submodule.sh index 99ed4cc546..d1c16ba33c 100755 --- a/t/t4134-apply-submodule.sh +++ b/t/t4134-apply-submodule.sh @@ -8,7 +8,6 @@ test_description='git apply submodule tests' . ./test-lib.sh test_expect_success setup ' - test_oid_init && cat > create-sm.patch <<EOF && diff --git a/dir/sm b/dir/sm new file mode 160000 diff --git a/t/t4200-rerere.sh b/t/t4200-rerere.sh index 831d424c47..d94d25e4f0 100755 --- a/t/t4200-rerere.sh +++ b/t/t4200-rerere.sh @@ -25,7 +25,6 @@ test_description='git rerere . ./test-lib.sh test_expect_success 'setup' ' - test_oid_init && cat >a1 <<-\EOF && Some title ========== diff --git a/t/t4202-log.sh b/t/t4202-log.sh index fd9af658af..a0930599aa 100755 --- a/t/t4202-log.sh +++ b/t/t4202-log.sh @@ -483,7 +483,7 @@ test_expect_success 'set up merge history' ' ' cat > expect <<\EOF -* Merge branch 'side' into master +* Merge branch 'side' |\ | * side-2 | * side-1 @@ -502,7 +502,7 @@ test_expect_success 'log --graph with merge' ' ' cat > expect <<\EOF -| | | * Merge branch 'side' into master +| | | * Merge branch 'side' | | | |\ | | | | * side-2 | | | | * side-1 @@ -521,7 +521,7 @@ test_expect_success 'log --graph --line-prefix="| | | " with merge' ' ' cat > expect.colors <<\EOF -* Merge branch 'side' into master +* Merge branch 'side' <BLUE>|<RESET><CYAN>\<RESET> <BLUE>|<RESET> * side-2 <BLUE>|<RESET> * side-1 @@ -555,7 +555,7 @@ cat > expect <<\EOF |\ Merge: A B | | Author: A U Thor <author@example.com> | | -| | Merge branch 'side' into master +| | Merge branch 'side' | | | * commit tags/side-2 | | Author: A U Thor <author@example.com> @@ -632,11 +632,11 @@ test_expect_success 'set up more tangled history' ' ' cat > expect <<\EOF -* Merge tag 'reach' into master +* Merge tag 'reach' |\ | \ | \ -*-. \ Merge tags 'octopus-a' and 'octopus-b' into master +*-. \ Merge tags 'octopus-a' and 'octopus-b' |\ \ \ * | | | seventh | | * | octopus-b @@ -646,14 +646,14 @@ cat > expect <<\EOF |/ / | * reach |/ -* Merge branch 'tangle' into master +* Merge branch 'tangle' |\ | * Merge branch 'side' (early part) into tangle | |\ | * \ Merge branch 'master' (early part) into tangle | |\ \ | * | | tangle-a -* | | | Merge branch 'side' into master +* | | | Merge branch 'side' |\ \ \ \ | * | | | side-2 | | |_|/ @@ -735,16 +735,16 @@ test_expect_success 'log.decorate configuration' ' test_expect_success 'decorate-refs with glob' ' cat >expect.decorate <<-\EOF && - Merge-tag-reach-into-master - Merge-tags-octopus-a-and-octopus-b-into-master + Merge-tag-reach + Merge-tags-octopus-a-and-octopus-b seventh octopus-b (octopus-b) octopus-a (octopus-a) reach EOF cat >expect.no-decorate <<-\EOF && - Merge-tag-reach-into-master - Merge-tags-octopus-a-and-octopus-b-into-master + Merge-tag-reach + Merge-tags-octopus-a-and-octopus-b seventh octopus-b octopus-a @@ -765,8 +765,8 @@ test_expect_success 'decorate-refs with glob' ' test_expect_success 'decorate-refs without globs' ' cat >expect.decorate <<-\EOF && - Merge-tag-reach-into-master - Merge-tags-octopus-a-and-octopus-b-into-master + Merge-tag-reach + Merge-tags-octopus-a-and-octopus-b seventh octopus-b octopus-a @@ -779,8 +779,8 @@ test_expect_success 'decorate-refs without globs' ' test_expect_success 'multiple decorate-refs' ' cat >expect.decorate <<-\EOF && - Merge-tag-reach-into-master - Merge-tags-octopus-a-and-octopus-b-into-master + Merge-tag-reach + Merge-tags-octopus-a-and-octopus-b seventh octopus-b (octopus-b) octopus-a (octopus-a) @@ -794,8 +794,8 @@ test_expect_success 'multiple decorate-refs' ' test_expect_success 'decorate-refs-exclude with glob' ' cat >expect.decorate <<-\EOF && - Merge-tag-reach-into-master (HEAD -> master) - Merge-tags-octopus-a-and-octopus-b-into-master + Merge-tag-reach (HEAD -> master) + Merge-tags-octopus-a-and-octopus-b seventh (tag: seventh) octopus-b (tag: octopus-b) octopus-a (tag: octopus-a) @@ -811,8 +811,8 @@ test_expect_success 'decorate-refs-exclude with glob' ' test_expect_success 'decorate-refs-exclude without globs' ' cat >expect.decorate <<-\EOF && - Merge-tag-reach-into-master (HEAD -> master) - Merge-tags-octopus-a-and-octopus-b-into-master + Merge-tag-reach (HEAD -> master) + Merge-tags-octopus-a-and-octopus-b seventh (tag: seventh) octopus-b (tag: octopus-b, octopus-b) octopus-a (tag: octopus-a, octopus-a) @@ -828,8 +828,8 @@ test_expect_success 'decorate-refs-exclude without globs' ' test_expect_success 'multiple decorate-refs-exclude' ' cat >expect.decorate <<-\EOF && - Merge-tag-reach-into-master (HEAD -> master) - Merge-tags-octopus-a-and-octopus-b-into-master + Merge-tag-reach (HEAD -> master) + Merge-tags-octopus-a-and-octopus-b seventh (tag: seventh) octopus-b (tag: octopus-b) octopus-a (tag: octopus-a) @@ -851,8 +851,8 @@ test_expect_success 'multiple decorate-refs-exclude' ' test_expect_success 'decorate-refs and decorate-refs-exclude' ' cat >expect.no-decorate <<-\EOF && - Merge-tag-reach-into-master (master) - Merge-tags-octopus-a-and-octopus-b-into-master + Merge-tag-reach (master) + Merge-tags-octopus-a-and-octopus-b seventh octopus-b octopus-a @@ -866,8 +866,8 @@ test_expect_success 'decorate-refs and decorate-refs-exclude' ' test_expect_success 'deocrate-refs and log.excludeDecoration' ' cat >expect.decorate <<-\EOF && - Merge-tag-reach-into-master (master) - Merge-tags-octopus-a-and-octopus-b-into-master + Merge-tag-reach (master) + Merge-tags-octopus-a-and-octopus-b seventh octopus-b (octopus-b) octopus-a (octopus-a) @@ -881,10 +881,10 @@ test_expect_success 'deocrate-refs and log.excludeDecoration' ' test_expect_success 'decorate-refs-exclude and simplify-by-decoration' ' cat >expect.decorate <<-\EOF && - Merge-tag-reach-into-master (HEAD -> master) + Merge-tag-reach (HEAD -> master) reach (tag: reach, reach) seventh (tag: seventh) - Merge-branch-tangle-into-master + Merge-branch-tangle Merge-branch-side-early-part-into-tangle (tangle) tangle-a (tag: tangle-a) EOF @@ -1068,7 +1068,7 @@ cat >expect <<\EOF |\ Merge: MERGE_PARENTS | | Author: A U Thor <author@example.com> | | -| | Merge branch 'tangle' into master +| | Merge branch 'tangle' | | | * commit COMMIT_OBJECT_NAME | |\ Merge: MERGE_PARENTS @@ -1102,7 +1102,7 @@ cat >expect <<\EOF |\ \ \ \ Merge: MERGE_PARENTS | | | | | Author: A U Thor <author@example.com> | | | | | -| | | | | Merge branch 'side' into master +| | | | | Merge branch 'side' | | | | | | * | | | commit COMMIT_OBJECT_NAME | | |_|/ Author: A U Thor <author@example.com> @@ -1343,7 +1343,7 @@ cat >expect <<\EOF *** |\ Merge: MERGE_PARENTS *** | | Author: A U Thor <author@example.com> *** | | -*** | | Merge branch 'tangle' into master +*** | | Merge branch 'tangle' *** | | *** | * commit COMMIT_OBJECT_NAME *** | |\ Merge: MERGE_PARENTS @@ -1377,7 +1377,7 @@ cat >expect <<\EOF *** |\ \ \ \ Merge: MERGE_PARENTS *** | | | | | Author: A U Thor <author@example.com> *** | | | | | -*** | | | | | Merge branch 'side' into master +*** | | | | | Merge branch 'side' *** | | | | | *** | * | | | commit COMMIT_OBJECT_NAME *** | | |_|/ Author: A U Thor <author@example.com> @@ -1540,8 +1540,8 @@ cat >expect <<-\EOF * reach | | A reach.t -* Merge branch 'tangle' into master -* Merge branch 'side' into master +* Merge branch 'tangle' +* Merge branch 'side' |\ | * side-2 | @@ -1562,8 +1562,8 @@ cat >expect <<-\EOF * reach | | reach.t -* Merge branch 'tangle' into master -* Merge branch 'side' into master +* Merge branch 'tangle' +* Merge branch 'side' |\ | * side-2 | diff --git a/t/t4211-line-log.sh b/t/t4211-line-log.sh index e186c83250..2d1d7b5d19 100755 --- a/t/t4211-line-log.sh +++ b/t/t4211-line-log.sh @@ -4,7 +4,6 @@ test_description='test log -L' . ./test-lib.sh test_expect_success 'setup (import history)' ' - test_oid_init && git fast-import < "$TEST_DIRECTORY"/t4211/history.export && git reset --hard ' diff --git a/t/t4216-log-bloom.sh b/t/t4216-log-bloom.sh index c855bcd3e7..c21cc160f3 100755 --- a/t/t4216-log-bloom.sh +++ b/t/t4216-log-bloom.sh @@ -60,7 +60,7 @@ setup () { test_bloom_filters_used () { log_args=$1 - bloom_trace_prefix="statistics:{\"filter_not_present\":0,\"zero_length_filter\":0,\"maybe\"" + bloom_trace_prefix="statistics:{\"filter_not_present\":0,\"maybe\"" setup "$log_args" && grep -q "$bloom_trace_prefix" "$TRASH_DIRECTORY/trace.perf" && test_cmp log_wo_bloom log_w_bloom && @@ -112,6 +112,10 @@ test_expect_success 'git log -- multiple path specs does not use Bloom filters' test_bloom_filters_not_used "-- file4 A/file1" ' +test_expect_success 'git log -- "." pathspec at root does not use Bloom filters' ' + test_bloom_filters_not_used "-- ." +' + test_expect_success 'git log with wildcard that resolves to a single path uses Bloom filters' ' test_bloom_filters_used "-- *4" && test_bloom_filters_used "-- *renamed" @@ -126,7 +130,7 @@ test_expect_success 'setup - add commit-graph to the chain without Bloom filters test_commit c14 A/anotherFile2 && test_commit c15 A/B/anotherFile2 && test_commit c16 A/B/C/anotherFile2 && - GIT_TEST_COMMIT_GRAPH_CHANGED_PATHS=0 git commit-graph write --reachable --split && + git commit-graph write --reachable --split --no-changed-paths && test_line_count = 2 .git/objects/info/commit-graphs/commit-graph-chain ' @@ -142,7 +146,7 @@ test_expect_success 'setup - add commit-graph to the chain with Bloom filters' ' test_bloom_filters_used_when_some_filters_are_missing () { log_args=$1 - bloom_trace_prefix="statistics:{\"filter_not_present\":3,\"zero_length_filter\":0,\"maybe\":8,\"definitely_not\":6" + bloom_trace_prefix="statistics:{\"filter_not_present\":3,\"maybe\":6,\"definitely_not\":8" setup "$log_args" && grep -q "$bloom_trace_prefix" "$TRASH_DIRECTORY/trace.perf" && test_cmp log_wo_bloom log_w_bloom @@ -152,4 +156,39 @@ test_expect_success 'Use Bloom filters if they exist in the latest but not all c test_bloom_filters_used_when_some_filters_are_missing "-- A/B" ' +test_expect_success 'persist filter settings' ' + test_when_finished rm -rf .git/objects/info/commit-graph* && + rm -rf .git/objects/info/commit-graph* && + GIT_TRACE2_EVENT="$(pwd)/trace2.txt" \ + GIT_TRACE2_EVENT_NESTING=5 \ + GIT_TEST_BLOOM_SETTINGS_NUM_HASHES=9 \ + GIT_TEST_BLOOM_SETTINGS_BITS_PER_ENTRY=15 \ + git commit-graph write --reachable --changed-paths && + grep "{\"hash_version\":1,\"num_hashes\":9,\"bits_per_entry\":15}" trace2.txt && + GIT_TRACE2_EVENT="$(pwd)/trace2-auto.txt" \ + GIT_TRACE2_EVENT_NESTING=5 \ + git commit-graph write --reachable --changed-paths && + grep "{\"hash_version\":1,\"num_hashes\":9,\"bits_per_entry\":15}" trace2-auto.txt +' + +test_expect_success 'correctly report changes over limit' ' + git init 513changes && + ( + cd 513changes && + for i in $(test_seq 1 513) + do + echo $i >file$i.txt || return 1 + done && + git add . && + git commit -m "files" && + git commit-graph write --reachable --changed-paths && + for i in $(test_seq 1 513) + do + git -c core.commitGraph=false log -- file$i.txt >expect && + git log -- file$i.txt >actual && + test_cmp expect actual || return 1 + done + ) +' + test_done diff --git a/t/t5300-pack-object.sh b/t/t5300-pack-object.sh index 746cdb626e..3d6a93343a 100755 --- a/t/t5300-pack-object.sh +++ b/t/t5300-pack-object.sh @@ -12,8 +12,7 @@ TRASH=$(pwd) test_expect_success \ 'setup' \ - 'test_oid_init && - rm -f .git/index* && + 'rm -f .git/index* && perl -e "print \"a\" x 4096;" > a && perl -e "print \"b\" x 4096;" > b && perl -e "print \"c\" x 4096;" > c && @@ -497,4 +496,40 @@ test_expect_success 'make sure index-pack detects the SHA1 collision (large blob ) ' +test_expect_success 'prefetch objects' ' + rm -rf server client && + + git init server && + test_config -C server uploadpack.allowanysha1inwant 1 && + test_config -C server uploadpack.allowfilter 1 && + test_config -C server protocol.version 2 && + + echo one >server/one && + git -C server add one && + git -C server commit -m one && + git -C server branch one_branch && + + echo two_a >server/two_a && + echo two_b >server/two_b && + git -C server add two_a two_b && + git -C server commit -m two && + + echo three >server/three && + git -C server add three && + git -C server commit -m three && + git -C server branch three_branch && + + # Clone, fetch "two" with blobs excluded, and re-push it. This requires + # the client to have the blobs of "two" - verify that these are + # prefetched in one batch. + git clone --filter=blob:none --single-branch -b one_branch \ + "file://$(pwd)/server" client && + test_config -C client protocol.version 2 && + TWO=$(git -C server rev-parse three_branch^) && + git -C client fetch --filter=blob:none origin "$TWO" && + GIT_TRACE_PACKET=$(pwd)/trace git -C client push origin "$TWO":refs/heads/two_branch && + grep "git> done" trace >donelines && + test_line_count = 1 donelines +' + test_done diff --git a/t/t5302-pack-index.sh b/t/t5302-pack-index.sh index 8981c9b90e..119494bd64 100755 --- a/t/t5302-pack-index.sh +++ b/t/t5302-pack-index.sh @@ -7,7 +7,6 @@ test_description='pack index with 64-bit offsets and object CRC' . ./test-lib.sh test_expect_success 'setup' ' - test_oid_init && rawsz=$(test_oid rawsz) && rm -rf .git && git init && diff --git a/t/t5308-pack-detect-duplicates.sh b/t/t5308-pack-detect-duplicates.sh index 6845c1f3c3..693b2411c8 100755 --- a/t/t5308-pack-detect-duplicates.sh +++ b/t/t5308-pack-detect-duplicates.sh @@ -4,23 +4,27 @@ test_description='handling of duplicate objects in incoming packfiles' . ./test-lib.sh . "$TEST_DIRECTORY"/lib-pack.sh -if ! test_have_prereq SHA1 -then - skip_all='not using SHA-1 for objects' - test_done -fi +test_expect_success 'setup' ' + test_oid_cache <<-EOF + lo_oid sha1:e68fe8129b546b101aee9510c5328e7f21ca1d18 + lo_oid sha256:471819e8c52bf11513f100b2810a8aa0622d5cd3d1c913758a071dd4b3bad8fe + + missing_oid sha1:e69d000000000000000000000000000000000000 + missing_oid sha256:4720000000000000000000000000000000000000000000000000000000000000 + EOF +' # The sha1s we have in our pack. It's important that these have the same # starting byte, so that they end up in the same fanout section of the index. # That lets us make sure we are exercising the binary search with both sets. -LO_SHA1=e68fe8129b546b101aee9510c5328e7f21ca1d18 -HI_SHA1=e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 +LO_SHA1=$(test_oid lo_oid) +HI_SHA1=$EMPTY_BLOB # And here's a "missing sha1" which will produce failed lookups. It must also # be in the same fanout section, and should be between the two (so that during # our binary search, we are sure to end up looking at one or the other of the # duplicate runs). -MISSING_SHA1='e69d000000000000000000000000000000000000' +MISSING_SHA1=$(test_oid missing_oid) # git will never intentionally create packfiles with # duplicate objects, so we have to construct them by hand. diff --git a/t/t5313-pack-bounds-checks.sh b/t/t5313-pack-bounds-checks.sh index 2a4557efc2..535313e4dc 100755 --- a/t/t5313-pack-bounds-checks.sh +++ b/t/t5313-pack-bounds-checks.sh @@ -45,7 +45,6 @@ extended_table () { } test_expect_success 'setup' ' - test_oid_init && test_oid_cache <<-EOF oid000 sha1:1485 oid000 sha256:4222 diff --git a/t/t5318-commit-graph.sh b/t/t5318-commit-graph.sh index 26f332d6a3..044cf8a3de 100755 --- a/t/t5318-commit-graph.sh +++ b/t/t5318-commit-graph.sh @@ -10,8 +10,7 @@ test_expect_success 'setup full repo' ' cd "$TRASH_DIRECTORY/full" && git init && git config core.commitGraph true && - objdir=".git/objects" && - test_oid_init + objdir=".git/objects" ' test_expect_success POSIXPERM 'tweak umask for modebit tests' ' @@ -476,7 +475,7 @@ corrupt_graph_verify() { cp $objdir/info/commit-graph commit-graph-pre-write-test fi && git status --short && - GIT_TEST_COMMIT_GRAPH_DIE_ON_LOAD=true git commit-graph write && + GIT_TEST_COMMIT_GRAPH_DIE_ON_PARSE=true git commit-graph write && chmod u+w $objdir/info/commit-graph && git commit-graph verify } @@ -529,7 +528,7 @@ test_expect_success 'detect bad hash version' ' ' test_expect_success 'detect low chunk count' ' - corrupt_graph_and_verify $GRAPH_BYTE_CHUNK_COUNT "\02" \ + corrupt_graph_and_verify $GRAPH_BYTE_CHUNK_COUNT "\01" \ "missing the .* chunk" ' @@ -615,7 +614,8 @@ test_expect_success 'detect invalid checksum hash' ' test_expect_success 'detect incorrect chunk count' ' corrupt_graph_and_verify $GRAPH_BYTE_CHUNK_COUNT "\377" \ - "chunk lookup table entry missing" $GRAPH_CHUNK_LOOKUP_OFFSET + "commit-graph file is too small to hold [0-9]* chunks" \ + $GRAPH_CHUNK_LOOKUP_OFFSET ' test_expect_success 'git fsck (checks commit-graph)' ' diff --git a/t/t5319-multi-pack-index.sh b/t/t5319-multi-pack-index.sh index 7214cab36c..7dfff0f8f4 100755 --- a/t/t5319-multi-pack-index.sh +++ b/t/t5319-multi-pack-index.sh @@ -29,7 +29,6 @@ midx_read_expect () { } test_expect_success 'setup' ' - test_oid_init && test_oid_cache <<-EOF idxoff sha1:2999 idxoff sha256:3739 diff --git a/t/t5324-split-commit-graph.sh b/t/t5324-split-commit-graph.sh index 269d0964a3..ea28d522b8 100755 --- a/t/t5324-split-commit-graph.sh +++ b/t/t5324-split-commit-graph.sh @@ -12,7 +12,6 @@ test_expect_success 'setup repo' ' git config gc.writeCommitGraph false && infodir=".git/objects/info" && graphdir="$infodir/commit-graphs" && - test_oid_init && test_oid_cache <<-EOM shallow sha1:1760 shallow sha256:2064 @@ -399,7 +398,7 @@ test_expect_success ULIMIT_FILE_DESCRIPTORS 'handles file descriptor exhaustion' for i in $(test_seq 64) do test_commit $i && - test_might_fail run_with_limited_open_files git commit-graph write \ + run_with_limited_open_files test_might_fail git commit-graph write \ --split=no-merge --reachable || return 1 done ) diff --git a/t/t5504-fetch-receive-strict.sh b/t/t5504-fetch-receive-strict.sh index a32efe2b6c..1a16ac4c0d 100755 --- a/t/t5504-fetch-receive-strict.sh +++ b/t/t5504-fetch-receive-strict.sh @@ -4,7 +4,6 @@ test_description='fetch/receive strict mode' . ./test-lib.sh test_expect_success 'setup and inject "corrupt or missing" object' ' - test_oid_init && echo hello >greetings && git add greetings && git commit -m greetings && diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh index a66dbe0bde..e567cba38d 100755 --- a/t/t5510-fetch.sh +++ b/t/t5510-fetch.sh @@ -281,15 +281,19 @@ test_expect_success 'create bundle 1' ' cd "$D" && echo >file updated again by origin && git commit -a -m "tip" && - git bundle create bundle1 master^..master + git bundle create --version=3 bundle1 master^..master ' test_expect_success 'header of bundle looks right' ' - head -n 4 "$D"/bundle1 && - head -n 1 "$D"/bundle1 | grep "^#" && - head -n 2 "$D"/bundle1 | grep "^-$OID_REGEX " && - head -n 3 "$D"/bundle1 | grep "^$OID_REGEX " && - head -n 4 "$D"/bundle1 | grep "^$" + cat >expect <<-EOF && + # v3 git bundle + @object-format=$(test_oid algo) + -OID updated by origin + OID refs/heads/master + + EOF + sed -e "s/$OID_REGEX/OID/g" -e "5q" "$D"/bundle1 >actual && + test_cmp expect actual ' test_expect_success 'create bundle 2' ' @@ -797,7 +801,7 @@ test_configured_prune true true unset unset pruned pruned \ "--prune origin refs/tags/*:refs/tags/* +refs/heads/*:refs/remotes/origin/*" # --prune-tags on its own does nothing, needs --prune as well, same -# for for fetch.pruneTags without fetch.prune +# for fetch.pruneTags without fetch.prune test_configured_prune unset unset unset unset kept kept "--prune-tags" test_configured_prune unset unset true unset kept kept "" test_configured_prune unset unset unset true kept kept "" diff --git a/t/t5530-upload-pack-error.sh b/t/t5530-upload-pack-error.sh index 4ce9a9f704..205a2631e7 100755 --- a/t/t5530-upload-pack-error.sh +++ b/t/t5530-upload-pack-error.sh @@ -14,7 +14,6 @@ corrupt_repo () { } test_expect_success 'setup and corrupt repository' ' - test_oid_init && echo file >file && git add file && git rev-parse :file && diff --git a/t/t5539-fetch-http-shallow.sh b/t/t5539-fetch-http-shallow.sh index c0d02dee89..82aa99ae87 100755 --- a/t/t5539-fetch-http-shallow.sh +++ b/t/t5539-fetch-http-shallow.sh @@ -9,10 +9,12 @@ start_httpd commit() { echo "$1" >tracked && git add tracked && + test_tick && git commit -m "$1" } test_expect_success 'setup shallow clone' ' + test_tick=1500000000 && commit 1 && commit 2 && commit 3 && @@ -48,7 +50,6 @@ EOF test_expect_success 'no shallow lines after receiving ACK ready' ' ( cd shallow && - test_tick && for i in $(test_seq 15) do git checkout --orphan unrelated$i && @@ -66,6 +67,7 @@ test_expect_success 'no shallow lines after receiving ACK ready' ' ( cd clone && git checkout --orphan newnew && + test_tick=1400000000 && test_commit new-too && # NEEDSWORK: If the overspecification of the expected result is reduced, we # might be able to run this test in all protocol versions. diff --git a/t/t5541-http-push-smart.sh b/t/t5541-http-push-smart.sh index 463d0f12e5..187454f5dd 100755 --- a/t/t5541-http-push-smart.sh +++ b/t/t5541-http-push-smart.sh @@ -479,6 +479,21 @@ test_expect_success 'clone/fetch scrubs password from reflogs' ' ! grep "$HTTPD_URL_USER_PASS" reflog ' +test_expect_success 'Non-ASCII branch name can be used with --force-with-lease' ' + cd "$ROOT_PATH" && + git clone "$HTTPD_URL_USER_PASS/smart/test_repo.git" non-ascii && + cd non-ascii && + git checkout -b rama-de-árbol && + test_commit F && + git push --force-with-lease origin rama-de-árbol && + git ls-remote origin refs/heads/rama-de-árbol >actual && + git ls-remote . refs/heads/rama-de-árbol >expect && + test_cmp expect actual && + git push --delete --force-with-lease origin rama-de-árbol && + git ls-remote origin refs/heads/rama-de-árbol >actual && + test_must_be_empty actual +' + test_expect_success 'colorize errors/hints' ' cd "$ROOT_PATH"/test_repo_clone && test_must_fail git -c color.transport=always -c color.advice=always \ diff --git a/t/t5562-http-backend-content-length.sh b/t/t5562-http-backend-content-length.sh index c6ec625497..e5d3d15ba8 100755 --- a/t/t5562-http-backend-content-length.sh +++ b/t/t5562-http-backend-content-length.sh @@ -46,7 +46,6 @@ ssize_b100dots() { } test_expect_success 'setup' ' - test_oid_init && HTTP_CONTENT_ENCODING="identity" && export HTTP_CONTENT_ENCODING && git config http.receivepack true && diff --git a/t/t5601-clone.sh b/t/t5601-clone.sh index 84ea2a3eb7..eb9a093e25 100755 --- a/t/t5601-clone.sh +++ b/t/t5601-clone.sh @@ -271,7 +271,9 @@ test_expect_success 'fetch from gitfile parent' ' test_expect_success 'clone separate gitdir where target already exists' ' rm -rf dst && - test_must_fail git clone --separate-git-dir realgitdir src dst + echo foo=bar >>realgitdir/config && + test_must_fail git clone --separate-git-dir realgitdir src dst && + grep foo=bar realgitdir/config ' test_expect_success 'clone --reference from original' ' diff --git a/t/t5607-clone-bundle.sh b/t/t5607-clone-bundle.sh index 6d5a977fcb..26985f4b44 100755 --- a/t/t5607-clone-bundle.sh +++ b/t/t5607-clone-bundle.sh @@ -4,6 +4,10 @@ test_description='some bundle related tests' . ./test-lib.sh test_expect_success 'setup' ' + test_oid_cache <<-EOF && + version sha1:2 + version sha256:3 + EOF test_commit initial && test_tick && git tag -m tag tag && @@ -94,4 +98,31 @@ test_expect_success 'fetch SHA-1 from bundle' ' git fetch --no-tags foo/tip.bundle "$(cat hash)" ' +test_expect_success 'git bundle uses expected default format' ' + git bundle create bundle HEAD^.. && + head -n1 bundle | grep "^# v$(test_oid version) git bundle$" +' + +test_expect_success 'git bundle v3 has expected contents' ' + git branch side HEAD && + git bundle create --version=3 bundle HEAD^..side && + head -n2 bundle >actual && + cat >expect <<-EOF && + # v3 git bundle + @object-format=$(test_oid algo) + EOF + test_cmp expect actual && + git bundle verify bundle +' + +test_expect_success 'git bundle v3 rejects unknown capabilities' ' + cat >new <<-EOF && + # v3 git bundle + @object-format=$(test_oid algo) + @unknown=silly + EOF + test_must_fail git bundle verify new 2>output && + test_i18ngrep "unknown capability .unknown=silly." output +' + test_done diff --git a/t/t5616-partial-clone.sh b/t/t5616-partial-clone.sh index 8a27452a51..37de0afb02 100755 --- a/t/t5616-partial-clone.sh +++ b/t/t5616-partial-clone.sh @@ -422,6 +422,44 @@ test_expect_success 'single-branch tag following respects partial clone' ' test_must_fail git -C single rev-parse --verify refs/tags/C ' +test_expect_success 'fetch from a partial clone, protocol v0' ' + rm -rf server client trace && + + # Pretend that the server is a partial clone + git init server && + git -C server remote add a_remote "file://$(pwd)/" && + test_config -C server core.repositoryformatversion 1 && + test_config -C server extensions.partialclone a_remote && + test_config -C server protocol.version 0 && + test_commit -C server foo && + + # Fetch from the server + git init client && + test_config -C client protocol.version 0 && + test_commit -C client bar && + GIT_TRACE_PACKET="$(pwd)/trace" git -C client fetch "file://$(pwd)/server" && + ! grep "version 2" trace +' + +test_expect_success 'fetch from a partial clone, protocol v2' ' + rm -rf server client trace && + + # Pretend that the server is a partial clone + git init server && + git -C server remote add a_remote "file://$(pwd)/" && + test_config -C server core.repositoryformatversion 1 && + test_config -C server extensions.partialclone a_remote && + test_config -C server protocol.version 2 && + test_commit -C server foo && + + # Fetch from the server + git init client && + test_config -C client protocol.version 2 && + test_commit -C client bar && + GIT_TRACE_PACKET="$(pwd)/trace" git -C client fetch "file://$(pwd)/server" && + grep "version 2" trace +' + . "$TEST_DIRECTORY"/lib-httpd.sh start_httpd diff --git a/t/t5702-protocol-v2.sh b/t/t5702-protocol-v2.sh index 1b54c35b01..5a60fbe3ed 100755 --- a/t/t5702-protocol-v2.sh +++ b/t/t5702-protocol-v2.sh @@ -13,7 +13,6 @@ start_git_daemon --export-all --enable=receive-pack daemon_parent=$GIT_DAEMON_DOCUMENT_ROOT_PATH/parent test_expect_success 'create repo to be served by git-daemon' ' - test_oid_init && git init "$daemon_parent" && test_commit -C "$daemon_parent" one ' @@ -829,7 +828,7 @@ test_expect_success 'part of packfile response provided as URI' ' # Ensure that my-blob and other-blob are in separate packfiles. for idx in http_child/.git/objects/pack/*.idx do - git verify-pack --verbose $idx >out && + git verify-pack --object-format=$(test_oid algo) --verbose $idx >out && { grep "^[0-9a-f]\{16,\} " out || : } >out.objectlist && diff --git a/t/t5703-upload-pack-ref-in-want.sh b/t/t5703-upload-pack-ref-in-want.sh index 748282f058..d9ecf0f4a9 100755 --- a/t/t5703-upload-pack-ref-in-want.sh +++ b/t/t5703-upload-pack-ref-in-want.sh @@ -43,7 +43,6 @@ write_command () { # \ | / # a test_expect_success 'setup repository' ' - test_oid_init && test_commit a && git checkout -b o/foo && test_commit b && diff --git a/t/t6000-rev-list-misc.sh b/t/t6000-rev-list-misc.sh index 3dc1ad8f71..3bb0e4ff8f 100755 --- a/t/t6000-rev-list-misc.sh +++ b/t/t6000-rev-list-misc.sh @@ -8,6 +8,7 @@ test_expect_success setup ' echo content1 >wanted_file && echo content2 >unwanted_file && git add wanted_file unwanted_file && + test_tick && git commit -m one ' @@ -21,6 +22,7 @@ test_expect_success 'rev-list --objects with pathspecs and deeper paths' ' mkdir foo && >foo/file && git add foo/file && + test_tick && git commit -m two && git rev-list --objects HEAD -- foo >output && @@ -69,6 +71,7 @@ test_expect_success '--no-object-names and --object-names are last-one-wins' ' ' test_expect_success 'rev-list A..B and rev-list ^A B are the same' ' + test_tick && git commit --allow-empty -m another && git tag -a -m "annotated" v1.0 && git rev-list --objects ^v1.0^ v1.0 >expect && @@ -84,10 +87,10 @@ test_expect_success 'propagate uninteresting flag down correctly' ' test_expect_success 'symleft flag bit is propagated down from tag' ' git log --format="%m %s" --left-right v1.0...master >actual && cat >expect <<-\EOF && - > two - > one < another < that + > two + > one EOF test_cmp expect actual ' diff --git a/t/t6006-rev-list-format.sh b/t/t6006-rev-list-format.sh index 7e82e43a63..bc95da8a5f 100755 --- a/t/t6006-rev-list-format.sh +++ b/t/t6006-rev-list-format.sh @@ -32,7 +32,6 @@ changed_iso88591=$(echo "$changed" | iconv -f utf-8 -t $test_encoding) truncate_count=20 test_expect_success 'setup' ' - test_oid_init && : >foo && git add foo && git config i18n.commitEncoding $test_encoding && diff --git a/t/t6038-merge-text-auto.sh b/t/t6038-merge-text-auto.sh index 5e8d5fa50c..89c86d4e56 100755 --- a/t/t6038-merge-text-auto.sh +++ b/t/t6038-merge-text-auto.sh @@ -158,7 +158,7 @@ test_expect_success 'Detect LF/CRLF conflict from addition of text=auto' ' compare_files expected file.fuzzy ' -test_expect_failure 'checkout -m after setting text=auto' ' +test_expect_success 'checkout -m after setting text=auto' ' cat <<-\EOF >expected && first line same line @@ -168,12 +168,12 @@ test_expect_failure 'checkout -m after setting text=auto' ' git rm -fr . && rm -f .gitattributes && git reset --hard initial && - git checkout a -- . && + git restore --source=a -- . && git checkout -m b && - compare_files expected file + git diff --no-index --ignore-cr-at-eol expected file ' -test_expect_failure 'checkout -m addition of text=auto' ' +test_expect_success 'checkout -m addition of text=auto' ' cat <<-\EOF >expected && first line same line @@ -183,23 +183,9 @@ test_expect_failure 'checkout -m addition of text=auto' ' git rm -fr . && rm -f .gitattributes file && git reset --hard initial && - git checkout b -- . && + git restore --source=b -- . && git checkout -m a && - compare_files expected file -' - -test_expect_failure 'cherry-pick patch from after text=auto was added' ' - append_cr <<-\EOF >expected && - first line - same line - EOF - - git config merge.renormalize true && - git rm -fr . && - git reset --hard b && - test_must_fail git cherry-pick a >err 2>&1 && - grep "[Nn]othing added" err && - compare_files expected file + git diff --no-index --ignore-cr-at-eol expected file ' test_expect_success 'Test delete/normalize conflict' ' diff --git a/t/t6046-merge-skip-unneeded-updates.sh b/t/t6046-merge-skip-unneeded-updates.sh index 1ddc9e6626..5a2d07e516 100755 --- a/t/t6046-merge-skip-unneeded-updates.sh +++ b/t/t6046-merge-skip-unneeded-updates.sh @@ -661,7 +661,7 @@ test_setup_4a () { } # NOTE: For as long as we continue using unpack_trees() without index_only -# set to true, it will error out on a case like this claiming the the locally +# set to true, it will error out on a case like this claiming that the locally # modified file would be overwritten by the merge. Getting this testcase # correct requires doing the merge in-memory first, then realizing that no # updates to the file are necessary, and thus that we can just leave the path diff --git a/t/t6100-rev-list-in-order.sh b/t/t6100-rev-list-in-order.sh index b2bb0a7f61..e934bc239c 100755 --- a/t/t6100-rev-list-in-order.sh +++ b/t/t6100-rev-list-in-order.sh @@ -22,7 +22,7 @@ test_expect_success 'setup a commit history with trees, blobs' ' test_expect_success 'rev-list --in-commit-order' ' git rev-list --in-commit-order --objects HEAD >actual.raw && - cut -c 1-40 >actual <actual.raw && + cut -d" " -f1 >actual <actual.raw && git cat-file --batch-check="%(objectname)" >expect.raw <<-\EOF && HEAD^{commit} @@ -49,7 +49,7 @@ test_expect_success 'rev-list --in-commit-order' ' test_expect_success 'rev-list lists blobs and trees after commits' ' git rev-list --objects HEAD >actual.raw && - cut -c 1-40 >actual <actual.raw && + cut -d" " -f1 >actual <actual.raw && git cat-file --batch-check="%(objectname)" >expect.raw <<-\EOF && HEAD^{commit} diff --git a/t/t6101-rev-parse-parents.sh b/t/t6101-rev-parse-parents.sh index 7683e4a114..7531262a5e 100755 --- a/t/t6101-rev-parse-parents.sh +++ b/t/t6101-rev-parse-parents.sh @@ -34,7 +34,7 @@ test_expect_success 'setup' ' ' test_expect_success 'start is valid' ' - git rev-parse start | grep "^[0-9a-f]\{40\}$" + git rev-parse start | grep "^$OID_REGEX$" ' test_expect_success 'start^0' ' diff --git a/t/t6200-fmt-merge-msg.sh b/t/t6200-fmt-merge-msg.sh index 2b3fd498d0..7d549748ef 100755 --- a/t/t6200-fmt-merge-msg.sh +++ b/t/t6200-fmt-merge-msg.sh @@ -79,7 +79,7 @@ test_expect_success GPG 'set up a signed tag' ' ' test_expect_success 'message for merging local branch' ' - echo "Merge branch ${apos}left${apos} into master" >expected && + echo "Merge branch ${apos}left${apos}" >expected && git checkout master && git fetch . left && @@ -107,7 +107,7 @@ test_expect_success GPG 'message for merging local tag signed by unknown key' ' ' test_expect_success 'message for merging external branch' ' - echo "Merge branch ${apos}left${apos} of $(pwd) into master" >expected && + echo "Merge branch ${apos}left${apos} of $(pwd)" >expected && git checkout master && git fetch "$(pwd)" left && @@ -118,7 +118,7 @@ test_expect_success 'message for merging external branch' ' test_expect_success '[merge] summary/log configuration' ' cat >expected <<-EOF && - Merge branch ${apos}left${apos} into master + Merge branch ${apos}left${apos} # By Another Author (3) and A U Thor (2) # Via Another Committer @@ -160,7 +160,7 @@ test_expect_success 'setup FETCH_HEAD' ' test_expect_success 'merge.log=3 limits shortlog length' ' cat >expected <<-EOF && - Merge branch ${apos}left${apos} into master + Merge branch ${apos}left${apos} # By Another Author (3) and A U Thor (2) # Via Another Committer @@ -177,7 +177,7 @@ test_expect_success 'merge.log=3 limits shortlog length' ' test_expect_success 'merge.log=5 shows all 5 commits' ' cat >expected <<-EOF && - Merge branch ${apos}left${apos} into master + Merge branch ${apos}left${apos} # By Another Author (3) and A U Thor (2) # Via Another Committer @@ -195,7 +195,7 @@ test_expect_success 'merge.log=5 shows all 5 commits' ' test_expect_success '--log=5 with custom comment character' ' cat >expected <<-EOF && - Merge branch ${apos}left${apos} into master + Merge branch ${apos}left${apos} x By Another Author (3) and A U Thor (2) x Via Another Committer @@ -212,14 +212,14 @@ test_expect_success '--log=5 with custom comment character' ' ' test_expect_success 'merge.log=0 disables shortlog' ' - echo "Merge branch ${apos}left${apos} into master" >expected && + echo "Merge branch ${apos}left${apos}" >expected && git -c merge.log=0 fmt-merge-msg <.git/FETCH_HEAD >actual && test_cmp expected actual ' test_expect_success '--log=3 limits shortlog length' ' cat >expected <<-EOF && - Merge branch ${apos}left${apos} into master + Merge branch ${apos}left${apos} # By Another Author (3) and A U Thor (2) # Via Another Committer @@ -236,7 +236,7 @@ test_expect_success '--log=3 limits shortlog length' ' test_expect_success '--log=5 shows all 5 commits' ' cat >expected <<-EOF && - Merge branch ${apos}left${apos} into master + Merge branch ${apos}left${apos} # By Another Author (3) and A U Thor (2) # Via Another Committer @@ -253,13 +253,13 @@ test_expect_success '--log=5 shows all 5 commits' ' ' test_expect_success '--no-log disables shortlog' ' - echo "Merge branch ${apos}left${apos} into master" >expected && + echo "Merge branch ${apos}left${apos}" >expected && git fmt-merge-msg --no-log <.git/FETCH_HEAD >actual && test_cmp expected actual ' test_expect_success '--log=0 disables shortlog' ' - echo "Merge branch ${apos}left${apos} into master" >expected && + echo "Merge branch ${apos}left${apos}" >expected && git fmt-merge-msg --no-log <.git/FETCH_HEAD >actual && test_cmp expected actual ' @@ -300,7 +300,7 @@ test_expect_success 'fmt-merge-msg -m' ' test_expect_success 'setup: expected shortlog for two branches' ' cat >expected <<-EOF - Merge branches ${apos}left${apos} and ${apos}right${apos} into master + Merge branches ${apos}left${apos} and ${apos}right${apos} # By Another Author (3) and A U Thor (2) # Via Another Committer @@ -397,7 +397,7 @@ test_expect_success 'merge-msg with nothing to merge' ' test_expect_success 'merge-msg tag' ' cat >expected <<-EOF && - Merge tag ${apos}tag-r3${apos} into master + Merge tag ${apos}tag-r3${apos} * tag ${apos}tag-r3${apos}: Right #3 @@ -418,7 +418,7 @@ test_expect_success 'merge-msg tag' ' test_expect_success 'merge-msg two tags' ' cat >expected <<-EOF && - Merge tags ${apos}tag-r3${apos} and ${apos}tag-l5${apos} into master + Merge tags ${apos}tag-r3${apos} and ${apos}tag-l5${apos} * tag ${apos}tag-r3${apos}: Right #3 @@ -448,7 +448,7 @@ test_expect_success 'merge-msg two tags' ' test_expect_success 'merge-msg tag and branch' ' cat >expected <<-EOF && - Merge branch ${apos}left${apos}, tag ${apos}tag-r3${apos} into master + Merge branch ${apos}left${apos}, tag ${apos}tag-r3${apos} * tag ${apos}tag-r3${apos}: Right #3 @@ -479,7 +479,7 @@ test_expect_success 'merge-msg tag and branch' ' test_expect_success 'merge-msg lots of commits' ' { cat <<-EOF && - Merge branch ${apos}long${apos} into master + Merge branch ${apos}long${apos} * long: (35 commits) EOF @@ -516,7 +516,7 @@ test_expect_success 'merge-msg with "merging" an annotated tag' ' git fmt-merge-msg <.git/FETCH_HEAD >actual && { cat <<-\EOF - Merge tag '\''annote'\'' into master + Merge tag '\''annote'\'' An annotated one @@ -531,7 +531,7 @@ test_expect_success 'merge-msg with "merging" an annotated tag' ' git merge --no-commit --no-ff $annote && { cat <<-EOF - Merge tag '\''$annote'\'' into master + Merge tag '\''$annote'\'' An annotated one @@ -542,4 +542,24 @@ test_expect_success 'merge-msg with "merging" an annotated tag' ' test_cmp expected .git/MERGE_MSG ' +test_expect_success 'merge.suppressDest configuration' ' + git checkout -B side master && + git commit --allow-empty -m "One step ahead" && + git checkout master && + git fetch . side && + + git -c merge.suppressDest="" fmt-merge-msg <.git/FETCH_HEAD >full.1 && + head -n1 full.1 >actual && + grep -e "Merge branch .side. into master" actual && + + git -c merge.suppressDest="mast" fmt-merge-msg <.git/FETCH_HEAD >full.2 && + head -n1 full.2 >actual && + grep -e "Merge branch .side. into master$" actual && + + git -c merge.suppressDest="ma??er" fmt-merge-msg <.git/FETCH_HEAD >full.3 && + head -n1 full.3 >actual && + grep -e "Merge branch .side." actual && + ! grep -e " into master$" actual +' + test_done diff --git a/t/t6300-for-each-ref.sh b/t/t6300-for-each-ref.sh index da59fadc5d..a83579fbdf 100755 --- a/t/t6300-for-each-ref.sh +++ b/t/t6300-for-each-ref.sh @@ -52,6 +52,25 @@ test_atom() { sanitize_pgp <actual >actual.clean && test_cmp expected actual.clean " + # Automatically test "contents:size" atom after testing "contents" + if test "$2" = "contents" + then + case $(git cat-file -t "$ref") in + tag) + # We cannot use $3 as it expects sanitize_pgp to run + expect=$(git cat-file tag $ref | tail -n +6 | wc -c) ;; + tree | blob) + expect='' ;; + commit) + expect=$(printf '%s' "$3" | wc -c) ;; + esac + # Leave $expect unquoted to lose possible leading whitespaces + echo $expect >expected + test_expect_${4:-success} $PREREQ "basic atom: $1 contents:size" ' + git for-each-ref --format="%(contents:size)" "$ref" >actual && + test_cmp expected actual + ' + fi } hexlen=$(test_oid hexsz) @@ -650,6 +669,25 @@ test_atom refs/tags/signed-long contents "subject line body contents $sig" +test_expect_success 'set up refs pointing to tree and blob' ' + git update-ref refs/mytrees/first refs/heads/master^{tree} && + git update-ref refs/myblobs/first refs/heads/master:one +' + +test_atom refs/mytrees/first subject "" +test_atom refs/mytrees/first contents:subject "" +test_atom refs/mytrees/first body "" +test_atom refs/mytrees/first contents:body "" +test_atom refs/mytrees/first contents:signature "" +test_atom refs/mytrees/first contents "" + +test_atom refs/myblobs/first subject "" +test_atom refs/myblobs/first contents:subject "" +test_atom refs/myblobs/first body "" +test_atom refs/myblobs/first contents:body "" +test_atom refs/myblobs/first contents:signature "" +test_atom refs/myblobs/first contents "" + test_expect_success 'set up multiple-sort tags' ' for when in 100000 200000 do diff --git a/t/t6301-for-each-ref-errors.sh b/t/t6301-for-each-ref-errors.sh index 49cc65bb58..809854fc0c 100755 --- a/t/t6301-for-each-ref-errors.sh +++ b/t/t6301-for-each-ref-errors.sh @@ -5,9 +5,9 @@ test_description='for-each-ref errors for broken refs' . ./test-lib.sh ZEROS=$ZERO_OID -MISSING=abababababababababababababababababababab test_expect_success setup ' + MISSING=$(test_oid deadbeef) && git commit --allow-empty -m "Initial" && git tag testtag && git for-each-ref >full-list && diff --git a/t/t6500-gc.sh b/t/t6500-gc.sh index 0a69a67117..4a3b8f48ac 100755 --- a/t/t6500-gc.sh +++ b/t/t6500-gc.sh @@ -10,7 +10,24 @@ test_expect_success 'setup' ' # do not let the amount of physical memory affects gc # behavior, make sure we always pack everything to one pack by # default - git config gc.bigPackThreshold 2g + git config gc.bigPackThreshold 2g && + + # These are simply values which, when hashed as a blob with a newline, + # produce a hash where the first byte is 0x17 in their respective + # algorithms. + test_oid_cache <<-EOF + obj1 sha1:263 + obj1 sha256:34 + + obj2 sha1:410 + obj2 sha256:174 + + obj3 sha1:523 + obj3 sha256:313 + + obj4 sha1:790 + obj4 sha256:481 + EOF ' test_expect_success 'gc empty repository' ' @@ -85,13 +102,13 @@ test_expect_success 'auto gc with too many loose objects does not attempt to cre # We need to create two object whose sha1s start with 17 # since this is what git gc counts. As it happens, these # two blobs will do so. - test_commit 263 && - test_commit 410 && + test_commit "$(test_oid obj1)" && + test_commit "$(test_oid obj2)" && # Our first gc will create a pack; our second will create a second pack git gc --auto && ls .git/objects/pack | sort >existing_packs && - test_commit 523 && - test_commit 790 && + test_commit "$(test_oid obj3)" && + test_commit "$(test_oid obj4)" && git gc --auto 2>err && test_i18ngrep ! "^warning:" err && diff --git a/t/t6501-freshen-objects.sh b/t/t6501-freshen-objects.sh index f30b4849b6..8a3bb4105b 100755 --- a/t/t6501-freshen-objects.sh +++ b/t/t6501-freshen-objects.sh @@ -128,9 +128,9 @@ for repack in '' true; do done test_expect_success 'do not complain about existing broken links (commit)' ' - cat >broken-commit <<-\EOF && - tree 0000000000000000000000000000000000000001 - parent 0000000000000000000000000000000000000002 + cat >broken-commit <<-EOF && + tree $(test_oid 001) + parent $(test_oid 002) author whatever <whatever@example.com> 1234 -0000 committer whatever <whatever@example.com> 1234 -0000 @@ -143,8 +143,8 @@ test_expect_success 'do not complain about existing broken links (commit)' ' ' test_expect_success 'do not complain about existing broken links (tree)' ' - cat >broken-tree <<-\EOF && - 100644 blob 0000000000000000000000000000000000000003 foo + cat >broken-tree <<-EOF && + 100644 blob $(test_oid 003) foo EOF tree=$(git mktree --missing <broken-tree) && git gc -q 2>stderr && @@ -153,8 +153,8 @@ test_expect_success 'do not complain about existing broken links (tree)' ' ' test_expect_success 'do not complain about existing broken links (tag)' ' - cat >broken-tag <<-\EOF && - object 0000000000000000000000000000000000000004 + cat >broken-tag <<-EOF && + object $(test_oid 004) type commit tag broken tagger whatever <whatever@example.com> 1234 -0000 diff --git a/t/t7001-mv.sh b/t/t7001-mv.sh index 36b50d0b4c..c978b6dee4 100755 --- a/t/t7001-mv.sh +++ b/t/t7001-mv.sh @@ -248,6 +248,23 @@ test_expect_success 'git mv should not change sha1 of moved cache entry' ' rm -f dirty dirty2 +# NB: This test is about the error message +# as well as the failure. +test_expect_success 'git mv error on conflicted file' ' + rm -fr .git && + git init && + >conflict && + test_when_finished "rm -f conflict" && + cfhash=$(git hash-object -w conflict) && + q_to_tab <<-EOF | git update-index --index-info && + 0 $cfhash 0Qconflict + 100644 $cfhash 1Qconflict + EOF + + test_must_fail git mv conflict newname 2>actual && + test_i18ngrep "conflicted" actual +' + test_expect_success 'git mv should overwrite symlink to a file' ' rm -fr .git && diff --git a/t/t7003-filter-branch.sh b/t/t7003-filter-branch.sh index e23de7d0b5..36477cb1f4 100755 --- a/t/t7003-filter-branch.sh +++ b/t/t7003-filter-branch.sh @@ -463,10 +463,11 @@ test_expect_success 'rewrite submodule with another content' ' ' test_expect_success 'replace submodule revision' ' + invalid=$(test_oid numeric) && git reset --hard original && git filter-branch -f --tree-filter \ "if git ls-files --error-unmatch -- submod > /dev/null 2>&1 - then git update-index --cacheinfo 160000 0123456789012345678901234567890123456789 submod + then git update-index --cacheinfo 160000 $invalid submod fi" HEAD && test $orig_head != $(git show-ref --hash --head HEAD) ' diff --git a/t/t7061-wtstatus-ignore.sh b/t/t7061-wtstatus-ignore.sh index e4cf5484f9..2f9bea9793 100755 --- a/t/t7061-wtstatus-ignore.sh +++ b/t/t7061-wtstatus-ignore.sh @@ -30,6 +30,31 @@ test_expect_success 'same with gitignore starting with BOM' ' test_cmp expected actual ' +test_expect_success 'status untracked files --ignored with pathspec (no match)' ' + git status --porcelain --ignored -- untracked/i >actual && + test_must_be_empty actual && + git status --porcelain --ignored -- untracked/u >actual && + test_must_be_empty actual +' + +test_expect_success 'status untracked files --ignored with pathspec (literal match)' ' + git status --porcelain --ignored -- untracked/ignored >actual && + echo "!! untracked/ignored" >expected && + test_cmp expected actual && + git status --porcelain --ignored -- untracked/uncommitted >actual && + echo "?? untracked/uncommitted" >expected && + test_cmp expected actual +' + +test_expect_success 'status untracked files --ignored with pathspec (glob match)' ' + git status --porcelain --ignored -- untracked/i\* >actual && + echo "!! untracked/ignored" >expected && + test_cmp expected actual && + git status --porcelain --ignored -- untracked/u\* >actual && + echo "?? untracked/uncommitted" >expected && + test_cmp expected actual +' + cat >expected <<\EOF ?? .gitignore ?? actual diff --git a/t/t7063-status-untracked-cache.sh b/t/t7063-status-untracked-cache.sh index 428cff9cf3..a682a3d826 100755 --- a/t/t7063-status-untracked-cache.sh +++ b/t/t7063-status-untracked-cache.sh @@ -75,14 +75,24 @@ test_expect_success 'setup' ' touch one two three done/one dtwo/two dthree/three && git add one two done/one && : >.git/info/exclude && - git update-index --untracked-cache + git update-index --untracked-cache && + test_oid_cache <<-EOF + root sha1:e6fcc8f2ee31bae321d66afd183fcb7237afae6e + root sha256:b90c672088c015b9c83876e919da311bad4cd39639fb139f988af6a11493b974 + + exclude sha1:13263c0978fb9fad16b2d580fb800b6d811c3ff0 + exclude sha256:fe4aaa1bbbbce4cb8f73426748a14c5ad6026b26f90505a0bf2494b165a5b76c + + done sha1:1946f0437f90c5005533cbe1736a6451ca301714 + done sha256:7f079501d79f665b3acc50f5e0e9e94509084d5032ac20113a37dd5029b757cc + EOF ' test_expect_success 'untracked cache is empty' ' test-tool dump-untracked-cache >../actual && cat >../expect-empty <<EOF && -info/exclude 0000000000000000000000000000000000000000 -core.excludesfile 0000000000000000000000000000000000000000 +info/exclude $ZERO_OID +core.excludesfile $ZERO_OID exclude_per_dir .gitignore flags 00000006 EOF @@ -100,17 +110,17 @@ EOF cat >../dump.expect <<EOF && info/exclude $EMPTY_BLOB -core.excludesfile 0000000000000000000000000000000000000000 +core.excludesfile $ZERO_OID exclude_per_dir .gitignore flags 00000006 -/ 0000000000000000000000000000000000000000 recurse valid +/ $ZERO_OID recurse valid dthree/ dtwo/ three -/done/ 0000000000000000000000000000000000000000 recurse valid -/dthree/ 0000000000000000000000000000000000000000 recurse check_only valid +/done/ $ZERO_OID recurse valid +/dthree/ $ZERO_OID recurse check_only valid three -/dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid +/dtwo/ $ZERO_OID recurse check_only valid two EOF @@ -190,18 +200,18 @@ test_expect_success 'verify untracked cache dump' ' test-tool dump-untracked-cache >../actual && cat >../expect <<EOF && info/exclude $EMPTY_BLOB -core.excludesfile 0000000000000000000000000000000000000000 +core.excludesfile $ZERO_OID exclude_per_dir .gitignore flags 00000006 -/ 0000000000000000000000000000000000000000 recurse valid +/ $ZERO_OID recurse valid dthree/ dtwo/ four three -/done/ 0000000000000000000000000000000000000000 recurse valid -/dthree/ 0000000000000000000000000000000000000000 recurse check_only valid +/done/ $ZERO_OID recurse valid +/dthree/ $ZERO_OID recurse check_only valid three -/dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid +/dtwo/ $ZERO_OID recurse check_only valid two EOF test_cmp ../expect ../actual @@ -239,18 +249,18 @@ test_expect_success 'verify untracked cache dump' ' test-tool dump-untracked-cache >../actual && cat >../expect <<EOF && info/exclude $EMPTY_BLOB -core.excludesfile 0000000000000000000000000000000000000000 +core.excludesfile $ZERO_OID exclude_per_dir .gitignore flags 00000006 -/ e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse valid +/ $(test_oid root) recurse valid .gitignore dthree/ dtwo/ three -/done/ 0000000000000000000000000000000000000000 recurse valid -/dthree/ 0000000000000000000000000000000000000000 recurse check_only valid +/done/ $ZERO_OID recurse valid +/dthree/ $ZERO_OID recurse check_only valid three -/dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid +/dtwo/ $ZERO_OID recurse check_only valid two EOF test_cmp ../expect ../actual @@ -284,16 +294,16 @@ EOF test_expect_success 'verify untracked cache dump' ' test-tool dump-untracked-cache >../actual && cat >../expect <<EOF && -info/exclude 13263c0978fb9fad16b2d580fb800b6d811c3ff0 -core.excludesfile 0000000000000000000000000000000000000000 +info/exclude $(test_oid exclude) +core.excludesfile $ZERO_OID exclude_per_dir .gitignore flags 00000006 -/ e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse valid +/ $(test_oid root) recurse valid .gitignore dtwo/ -/done/ 0000000000000000000000000000000000000000 recurse valid -/dthree/ 0000000000000000000000000000000000000000 recurse check_only valid -/dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid +/done/ $ZERO_OID recurse valid +/dthree/ $ZERO_OID recurse check_only valid +/dtwo/ $ZERO_OID recurse check_only valid two EOF test_cmp ../expect ../actual @@ -303,14 +313,14 @@ test_expect_success 'move two from tracked to untracked' ' git rm --cached two && test-tool dump-untracked-cache >../actual && cat >../expect <<EOF && -info/exclude 13263c0978fb9fad16b2d580fb800b6d811c3ff0 -core.excludesfile 0000000000000000000000000000000000000000 +info/exclude $(test_oid exclude) +core.excludesfile $ZERO_OID exclude_per_dir .gitignore flags 00000006 -/ e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse -/done/ 0000000000000000000000000000000000000000 recurse valid -/dthree/ 0000000000000000000000000000000000000000 recurse check_only valid -/dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid +/ $(test_oid root) recurse +/done/ $ZERO_OID recurse valid +/dthree/ $ZERO_OID recurse check_only valid +/dtwo/ $ZERO_OID recurse check_only valid two EOF test_cmp ../expect ../actual @@ -342,17 +352,17 @@ EOF test_expect_success 'verify untracked cache dump' ' test-tool dump-untracked-cache >../actual && cat >../expect <<EOF && -info/exclude 13263c0978fb9fad16b2d580fb800b6d811c3ff0 -core.excludesfile 0000000000000000000000000000000000000000 +info/exclude $(test_oid exclude) +core.excludesfile $ZERO_OID exclude_per_dir .gitignore flags 00000006 -/ e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse valid +/ $(test_oid root) recurse valid .gitignore dtwo/ two -/done/ 0000000000000000000000000000000000000000 recurse valid -/dthree/ 0000000000000000000000000000000000000000 recurse check_only valid -/dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid +/done/ $ZERO_OID recurse valid +/dthree/ $ZERO_OID recurse check_only valid +/dtwo/ $ZERO_OID recurse check_only valid two EOF test_cmp ../expect ../actual @@ -362,14 +372,14 @@ test_expect_success 'move two from untracked to tracked' ' git add two && test-tool dump-untracked-cache >../actual && cat >../expect <<EOF && -info/exclude 13263c0978fb9fad16b2d580fb800b6d811c3ff0 -core.excludesfile 0000000000000000000000000000000000000000 +info/exclude $(test_oid exclude) +core.excludesfile $ZERO_OID exclude_per_dir .gitignore flags 00000006 -/ e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse -/done/ 0000000000000000000000000000000000000000 recurse valid -/dthree/ 0000000000000000000000000000000000000000 recurse check_only valid -/dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid +/ $(test_oid root) recurse +/done/ $ZERO_OID recurse valid +/dthree/ $ZERO_OID recurse check_only valid +/dtwo/ $ZERO_OID recurse check_only valid two EOF test_cmp ../expect ../actual @@ -401,16 +411,16 @@ EOF test_expect_success 'verify untracked cache dump' ' test-tool dump-untracked-cache >../actual && cat >../expect <<EOF && -info/exclude 13263c0978fb9fad16b2d580fb800b6d811c3ff0 -core.excludesfile 0000000000000000000000000000000000000000 +info/exclude $(test_oid exclude) +core.excludesfile $ZERO_OID exclude_per_dir .gitignore flags 00000006 -/ e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse valid +/ $(test_oid root) recurse valid .gitignore dtwo/ -/done/ 0000000000000000000000000000000000000000 recurse valid -/dthree/ 0000000000000000000000000000000000000000 recurse check_only valid -/dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid +/done/ $ZERO_OID recurse valid +/dthree/ $ZERO_OID recurse check_only valid +/dtwo/ $ZERO_OID recurse check_only valid two EOF test_cmp ../expect ../actual @@ -447,16 +457,16 @@ EOF test_expect_success 'untracked cache correct after commit' ' test-tool dump-untracked-cache >../actual && cat >../expect <<EOF && -info/exclude 13263c0978fb9fad16b2d580fb800b6d811c3ff0 -core.excludesfile 0000000000000000000000000000000000000000 +info/exclude $(test_oid exclude) +core.excludesfile $ZERO_OID exclude_per_dir .gitignore flags 00000006 -/ e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse valid +/ $(test_oid root) recurse valid .gitignore dtwo/ -/done/ 0000000000000000000000000000000000000000 recurse valid -/dthree/ 0000000000000000000000000000000000000000 recurse check_only valid -/dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid +/done/ $ZERO_OID recurse valid +/dthree/ $ZERO_OID recurse check_only valid +/dtwo/ $ZERO_OID recurse check_only valid two EOF test_cmp ../expect ../actual @@ -508,17 +518,17 @@ EOF test_expect_success 'untracked cache correct after status' ' test-tool dump-untracked-cache >../actual && cat >../expect <<EOF && -info/exclude 13263c0978fb9fad16b2d580fb800b6d811c3ff0 -core.excludesfile 0000000000000000000000000000000000000000 +info/exclude $(test_oid exclude) +core.excludesfile $ZERO_OID exclude_per_dir .gitignore flags 00000006 -/ e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse valid +/ $(test_oid root) recurse valid .gitignore dtwo/ -/done/ 1946f0437f90c5005533cbe1736a6451ca301714 recurse valid +/done/ $(test_oid done) recurse valid five -/dthree/ 0000000000000000000000000000000000000000 recurse check_only valid -/dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid +/dthree/ $ZERO_OID recurse check_only valid +/dtwo/ $ZERO_OID recurse check_only valid two EOF test_cmp ../expect ../actual @@ -580,22 +590,22 @@ EOF test_expect_success 'verify untracked cache dump (sparse/subdirs)' ' test-tool dump-untracked-cache >../actual && cat >../expect-from-test-dump <<EOF && -info/exclude 13263c0978fb9fad16b2d580fb800b6d811c3ff0 -core.excludesfile 0000000000000000000000000000000000000000 +info/exclude $(test_oid exclude) +core.excludesfile $ZERO_OID exclude_per_dir .gitignore flags 00000006 -/ e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse valid +/ $(test_oid root) recurse valid .gitignore dtwo/ -/done/ 1946f0437f90c5005533cbe1736a6451ca301714 recurse valid +/done/ $(test_oid done) recurse valid five sub/ -/done/sub/ 0000000000000000000000000000000000000000 recurse check_only valid +/done/sub/ $ZERO_OID recurse check_only valid sub/ -/done/sub/sub/ 0000000000000000000000000000000000000000 recurse check_only valid +/done/sub/sub/ $ZERO_OID recurse check_only valid file -/dthree/ 0000000000000000000000000000000000000000 recurse check_only valid -/dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid +/dthree/ $ZERO_OID recurse check_only valid +/dtwo/ $ZERO_OID recurse check_only valid two EOF test_cmp ../expect-from-test-dump ../actual @@ -806,8 +816,8 @@ test_expect_success '"status" after file replacement should be clean with UC=tru test-tool dump-untracked-cache >../actual && grep -F "recurse valid" ../actual >../actual.grep && cat >../expect.grep <<EOF && -/ 0000000000000000000000000000000000000000 recurse valid -/two/ 0000000000000000000000000000000000000000 recurse valid +/ $ZERO_OID recurse valid +/two/ $ZERO_OID recurse valid EOF status_is_clean && test_cmp ../expect.grep ../actual.grep diff --git a/t/t7102-reset.sh b/t/t7102-reset.sh index 97be0d968d..22161b3b2d 100755 --- a/t/t7102-reset.sh +++ b/t/t7102-reset.sh @@ -37,17 +37,23 @@ test_expect_success 'creating initial files and commits' ' echo "2nd line 1st file" >>first && git commit -a -m "modify 1st file" && + head5p2=$(git rev-parse --verify HEAD) && + head5p2f=$(git rev-parse --short HEAD:first) && git rm first && git mv second secondfile && git commit -a -m "remove 1st and rename 2nd" && + head5p1=$(git rev-parse --verify HEAD) && + head5p1s=$(git rev-parse --short HEAD:secondfile) && echo "1st line 2nd file" >secondfile && echo "2nd line 2nd file" >>secondfile && # "git commit -m" would break MinGW, as Windows refuse to pass # $test_encoding encoded parameter to git. commit_msg $test_encoding | git -c "i18n.commitEncoding=$test_encoding" commit -a -F - && - head5=$(git rev-parse --verify HEAD) + head5=$(git rev-parse --verify HEAD) && + head5s=$(git rev-parse --short HEAD:secondfile) && + head5sl=$(git rev-parse HEAD:secondfile) ' # git log --pretty=oneline # to see those SHA1 involved @@ -94,7 +100,7 @@ test_expect_success 'giving a non existing revision should fail' ' test_expect_success 'reset --soft with unmerged index should fail' ' touch .git/MERGE_HEAD && - echo "100644 44c5b5884550c17758737edcced463447b91d42b 1 un" | + echo "100644 $head5sl 1 un" | git update-index --index-info && test_must_fail git reset --soft HEAD && rm .git/MERGE_HEAD && @@ -192,7 +198,7 @@ test_expect_success \ >.diff_expect cat >.cached_expect <<EOF diff --git a/secondfile b/secondfile -index 1bbba79..44c5b58 100644 +index $head5p1s..$head5s 100644 --- a/secondfile +++ b/secondfile @@ -1 +1,2 @@ @@ -207,7 +213,7 @@ secondfile: EOF test_expect_success '--soft reset only should show changes in diff --cached' ' git reset --soft HEAD^ && - check_changes d1a4bc3abce4829628ae2dcb0d60ef3d1a78b1c4 && + check_changes $head5p1 && test "$(git rev-parse ORIG_HEAD)" = \ $head5 ' @@ -242,7 +248,7 @@ EOF test_expect_success \ '--hard reset should change the files and undo commits permanently' ' git reset --hard HEAD~2 && - check_changes ddaefe00f1da16864591c61fdc7adb5d7cd6b74e && + check_changes $head5p2 && test "$(git rev-parse ORIG_HEAD)" = \ $head4 ' @@ -251,7 +257,7 @@ test_expect_success \ cat >.cached_expect <<EOF diff --git a/first b/first deleted file mode 100644 -index 8206c22..0000000 +index $head5p2f..0000000 --- a/first +++ /dev/null @@ -1,2 +0,0 @@ @@ -259,14 +265,14 @@ index 8206c22..0000000 -2nd line 1st file diff --git a/second b/second deleted file mode 100644 -index 1bbba79..0000000 +index $head5p1s..0000000 --- a/second +++ /dev/null @@ -1 +0,0 @@ -2nd file diff --git a/secondfile b/secondfile new file mode 100644 -index 0000000..44c5b58 +index 0000000..$head5s --- /dev/null +++ b/secondfile @@ -0,0 +1,2 @@ @@ -286,13 +292,13 @@ test_expect_success \ echo "1st line 2nd file" >secondfile && echo "2nd line 2nd file" >>secondfile && git add secondfile && - check_changes ddaefe00f1da16864591c61fdc7adb5d7cd6b74e + check_changes $head5p2 ' cat >.diff_expect <<EOF diff --git a/first b/first deleted file mode 100644 -index 8206c22..0000000 +index $head5p2f..0000000 --- a/first +++ /dev/null @@ -1,2 +0,0 @@ @@ -300,7 +306,7 @@ index 8206c22..0000000 -2nd line 1st file diff --git a/second b/second deleted file mode 100644 -index 1bbba79..0000000 +index $head5p1s..0000000 --- a/second +++ /dev/null @@ -1 +0,0 @@ @@ -314,9 +320,8 @@ secondfile: EOF test_expect_success '--mixed reset to HEAD should unadd the files' ' git reset && - check_changes ddaefe00f1da16864591c61fdc7adb5d7cd6b74e && - test "$(git rev-parse ORIG_HEAD)" = \ - ddaefe00f1da16864591c61fdc7adb5d7cd6b74e + check_changes $head5p2 && + test "$(git rev-parse ORIG_HEAD)" = $head5p2 ' >.diff_expect @@ -328,7 +333,7 @@ secondfile: EOF test_expect_success 'redoing the last two commits should succeed' ' git add secondfile && - git reset --hard ddaefe00f1da16864591c61fdc7adb5d7cd6b74e && + git reset --hard $head5p2 && git rm first && git mv second secondfile && @@ -389,47 +394,55 @@ test_expect_success \ check_changes $head5 ' -cat > expect << EOF -diff --git a/file1 b/file1 -index d00491f..7ed6ff8 100644 ---- a/file1 -+++ b/file1 -@@ -1 +1 @@ --1 -+5 -diff --git a/file2 b/file2 -deleted file mode 100644 -index 0cfbf08..0000000 ---- a/file2 -+++ /dev/null -@@ -1 +0,0 @@ --2 -EOF -cat > cached_expect << EOF -diff --git a/file4 b/file4 -new file mode 100644 -index 0000000..b8626c4 ---- /dev/null -+++ b/file4 -@@ -0,0 +1 @@ -+4 -EOF test_expect_success 'test --mixed <paths>' ' echo 1 > file1 && echo 2 > file2 && git add file1 file2 && test_tick && git commit -m files && + before1=$(git rev-parse --short HEAD:file1) && + before2=$(git rev-parse --short HEAD:file2) && git rm file2 && echo 3 > file3 && echo 4 > file4 && echo 5 > file1 && + after1=$(git rev-parse --short $(git hash-object file1)) && + after4=$(git rev-parse --short $(git hash-object file4)) && git add file1 file3 file4 && git reset HEAD -- file1 file2 file3 && test_must_fail git diff --quiet && git diff > output && + + cat > expect <<-EOF && + diff --git a/file1 b/file1 + index $before1..$after1 100644 + --- a/file1 + +++ b/file1 + @@ -1 +1 @@ + -1 + +5 + diff --git a/file2 b/file2 + deleted file mode 100644 + index $before2..0000000 + --- a/file2 + +++ /dev/null + @@ -1 +0,0 @@ + -2 + EOF + test_cmp expect output && git diff --cached > output && + + cat > cached_expect <<-EOF && + diff --git a/file4 b/file4 + new file mode 100644 + index 0000000..$after4 + --- /dev/null + +++ b/file4 + @@ -0,0 +1 @@ + +4 + EOF + test_cmp cached_expect output ' diff --git a/t/t7107-reset-pathspec-file.sh b/t/t7107-reset-pathspec-file.sh index cad3a9de9e..15ccb14f7e 100755 --- a/t/t7107-reset-pathspec-file.sh +++ b/t/t7107-reset-pathspec-file.sh @@ -22,7 +22,12 @@ restore_checkpoint () { verify_expect () { git status --porcelain -- fileA.t fileB.t fileC.t fileD.t >actual && - test_cmp expect actual + if test "x$1" = 'x!' + then + ! test_cmp expect actual + else + test_cmp expect actual + fi } test_expect_success '--pathspec-from-file from stdin' ' @@ -131,7 +136,7 @@ test_expect_success 'quotes not compatible with --pathspec-file-nul' ' cat >expect <<-\EOF && D fileA.t EOF - test_must_fail verify_expect + verify_expect ! ' test_expect_success 'only touches what was listed' ' diff --git a/t/t7201-co.sh b/t/t7201-co.sh index b696bae5f5..4d62b9b00f 100755 --- a/t/t7201-co.sh +++ b/t/t7201-co.sh @@ -230,9 +230,10 @@ test_expect_success 'switch to another branch while carrying a deletion' ' test_expect_success 'checkout to detach HEAD (with advice declined)' ' git config advice.detachedHead false && + rev=$(git rev-parse --short renamer^) && git checkout -f renamer && git clean -f && git checkout renamer^ 2>messages && - test_i18ngrep "HEAD is now at 7329388" messages && + test_i18ngrep "HEAD is now at $rev" messages && test_line_count = 1 messages && H=$(git rev-parse --verify HEAD) && M=$(git show-ref -s --verify refs/heads/master) && @@ -248,9 +249,10 @@ test_expect_success 'checkout to detach HEAD (with advice declined)' ' test_expect_success 'checkout to detach HEAD' ' git config advice.detachedHead true && + rev=$(git rev-parse --short renamer^) && git checkout -f renamer && git clean -f && GIT_TEST_GETTEXT_POISON=false git checkout renamer^ 2>messages && - grep "HEAD is now at 7329388" messages && + grep "HEAD is now at $rev" messages && test_line_count -gt 1 messages && H=$(git rev-parse --verify HEAD) && M=$(git show-ref -s --verify refs/heads/master) && diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh index 956e17abb3..fec7e0299d 100755 --- a/t/t7400-submodule-basic.sh +++ b/t/t7400-submodule-basic.sh @@ -1231,7 +1231,7 @@ test_expect_success 'submodule helper list is not confused by common prefixes' ' git submodule add /dir1/b dir1/b && git submodule add /dir2/b dir2/b && git commit -m "first submodule commit" && - git submodule--helper list dir1/b |cut -c51- >actual && + git submodule--helper list dir1/b | cut -f 2 >actual && echo "dir1/b" >expect && test_cmp expect actual ' @@ -1260,7 +1260,7 @@ test_expect_success 'submodule update --init with a specification' ' pwd=$(pwd) && git clone file://"$pwd"/multisuper multisuper_clone && git -C multisuper_clone submodule update --init . ":(exclude)sub0" && - git -C multisuper_clone submodule status |cut -c 1,43- >actual && + git -C multisuper_clone submodule status | sed "s/$OID_REGEX //" >actual && test_cmp expect actual ' @@ -1271,7 +1271,7 @@ test_expect_success 'submodule update --init with submodule.active set' ' git -C multisuper_clone config submodule.active "." && git -C multisuper_clone config --add submodule.active ":(exclude)sub0" && git -C multisuper_clone submodule update --init && - git -C multisuper_clone submodule status |cut -c 1,43- >actual && + git -C multisuper_clone submodule status | sed "s/$OID_REGEX //" >actual && test_cmp expect actual ' @@ -1290,7 +1290,7 @@ test_expect_success 'submodule update and setting submodule.<name>.active' ' -sub3 EOF git -C multisuper_clone submodule update && - git -C multisuper_clone submodule status |cut -c 1,43- >actual && + git -C multisuper_clone submodule status | sed "s/$OID_REGEX //" >actual && test_cmp expect actual ' @@ -1307,12 +1307,12 @@ test_expect_success 'clone active submodule without submodule url set' ' git submodule update && git submodule status >actual_raw && - cut -c 1,43- actual_raw >actual && + cut -d" " -f3- actual_raw >actual && cat >expect <<-\EOF && - sub0 (test2) - sub1 (test2) - sub2 (test2) - sub3 (test2) + sub0 (test2) + sub1 (test2) + sub2 (test2) + sub3 (test2) EOF test_cmp expect actual ) @@ -1328,7 +1328,7 @@ test_expect_success 'clone --recurse-submodules with a pathspec works' ' EOF git clone --recurse-submodules="sub0" multisuper multisuper_clone && - git -C multisuper_clone submodule status |cut -c1,43- >actual && + git -C multisuper_clone submodule status | sed "s/$OID_REGEX //" >actual && test_cmp expected actual ' @@ -1345,7 +1345,7 @@ test_expect_success 'clone with multiple --recurse-submodules options' ' --recurse-submodules=":(exclude)sub0" \ --recurse-submodules=":(exclude)sub2" \ multisuper multisuper_clone && - git -C multisuper_clone submodule status |cut -c1,43- >actual && + git -C multisuper_clone submodule status | sed "s/$OID_REGEX //" >actual && test_cmp expect actual ' @@ -1373,7 +1373,7 @@ test_expect_success 'clone and subsequent updates correctly auto-initialize subm --recurse-submodules=":(exclude)sub4" \ multisuper multisuper_clone && - git -C multisuper_clone submodule status |cut -c1,43- >actual && + git -C multisuper_clone submodule status | sed "s/$OID_REGEX //" >actual && test_cmp expect actual && git -C multisuper submodule add ../sub1 sub4 && @@ -1382,7 +1382,7 @@ test_expect_success 'clone and subsequent updates correctly auto-initialize subm # obtain the new superproject git -C multisuper_clone pull && git -C multisuper_clone submodule update --init && - git -C multisuper_clone submodule status |cut -c1,43- >actual && + git -C multisuper_clone submodule status | sed "s/$OID_REGEX //" >actual && test_cmp expect2 actual ' diff --git a/t/t7405-submodule-merge.sh b/t/t7405-submodule-merge.sh index aa33978ed2..6a1e5f8232 100755 --- a/t/t7405-submodule-merge.sh +++ b/t/t7405-submodule-merge.sh @@ -195,7 +195,7 @@ test_expect_success 'git submodule status should display the merge conflict prop url = $TRASH_DIRECTORY/sub EOF cat >expect <<EOF && -U0000000000000000000000000000000000000000 sub +U$ZERO_OID sub EOF git submodule status > actual && test_cmp expect actual && @@ -214,7 +214,7 @@ test_expect_success 'git submodule status should display the merge conflict prop url = $TRASH_DIRECTORY/sub EOF cat >expect <<EOF && -U0000000000000000000000000000000000000000 sub +U$ZERO_OID sub EOF git submodule status > actual && test_cmp expect actual && diff --git a/t/t7506-status-submodule.sh b/t/t7506-status-submodule.sh index 08629a6e70..3fcb44767f 100755 --- a/t/t7506-status-submodule.sh +++ b/t/t7506-status-submodule.sh @@ -22,6 +22,10 @@ sanitize_output () { mv output2 output } +sanitize_diff () { + sed -e "/^index [0-9a-f,]*\.\.[0-9a-f]*/d" "$1" +} + test_expect_success 'setup' ' test_create_repo_with_commit sub && @@ -269,7 +273,6 @@ short_sha1_merge_sub1=$(cd sub1 && git rev-parse --short HEAD) short_sha1_merge_sub2=$(cd sub2 && git rev-parse --short HEAD) cat >diff_expect <<\EOF diff --cc .gitmodules -index badaa4c,44f999a..0000000 --- a/.gitmodules +++ b/.gitmodules @@@ -1,3 -1,3 +1,9 @@@ @@ -286,7 +289,6 @@ EOF cat >diff_submodule_expect <<\EOF diff --cc .gitmodules -index badaa4c,44f999a..0000000 --- a/.gitmodules +++ b/.gitmodules @@@ -1,3 -1,3 +1,9 @@@ @@ -306,7 +308,8 @@ test_expect_success 'diff with merge conflict in .gitmodules' ' cd super && git diff >../diff_actual 2>&1 ) && - test_cmp diff_expect diff_actual + sanitize_diff diff_actual >diff_sanitized && + test_cmp diff_expect diff_sanitized ' test_expect_success 'diff --submodule with merge conflict in .gitmodules' ' @@ -314,7 +317,8 @@ test_expect_success 'diff --submodule with merge conflict in .gitmodules' ' cd super && git diff --submodule >../diff_submodule_actual 2>&1 ) && - test_cmp diff_submodule_expect diff_submodule_actual + sanitize_diff diff_submodule_actual >diff_sanitized && + test_cmp diff_submodule_expect diff_sanitized ' # We'll setup different cases for further testing: diff --git a/t/t7508-status.sh b/t/t7508-status.sh index 8e969f3e36..e81759319f 100755 --- a/t/t7508-status.sh +++ b/t/t7508-status.sh @@ -837,7 +837,7 @@ EOF ' cat >expect <<EOF -:100644 100644 $EMPTY_BLOB 0000000000000000000000000000000000000000 M dir1/modified +:100644 100644 $EMPTY_BLOB $ZERO_OID M dir1/modified EOF test_expect_success 'status refreshes the index' ' touch dir2/added && diff --git a/t/t7600-merge.sh b/t/t7600-merge.sh index 1d45f9a4ed..5883a6adc3 100755 --- a/t/t7600-merge.sh +++ b/t/t7600-merge.sh @@ -14,9 +14,9 @@ Testing basic merge operations/option parsing. ! [c4] c4 ! [c5] c5 ! [c6] c6 - * [master] Merge commit 'c1' into master + * [master] Merge commit 'c1' -------- - - [master] Merge commit 'c1' into master + - [master] Merge commit 'c1' + * [c1] commit 1 + [c6] c6 + [c5] c5 @@ -44,8 +44,8 @@ test_write_lines '1 X' 2 '3 X' 4 '5 X' 6 7 8 '9 X' >result.1-3-5-9 test_write_lines 1 2 3 4 5 6 7 8 '9 Z' >result.9z create_merge_msgs () { - echo "Merge tag 'c2' into master" >msg.1-5 && - echo "Merge tags 'c2' and 'c3' into master" >msg.1-5-9 && + echo "Merge tag 'c2'" >msg.1-5 && + echo "Merge tags 'c2' and 'c3'" >msg.1-5-9 && { echo "Squashed commit of the following:" && echo && @@ -258,7 +258,7 @@ test_expect_success 'merge c3 with c7 with commit.cleanup = scissors' ' git commit --no-edit -a && cat >expect <<-\EOF && - Merge tag '"'"'c7'"'"' into master + Merge tag '"'"'c7'"'"' # ------------------------ >8 ------------------------ # Do not modify or remove the line above. @@ -808,10 +808,10 @@ test_expect_success 'merge with conflicted --autostash changes' ' ' cat >expected.branch <<\EOF -Merge branch 'c5-branch' (early part) into master +Merge branch 'c5-branch' (early part) EOF cat >expected.tag <<\EOF -Merge commit 'c5~1' into master +Merge commit 'c5~1' EOF test_expect_success 'merge early part of c2' ' diff --git a/t/t7608-merge-messages.sh b/t/t7608-merge-messages.sh index 2af33f195b..8e7e0a5865 100755 --- a/t/t7608-merge-messages.sh +++ b/t/t7608-merge-messages.sh @@ -16,7 +16,7 @@ test_expect_success 'merge local branch' ' git checkout master && test_commit master-2 && git merge local-branch && - check_oneline "Merge branch Qlocal-branchQ into master" + check_oneline "Merge branch Qlocal-branchQ" ' test_expect_success 'merge octopus branches' ' @@ -26,7 +26,7 @@ test_expect_success 'merge octopus branches' ' test_commit octopus-2 && git checkout master && git merge octopus-a octopus-b && - check_oneline "Merge branches Qoctopus-aQ and Qoctopus-bQ into master" + check_oneline "Merge branches Qoctopus-aQ and Qoctopus-bQ" ' test_expect_success 'merge tag' ' @@ -35,7 +35,7 @@ test_expect_success 'merge tag' ' git checkout master && test_commit master-3 && git merge tag-1 && - check_oneline "Merge tag Qtag-1Q into master" + check_oneline "Merge tag Qtag-1Q" ' test_expect_success 'ambiguous tag' ' @@ -44,7 +44,7 @@ test_expect_success 'ambiguous tag' ' git checkout master && test_commit master-4 && git merge ambiguous && - check_oneline "Merge tag QambiguousQ into master" + check_oneline "Merge tag QambiguousQ" ' test_expect_success 'remote-tracking branch' ' @@ -54,7 +54,7 @@ test_expect_success 'remote-tracking branch' ' git checkout master && test_commit master-5 && git merge origin/master && - check_oneline "Merge remote-tracking branch Qorigin/masterQ into master" + check_oneline "Merge remote-tracking branch Qorigin/masterQ" ' test_done diff --git a/t/t8002-blame.sh b/t/t8002-blame.sh index eea048e52c..015973e8fe 100755 --- a/t/t8002-blame.sh +++ b/t/t8002-blame.sh @@ -6,6 +6,10 @@ test_description='git blame' PROG='git blame -c' . "$TEST_DIRECTORY"/annotate-tests.sh +test_expect_success 'setup' ' + hexsz=$(test_oid hexsz) +' + test_expect_success 'blame untracked file in empty repo' ' >untracked && test_must_fail git blame untracked @@ -105,21 +109,32 @@ test_expect_success 'blame --abbrev=<n> works' ' ' test_expect_success 'blame -l aligns regular and boundary commits' ' - check_abbrev 40 -l HEAD && - check_abbrev 39 -l ^HEAD + check_abbrev $hexsz -l HEAD && + check_abbrev $((hexsz - 1)) -l ^HEAD ' -test_expect_success 'blame --abbrev=40 behaves like -l' ' - check_abbrev 40 --abbrev=40 HEAD && - check_abbrev 39 --abbrev=40 ^HEAD +test_expect_success 'blame --abbrev with full length behaves like -l' ' + check_abbrev $hexsz --abbrev=$hexsz HEAD && + check_abbrev $((hexsz - 1)) --abbrev=$hexsz ^HEAD ' -test_expect_success '--no-abbrev works like --abbrev=40' ' - check_abbrev 40 --no-abbrev +test_expect_success '--no-abbrev works like --abbrev with full length' ' + check_abbrev $hexsz --no-abbrev ' test_expect_success '--exclude-promisor-objects does not BUG-crash' ' test_must_fail git blame --exclude-promisor-objects one ' +test_expect_success 'blame with uncommitted edits in partial clone does not crash' ' + git init server && + echo foo >server/file.txt && + git -C server add file.txt && + git -C server commit -m file && + + git clone --filter=blob:none "file://$(pwd)/server" client && + echo bar >>client/file.txt && + git -C client blame file.txt +' + test_done diff --git a/t/t8003-blame-corner-cases.sh b/t/t8003-blame-corner-cases.sh index 9130b887d2..b871dd4f86 100755 --- a/t/t8003-blame-corner-cases.sh +++ b/t/t8003-blame-corner-cases.sh @@ -6,7 +6,6 @@ test_description='git blame corner cases' pick_fc='s/^[0-9a-f^]* *\([^ ]*\) *(\([^ ]*\) .*/\1-\2/' test_expect_success setup ' - echo A A A A A >one && echo B B B B B >two && echo C C C C C >tres && @@ -306,7 +305,7 @@ test_expect_success 'blame coalesce' ' $oid 1) ABC $oid 2) DEF EOF - git -c core.abbrev=40 blame -s giraffe >actual && + git -c core.abbrev=$(test_oid hexsz) blame -s giraffe >actual && test_cmp expect actual ' diff --git a/t/t8011-blame-split-file.sh b/t/t8011-blame-split-file.sh index 831125047b..bdda0c03fe 100755 --- a/t/t8011-blame-split-file.sh +++ b/t/t8011-blame-split-file.sh @@ -54,7 +54,7 @@ test_expect_success 'setup simulated porcelain' ' cat >read-porcelain.pl <<-\EOF my $field = shift; while (<>) { - if (/^[0-9a-f]{40} /) { + if (/^[0-9a-f]{40,} /) { flush(); $hash = $&; } elsif (/^$field (.*)/) { diff --git a/t/t8014-blame-ignore-fuzzy.sh b/t/t8014-blame-ignore-fuzzy.sh index 6e61882b6f..e68e6115a6 100755 --- a/t/t8014-blame-ignore-fuzzy.sh +++ b/t/t8014-blame-ignore-fuzzy.sh @@ -248,7 +248,7 @@ Final EOF # The first line of b matches best with the last line of a, but the overall -# match is better if we match it with the the first line of a. +# match is better if we match it with the first line of a. title11="Piggy in the middle" cat <<EOF >a11 abcdefg diff --git a/t/t9100-git-svn-basic.sh b/t/t9100-git-svn-basic.sh index 9f2d19ecc4..3055943a22 100755 --- a/t/t9100-git-svn-basic.sh +++ b/t/t9100-git-svn-basic.sh @@ -200,8 +200,9 @@ GIT_SVN_ID=alt export GIT_SVN_ID test_expect_success "$name" \ 'git svn init "$svnrepo" && git svn fetch && - git rev-list --pretty=raw remotes/git-svn | grep ^tree | uniq > a && - git rev-list --pretty=raw remotes/alt | grep ^tree | uniq > b && + git log --format="tree %T %s" remotes/git-svn | + awk "!seen[\$0]++ { print \$1, \$2 }" >a && + git log --format="tree %T" alt >b && test_cmp a b' name='check imported tree checksums expected tree checksums' diff --git a/t/t9300-fast-import.sh b/t/t9300-fast-import.sh index e151df81c0..308c1ef42c 100755 --- a/t/t9300-fast-import.sh +++ b/t/t9300-fast-import.sh @@ -92,7 +92,7 @@ test_expect_success 'A: create pack from stdin' ' EOF reset refs/tags/to-be-deleted - from 0000000000000000000000000000000000000000 + from $ZERO_OID tag nested mark :6 @@ -102,7 +102,7 @@ test_expect_success 'A: create pack from stdin' ' EOF reset refs/tags/nested - from 0000000000000000000000000000000000000000 + from $ZERO_OID tag nested mark :7 @@ -284,8 +284,9 @@ test_expect_success 'A: verify pack' ' ' test_expect_success 'A: verify diff' ' + copy=$(git rev-parse --verify master:file2) && cat >expect <<-EOF && - :000000 100755 0000000000000000000000000000000000000000 7123f7f44e39be127c5eb701e5968176ee9d78b1 A copy-of-file2 + :000000 100755 $ZERO_OID $copy A copy-of-file2 EOF git diff-tree -M -r master verify--import-marks >actual && compare_diff_raw expect actual && @@ -364,7 +365,7 @@ test_expect_success 'B: fail on invalid blob sha1' ' COMMIT from refs/heads/master - M 755 0000000000000000000000000000000000000001 zero1 + M 755 $(echo $ZERO_OID | sed -e "s/0$/1/") zero1 INPUT_END @@ -528,6 +529,7 @@ test_expect_success 'B: fail on invalid committer (5)' ' test_expect_success 'C: incremental import create pack from stdin' ' newf=$(echo hi newf | git hash-object -w --stdin) && oldf=$(git rev-parse --verify master:file2) && + thrf=$(git rev-parse --verify master:file3) && test_tick && cat >input <<-INPUT_END && commit refs/heads/branch @@ -570,10 +572,11 @@ test_expect_success 'C: verify commit' ' ' test_expect_success 'C: validate rename result' ' + zero=$ZERO_OID && cat >expect <<-EOF && - :000000 100755 0000000000000000000000000000000000000000 f1fb5da718392694d0076d677d6d0e364c79b0bc A file2/newf - :100644 100644 7123f7f44e39be127c5eb701e5968176ee9d78b1 7123f7f44e39be127c5eb701e5968176ee9d78b1 R100 file2 file2/oldf - :100644 000000 0d92e9f3374ae2947c23aa477cbc68ce598135f1 0000000000000000000000000000000000000000 D file3 + :000000 100755 $zero $newf A file2/newf + :100644 100644 $oldf $oldf R100 file2 file2/oldf + :100644 000000 $thrf $zero D file3 EOF git diff-tree -M -r master branch >actual && compare_diff_raw expect actual @@ -614,9 +617,11 @@ test_expect_success 'D: verify pack' ' ' test_expect_success 'D: validate new files added' ' + f5id=$(echo "$file5_data" | git hash-object --stdin) && + f6id=$(echo "$file6_data" | git hash-object --stdin) && cat >expect <<-EOF && - :000000 100755 0000000000000000000000000000000000000000 e74b7d465e52746be2b4bae983670711e6e66657 A newdir/exec.sh - :000000 100644 0000000000000000000000000000000000000000 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 A newdir/interesting + :000000 100755 $ZERO_OID $f6id A newdir/exec.sh + :000000 100644 $ZERO_OID $f5id A newdir/interesting EOF git diff-tree -M -r branch^ branch >actual && compare_diff_raw expect actual @@ -779,12 +784,13 @@ test_expect_success 'H: verify pack' ' ' test_expect_success 'H: validate old files removed, new files added' ' + f4id=$(git rev-parse HEAD:file4) && cat >expect <<-EOF && - :100755 000000 f1fb5da718392694d0076d677d6d0e364c79b0bc 0000000000000000000000000000000000000000 D file2/newf - :100644 000000 7123f7f44e39be127c5eb701e5968176ee9d78b1 0000000000000000000000000000000000000000 D file2/oldf - :100755 000000 85df50785d62d3b05ab03d9cbf7e4a0b49449730 0000000000000000000000000000000000000000 D file4 - :100644 100644 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 R100 newdir/interesting h/e/l/lo - :100755 000000 e74b7d465e52746be2b4bae983670711e6e66657 0000000000000000000000000000000000000000 D newdir/exec.sh + :100755 000000 $newf $zero D file2/newf + :100644 000000 $oldf $zero D file2/oldf + :100755 000000 $f4id $zero D file4 + :100644 100644 $f5id $f5id R100 newdir/interesting h/e/l/lo + :100755 000000 $f6id $zero D newdir/exec.sh EOF git diff-tree -M -r H^ H >actual && compare_diff_raw expect actual @@ -935,14 +941,15 @@ test_expect_success 'L: verify internal tree sorting' ' INPUT_END cat >expect <<-EXPECT_END && - :100644 100644 4268632... 55d3a52... M b. - :040000 040000 0ae5cac... 443c768... M b - :100644 100644 4268632... 55d3a52... M ba + :100644 100644 M b. + :040000 040000 M b + :100644 100644 M ba EXPECT_END git fast-import <input && GIT_PRINT_SHA1_ELLIPSIS="yes" git diff-tree --abbrev --raw L^ L >output && - test_cmp expect output + cut -d" " -f1,2,5 output >actual && + test_cmp expect actual ' test_expect_success 'L: nested tree copy does not corrupt deltas' ' @@ -1004,7 +1011,7 @@ test_expect_success 'M: rename file in same subdirectory' ' INPUT_END cat >expect <<-EOF && - :100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc R100 file2/newf file2/n.e.w.f + :100755 100755 $newf $newf R100 file2/newf file2/n.e.w.f EOF git fast-import <input && git diff-tree -M -r M1^ M1 >actual && @@ -1025,7 +1032,7 @@ test_expect_success 'M: rename file to new subdirectory' ' INPUT_END cat >expect <<-EOF && - :100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc R100 file2/newf i/am/new/to/you + :100755 100755 $newf $newf R100 file2/newf i/am/new/to/you EOF git fast-import <input && git diff-tree -M -r M2^ M2 >actual && @@ -1046,7 +1053,7 @@ test_expect_success 'M: rename subdirectory to new subdirectory' ' INPUT_END cat >expect <<-EOF && - :100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc R100 i/am/new/to/you other/sub/am/new/to/you + :100755 100755 $newf $newf R100 i/am/new/to/you other/sub/am/new/to/you EOF git fast-import <input && git diff-tree -M -r M3^ M3 >actual && @@ -1067,11 +1074,11 @@ test_expect_success 'M: rename root to subdirectory' ' INPUT_END cat >expect <<-EOF && - :100644 100644 7123f7f44e39be127c5eb701e5968176ee9d78b1 7123f7f44e39be127c5eb701e5968176ee9d78b1 R100 file2/oldf sub/file2/oldf - :100755 100755 85df50785d62d3b05ab03d9cbf7e4a0b49449730 85df50785d62d3b05ab03d9cbf7e4a0b49449730 R100 file4 sub/file4 - :100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc R100 i/am/new/to/you sub/i/am/new/to/you - :100755 100755 e74b7d465e52746be2b4bae983670711e6e66657 e74b7d465e52746be2b4bae983670711e6e66657 R100 newdir/exec.sh sub/newdir/exec.sh - :100644 100644 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 R100 newdir/interesting sub/newdir/interesting + :100644 100644 $oldf $oldf R100 file2/oldf sub/file2/oldf + :100755 100755 $f4id $f4id R100 file4 sub/file4 + :100755 100755 $newf $newf R100 i/am/new/to/you sub/i/am/new/to/you + :100755 100755 $f6id $f6id R100 newdir/exec.sh sub/newdir/exec.sh + :100644 100644 $f5id $f5id R100 newdir/interesting sub/newdir/interesting EOF git fast-import <input && git diff-tree -M -r M4^ M4 >actual && @@ -1097,7 +1104,7 @@ test_expect_success 'N: copy file in same subdirectory' ' INPUT_END cat >expect <<-EOF && - :100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc C100 file2/newf file2/n.e.w.f + :100755 100755 $newf $newf C100 file2/newf file2/n.e.w.f EOF git fast-import <input && git diff-tree -C --find-copies-harder -r N1^ N1 >actual && @@ -1129,9 +1136,9 @@ test_expect_success 'N: copy then modify subdirectory' ' INPUT_END cat >expect <<-EOF && - :100644 100644 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 C100 newdir/interesting file3/file5 - :100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc C100 file2/newf file3/newf - :100644 100644 7123f7f44e39be127c5eb701e5968176ee9d78b1 7123f7f44e39be127c5eb701e5968176ee9d78b1 C100 file2/oldf file3/oldf + :100644 100644 $f5id $f5id C100 newdir/interesting file3/file5 + :100755 100755 $newf $newf C100 file2/newf file3/newf + :100644 100644 $oldf $oldf C100 file2/oldf file3/oldf EOF git fast-import <input && git diff-tree -C --find-copies-harder -r N2^^ N2 >actual && @@ -1162,9 +1169,9 @@ test_expect_success 'N: copy dirty subdirectory' ' ' test_expect_success 'N: copy directory by id' ' - cat >expect <<-\EOF && - :100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc C100 file2/newf file3/newf - :100644 100644 7123f7f44e39be127c5eb701e5968176ee9d78b1 7123f7f44e39be127c5eb701e5968176ee9d78b1 C100 file2/oldf file3/oldf + cat >expect <<-EOF && + :100755 100755 $newf $newf C100 file2/newf file3/newf + :100644 100644 $oldf $oldf C100 file2/oldf file3/oldf EOF subdir=$(git rev-parse refs/heads/branch^0:file2) && cat >input <<-INPUT_END && @@ -1183,9 +1190,9 @@ test_expect_success 'N: copy directory by id' ' ' test_expect_success PIPE 'N: read and copy directory' ' - cat >expect <<-\EOF && - :100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc C100 file2/newf file3/newf - :100644 100644 7123f7f44e39be127c5eb701e5968176ee9d78b1 7123f7f44e39be127c5eb701e5968176ee9d78b1 C100 file2/oldf file3/oldf + cat >expect <<-EOF && + :100755 100755 $newf $newf C100 file2/newf file3/newf + :100644 100644 $oldf $oldf C100 file2/oldf file3/oldf EOF git update-ref -d refs/heads/N4 && rm -f backflow && @@ -1254,9 +1261,9 @@ test_expect_success PIPE 'N: empty directory reads as missing' ' ' test_expect_success 'N: copy root directory by tree hash' ' - cat >expect <<-\EOF && - :100755 000000 f1fb5da718392694d0076d677d6d0e364c79b0bc 0000000000000000000000000000000000000000 D file3/newf - :100644 000000 7123f7f44e39be127c5eb701e5968176ee9d78b1 0000000000000000000000000000000000000000 D file3/oldf + cat >expect <<-EOF && + :100755 000000 $newf $zero D file3/newf + :100644 000000 $oldf $zero D file3/oldf EOF root=$(git rev-parse refs/heads/branch^0^{tree}) && cat >input <<-INPUT_END && @@ -1275,12 +1282,12 @@ test_expect_success 'N: copy root directory by tree hash' ' ' test_expect_success 'N: copy root by path' ' - cat >expect <<-\EOF && - :100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc C100 file2/newf oldroot/file2/newf - :100644 100644 7123f7f44e39be127c5eb701e5968176ee9d78b1 7123f7f44e39be127c5eb701e5968176ee9d78b1 C100 file2/oldf oldroot/file2/oldf - :100755 100755 85df50785d62d3b05ab03d9cbf7e4a0b49449730 85df50785d62d3b05ab03d9cbf7e4a0b49449730 C100 file4 oldroot/file4 - :100755 100755 e74b7d465e52746be2b4bae983670711e6e66657 e74b7d465e52746be2b4bae983670711e6e66657 C100 newdir/exec.sh oldroot/newdir/exec.sh - :100644 100644 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 C100 newdir/interesting oldroot/newdir/interesting + cat >expect <<-EOF && + :100755 100755 $newf $newf C100 file2/newf oldroot/file2/newf + :100644 100644 $oldf $oldf C100 file2/oldf oldroot/file2/oldf + :100755 100755 $f4id $f4id C100 file4 oldroot/file4 + :100755 100755 $f6id $f6id C100 newdir/exec.sh oldroot/newdir/exec.sh + :100644 100644 $f5id $f5id C100 newdir/interesting oldroot/newdir/interesting EOF cat >input <<-INPUT_END && commit refs/heads/N-copy-root-path @@ -1340,10 +1347,10 @@ test_expect_success 'N: delete directory by copying' ' ' test_expect_success 'N: modify copied tree' ' - cat >expect <<-\EOF && - :100644 100644 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 C100 newdir/interesting file3/file5 - :100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc C100 file2/newf file3/newf - :100644 100644 7123f7f44e39be127c5eb701e5968176ee9d78b1 7123f7f44e39be127c5eb701e5968176ee9d78b1 C100 file2/oldf file3/oldf + cat >expect <<-EOF && + :100644 100644 $f5id $f5id C100 newdir/interesting file3/file5 + :100755 100755 $newf $newf C100 file2/newf file3/newf + :100644 100644 $oldf $oldf C100 file2/oldf file3/oldf EOF subdir=$(git rev-parse refs/heads/branch^0:file2) && cat >input <<-INPUT_END && @@ -2726,7 +2733,7 @@ test_expect_success 'R: corrupt lines do not mess marks file' ' rm -f io.marks && blob=$(echo hi | git hash-object --stdin) && cat >expect <<-EOF && - :3 0000000000000000000000000000000000000000 + :3 $ZERO_OID :1 $blob :2 $blob EOF @@ -3077,7 +3084,7 @@ test_expect_success 'T: delete branch' ' git branch to-delete && git fast-import <<-EOF && reset refs/heads/to-delete - from 0000000000000000000000000000000000000000 + from $ZERO_OID EOF test_must_fail git rev-parse --verify refs/heads/to-delete ' @@ -3117,6 +3124,9 @@ test_expect_success 'U: initialize for U tests' ' INPUT_END + f7id=$(echo "blob 1" | git hash-object --stdin) && + f8id=$(echo "sleep well" | git hash-object --stdin) && + f9id=$(echo "au revoir" | git hash-object --stdin) && git fast-import <input ' @@ -3137,7 +3147,7 @@ test_expect_success 'U: filedelete file succeeds' ' test_expect_success 'U: validate file delete result' ' cat >expect <<-EOF && - :100644 000000 2907ebb4bf85d91bf0716bb3bd8a68ef48d6da76 0000000000000000000000000000000000000000 D good/night.txt + :100644 000000 $f8id $ZERO_OID D good/night.txt EOF git diff-tree -M -r U^1 U >actual && @@ -3162,7 +3172,7 @@ test_expect_success 'U: filedelete directory succeeds' ' test_expect_success 'U: validate directory delete result' ' cat >expect <<-EOF && - :100644 000000 69cb75792f55123d8389c156b0b41c2ff00ed507 0000000000000000000000000000000000000000 D good/bye.txt + :100644 000000 $f9id $ZERO_OID D good/bye.txt EOF git diff-tree -M -r U^1 U >actual && @@ -3187,7 +3197,7 @@ test_expect_success 'U: filedelete root succeeds' ' test_expect_success 'U: validate root delete result' ' cat >expect <<-EOF && - :100644 000000 c18147dc648481eeb65dc5e66628429a64843327 0000000000000000000000000000000000000000 D hello.c + :100644 000000 $f7id $ZERO_OID D hello.c EOF git diff-tree -M -r U^1 U >actual && diff --git a/t/t9301-fast-import-notes.sh b/t/t9301-fast-import-notes.sh index ca223dca98..14c1baa739 100755 --- a/t/t9301-fast-import-notes.sh +++ b/t/t9301-fast-import-notes.sh @@ -470,12 +470,13 @@ test_expect_success 'add lots of commits and notes' ' ' test_expect_success 'verify that lots of notes trigger a fanout scheme' ' + hexsz=$(test_oid hexsz) && # None of the entries in the top-level notes tree should be a full SHA1 git ls-tree --name-only refs/notes/many_notes | while read path do - if test $(expr length "$path") -ge 40 + if test $(expr length "$path") -ge $hexsz then return 1 fi @@ -518,7 +519,7 @@ test_expect_success 'verify that importing a notes tree respects the fanout sche git ls-tree --name-only refs/notes/other_notes | while read path do - if test $(expr length "$path") -ge 40 + if test $(expr length "$path") -ge $hexsz then return 1 fi @@ -593,7 +594,7 @@ test_expect_success 'verify that changing notes respect existing fanout' ' git ls-tree --name-only refs/notes/many_notes | while read path do - if test $(expr length "$path") -ge 40 + if test $(expr length "$path") -ge $hexsz then return 1 fi @@ -616,7 +617,7 @@ i=$(($num_commits - $remaining_notes)) for sha1 in $(git rev-list -n $i refs/heads/many_commits) do cat >>input <<INPUT_END -N 0000000000000000000000000000000000000000 $sha1 +N $ZERO_OID $sha1 INPUT_END done @@ -646,7 +647,6 @@ test_expect_success 'remove lots of notes' ' ' test_expect_success 'verify that removing notes trigger fanout consolidation' ' - # All entries in the top-level notes tree should be a full SHA1 git ls-tree --name-only -r refs/notes/many_notes | while read path @@ -656,7 +656,7 @@ test_expect_success 'verify that removing notes trigger fanout consolidation' ' test "$path" = "deadbeef" && continue test "$path" = "de/adbeef" && continue - if test $(expr length "$path") -ne 40 + if test $(expr length "$path") -ne $hexsz then return 1 fi diff --git a/t/t9350-fast-export.sh b/t/t9350-fast-export.sh index 690c90fb82..1372842559 100755 --- a/t/t9350-fast-export.sh +++ b/t/t9350-fast-export.sh @@ -132,12 +132,12 @@ test_expect_success 'reencoding iso-8859-7' ' sed "s/wer/i18n/" iso-8859-7.fi | (cd new && git fast-import && - # The commit object, if not re-encoded, would be 240 bytes. + # The commit object, if not re-encoded, would be 200 bytes plus hash. # Removing the "encoding iso-8859-7\n" header drops 20 bytes. # Re-encoding the Pi character from \xF0 (\360) in iso-8859-7 # to \xCF\x80 (\317\200) in UTF-8 adds a byte. Check for # the expected size. - test 221 -eq "$(git cat-file -s i18n)" && + test $(($(test_oid hexsz) + 181)) -eq "$(git cat-file -s i18n)" && # ...and for the expected translation of bytes. git cat-file commit i18n >actual && grep $(printf "\317\200") actual && @@ -164,12 +164,12 @@ test_expect_success 'preserving iso-8859-7' ' sed "s/wer/i18n-no-recoding/" iso-8859-7.fi | (cd new && git fast-import && - # The commit object, if not re-encoded, is 240 bytes. + # The commit object, if not re-encoded, is 200 bytes plus hash. # Removing the "encoding iso-8859-7\n" header would drops 20 # bytes. Re-encoding the Pi character from \xF0 (\360) in # iso-8859-7 to \xCF\x80 (\317\200) in UTF-8 adds a byte. # Check for the expected size... - test 240 -eq "$(git cat-file -s i18n-no-recoding)" && + test $(($(test_oid hexsz) + 200)) -eq "$(git cat-file -s i18n-no-recoding)" && # ...as well as the expected byte. git cat-file commit i18n-no-recoding >actual && grep $(printf "\360") actual && @@ -192,7 +192,7 @@ test_expect_success 'encoding preserved if reencoding fails' ' grep ^encoding actual && # Verify that the commit has the expected size; i.e. # that no bytes were re-encoded to a different encoding. - test 252 -eq "$(git cat-file -s i18n-invalid)" && + test $(($(test_oid hexsz) + 212)) -eq "$(git cat-file -s i18n-invalid)" && # ...and check for the original special bytes grep $(printf "\360") actual && grep $(printf "\377") actual) @@ -694,7 +694,7 @@ test_expect_success 'delete ref because entire history excluded' ' git fast-export to-delete ^to-delete >actual && cat >expected <<-EOF && reset refs/heads/to-delete - from 0000000000000000000000000000000000000000 + from $ZERO_OID EOF test_cmp expected actual @@ -704,7 +704,7 @@ test_expect_success 'delete refspec' ' git fast-export --refspec :refs/heads/to-delete >actual && cat >expected <<-EOF && reset refs/heads/to-delete - from 0000000000000000000000000000000000000000 + from $ZERO_OID EOF test_cmp expected actual diff --git a/t/t9400-git-cvsserver-server.sh b/t/t9400-git-cvsserver-server.sh index a5e5dca753..4a46f31c41 100755 --- a/t/t9400-git-cvsserver-server.sh +++ b/t/t9400-git-cvsserver-server.sh @@ -603,7 +603,7 @@ test_expect_success 'cvs server does not run with vanilla git-shell' ' cd cvswork && CVS_SERVER=$WORKDIR/remote-cvs && export CVS_SERVER && - test_must_fail cvs log merge + ! cvs log merge ) ' diff --git a/t/t9500-gitweb-standalone-no-errors.sh b/t/t9500-gitweb-standalone-no-errors.sh index 267ddc997d..b484e3e250 100755 --- a/t/t9500-gitweb-standalone-no-errors.sh +++ b/t/t9500-gitweb-standalone-no-errors.sh @@ -621,12 +621,22 @@ test_expect_success \ git config gitweb.snapshot "zip,tgz, tbz2" && gitweb_run "p=.git;a=tree"' -cat >.git/config <<\EOF -# testing noval and alternate separator -[gitweb] - blame - snapshot = zip tgz -EOF +test_expect_success 'setup' ' + version=$(git config core.repositoryformatversion) && + algo=$(test_might_fail git config extensions.objectformat) && + cat >.git/config <<-\EOF && + # testing noval and alternate separator + [gitweb] + blame + snapshot = zip tgz + EOF + git config core.repositoryformatversion "$version" && + if test -n "$algo" + then + git config extensions.objectformat "$algo" + fi +' + test_expect_success \ 'config override: tree view, features enabled in repo config (2)' \ 'gitweb_run "p=.git;a=tree"' diff --git a/t/t9700/test.pl b/t/t9700/test.pl index 34cd01366f..e046f7db76 100755 --- a/t/t9700/test.pl +++ b/t/t9700/test.pl @@ -23,6 +23,8 @@ sub adjust_dirsep { return $path; } +my $oid_re = qr/^[0-9a-fA-F]{40}(?:[0-9a-fA-F]{24})?$/; + BEGIN { use_ok('Git') } # set up @@ -59,15 +61,15 @@ ok($@, "config_bool: non-boolean values fail"); open STDERR, ">&", $tmpstderr or die "cannot restore STDERR"; # ident -like($r->ident("aUthor"), qr/^A U Thor <author\@example.com> [0-9]+ \+0000$/, +like($r->ident("aUthor"), qr/^A U Thor <author\@example.com> [0-9]+ [+-]\d{4}$/, "ident scalar: author (type)"); -like($r->ident("cOmmitter"), qr/^C O Mitter <committer\@example.com> [0-9]+ \+0000$/, +like($r->ident("cOmmitter"), qr/^C O Mitter <committer\@example.com> [0-9]+ [+-]\d{4}$/, "ident scalar: committer (type)"); is($r->ident("invalid"), "invalid", "ident scalar: invalid ident string (no parsing)"); my ($name, $email, $time_tz) = $r->ident('author'); is_deeply([$name, $email], ["A U Thor", "author\@example.com"], "ident array: author"); -like($time_tz, qr/[0-9]+ \+0000/, "ident array: author"); +like($time_tz, qr/[0-9]+ [+-]\d{4}/, "ident array: author"); is_deeply([$r->ident("Name <email> 123 +0000")], ["Name", "email", "123 +0000"], "ident array: ident string"); is_deeply([$r->ident("invalid")], [], "ident array: invalid ident string"); @@ -93,7 +95,7 @@ is(Git::hash_object("blob", $tmpfile), $file1hash, "hash_object: roundtrip"); open TEMPFILE, ">$tmpfile" or die "Can't open $tmpfile: $!"; print TEMPFILE my $test_text = "test blob, to be inserted\n"; close TEMPFILE or die "Failed writing to $tmpfile: $!"; -like(our $newhash = $r->hash_and_insert_object($tmpfile), qr/[0-9a-fA-F]{40}/, +like(our $newhash = $r->hash_and_insert_object($tmpfile), $oid_re, "hash_and_insert_object: returns hash"); open TEMPFILE, "+>$tmpfile" or die "Can't open $tmpfile: $!"; is($r->cat_blob($newhash, \*TEMPFILE), length $test_text, "cat_blob: roundtrip size"); @@ -119,7 +121,7 @@ is($r2->wc_subdir, "directory2/", "wc_subdir initial (2)"); # commands in sub directory my $last_commit = $r2->command_oneline(qw(rev-parse --verify HEAD)); -like($last_commit, qr/^[0-9a-fA-F]{40}$/, 'rev-parse returned hash'); +like($last_commit, $oid_re, 'rev-parse returned hash'); my $dir_commit = $r2->command_oneline('log', '-n1', '--pretty=format:%H', '.'); isnt($last_commit, $dir_commit, 'log . does not show last commit'); diff --git a/t/t9834-git-p4-file-dir-bug.sh b/t/t9834-git-p4-file-dir-bug.sh index 031e1f8668..dac67e89d7 100755 --- a/t/t9834-git-p4-file-dir-bug.sh +++ b/t/t9834-git-p4-file-dir-bug.sh @@ -10,7 +10,7 @@ repository.' test_expect_success 'start p4d' ' start_p4d && - test_might_fail p4 configure set submit.collision.check=0 + { p4 configure set submit.collision.check=0 || :; } ' test_expect_success 'init depot' ' diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh index 3103be8a32..596c549cdd 100644 --- a/t/test-lib-functions.sh +++ b/t/test-lib-functions.sh @@ -798,6 +798,37 @@ list_contains () { return 1 } +# Returns success if the arguments indicate that a command should be +# accepted by test_must_fail(). If the command is run with env, the env +# and its corresponding variable settings will be stripped before we +# test the command being run. +test_must_fail_acceptable () { + if test "$1" = "env" + then + shift + while test $# -gt 0 + do + case "$1" in + *?=*) + shift + ;; + *) + break + ;; + esac + done + fi + + case "$1" in + git|__git*|test-tool|test-svn-fe|test_terminal) + return 0 + ;; + *) + return 1 + ;; + esac +} + # This is not among top-level (test_expect_success | test_expect_failure) # but is a prefix that can be used in the test script, like: # @@ -817,6 +848,17 @@ list_contains () { # Multiple signals can be specified as a comma separated list. # Currently recognized signal names are: sigpipe, success. # (Don't use 'success', use 'test_might_fail' instead.) +# +# Do not use this to run anything but "git" and other specific testable +# commands (see test_must_fail_acceptable()). We are not in the +# business of vetting system supplied commands -- in other words, this +# is wrong: +# +# test_must_fail grep pattern output +# +# Instead use '!': +# +# ! grep pattern output test_must_fail () { case "$1" in @@ -828,6 +870,11 @@ test_must_fail () { _test_ok= ;; esac + if ! test_must_fail_acceptable "$@" + then + echo >&7 "test_must_fail: only 'git' is allowed: $*" + return 1 + fi "$@" 2>&7 exit_code=$? if test $exit_code -eq 0 && ! list_contains "$_test_ok" success @@ -1417,9 +1464,7 @@ test_set_hash () { # Detect the hash algorithm in use. test_detect_hash () { - # Currently we only support SHA-1, but in the future this function will - # actually detect the algorithm in use. - test_hash_algo='sha1' + test_hash_algo="${GIT_TEST_DEFAULT_HASH:-sha1}" } # Load common hash metadata and common placeholder object IDs for use with @@ -1468,7 +1513,17 @@ test_oid_cache () { # Look up a per-hash value based on a key ($1). The value must have been loaded # by test_oid_init or test_oid_cache. test_oid () { - local var="test_oid_${test_hash_algo}_$1" && + local algo="${test_hash_algo}" && + + case "$1" in + --hash=*) + algo="${1#--hash=}" && + shift;; + *) + ;; + esac && + + local var="test_oid_${algo}_$1" && # If the variable is unset, we must be missing an entry for this # key-hash pair, so exit with an error. diff --git a/t/test-lib.sh b/t/test-lib.sh index 618a7c8d5b..ef31f40037 100644 --- a/t/test-lib.sh +++ b/t/test-lib.sh @@ -441,17 +441,23 @@ TEST_AUTHOR_LOCALNAME=author TEST_AUTHOR_DOMAIN=example.com GIT_AUTHOR_EMAIL=${TEST_AUTHOR_LOCALNAME}@${TEST_AUTHOR_DOMAIN} GIT_AUTHOR_NAME='A U Thor' +GIT_AUTHOR_DATE='1112354055 +0200' TEST_COMMITTER_LOCALNAME=committer TEST_COMMITTER_DOMAIN=example.com GIT_COMMITTER_EMAIL=${TEST_COMMITTER_LOCALNAME}@${TEST_COMMITTER_DOMAIN} GIT_COMMITTER_NAME='C O Mitter' +GIT_COMMITTER_DATE='1112354055 +0200' GIT_MERGE_VERBOSITY=5 GIT_MERGE_AUTOEDIT=no export GIT_MERGE_VERBOSITY GIT_MERGE_AUTOEDIT export GIT_AUTHOR_EMAIL GIT_AUTHOR_NAME export GIT_COMMITTER_EMAIL GIT_COMMITTER_NAME +export GIT_COMMITTER_DATE GIT_AUTHOR_DATE export EDITOR +GIT_DEFAULT_HASH="${GIT_TEST_DEFAULT_HASH:-sha1}" +export GIT_DEFAULT_HASH + # Tests using GIT_TRACE typically don't want <timestamp> <file>:<line> output GIT_TRACE_BARE=1 export GIT_TRACE_BARE @@ -1686,7 +1692,11 @@ test_lazy_prereq CURL ' # which will not work with other hash algorithms and tests that work but don't # test anything meaningful (e.g. special values which cause short collisions). test_lazy_prereq SHA1 ' - test $(git hash-object /dev/null) = e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 + case "$GIT_DEFAULT_HASH" in + sha1) true ;; + "") test $(git hash-object /dev/null) = e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 ;; + *) false ;; + esac ' test_lazy_prereq REBASE_P ' diff --git a/tmp-objdir.c b/tmp-objdir.c index 91c00567f4..42ed4db5d3 100644 --- a/tmp-objdir.c +++ b/tmp-objdir.c @@ -4,13 +4,13 @@ #include "sigchain.h" #include "string-list.h" #include "strbuf.h" -#include "argv-array.h" +#include "strvec.h" #include "quote.h" #include "object-store.h" struct tmp_objdir { struct strbuf path; - struct argv_array env; + struct strvec env; }; /* @@ -24,7 +24,7 @@ static struct tmp_objdir *the_tmp_objdir; static void tmp_objdir_free(struct tmp_objdir *t) { strbuf_release(&t->path); - argv_array_clear(&t->env); + strvec_clear(&t->env); free(t); } @@ -79,7 +79,7 @@ static void remove_tmp_objdir_on_signal(int signo) * separated by PATH_SEP (which is what separate values in * GIT_ALTERNATE_OBJECT_DIRECTORIES). */ -static void env_append(struct argv_array *env, const char *key, const char *val) +static void env_append(struct strvec *env, const char *key, const char *val) { struct strbuf quoted = STRBUF_INIT; const char *old; @@ -97,16 +97,16 @@ static void env_append(struct argv_array *env, const char *key, const char *val) old = getenv(key); if (!old) - argv_array_pushf(env, "%s=%s", key, val); + strvec_pushf(env, "%s=%s", key, val); else - argv_array_pushf(env, "%s=%s%c%s", key, old, PATH_SEP, val); + strvec_pushf(env, "%s=%s%c%s", key, old, PATH_SEP, val); strbuf_release("ed); } -static void env_replace(struct argv_array *env, const char *key, const char *val) +static void env_replace(struct strvec *env, const char *key, const char *val) { - argv_array_pushf(env, "%s=%s", key, val); + strvec_pushf(env, "%s=%s", key, val); } static int setup_tmp_objdir(const char *root) @@ -131,7 +131,7 @@ struct tmp_objdir *tmp_objdir_create(void) t = xmalloc(sizeof(*t)); strbuf_init(&t->path, 0); - argv_array_init(&t->env); + strvec_init(&t->env); strbuf_addf(&t->path, "%s/incoming-XXXXXX", get_object_directory()); @@ -283,7 +283,7 @@ const char **tmp_objdir_env(const struct tmp_objdir *t) { if (!t) return NULL; - return t->env.argv; + return t->env.v; } void tmp_objdir_add_as_alternate(const struct tmp_objdir *t) diff --git a/transport-helper.c b/transport-helper.c index c6b753bfae..defafbf4c1 100644 --- a/transport-helper.c +++ b/transport-helper.c @@ -9,7 +9,7 @@ #include "string-list.h" #include "thread-utils.h" #include "sigchain.h" -#include "argv-array.h" +#include "strvec.h" #include "refs.h" #include "refspec.h" #include "transport-internal.h" @@ -128,17 +128,17 @@ static struct child_process *get_helper(struct transport *transport) helper->in = -1; helper->out = -1; helper->err = 0; - argv_array_pushf(&helper->args, "git-remote-%s", data->name); - argv_array_push(&helper->args, transport->remote->name); - argv_array_push(&helper->args, remove_ext_force(transport->url)); + strvec_pushf(&helper->args, "git-remote-%s", data->name); + strvec_push(&helper->args, transport->remote->name); + strvec_push(&helper->args, remove_ext_force(transport->url)); helper->git_cmd = 0; helper->silent_exec_failure = 1; if (have_git_dir()) - argv_array_pushf(&helper->env_array, "%s=%s", - GIT_DIR_ENVIRONMENT, get_git_dir()); + strvec_pushf(&helper->env_array, "%s=%s", + GIT_DIR_ENVIRONMENT, get_git_dir()); - helper->trace2_child_class = helper->args.argv[0]; /* "remote-<name>" */ + helper->trace2_child_class = helper->args.v[0]; /* "remote-<name>" */ code = start_command(helper); if (code < 0 && errno == ENOENT) @@ -439,13 +439,13 @@ static int get_importer(struct transport *transport, struct child_process *fasti int cat_blob_fd, code; child_process_init(fastimport); fastimport->in = xdup(helper->out); - argv_array_push(&fastimport->args, "fast-import"); - argv_array_push(&fastimport->args, "--allow-unsafe-features"); - argv_array_push(&fastimport->args, debug ? "--stats" : "--quiet"); + strvec_push(&fastimport->args, "fast-import"); + strvec_push(&fastimport->args, "--allow-unsafe-features"); + strvec_push(&fastimport->args, debug ? "--stats" : "--quiet"); if (data->bidi_import) { cat_blob_fd = xdup(helper->in); - argv_array_pushf(&fastimport->args, "--cat-blob-fd=%d", cat_blob_fd); + strvec_pushf(&fastimport->args, "--cat-blob-fd=%d", cat_blob_fd); } fastimport->git_cmd = 1; @@ -466,17 +466,17 @@ static int get_exporter(struct transport *transport, /* we need to duplicate helper->in because we want to use it after * fastexport is done with it. */ fastexport->out = dup(helper->in); - argv_array_push(&fastexport->args, "fast-export"); - argv_array_push(&fastexport->args, "--use-done-feature"); - argv_array_push(&fastexport->args, data->signed_tags ? + strvec_push(&fastexport->args, "fast-export"); + strvec_push(&fastexport->args, "--use-done-feature"); + strvec_push(&fastexport->args, data->signed_tags ? "--signed-tags=verbatim" : "--signed-tags=warn-strip"); if (data->export_marks) - argv_array_pushf(&fastexport->args, "--export-marks=%s.tmp", data->export_marks); + strvec_pushf(&fastexport->args, "--export-marks=%s.tmp", data->export_marks); if (data->import_marks) - argv_array_pushf(&fastexport->args, "--import-marks=%s", data->import_marks); + strvec_pushf(&fastexport->args, "--import-marks=%s", data->import_marks); for (i = 0; i < revlist_args->nr; i++) - argv_array_push(&fastexport->args, revlist_args->items[i].string); + strvec_push(&fastexport->args, revlist_args->items[i].string); fastexport->git_cmd = 1; return start_command(fastexport); @@ -1082,7 +1082,7 @@ static int has_attribute(const char *attrs, const char *attr) } static struct ref *get_refs_list(struct transport *transport, int for_push, - const struct argv_array *ref_prefixes) + const struct strvec *ref_prefixes) { get_helper(transport); diff --git a/transport-internal.h b/transport-internal.h index 1cde6258a7..27c9daffc4 100644 --- a/transport-internal.h +++ b/transport-internal.h @@ -3,7 +3,7 @@ struct ref; struct transport; -struct argv_array; +struct strvec; struct transport_vtable { /** @@ -30,7 +30,7 @@ struct transport_vtable { * in the ref's old_sha1 field; otherwise it should be all 0. **/ struct ref *(*get_refs_list)(struct transport *transport, int for_push, - const struct argv_array *ref_prefixes); + const struct strvec *ref_prefixes); /** * Fetch the objects for the given refs. Note that this gets diff --git a/transport.c b/transport.c index b41386eccb..2d4fd851dc 100644 --- a/transport.c +++ b/transport.c @@ -127,7 +127,7 @@ struct bundle_transport_data { static struct ref *get_refs_from_bundle(struct transport *transport, int for_push, - const struct argv_array *ref_prefixes) + const struct strvec *ref_prefixes) { struct bundle_transport_data *data = transport->data; struct ref *result = NULL; @@ -283,7 +283,7 @@ static void die_if_server_options(struct transport *transport) * remote refs. */ static struct ref *handshake(struct transport *transport, int for_push, - const struct argv_array *ref_prefixes, + const struct strvec *ref_prefixes, int must_list_refs) { struct git_transport_data *data = transport->data; @@ -327,7 +327,7 @@ static struct ref *handshake(struct transport *transport, int for_push, } static struct ref *get_refs_via_connect(struct transport *transport, int for_push, - const struct argv_array *ref_prefixes) + const struct strvec *ref_prefixes) { return handshake(transport, for_push, ref_prefixes, 1); } @@ -1153,7 +1153,7 @@ int transport_push(struct repository *r, int porcelain = flags & TRANSPORT_PUSH_PORCELAIN; int pretend = flags & TRANSPORT_PUSH_DRY_RUN; int push_ret, ret, err; - struct argv_array ref_prefixes = ARGV_ARRAY_INIT; + struct strvec ref_prefixes = STRVEC_INIT; if (check_push_refs(local_refs, rs) < 0) return -1; @@ -1165,7 +1165,7 @@ int transport_push(struct repository *r, &ref_prefixes); trace2_region_leave("transport_push", "get_refs_list", r); - argv_array_clear(&ref_prefixes); + strvec_clear(&ref_prefixes); if (flags & TRANSPORT_PUSH_ALL) match_flags |= MATCH_REFS_ALL; @@ -1281,7 +1281,7 @@ int transport_push(struct repository *r, } const struct ref *transport_get_remote_refs(struct transport *transport, - const struct argv_array *ref_prefixes) + const struct strvec *ref_prefixes) { if (!transport->got_remote_refs) { transport->remote_refs = diff --git a/transport.h b/transport.h index b3c30133ea..1be4013dec 100644 --- a/transport.h +++ b/transport.h @@ -243,7 +243,7 @@ int transport_push(struct repository *repo, * ref_prefixes. */ const struct ref *transport_get_remote_refs(struct transport *transport, - const struct argv_array *ref_prefixes); + const struct strvec *ref_prefixes); /* * Fetch the hash algorithm used by a remote. diff --git a/tree-diff.c b/tree-diff.c index f3d303c6e5..6ebad1a46f 100644 --- a/tree-diff.c +++ b/tree-diff.c @@ -29,9 +29,9 @@ static struct combine_diff_path *ll_diff_tree_paths( struct combine_diff_path *p, const struct object_id *oid, const struct object_id **parents_oid, int nparent, struct strbuf *base, struct diff_options *opt); -static int ll_diff_tree_oid(const struct object_id *old_oid, - const struct object_id *new_oid, - struct strbuf *base, struct diff_options *opt); +static void ll_diff_tree_oid(const struct object_id *old_oid, + const struct object_id *new_oid, + struct strbuf *base, struct diff_options *opt); /* * Compare two tree entries, taking into account only path/S_ISDIR(mode), @@ -679,9 +679,9 @@ static void try_to_follow_renames(const struct object_id *old_oid, q->nr = 1; } -static int ll_diff_tree_oid(const struct object_id *old_oid, - const struct object_id *new_oid, - struct strbuf *base, struct diff_options *opt) +static void ll_diff_tree_oid(const struct object_id *old_oid, + const struct object_id *new_oid, + struct strbuf *base, struct diff_options *opt) { struct combine_diff_path phead, *p; pathchange_fn_t pathchange_old = opt->pathchange; @@ -697,29 +697,27 @@ static int ll_diff_tree_oid(const struct object_id *old_oid, } opt->pathchange = pathchange_old; - return 0; } -int diff_tree_oid(const struct object_id *old_oid, - const struct object_id *new_oid, - const char *base_str, struct diff_options *opt) +void diff_tree_oid(const struct object_id *old_oid, + const struct object_id *new_oid, + const char *base_str, struct diff_options *opt) { struct strbuf base; - int retval; strbuf_init(&base, PATH_MAX); strbuf_addstr(&base, base_str); - retval = ll_diff_tree_oid(old_oid, new_oid, &base, opt); + ll_diff_tree_oid(old_oid, new_oid, &base, opt); if (!*base_str && opt->flags.follow_renames && diff_might_be_rename()) try_to_follow_renames(old_oid, new_oid, &base, opt); strbuf_release(&base); - - return retval; } -int diff_root_tree_oid(const struct object_id *new_oid, const char *base, struct diff_options *opt) +void diff_root_tree_oid(const struct object_id *new_oid, + const char *base, + struct diff_options *opt) { - return diff_tree_oid(NULL, new_oid, base, opt); + diff_tree_oid(NULL, new_oid, base, opt); } diff --git a/tree-walk.c b/tree-walk.c index bb0ad34c54..0160294712 100644 --- a/tree-walk.c +++ b/tree-walk.c @@ -851,7 +851,14 @@ static int match_entry(const struct pathspec_item *item, if (matchlen > pathlen) { if (match[pathlen] != '/') return 0; - if (!S_ISDIR(entry->mode) && !S_ISGITLINK(entry->mode)) + /* + * Reject non-directories as partial pathnames, except + * when match is a submodule with a trailing slash and + * nothing else (to handle 'submod/' and 'submod' + * uniformly). + */ + if (!S_ISDIR(entry->mode) && + (!S_ISGITLINK(entry->mode) || matchlen > pathlen + 1)) return 0; } diff --git a/unpack-trees.c b/unpack-trees.c index 4be5fc3075..323280dd48 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -1,5 +1,5 @@ #include "cache.h" -#include "argv-array.h" +#include "strvec.h" #include "repository.h" #include "config.h" #include "dir.h" @@ -106,7 +106,7 @@ void setup_unpack_trees_porcelain(struct unpack_trees_options *opts, const char **msgs = opts->msgs; const char *msg; - argv_array_init(&opts->msgs_to_free); + strvec_init(&opts->msgs_to_free); if (!strcmp(cmd, "checkout")) msg = advice_commit_before_merge @@ -124,7 +124,7 @@ void setup_unpack_trees_porcelain(struct unpack_trees_options *opts, "Please commit your changes or stash them before you %s.") : _("Your local changes to the following files would be overwritten by %s:\n%%s"); msgs[ERROR_WOULD_OVERWRITE] = msgs[ERROR_NOT_UPTODATE_FILE] = - argv_array_pushf(&opts->msgs_to_free, msg, cmd, cmd); + strvec_pushf(&opts->msgs_to_free, msg, cmd, cmd); msgs[ERROR_NOT_UPTODATE_DIR] = _("Updating the following directories would lose untracked files in them:\n%s"); @@ -145,7 +145,7 @@ void setup_unpack_trees_porcelain(struct unpack_trees_options *opts, "Please move or remove them before you %s.") : _("The following untracked working tree files would be removed by %s:\n%%s"); msgs[ERROR_WOULD_LOSE_UNTRACKED_REMOVED] = - argv_array_pushf(&opts->msgs_to_free, msg, cmd, cmd); + strvec_pushf(&opts->msgs_to_free, msg, cmd, cmd); if (!strcmp(cmd, "checkout")) msg = advice_commit_before_merge @@ -163,7 +163,7 @@ void setup_unpack_trees_porcelain(struct unpack_trees_options *opts, "Please move or remove them before you %s.") : _("The following untracked working tree files would be overwritten by %s:\n%%s"); msgs[ERROR_WOULD_LOSE_UNTRACKED_OVERWRITTEN] = - argv_array_pushf(&opts->msgs_to_free, msg, cmd, cmd); + strvec_pushf(&opts->msgs_to_free, msg, cmd, cmd); /* * Special case: ERROR_BIND_OVERLAP refers to a pair of paths, we @@ -189,7 +189,7 @@ void setup_unpack_trees_porcelain(struct unpack_trees_options *opts, void clear_unpack_trees_porcelain(struct unpack_trees_options *opts) { - argv_array_clear(&opts->msgs_to_free); + strvec_clear(&opts->msgs_to_free); memset(opts->msgs, 0, sizeof(opts->msgs)); } diff --git a/unpack-trees.h b/unpack-trees.h index 9c2f08277e..2e87875b15 100644 --- a/unpack-trees.h +++ b/unpack-trees.h @@ -2,7 +2,7 @@ #define UNPACK_TREES_H #include "cache.h" -#include "argv-array.h" +#include "strvec.h" #include "string-list.h" #include "tree-walk.h" @@ -70,7 +70,7 @@ struct unpack_trees_options { struct pathspec *pathspec; merge_fn_t fn; const char *msgs[NB_UNPACK_TREES_WARNING_TYPES]; - struct argv_array msgs_to_free; + struct strvec msgs_to_free; /* * Store error messages in an array, each case * corresponding to a error message type diff --git a/upload-pack.c b/upload-pack.c index 951a2b23aa..d087113d23 100644 --- a/upload-pack.c +++ b/upload-pack.c @@ -18,7 +18,7 @@ #include "sigchain.h" #include "version.h" #include "string-list.h" -#include "argv-array.h" +#include "strvec.h" #include "prio-queue.h" #include "protocol.h" #include "quote.h" @@ -269,45 +269,44 @@ static void create_pack_file(struct upload_pack_data *pack_data, if (!pack_data->pack_objects_hook) pack_objects.git_cmd = 1; else { - argv_array_push(&pack_objects.args, pack_data->pack_objects_hook); - argv_array_push(&pack_objects.args, "git"); + strvec_push(&pack_objects.args, pack_data->pack_objects_hook); + strvec_push(&pack_objects.args, "git"); pack_objects.use_shell = 1; } if (pack_data->shallow_nr) { - argv_array_push(&pack_objects.args, "--shallow-file"); - argv_array_push(&pack_objects.args, ""); + strvec_push(&pack_objects.args, "--shallow-file"); + strvec_push(&pack_objects.args, ""); } - argv_array_push(&pack_objects.args, "pack-objects"); - argv_array_push(&pack_objects.args, "--revs"); + strvec_push(&pack_objects.args, "pack-objects"); + strvec_push(&pack_objects.args, "--revs"); if (pack_data->use_thin_pack) - argv_array_push(&pack_objects.args, "--thin"); + strvec_push(&pack_objects.args, "--thin"); - argv_array_push(&pack_objects.args, "--stdout"); + strvec_push(&pack_objects.args, "--stdout"); if (pack_data->shallow_nr) - argv_array_push(&pack_objects.args, "--shallow"); + strvec_push(&pack_objects.args, "--shallow"); if (!pack_data->no_progress) - argv_array_push(&pack_objects.args, "--progress"); + strvec_push(&pack_objects.args, "--progress"); if (pack_data->use_ofs_delta) - argv_array_push(&pack_objects.args, "--delta-base-offset"); + strvec_push(&pack_objects.args, "--delta-base-offset"); if (pack_data->use_include_tag) - argv_array_push(&pack_objects.args, "--include-tag"); + strvec_push(&pack_objects.args, "--include-tag"); if (pack_data->filter_options.choice) { const char *spec = expand_list_objects_filter_spec(&pack_data->filter_options); if (pack_objects.use_shell) { struct strbuf buf = STRBUF_INIT; sq_quote_buf(&buf, spec); - argv_array_pushf(&pack_objects.args, "--filter=%s", buf.buf); + strvec_pushf(&pack_objects.args, "--filter=%s", buf.buf); strbuf_release(&buf); } else { - argv_array_pushf(&pack_objects.args, "--filter=%s", - spec); + strvec_pushf(&pack_objects.args, "--filter=%s", spec); } } if (uri_protocols) { for (i = 0; i < uri_protocols->nr; i++) - argv_array_pushf(&pack_objects.args, "--uri-protocol=%s", + strvec_pushf(&pack_objects.args, "--uri-protocol=%s", uri_protocols->items[i].string); } @@ -482,7 +481,8 @@ static int got_oid(struct upload_pack_data *data, { if (get_oid_hex(hex, oid)) die("git upload-pack: expected SHA1 object, got '%s'", hex); - if (!has_object_file(oid)) + if (!has_object_file_with_flags(oid, + OBJECT_INFO_QUICK | OBJECT_INFO_SKIP_FETCH_OBJECT)) return -1; return do_got_oid(data, oid); } @@ -880,26 +880,26 @@ static int send_shallow_list(struct upload_pack_data *data) deepen(data, data->depth); ret = 1; } else if (data->deepen_rev_list) { - struct argv_array av = ARGV_ARRAY_INIT; + struct strvec av = STRVEC_INIT; int i; - argv_array_push(&av, "rev-list"); + strvec_push(&av, "rev-list"); if (data->deepen_since) - argv_array_pushf(&av, "--max-age=%"PRItime, data->deepen_since); + strvec_pushf(&av, "--max-age=%"PRItime, data->deepen_since); if (data->deepen_not.nr) { - argv_array_push(&av, "--not"); + strvec_push(&av, "--not"); for (i = 0; i < data->deepen_not.nr; i++) { struct string_list_item *s = data->deepen_not.items + i; - argv_array_push(&av, s->string); + strvec_push(&av, s->string); } - argv_array_push(&av, "--not"); + strvec_push(&av, "--not"); } for (i = 0; i < data->want_obj.nr; i++) { struct object *o = data->want_obj.objects[i].item; - argv_array_push(&av, oid_to_hex(&o->oid)); + strvec_push(&av, oid_to_hex(&o->oid)); } - deepen_by_rev_list(data, av.argc, av.argv); - argv_array_clear(&av); + deepen_by_rev_list(data, av.nr, av.v); + strvec_clear(&av); ret = 1; } else { if (data->shallows.nr > 0) { @@ -1423,7 +1423,8 @@ static int process_haves(struct upload_pack_data *data, struct oid_array *common for (i = 0; i < data->haves.nr; i++) { const struct object_id *oid = &data->haves.oid[i]; - if (!has_object_file(oid)) + if (!has_object_file_with_flags(oid, + OBJECT_INFO_QUICK | OBJECT_INFO_SKIP_FETCH_OBJECT)) continue; oid_array_append(common, oid); @@ -1521,7 +1522,7 @@ enum fetch_state { FETCH_DONE, }; -int upload_pack_v2(struct repository *r, struct argv_array *keys, +int upload_pack_v2(struct repository *r, struct strvec *keys, struct packet_reader *request) { enum fetch_state state = FETCH_PROCESS_ARGS; diff --git a/upload-pack.h b/upload-pack.h index 4bafe16a22..27ddcdc6cb 100644 --- a/upload-pack.h +++ b/upload-pack.h @@ -11,9 +11,9 @@ struct upload_pack_options { void upload_pack(struct upload_pack_options *options); struct repository; -struct argv_array; +struct strvec; struct packet_reader; -int upload_pack_v2(struct repository *r, struct argv_array *keys, +int upload_pack_v2(struct repository *r, struct strvec *keys, struct packet_reader *request); struct strbuf; diff --git a/worktree.c b/worktree.c index cba2e54598..62217b4a6b 100644 --- a/worktree.c +++ b/worktree.c @@ -49,10 +49,8 @@ static struct worktree *get_main_worktree(void) struct worktree *worktree = NULL; struct strbuf worktree_path = STRBUF_INIT; - strbuf_add_absolute_path(&worktree_path, get_git_common_dir()); - if (!strbuf_strip_suffix(&worktree_path, "/.git/.") && /* in .git */ - !strbuf_strip_suffix(&worktree_path, "/.git")) /* in worktree */ - strbuf_strip_suffix(&worktree_path, "/."); /* in bare repo */ + strbuf_add_real_path(&worktree_path, get_git_common_dir()); + strbuf_strip_suffix(&worktree_path, "/.git"); worktree = xcalloc(1, sizeof(*worktree)); worktree->path = strbuf_detach(&worktree_path, NULL); @@ -66,8 +64,6 @@ static struct worktree *get_main_worktree(void) worktree->is_bare = (is_bare_repository_cfg == 1) || is_bare_repository(); add_head_info(worktree); - - strbuf_release(&worktree_path); return worktree; } @@ -84,16 +80,8 @@ static struct worktree *get_linked_worktree(const char *id) if (strbuf_read_file(&worktree_path, path.buf, 0) <= 0) /* invalid gitdir file */ goto done; - strbuf_rtrim(&worktree_path); - if (!strbuf_strip_suffix(&worktree_path, "/.git")) { - strbuf_reset(&worktree_path); - strbuf_add_absolute_path(&worktree_path, "."); - strbuf_strip_suffix(&worktree_path, "/."); - } - - strbuf_reset(&path); - strbuf_addf(&path, "%s/worktrees/%s/HEAD", get_git_common_dir(), id); + strbuf_strip_suffix(&worktree_path, "/.git"); worktree = xcalloc(1, sizeof(*worktree)); worktree->path = strbuf_detach(&worktree_path, NULL); diff --git a/wt-status.c b/wt-status.c index c560cbe860..d75399085d 100644 --- a/wt-status.c +++ b/wt-status.c @@ -8,7 +8,7 @@ #include "diffcore.h" #include "quote.h" #include "run-command.h" -#include "argv-array.h" +#include "strvec.h" #include "remote.h" #include "refs.h" #include "submodule.h" @@ -913,17 +913,16 @@ static void wt_longstatus_print_submodule_summary(struct wt_status *s, int uncom struct strbuf summary = STRBUF_INIT; char *summary_content; - argv_array_pushf(&sm_summary.env_array, "GIT_INDEX_FILE=%s", - s->index_file); + strvec_pushf(&sm_summary.env_array, "GIT_INDEX_FILE=%s", s->index_file); - argv_array_push(&sm_summary.args, "submodule"); - argv_array_push(&sm_summary.args, "summary"); - argv_array_push(&sm_summary.args, uncommitted ? "--files" : "--cached"); - argv_array_push(&sm_summary.args, "--for-status"); - argv_array_push(&sm_summary.args, "--summary-limit"); - argv_array_pushf(&sm_summary.args, "%d", s->submodule_summary); + strvec_push(&sm_summary.args, "submodule"); + strvec_push(&sm_summary.args, "summary"); + strvec_push(&sm_summary.args, uncommitted ? "--files" : "--cached"); + strvec_push(&sm_summary.args, "--for-status"); + strvec_push(&sm_summary.args, "--summary-limit"); + strvec_pushf(&sm_summary.args, "%d", s->submodule_summary); if (!uncommitted) - argv_array_push(&sm_summary.args, s->amend ? "HEAD^" : "HEAD"); + strvec_push(&sm_summary.args, s->amend ? "HEAD^" : "HEAD"); sm_summary.git_cmd = 1; sm_summary.no_stdin = 1; @@ -2035,7 +2034,7 @@ static void wt_porcelain_print(struct wt_status *s) * [# branch.upstream <upstream><eol> * [# branch.ab +<ahead> -<behind><eol>]] * - * <commit> ::= the current commit hash or the the literal + * <commit> ::= the current commit hash or the literal * "(initial)" to indicate an initialized repo * with no commits. * |