diff options
45 files changed, 448 insertions, 193 deletions
diff --git a/Documentation/RelNotes/2.12.0.txt b/Documentation/RelNotes/2.12.0.txt index 0c6eed2007..3c539da725 100644 --- a/Documentation/RelNotes/2.12.0.txt +++ b/Documentation/RelNotes/2.12.0.txt @@ -131,6 +131,9 @@ UI, Workflows & Features other than the ones that are expected to be updated (i.e. branches, remote-tracking branches and notes). + * Comes with more command line completion (in contrib/) for recently + introduced options. + Performance, Internal Implementation, Development Support etc. @@ -436,6 +439,29 @@ notes for details). with AsciiDoc. "make USE_ASCIIDOCTOR=YesPlease" to use it out of the box to document our pages is getting closer to reality. + * Correct command line completion (in contrib/) on "git svn" + (merge 2cbad17642 ew/complete-svn-authorship-options later to maint). + + * Incorrect usage help message for "git worktree prune" has been fixed. + (merge 2488dcab22 ps/worktree-prune-help-fix later to maint). + + * Adjust a perf test to new world order where commands that do + require a repository are really strict about having a repository. + (merge c86000c1a7 rs/p5302-create-repositories-before-tests later to maint). + + * "git log --graph" did not work well with "--name-only", even though + other forms of "diff" output were handled correctly. + (merge f5022b5fed jk/log-graph-name-only later to maint). + + * The push-options given via the "--push-options" option were not + passed through to external remote helpers such as "smart HTTP" that + are invoked via the transport helper. + + * The documentation explained what "git stash" does to the working + tree (after stashing away the local changes) in terms of "reset + --hard", which was exposing an unnecessary implementation detail. + (merge 20a7e06172 tg/stash-doc-cleanup later to maint). + * Other minor doc, test and build updates and code cleanups. (merge f2627d9b19 sb/submodule-config-cleanup later to maint). (merge 384f1a167b sb/unpack-trees-cleanup later to maint). @@ -444,3 +470,7 @@ notes for details). (merge 0aaad415bc rs/absolute-pathdup later to maint). (merge 4432dd6b5b rs/receive-pack-cleanup later to maint). (merge 540a398e9c sg/mailmap-self later to maint). + (merge 209df269a6 nd/rev-list-all-includes-HEAD-doc later to maint). + (merge 941b9c5270 sb/doc-unify-bottom later to maint). + (merge 2aaf37b62c jk/doc-remote-helpers-markup-fix later to maint). + (merge e91461b332 jk/doc-submodule-markup-fix later to maint). diff --git a/Documentation/git-difftool.txt b/Documentation/git-difftool.txt index 224fb3090b..96c26e6aa8 100644 --- a/Documentation/git-difftool.txt +++ b/Documentation/git-difftool.txt @@ -86,10 +86,11 @@ instead. `--no-symlinks` is the default on Windows. Additionally, `$BASE` is set in the environment. -g:: ---gui:: +--[no-]gui:: When 'git-difftool' is invoked with the `-g` or `--gui` option the default diff tool will be read from the configured - `diff.guitool` variable instead of `diff.tool`. + `diff.guitool` variable instead of `diff.tool`. The `--no-gui` + option can be used to override this setting. --[no-]trust-exit-code:: 'git-difftool' invokes a diff tool individually on each file. diff --git a/Documentation/git-push.txt b/Documentation/git-push.txt index 8eefabd0d1..1624a35888 100644 --- a/Documentation/git-push.txt +++ b/Documentation/git-push.txt @@ -272,7 +272,7 @@ origin +master` to force a push to the `master` branch). See the standard error stream is not directed to a terminal. --no-recurse-submodules:: ---recurse-submodules=check|on-demand|no:: +--recurse-submodules=check|on-demand|only|no:: May be used to make sure all submodule commits used by the revisions to be pushed are available on a remote-tracking branch. If 'check' is used Git will verify that all submodule commits that @@ -280,11 +280,12 @@ origin +master` to force a push to the `master` branch). See the remote of the submodule. If any commits are missing the push will be aborted and exit with non-zero status. If 'on-demand' is used all submodules that changed in the revisions to be pushed will be - pushed. If on-demand was not able to push all necessary revisions - it will also be aborted and exit with non-zero status. A value of - 'no' or using `--no-recurse-submodules` can be used to override the - push.recurseSubmodules configuration variable when no submodule - recursion is required. + pushed. If on-demand was not able to push all necessary revisions it will + also be aborted and exit with non-zero status. If 'only' is used all + submodules will be recursively pushed while the superproject is left + unpushed. A value of 'no' or using `--no-recurse-submodules` can be used + to override the push.recurseSubmodules configuration variable when no + submodule recursion is required. --[no-]verify:: Toggle the pre-push hook (see linkgit:githooks[5]). The diff --git a/Documentation/git-stash.txt b/Documentation/git-stash.txt index 2e9cef06e6..2e9e344cd7 100644 --- a/Documentation/git-stash.txt +++ b/Documentation/git-stash.txt @@ -47,8 +47,9 @@ OPTIONS save [-p|--patch] [-k|--[no-]keep-index] [-u|--include-untracked] [-a|--all] [-q|--quiet] [<message>]:: - Save your local modifications to a new 'stash', and run `git reset - --hard` to revert them. The <message> part is optional and gives + Save your local modifications to a new 'stash' and roll them + back to HEAD (in the working tree and in the index). + The <message> part is optional and gives the description along with the stashed state. For quickly making a snapshot, you can omit _both_ "save" and <message>, but giving only <message> does not trigger this action to prevent a misspelled diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt index 918bd1d1bd..8acc72ebb8 100644 --- a/Documentation/git-submodule.txt +++ b/Documentation/git-submodule.txt @@ -9,17 +9,12 @@ git-submodule - Initialize, update or inspect submodules SYNOPSIS -------- [verse] -'git submodule' [--quiet] add [-b <branch>] [-f|--force] [--name <name>] - [--reference <repository>] [--depth <depth>] [--] <repository> [<path>] +'git submodule' [--quiet] add [<options>] [--] <repository> [<path>] 'git submodule' [--quiet] status [--cached] [--recursive] [--] [<path>...] 'git submodule' [--quiet] init [--] [<path>...] 'git submodule' [--quiet] deinit [-f|--force] (--all|[--] <path>...) -'git submodule' [--quiet] update [--init] [--remote] [-N|--no-fetch] - [--[no-]recommend-shallow] [-f|--force] [--rebase|--merge] - [--reference <repository>] [--depth <depth>] [--recursive] - [--jobs <n>] [--] [<path>...] -'git submodule' [--quiet] summary [--cached|--files] [(-n|--summary-limit) <n>] - [commit] [--] [<path>...] +'git submodule' [--quiet] update [<options>] [--] [<path>...] +'git submodule' [--quiet] summary [<options>] [--] [<path>...] 'git submodule' [--quiet] foreach [--recursive] <command> 'git submodule' [--quiet] sync [--recursive] [--] [<path>...] 'git submodule' [--quiet] absorbgitdirs [--] [<path>...] @@ -63,7 +58,7 @@ if you choose to go that route. COMMANDS -------- -add:: +add [-b <branch>] [-f|--force] [--name <name>] [--reference <repository>] [--depth <depth>] [--] <repository> [<path>]:: Add the given repository as a submodule at the given path to the changeset to be committed next to the current project: the current project is termed the "superproject". @@ -104,7 +99,7 @@ together in the same relative location, and only the superproject's URL needs to be provided: git-submodule will correctly locate the submodule using the relative URL in .gitmodules. -status:: +status [--cached] [--recursive] [--] [<path>...]:: Show the status of the submodules. This will print the SHA-1 of the currently checked out commit for each submodule, along with the submodule path and the output of 'git describe' for the @@ -121,7 +116,7 @@ submodules with respect to the commit recorded in the index or the HEAD, linkgit:git-status[1] and linkgit:git-diff[1] will provide that information too (and can also report changes to a submodule's work tree). -init:: +init [--] [<path>...]:: Initialize the submodules recorded in the index (which were added and committed elsewhere) by copying submodule names and urls from .gitmodules to .git/config. @@ -136,7 +131,7 @@ init:: the explicit 'init' step if you do not intend to customize any submodule locations. -deinit:: +deinit [-f|--force] (--all|[--] <path>...):: Unregister the given submodules, i.e. remove the whole `submodule.$name` section from .git/config together with their work tree. Further calls to `git submodule update`, `git submodule foreach` @@ -152,20 +147,20 @@ instead of deinit-ing everything, to prevent mistakes. If `--force` is specified, the submodule's working tree will be removed even if it contains local modifications. -update:: +update [--init] [--remote] [-N|--no-fetch] [--[no-]recommend-shallow] [-f|--force] [--checkout|--rebase|--merge] [--reference <repository>] [--depth <depth>] [--recursive] [--jobs <n>] [--] [<path>...]:: + -- Update the registered submodules to match what the superproject expects by cloning missing submodules and updating the working tree of the submodules. The "updating" can be done in several ways depending on command line options and the value of `submodule.<name>.update` -configuration variable. Supported update procedures are: +configuration variable. The command line option takes precedence over +the configuration variable. if neither is given, a checkout is performed. +update procedures supported both from the command line as well as setting +`submodule.<name>.update`: checkout;; the commit recorded in the superproject will be - checked out in the submodule on a detached HEAD. This is - done when `--checkout` option is given, or no option is - given, and `submodule.<name>.update` is unset, or if it is - set to 'checkout'. + checked out in the submodule on a detached HEAD. + If `--force` is specified, the submodule will be checked out (using `git checkout --force` if appropriate), even if the commit specified @@ -173,23 +168,21 @@ in the index of the containing repository already matches the commit checked out in the submodule. rebase;; the current branch of the submodule will be rebased - onto the commit recorded in the superproject. This is done - when `--rebase` option is given, or no option is given, and - `submodule.<name>.update` is set to 'rebase'. + onto the commit recorded in the superproject. merge;; the commit recorded in the superproject will be merged - into the current branch in the submodule. This is done - when `--merge` option is given, or no option is given, and - `submodule.<name>.update` is set to 'merge'. + into the current branch in the submodule. + +The following procedures are only available via the `submodule.<name>.update` +configuration variable: custom command;; arbitrary shell command that takes a single argument (the sha1 of the commit recorded in the - superproject) is executed. This is done when no option is - given, and `submodule.<name>.update` has the form of - '!command'. + superproject) is executed. When `submodule.<name>.update` + is set to '!command', the remainder after the exclamation mark + is the custom command. -When no option is given and `submodule.<name>.update` is set to 'none', -the submodule is not updated. + none;; the submodule is not updated. If the submodule is not yet initialized, and you just want to use the setting as stored in .gitmodules, you can automatically initialize the @@ -198,7 +191,7 @@ submodule with the `--init` option. If `--recursive` is specified, this command will recurse into the registered submodules, and update any nested submodules within. -- -summary:: +summary [--cached|--files] [(-n|--summary-limit) <n>] [commit] [--] [<path>...]:: Show commit summary between the given commit (defaults to HEAD) and working tree/index. For a submodule in question, a series of commits in the submodule between the given super project commit and the @@ -211,7 +204,7 @@ summary:: Using the `--submodule=log` option with linkgit:git-diff[1] will provide that information too. -foreach:: +foreach [--recursive] <command>:: Evaluates an arbitrary shell command in each checked out submodule. The command has access to the variables $name, $path, $sha1 and $toplevel: @@ -228,11 +221,14 @@ foreach:: the processing to terminate. This can be overridden by adding '|| :' to the end of the command. + -As an example, +git submodule foreach \'echo $path {backtick}git -rev-parse HEAD{backtick}'+ will show the path and currently checked out -commit for each submodule. +As an example, the command below will show the path and currently +checked out commit for each submodule: ++ +-------------- +git submodule foreach 'echo $path `git rev-parse HEAD`' +-------------- -sync:: +sync [--recursive] [--] [<path>...]:: Synchronizes submodules' remote URL configuration setting to the value specified in .gitmodules. It will only affect those submodules which already have a URL entry in .git/config (that is the diff --git a/Documentation/gitcore-tutorial.txt b/Documentation/gitcore-tutorial.txt index 22309cfb48..3a0ec8c53a 100644 --- a/Documentation/gitcore-tutorial.txt +++ b/Documentation/gitcore-tutorial.txt @@ -1658,4 +1658,4 @@ link:user-manual.html[The Git User's Manual] GIT --- -Part of the linkgit:git[1] suite. +Part of the linkgit:git[1] suite diff --git a/Documentation/gitcvs-migration.txt b/Documentation/gitcvs-migration.txt index 4c6143c511..1cd1283d0f 100644 --- a/Documentation/gitcvs-migration.txt +++ b/Documentation/gitcvs-migration.txt @@ -203,4 +203,4 @@ link:user-manual.html[The Git User's Manual] GIT --- -Part of the linkgit:git[1] suite. +Part of the linkgit:git[1] suite diff --git a/Documentation/gitdiffcore.txt b/Documentation/gitdiffcore.txt index 08cf62278e..46bc6d077c 100644 --- a/Documentation/gitdiffcore.txt +++ b/Documentation/gitdiffcore.txt @@ -288,4 +288,4 @@ link:user-manual.html[The Git User's Manual] GIT --- -Part of the linkgit:git[1] suite. +Part of the linkgit:git[1] suite diff --git a/Documentation/gitglossary.txt b/Documentation/gitglossary.txt index 212e254adc..571f640f5c 100644 --- a/Documentation/gitglossary.txt +++ b/Documentation/gitglossary.txt @@ -24,4 +24,4 @@ link:user-manual.html[The Git User's Manual] GIT --- -Part of the linkgit:git[1] suite. +Part of the linkgit:git[1] suite diff --git a/Documentation/gitremote-helpers.txt b/Documentation/gitremote-helpers.txt index 9e8681f9e1..e4b785eb60 100644 --- a/Documentation/gitremote-helpers.txt +++ b/Documentation/gitremote-helpers.txt @@ -452,16 +452,20 @@ set by Git if the remote helper has the 'option' capability. Request the helper to perform a force update. Defaults to 'false'. -'option cloning {'true'|'false'}:: +'option cloning' {'true'|'false'}:: Notify the helper this is a clone request (i.e. the current repository is guaranteed empty). -'option update-shallow {'true'|'false'}:: +'option update-shallow' {'true'|'false'}:: Allow to extend .git/shallow if the new refs require it. -'option pushcert {'true'|'false'}:: +'option pushcert' {'true'|'false'}:: GPG sign pushes. +'option push-option <string>:: + Transmit <string> as a push option. As the a push option + must not contain LF or NUL characters, the string is not encoded. + SEE ALSO -------- linkgit:git-remote[1] diff --git a/Documentation/gitrepository-layout.txt b/Documentation/gitrepository-layout.txt index a5f99cbb11..f51ed4e37c 100644 --- a/Documentation/gitrepository-layout.txt +++ b/Documentation/gitrepository-layout.txt @@ -289,4 +289,4 @@ link:user-manual.html[The Git User's Manual] GIT --- -Part of the linkgit:git[1] suite. +Part of the linkgit:git[1] suite diff --git a/Documentation/gittutorial-2.txt b/Documentation/gittutorial-2.txt index 30d2119565..e0976f6017 100644 --- a/Documentation/gittutorial-2.txt +++ b/Documentation/gittutorial-2.txt @@ -433,4 +433,4 @@ link:user-manual.html[The Git User's Manual] GIT --- -Part of the linkgit:git[1] suite. +Part of the linkgit:git[1] suite diff --git a/Documentation/gittutorial.txt b/Documentation/gittutorial.txt index b3b58d324e..794b83393e 100644 --- a/Documentation/gittutorial.txt +++ b/Documentation/gittutorial.txt @@ -674,4 +674,4 @@ link:user-manual.html[The Git User's Manual] GIT --- -Part of the linkgit:git[1] suite. +Part of the linkgit:git[1] suite diff --git a/Documentation/gitworkflows.txt b/Documentation/gitworkflows.txt index f16c414ea7..177610e44e 100644 --- a/Documentation/gitworkflows.txt +++ b/Documentation/gitworkflows.txt @@ -477,4 +477,4 @@ linkgit:git-am[1] GIT --- -Part of the linkgit:git[1] suite. +Part of the linkgit:git[1] suite diff --git a/Documentation/rev-list-options.txt b/Documentation/rev-list-options.txt index 5da7cf5a8d..a02f7324c0 100644 --- a/Documentation/rev-list-options.txt +++ b/Documentation/rev-list-options.txt @@ -133,8 +133,8 @@ parents) and `--max-parents=-1` (negative numbers denote no upper limit). for all following revision specifiers, up to the next `--not`. --all:: - Pretend as if all the refs in `refs/` are listed on the - command line as '<commit>'. + Pretend as if all the refs in `refs/`, along with `HEAD`, are + listed on the command line as '<commit>'. --branches[=<pattern>]:: Pretend as if all the refs in `refs/heads` are listed diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN index 4bed33d2ae..1eabbd88ac 100755 --- a/GIT-VERSION-GEN +++ b/GIT-VERSION-GEN @@ -1,7 +1,7 @@ #!/bin/sh GVF=GIT-VERSION-FILE -DEF_VER=v2.12.0-rc0 +DEF_VER=v2.12.0-rc1 LF=' ' @@ -2187,29 +2187,20 @@ static int parse_chunk(struct apply_state *state, char *buffer, unsigned long si return offset + hdrsize + patchsize; } -#define swap(a,b) myswap((a),(b),sizeof(a)) - -#define myswap(a, b, size) do { \ - unsigned char mytmp[size]; \ - memcpy(mytmp, &a, size); \ - memcpy(&a, &b, size); \ - memcpy(&b, mytmp, size); \ -} while (0) - static void reverse_patches(struct patch *p) { for (; p; p = p->next) { struct fragment *frag = p->fragments; - swap(p->new_name, p->old_name); - swap(p->new_mode, p->old_mode); - swap(p->is_new, p->is_delete); - swap(p->lines_added, p->lines_deleted); - swap(p->old_sha1_prefix, p->new_sha1_prefix); + SWAP(p->new_name, p->old_name); + SWAP(p->new_mode, p->old_mode); + SWAP(p->is_new, p->is_delete); + SWAP(p->lines_added, p->lines_deleted); + SWAP(p->old_sha1_prefix, p->new_sha1_prefix); for (; frag; frag = frag->next) { - swap(frag->newpos, frag->oldpos); - swap(frag->newlines, frag->oldlines); + SWAP(frag->newpos, frag->oldpos); + SWAP(frag->newlines, frag->oldlines); } } } diff --git a/builtin/diff-tree.c b/builtin/diff-tree.c index 806dd7a885..8ce00480cd 100644 --- a/builtin/diff-tree.c +++ b/builtin/diff-tree.c @@ -147,9 +147,7 @@ int cmd_diff_tree(int argc, const char **argv, const char *prefix) tree1 = opt->pending.objects[0].item; tree2 = opt->pending.objects[1].item; if (tree2->flags & UNINTERESTING) { - struct object *tmp = tree2; - tree2 = tree1; - tree1 = tmp; + SWAP(tree2, tree1); } diff_tree_sha1(tree1->oid.hash, tree2->oid.hash, diff --git a/builtin/diff.c b/builtin/diff.c index 7f91f6d226..3d64b85337 100644 --- a/builtin/diff.c +++ b/builtin/diff.c @@ -45,12 +45,9 @@ static void stuff_change(struct diff_options *opt, return; if (DIFF_OPT_TST(opt, REVERSE_DIFF)) { - unsigned tmp; - const unsigned char *tmp_u; - const char *tmp_c; - tmp = old_mode; old_mode = new_mode; new_mode = tmp; - tmp_u = old_sha1; old_sha1 = new_sha1; new_sha1 = tmp_u; - tmp_c = old_name; old_name = new_name; new_name = tmp_c; + SWAP(old_mode, new_mode); + SWAP(old_sha1, new_sha1); + SWAP(old_name, new_name); } if (opt->prefix && diff --git a/builtin/difftool.c b/builtin/difftool.c index b5e85ab079..d13350ce83 100644 --- a/builtin/difftool.c +++ b/builtin/difftool.c @@ -647,10 +647,6 @@ int cmd_difftool(int argc, const char **argv, const char *prefix) OPT_END() }; - /* NEEDSWORK: once we no longer spawn anything, remove this */ - setenv(GIT_DIR_ENVIRONMENT, absolute_path(get_git_dir()), 1); - setenv(GIT_WORK_TREE_ENVIRONMENT, absolute_path(get_git_work_tree()), 1); - git_config(difftool_config, NULL); symlinks = has_symlinks; @@ -661,6 +657,10 @@ int cmd_difftool(int argc, const char **argv, const char *prefix) if (tool_help) return print_tool_help(); + /* NEEDSWORK: once we no longer spawn anything, remove this */ + setenv(GIT_DIR_ENVIRONMENT, absolute_path(get_git_dir()), 1); + setenv(GIT_WORK_TREE_ENVIRONMENT, absolute_path(get_git_work_tree()), 1); + if (use_gui_tool && diff_gui_tool && *diff_gui_tool) setenv("GIT_DIFF_TOOL", diff_gui_tool, 1); else if (difftool_cmd) { diff --git a/builtin/ls-files.c b/builtin/ls-files.c index 1592290815..1c0f057d02 100644 --- a/builtin/ls-files.c +++ b/builtin/ls-files.c @@ -369,28 +369,30 @@ static void show_files(struct dir_struct *dir) /* * Prune the index to only contain stuff starting with "prefix" */ -static void prune_cache(const char *prefix) +static void prune_cache(const char *prefix, size_t prefixlen) { - int pos = cache_name_pos(prefix, max_prefix_len); + int pos; unsigned int first, last; + if (!prefix) + return; + pos = cache_name_pos(prefix, prefixlen); if (pos < 0) pos = -pos-1; - memmove(active_cache, active_cache + pos, - (active_nr - pos) * sizeof(struct cache_entry *)); - active_nr -= pos; - first = 0; + first = pos; last = active_nr; while (last > first) { int next = (last + first) >> 1; const struct cache_entry *ce = active_cache[next]; - if (!strncmp(ce->name, prefix, max_prefix_len)) { + if (!strncmp(ce->name, prefix, prefixlen)) { first = next+1; continue; } last = next; } - active_nr = last; + memmove(active_cache, active_cache + pos, + (last - pos) * sizeof(struct cache_entry *)); + active_nr = last - pos; } /* @@ -641,8 +643,7 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix) show_killed || show_modified || show_resolve_undo)) show_cached = 1; - if (max_prefix) - prune_cache(max_prefix); + prune_cache(max_prefix, max_prefix_len); if (with_tree) { /* * Basic sanity check; show-stages and show-unmerged diff --git a/builtin/rm.c b/builtin/rm.c index 452170a3ab..fb79dcab18 100644 --- a/builtin/rm.c +++ b/builtin/rm.c @@ -360,15 +360,14 @@ int cmd_rm(int argc, const char **argv, const char *prefix) */ if (!index_only) { int removed = 0, gitmodules_modified = 0; + struct strbuf buf = STRBUF_INIT; for (i = 0; i < list.nr; i++) { const char *path = list.entry[i].name; if (list.entry[i].is_submodule) { - struct strbuf buf = STRBUF_INIT; - + strbuf_reset(&buf); strbuf_addstr(&buf, path); if (remove_dir_recursively(&buf, 0)) die(_("could not remove '%s'"), path); - strbuf_release(&buf); removed = 1; if (!remove_path_from_gitmodules(path)) @@ -382,6 +381,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix) if (!removed) die_errno("git rm: '%s'", path); } + strbuf_release(&buf); if (gitmodules_modified) stage_updated_gitmodules(); } diff --git a/builtin/worktree.c b/builtin/worktree.c index 9a97e37a3f..831fe058a5 100644 --- a/builtin/worktree.c +++ b/builtin/worktree.c @@ -125,9 +125,9 @@ static int prune(int ac, const char **av, const char *prefix) { struct option options[] = { OPT__DRY_RUN(&show_only, N_("do not remove, show only")), - OPT__VERBOSE(&verbose, N_("report pruned objects")), + OPT__VERBOSE(&verbose, N_("report pruned working trees")), OPT_EXPIRY_DATE(0, "expire", &expire, - N_("expire objects older than <time>")), + N_("expire working trees older than <time>")), OPT_END() }; diff --git a/compat/winansi.c b/compat/winansi.c index 82b89ab137..793420f9d0 100644 --- a/compat/winansi.c +++ b/compat/winansi.c @@ -510,6 +510,8 @@ static HANDLE swap_osfhnd(int fd, HANDLE new_handle) */ close(new_fd); + if (fd == 2) + setvbuf(stderr, NULL, _IONBF, BUFSIZ); fd_is_interactive[fd] |= FD_SWAPPED; return duplicate; @@ -547,6 +549,8 @@ static void detect_msys_tty(int fd) !wcsstr(name, L"-pty")) return; + if (fd == 2) + setvbuf(stderr, NULL, _IONBF, BUFSIZ); fd_is_interactive[fd] |= FD_MSYS; } diff --git a/contrib/coccinelle/free.cocci b/contrib/coccinelle/free.cocci index e28213161a..c03ba737e5 100644 --- a/contrib/coccinelle/free.cocci +++ b/contrib/coccinelle/free.cocci @@ -3,3 +3,9 @@ expression E; @@ - if (E) free(E); + +@@ +expression E; +@@ +- if (!E) + free(E); diff --git a/contrib/coccinelle/swap.cocci b/contrib/coccinelle/swap.cocci new file mode 100644 index 0000000000..a0934d1fda --- /dev/null +++ b/contrib/coccinelle/swap.cocci @@ -0,0 +1,28 @@ +@ swap_with_declaration @ +type T; +identifier tmp; +T a, b; +@@ +- T tmp = a; ++ T tmp; ++ tmp = a; + a = b; + b = tmp; + +@ swap @ +type T; +T tmp, a, b; +@@ +- tmp = a; +- a = b; +- b = tmp; ++ SWAP(a, b); + +@ extends swap @ +identifier unused; +@@ + { + ... +- T unused; + ... when != unused + } diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index 97d73ad88f..41ee52991d 100644 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -936,6 +936,7 @@ _git_apply () --apply --no-add --exclude= --ignore-whitespace --ignore-space-change --whitespace= --inaccurate-eof --verbose + --recount --directory= " return esac @@ -947,13 +948,17 @@ _git_add () --*) __gitcomp " --interactive --refresh --patch --update --dry-run - --ignore-errors --intent-to-add + --ignore-errors --intent-to-add --force --edit --chmod= " return esac - # XXX should we check for --update and --all options ? - __git_complete_index_file "--others --modified --directory --no-empty-directory" + local complete_opt="--others --modified --directory --no-empty-directory" + if test -n "$(__git_find_on_cmdline "-u --update")" + then + complete_opt="--modified" + fi + __git_complete_index_file "$complete_opt" } _git_archive () @@ -970,7 +975,7 @@ _git_archive () --*) __gitcomp " --format= --list --verbose - --prefix= --remote= --exec= + --prefix= --remote= --exec= --output " return ;; @@ -1025,6 +1030,7 @@ _git_branch () --track --no-track --contains --merged --no-merged --set-upstream-to= --edit-description --list --unset-upstream --delete --move --remotes + --column --no-column --sort= --points-at " ;; *) @@ -1138,6 +1144,8 @@ _git_clone () --single-branch --branch --recurse-submodules + --no-single-branch + --shallow-submodules " return ;; @@ -1179,6 +1187,7 @@ _git_commit () --reset-author --file= --message= --template= --cleanup= --untracked-files --untracked-files= --verbose --quiet --fixup= --squash= + --patch --short --date --allow-empty " return esac @@ -1197,7 +1206,7 @@ _git_describe () --*) __gitcomp " --all --tags --contains --abbrev= --candidates= - --exact-match --debug --long --match --always + --exact-match --debug --long --match --always --first-parent " return esac @@ -1280,6 +1289,7 @@ __git_fetch_recurse_submodules="yes on-demand no" __git_fetch_options=" --quiet --verbose --append --upload-pack --force --keep --depth= --tags --no-tags --all --prune --dry-run --recurse-submodules= + --unshallow --update-shallow " _git_fetch () @@ -1329,7 +1339,7 @@ _git_fsck () --*) __gitcomp " --tags --root --unreachable --cache --no-reflogs --full - --strict --verbose --lost-found + --strict --verbose --lost-found --name-objects " return ;; @@ -1373,6 +1383,8 @@ _git_grep () --max-depth --count --and --or --not --all-match + --break --heading --show-function --function-context + --untracked --no-index " return ;; @@ -1445,6 +1457,12 @@ _git_ls_files () _git_ls_remote () { + case "$cur" in + --*) + __gitcomp "--heads --tags --refs --get-url --symref" + return + ;; + esac __gitcomp_nl "$(__git_remotes)" } @@ -1566,7 +1584,7 @@ _git_mergetool () return ;; --*) - __gitcomp "--tool=" + __gitcomp "--tool= --prompt --no-prompt" return ;; esac @@ -1674,7 +1692,7 @@ _git_pull () __git_complete_remote_or_refspec } -__git_push_recurse_submodules="check on-demand" +__git_push_recurse_submodules="check on-demand only" __git_complete_force_with_lease () { @@ -2374,40 +2392,88 @@ _git_config () _git_remote () { - local subcommands="add rename remove set-head set-branches set-url show prune update" + local subcommands=" + add rename remove set-head set-branches + get-url set-url show prune update + " local subcommand="$(__git_find_on_cmdline "$subcommands")" if [ -z "$subcommand" ]; then - __gitcomp "$subcommands" + case "$cur" in + --*) + __gitcomp "--verbose" + ;; + *) + __gitcomp "$subcommands" + ;; + esac return fi - case "$subcommand" in - rename|remove|set-url|show|prune) - __gitcomp_nl "$(__git_remotes)" + case "$subcommand,$cur" in + add,--*) + __gitcomp "--track --master --fetch --tags --no-tags --mirror=" + ;; + add,*) + ;; + set-head,--*) + __gitcomp "--auto --delete" + ;; + set-branches,--*) + __gitcomp "--add" ;; - set-head|set-branches) + set-head,*|set-branches,*) __git_complete_remote_or_refspec ;; - update) + update,--*) + __gitcomp "--prune" + ;; + update,*) __gitcomp "$(__git_get_config_variables "remotes")" ;; + set-url,--*) + __gitcomp "--push --add --delete" + ;; + get-url,--*) + __gitcomp "--push --all" + ;; + prune,--*) + __gitcomp "--dry-run" + ;; *) + __gitcomp_nl "$(__git_remotes)" ;; esac } _git_replace () { + case "$cur" in + --*) + __gitcomp "--edit --graft --format= --list --delete" + return + ;; + esac __gitcomp_nl "$(__git_refs)" } +_git_rerere () +{ + local subcommands="clear forget diff remaining status gc" + local subcommand="$(__git_find_on_cmdline "$subcommands")" + if test -z "$subcommand" + then + __gitcomp "$subcommands" + return + fi +} + _git_reset () { __git_has_doubledash && return case "$cur" in --*) - __gitcomp "--merge --mixed --hard --soft --patch" + __gitcomp "--merge --mixed --hard --soft --patch --keep" return ;; esac @@ -2423,7 +2489,10 @@ _git_revert () fi case "$cur" in --*) - __gitcomp "--edit --mainline --no-edit --no-commit --signoff" + __gitcomp " + --edit --mainline --no-edit --no-commit --signoff + --strategy= --strategy-option= + " return ;; esac @@ -2451,7 +2520,7 @@ _git_shortlog () __gitcomp " $__git_log_common_options $__git_log_shortlog_options - --numbered --summary + --numbered --summary --email " return ;; @@ -2556,10 +2625,11 @@ _git_submodule () __git_has_doubledash && return local subcommands="add status init deinit update summary foreach sync" - if [ -z "$(__git_find_on_cmdline "$subcommands")" ]; then + local subcommand="$(__git_find_on_cmdline "$subcommands")" + if [ -z "$subcommand" ]; then case "$cur" in --*) - __gitcomp "--quiet --cached" + __gitcomp "--quiet" ;; *) __gitcomp "$subcommands" @@ -2567,6 +2637,33 @@ _git_submodule () esac return fi + + case "$subcommand,$cur" in + add,--*) + __gitcomp "--branch --force --name --reference --depth" + ;; + status,--*) + __gitcomp "--cached --recursive" + ;; + deinit,--*) + __gitcomp "--force --all" + ;; + update,--*) + __gitcomp " + --init --remote --no-fetch + --recommend-shallow --no-recommend-shallow + --force --rebase --merge --reference --depth --recursive --jobs + " + ;; + summary,--*) + __gitcomp "--cached --files --summary-limit" + ;; + foreach,--*|sync,--*) + __gitcomp "--recursive" + ;; + *) + ;; + esac } _git_svn () @@ -2587,14 +2684,14 @@ _git_svn () --no-metadata --use-svm-props --use-svnsync-props --log-window-size= --no-checkout --quiet --repack-flags --use-log-author --localtime + --add-author-from --ignore-paths= --include-paths= $remote_opts " local init_opts=" --template= --shared= --trunk= --tags= --branches= --stdlayout --minimize-url --no-metadata --use-svm-props --use-svnsync-props - --rewrite-root= --prefix= --use-log-author - --add-author-from $remote_opts + --rewrite-root= --prefix= $remote_opts " local cmt_opts=" --edit --rmdir --find-copies-harder --copy-similarity= @@ -2701,8 +2798,8 @@ _git_tag () --*) __gitcomp " --list --delete --verify --annotate --message --file - --sign --cleanup --local-user --force --column --sort - --contains --points-at + --sign --cleanup --local-user --force --column --sort= + --contains --points-at --merged --no-merged --create-reflog " ;; esac diff --git a/diff-no-index.c b/diff-no-index.c index f420786039..df762fd0f7 100644 --- a/diff-no-index.c +++ b/diff-no-index.c @@ -185,10 +185,8 @@ static int queue_diff(struct diff_options *o, struct diff_filespec *d1, *d2; if (DIFF_OPT_TST(o, REVERSE_DIFF)) { - unsigned tmp; - const char *tmp_c; - tmp = mode1; mode1 = mode2; mode2 = tmp; - tmp_c = name1; name1 = name2; name2 = tmp_c; + SWAP(mode1, mode2); + SWAP(name1, name2); } d1 = noindex_filespec(name1, mode1); @@ -4450,6 +4450,7 @@ static void flush_one_pair(struct diff_filepair *p, struct diff_options *opt) name_a = p->two->path; name_b = NULL; strip_prefix(opt->prefix_length, &name_a, &name_b); + fprintf(opt->file, "%s", diff_line_prefix(opt)); write_name_quoted(name_a, opt->file, opt->line_termination); } } @@ -5117,14 +5118,10 @@ void diff_change(struct diff_options *options, return; if (DIFF_OPT_TST(options, REVERSE_DIFF)) { - unsigned tmp; - const unsigned char *tmp_c; - tmp = old_mode; old_mode = new_mode; new_mode = tmp; - tmp_c = old_sha1; old_sha1 = new_sha1; new_sha1 = tmp_c; - tmp = old_sha1_valid; old_sha1_valid = new_sha1_valid; - new_sha1_valid = tmp; - tmp = old_dirty_submodule; old_dirty_submodule = new_dirty_submodule; - new_dirty_submodule = tmp; + SWAP(old_mode, new_mode); + SWAP(old_sha1, new_sha1); + SWAP(old_sha1_valid, new_sha1_valid); + SWAP(old_dirty_submodule, new_dirty_submodule); } if (options->prefix && @@ -174,20 +174,19 @@ char *common_prefix(const struct pathspec *pathspec) int fill_directory(struct dir_struct *dir, const struct pathspec *pathspec) { - char *prefix; + const char *prefix; size_t prefix_len; /* * Calculate common prefix for the pathspec, and * use that to optimize the directory walk */ - prefix = common_prefix(pathspec); - prefix_len = prefix ? strlen(prefix) : 0; + prefix_len = common_prefix_len(pathspec); + prefix = prefix_len ? pathspec->items[0].match : ""; /* Read the directory and prune it */ read_directory(dir, prefix, prefix_len, pathspec); - free(prefix); return prefix_len; } diff --git a/git-compat-util.h b/git-compat-util.h index f46d40e4a4..ef6d560e15 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -527,6 +527,16 @@ static inline int ends_with(const char *str, const char *suffix) return strip_suffix(str, suffix, &len); } +#define SWAP(a, b) do { \ + void *_swap_a_ptr = &(a); \ + void *_swap_b_ptr = &(b); \ + unsigned char _swap_buffer[sizeof(a)]; \ + memcpy(_swap_buffer, _swap_a_ptr, sizeof(a)); \ + memcpy(_swap_a_ptr, _swap_b_ptr, sizeof(a) + \ + BUILD_ASSERT_OR_ZERO(sizeof(a) == sizeof(b))); \ + memcpy(_swap_b_ptr, _swap_buffer, sizeof(a)); \ +} while (0) + #if defined(NO_MMAP) || defined(USE_WIN32_MMAP) #ifndef PROT_READ @@ -2484,11 +2484,24 @@ class P4Sync(Command, P4UserMap): self.gitStream.write(d) self.gitStream.write('\n') + def encodeWithUTF8(self, path): + try: + path.decode('ascii') + except: + encoding = 'utf8' + if gitConfig('git-p4.pathEncoding'): + encoding = gitConfig('git-p4.pathEncoding') + path = path.decode(encoding, 'replace').encode('utf8', 'replace') + if self.verbose: + print 'Path with non-ASCII characters detected. Used %s to encode: %s ' % (encoding, path) + return path + # output one file from the P4 stream # - helper for streamP4Files def streamOneP4File(self, file, contents): relPath = self.stripRepoPath(file['depotFile'], self.branchPrefixes) + relPath = self.encodeWithUTF8(relPath) if verbose: size = int(self.stream_file['fileSize']) sys.stdout.write('\r%s --> %s (%i MB)\n' % (file['depotFile'], relPath, size/1024/1024)) @@ -2561,16 +2574,6 @@ class P4Sync(Command, P4UserMap): text = regexp.sub(r'$\1$', text) contents = [ text ] - try: - relPath.decode('ascii') - except: - encoding = 'utf8' - if gitConfig('git-p4.pathEncoding'): - encoding = gitConfig('git-p4.pathEncoding') - relPath = relPath.decode(encoding, 'replace').encode('utf8', 'replace') - if self.verbose: - print 'Path with non-ASCII characters detected. Used %s to encode: %s ' % (encoding, relPath) - if self.largeFileSystem: (git_mode, contents) = self.largeFileSystem.processContent(git_mode, relPath, contents) @@ -2578,6 +2581,7 @@ class P4Sync(Command, P4UserMap): def streamOneP4Deletion(self, file): relPath = self.stripRepoPath(file['path'], self.branchPrefixes) + relPath = self.encodeWithUTF8(relPath) if verbose: sys.stdout.write("delete %s\n" % relPath) sys.stdout.flush() @@ -497,7 +497,6 @@ static void graph_update_width(struct git_graph *graph, static void graph_update_columns(struct git_graph *graph) { struct commit_list *parent; - struct column *tmp_columns; int max_new_columns; int mapping_idx; int i, seen_this, is_commit_in_columns; @@ -510,11 +509,8 @@ static void graph_update_columns(struct git_graph *graph) * We'll re-use the old columns array as storage to compute the new * columns list for the commit after this one. */ - tmp_columns = graph->columns; - graph->columns = graph->new_columns; + SWAP(graph->columns, graph->new_columns); graph->num_columns = graph->num_new_columns; - - graph->new_columns = tmp_columns; graph->num_new_columns = 0; /* @@ -1031,7 +1027,6 @@ static void graph_output_post_merge_line(struct git_graph *graph, struct strbuf static void graph_output_collapsing_line(struct git_graph *graph, struct strbuf *sb) { int i; - int *tmp_mapping; short used_horizontal = 0; int horizontal_edge = -1; int horizontal_edge_target = -1; @@ -1166,9 +1161,7 @@ static void graph_output_collapsing_line(struct git_graph *graph, struct strbuf /* * Swap mapping and new_mapping */ - tmp_mapping = graph->mapping; - graph->mapping = graph->new_mapping; - graph->new_mapping = tmp_mapping; + SWAP(graph->mapping, graph->new_mapping); /* * If graph->mapping indicates that all of the branch lines diff --git a/line-range.c b/line-range.c index de4e32f942..323399d16c 100644 --- a/line-range.c +++ b/line-range.c @@ -269,8 +269,7 @@ int parse_range_arg(const char *arg, nth_line_fn_t nth_line_cb, return -1; if (*begin && *end && *end < *begin) { - long tmp; - tmp = *end; *end = *begin; *begin = tmp; + SWAP(*end, *begin); } return 0; diff --git a/merge-recursive.c b/merge-recursive.c index d327209443..b7ff1ada3c 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -1390,14 +1390,11 @@ static int process_renames(struct merge_options *o, branch1 = o->branch1; branch2 = o->branch2; } else { - struct rename *tmp; renames1 = b_renames; renames2Dst = &a_by_dst; branch1 = o->branch2; branch2 = o->branch1; - tmp = ren2; - ren2 = ren1; - ren1 = tmp; + SWAP(ren2, ren1); } if (ren1->processed) @@ -104,9 +104,7 @@ struct object *lookup_object(const unsigned char *sha1) * that we do not need to walk the hash table the next * time we look for it. */ - struct object *tmp = obj_hash[i]; - obj_hash[i] = obj_hash[first]; - obj_hash[first] = tmp; + SWAP(obj_hash[i], obj_hash[first]); } return obj; } diff --git a/pack-revindex.c b/pack-revindex.c index 6bc7c94033..1b7ebd8d7e 100644 --- a/pack-revindex.c +++ b/pack-revindex.c @@ -59,7 +59,6 @@ static void sort_revindex(struct revindex_entry *entries, unsigned n, off_t max) * be a no-op, as everybody lands in the same zero-th bucket. */ for (bits = 0; max >> bits; bits += DIGIT_SIZE) { - struct revindex_entry *swap; unsigned i; memset(pos, 0, BUCKETS * sizeof(*pos)); @@ -97,9 +96,7 @@ static void sort_revindex(struct revindex_entry *entries, unsigned n, off_t max) * Now "to" contains the most sorted list, so we swap "from" and * "to" for the next iteration. */ - swap = from; - from = to; - to = swap; + SWAP(from, to); } /* diff --git a/prio-queue.c b/prio-queue.c index e4365b00d6..17252d231b 100644 --- a/prio-queue.c +++ b/prio-queue.c @@ -12,9 +12,7 @@ static inline int compare(struct prio_queue *queue, int i, int j) static inline void swap(struct prio_queue *queue, int i, int j) { - struct prio_queue_entry tmp = queue->array[i]; - queue->array[i] = queue->array[j]; - queue->array[j] = tmp; + SWAP(queue->array[i], queue->array[j]); } void prio_queue_reverse(struct prio_queue *queue) @@ -109,9 +109,7 @@ extern void strbuf_attach(struct strbuf *, void *, size_t, size_t); */ static inline void strbuf_swap(struct strbuf *a, struct strbuf *b) { - struct strbuf tmp = *a; - *a = *b; - *b = tmp; + SWAP(*a, *b); } diff --git a/t/perf/p5302-pack-index.sh b/t/perf/p5302-pack-index.sh index 5ee9211f98..99bdb16c85 100755 --- a/t/perf/p5302-pack-index.sh +++ b/t/perf/p5302-pack-index.sh @@ -13,6 +13,13 @@ test_expect_success 'repack' ' export PACK ' +test_expect_success 'create target repositories' ' + for repo in t1 t2 t3 t4 t5 t6 + do + git init --bare $repo + done +' + test_perf 'index-pack 0 threads' ' GIT_DIR=t1 git index-pack --threads=1 --stdin < $PACK ' diff --git a/t/t4202-log.sh b/t/t4202-log.sh index 08ea725de3..48b55bfd27 100755 --- a/t/t4202-log.sh +++ b/t/t4202-log.sh @@ -1212,6 +1212,54 @@ test_expect_success 'log --line-prefix="*** " --graph with diff and stats' ' test_i18ncmp expect actual.sanitized ' +cat >expect <<-\EOF +* reach +| +| A reach.t +* Merge branch 'tangle' +* Merge branch 'side' +|\ +| * side-2 +| +| A 2 +* Second +| +| A one +* sixth + + D a/two +EOF + +test_expect_success 'log --graph with --name-status' ' + git log --graph --format=%s --name-status tangle..reach >actual && + sanitize_output <actual >actual.sanitized && + test_cmp expect actual.sanitized +' + +cat >expect <<-\EOF +* reach +| +| reach.t +* Merge branch 'tangle' +* Merge branch 'side' +|\ +| * side-2 +| +| 2 +* Second +| +| one +* sixth + + a/two +EOF + +test_expect_success 'log --graph with --name-only' ' + git log --graph --format=%s --name-only tangle..reach >actual && + sanitize_output <actual >actual.sanitized && + test_cmp expect actual.sanitized +' + test_expect_success 'dotdot is a parent directory' ' mkdir -p a/b && ( echo sixth && echo fifth ) >expect && diff --git a/t/t5545-push-options.sh b/t/t5545-push-options.sh index ea813b9383..9a57a7d8f2 100755 --- a/t/t5545-push-options.sh +++ b/t/t5545-push-options.sh @@ -3,6 +3,8 @@ test_description='pushing to a repository using push options' . ./test-lib.sh +. "$TEST_DIRECTORY"/lib-httpd.sh +start_httpd mk_repo_pair () { rm -rf workbench upstream && @@ -100,4 +102,17 @@ test_expect_success 'two push options work' ' test_cmp expect upstream/.git/hooks/post-receive.push_options ' +test_expect_success 'push option denied properly by http remote helper' '\ + mk_repo_pair && + git -C upstream config receive.advertisePushOptions false && + git -C upstream config http.receivepack true && + cp -R upstream/.git "$HTTPD_DOCUMENT_ROOT_PATH"/upstream.git && + git clone "$HTTPD_URL"/smart/upstream test_http_clone && + test_commit -C test_http_clone one && + test_must_fail git -C test_http_clone push --push-option=asdf origin master && + git -C test_http_clone push origin master +' + +stop_httpd + test_done diff --git a/t/t7800-difftool.sh b/t/t7800-difftool.sh index aa0ef02597..25241f4096 100755 --- a/t/t7800-difftool.sh +++ b/t/t7800-difftool.sh @@ -23,6 +23,18 @@ prompt_given () test "$prompt" = "Launch 'test-tool' [Y/n]? branch" } +test_expect_success 'basic usage requires no repo' ' + test_expect_code 129 git difftool -h >output && + grep ^usage: output && + # create a ceiling directory to prevent Git from finding a repo + mkdir -p not/repo && + test_when_finished rm -r not && + test_expect_code 129 \ + env GIT_CEILING_DIRECTORIES="$(pwd)/not" \ + git -C not/repo difftool -h >output && + grep ^usage: output +' + # Create a file on master and change it on branch test_expect_success 'setup' ' echo master >file && @@ -278,8 +290,8 @@ test_expect_success 'difftool + mergetool config variables' ' test_expect_success 'difftool.<tool>.path' ' test_config difftool.tkdiff.path echo && git difftool --tool=tkdiff --no-prompt branch >output && - lines=$(grep file output | wc -l) && - test "$lines" -eq 1 + grep file output >grep-output && + test_line_count = 1 grep-output ' test_expect_success 'difftool --extcmd=cat' ' @@ -416,9 +428,12 @@ run_dir_diff_test 'difftool --dir-diff branch from subdirectory' ' git difftool --dir-diff $symlinks --extcmd ls branch >output && # "sub" must only exist in "right" # "file" and "file2" must be listed in both "left" and "right" - test "1" = $(grep sub output | wc -l) && - test "2" = $(grep file"$" output | wc -l) && - test "2" = $(grep file2 output | wc -l) + grep sub output > sub-output && + test_line_count = 1 sub-output && + grep file"$" output >file-output && + test_line_count = 2 file-output && + grep file2 output >file2-output && + test_line_count = 2 file2-output ) ' @@ -428,9 +443,11 @@ run_dir_diff_test 'difftool --dir-diff v1 from subdirectory' ' git difftool --dir-diff $symlinks --extcmd ls v1 >output && # "sub" and "file" exist in both v1 and HEAD. # "file2" is unchanged. - test "2" = $(grep sub output | wc -l) && - test "2" = $(grep file output | wc -l) && - test "0" = $(grep file2 output | wc -l) + grep sub output >sub-output && + test_line_count = 2 sub-output && + grep file output >file-output && + test_line_count = 2 file-output && + ! grep file2 output ) ' @@ -440,8 +457,9 @@ run_dir_diff_test 'difftool --dir-diff branch from subdirectory w/ pathspec' ' git difftool --dir-diff $symlinks --extcmd ls branch -- .>output && # "sub" only exists in "right" # "file" and "file2" must not be listed - test "1" = $(grep sub output | wc -l) && - test "0" = $(grep file output | wc -l) + grep sub output >sub-output && + test_line_count = 1 sub-output && + ! grep file output ) ' @@ -451,8 +469,9 @@ run_dir_diff_test 'difftool --dir-diff v1 from subdirectory w/ pathspec' ' git difftool --dir-diff $symlinks --extcmd ls v1 -- .>output && # "sub" exists in v1 and HEAD # "file" is filtered out by the pathspec - test "2" = $(grep sub output | wc -l) && - test "0" = $(grep file output | wc -l) + grep sub output >sub-output && + test_line_count = 2 sub-output && + ! grep file output ) ' diff --git a/t/t9822-git-p4-path-encoding.sh b/t/t9822-git-p4-path-encoding.sh index 7b83e696a9..c78477c19b 100755 --- a/t/t9822-git-p4-path-encoding.sh +++ b/t/t9822-git-p4-path-encoding.sh @@ -51,6 +51,22 @@ test_expect_success 'Clone repo containing iso8859-1 encoded paths with git-p4.p ) ' +test_expect_success 'Delete iso8859-1 encoded paths and clone' ' + ( + cd "$cli" && + ISO8859="$(printf "$ISO8859_ESCAPED")" && + p4 delete "$ISO8859" && + p4 submit -d "remove file" + ) && + git p4 clone --destination="$git" //depot@all && + test_when_finished cleanup_git && + ( + cd "$git" && + git -c core.quotepath=false ls-files >actual && + test_must_be_empty actual + ) +' + test_expect_success 'kill p4d' ' kill_p4d ' diff --git a/transport-helper.c b/transport-helper.c index 91aed35ebb..1258d6aedd 100644 --- a/transport-helper.c +++ b/transport-helper.c @@ -826,6 +826,13 @@ static void set_common_push_options(struct transport *transport, if (set_helper_option(transport, TRANS_OPT_PUSH_CERT, "if-asked") != 0) die("helper %s does not support --signed=if-asked", name); } + + if (flags & TRANSPORT_PUSH_OPTIONS) { + struct string_list_item *item; + for_each_string_list_item(item, transport->push_options) + if (set_helper_option(transport, "push-option", item->string) != 0) + die("helper %s does not support 'push-option'", name); + } } static int push_refs_with_push(struct transport *transport, |