aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/RelNotes/2.12.0.txt15
-rw-r--r--Documentation/git-difftool.txt5
-rw-r--r--Documentation/git-push.txt13
-rw-r--r--Documentation/git-reset.txt38
-rw-r--r--Documentation/git-submodule.txt57
-rw-r--r--Documentation/rev-list-options.txt4
-rwxr-xr-xGIT-VERSION-GEN2
-rw-r--r--apply.c23
-rw-r--r--builtin/diff-tree.c4
-rw-r--r--builtin/diff.c9
-rw-r--r--builtin/difftool.c8
-rw-r--r--builtin/worktree.c4
-rw-r--r--contrib/coccinelle/swap.cocci28
-rw-r--r--contrib/completion/git-completion.bash145
-rw-r--r--diff-no-index.c6
-rw-r--r--diff.c13
-rw-r--r--dir.c7
-rw-r--r--git-compat-util.h10
-rw-r--r--graph.c11
-rw-r--r--line-range.c3
-rw-r--r--merge-recursive.c5
-rw-r--r--object.c4
-rw-r--r--pack-revindex.c5
-rw-r--r--prio-queue.c4
-rw-r--r--strbuf.h4
-rwxr-xr-xt/perf/p5302-pack-index.sh7
-rwxr-xr-xt/t4202-log.sh48
-rwxr-xr-xt/t7800-difftool.sh43
28 files changed, 371 insertions, 154 deletions
diff --git a/Documentation/RelNotes/2.12.0.txt b/Documentation/RelNotes/2.12.0.txt
index 0c6eed200..1841b065e 100644
--- a/Documentation/RelNotes/2.12.0.txt
+++ b/Documentation/RelNotes/2.12.0.txt
@@ -436,6 +436,20 @@ 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).
+
* 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 +458,4 @@ 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).
diff --git a/Documentation/git-difftool.txt b/Documentation/git-difftool.txt
index 224fb3090..96c26e6aa 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 8eefabd0d..1624a3588 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-reset.txt b/Documentation/git-reset.txt
index 25432d925..add6220fc 100644
--- a/Documentation/git-reset.txt
+++ b/Documentation/git-reset.txt
@@ -292,6 +292,44 @@ $ git reset --keep start <3>
<3> But you can use "reset --keep" to remove the unwanted commit after
you switched to "branch2".
+Split a commit into two::
++
+Suppose that you have created a commit, but later decide that you want to break
+apart the changes into two logical chunks and commit each separately. You want
+to include part of the original commit into the first commit, while including
+the remainder in a second commit. You can use git reset to rewind the history
+without changing the index, and then use git add -p to interactively select
+which hunks to put into the first commit.
++
+------------
+$ git reset HEAD^ <1>
+$ git add -p <2>
+$ git diff --cached <3>
+$ git commit -c HEAD@{1} <4>
+...
+$ git add ... <5>
+$ git diff --cached <6>
+$ git commit ... <7>
+------------
++
+<1> First, reset the history back one commit so that we remove the original
+ commit, but leave the working tree with all the changes.
+<2> Now, interactively select hunks to add to a new commit using git add -p.
+ This will ask for each hunk separately and you can use simple commands like
+ "yes, include", "no don't include" or even "edit".
+<3> Once satisfied with the hunks, you should verify that it is what you
+ expected by using git diff --cached to show all changes in the index.
+<4> Next, commit the changes stored in the index. "-c" specifies to load the
+ editor with a commit message from a previous commit so that you can re-use the
+ original commit message. HEAD@{1} is special notation to reference what
+ HEAD used to be prior to the reset command. See linkgit:git-reflog[1] for
+ more details.
+<5> Now you've created the first commit, and can repeat steps 2-4 as often as
+ you like to break the work into any number of commits. Here we show a second
+ step which simply adds the remaining changes.
+<6> Then check again that the changes are what you expected to add.
+<7> And finally commit the remaining changes.
+
DISCUSSION
----------
diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt
index 918bd1d1b..4a4cede14 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:
@@ -232,7 +225,7 @@ 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.
-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/rev-list-options.txt b/Documentation/rev-list-options.txt
index 5da7cf5a8..a02f7324c 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 4bed33d2a..1eabbd88a 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='
'
diff --git a/apply.c b/apply.c
index 2ed808d42..0e2caeab9 100644
--- a/apply.c
+++ b/apply.c
@@ -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 806dd7a88..8ce00480c 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 7f91f6d22..3d64b8533 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 b5e85ab07..d13350ce8 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/worktree.c b/builtin/worktree.c
index 9a97e37a3..831fe058a 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/contrib/coccinelle/swap.cocci b/contrib/coccinelle/swap.cocci
new file mode 100644
index 000000000..a0934d1fd
--- /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 97d73ad88..41ee52991 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 f42078603..df762fd0f 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);
diff --git a/diff.c b/diff.c
index d91a34490..051761be4 100644
--- a/diff.c
+++ b/diff.c
@@ -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 &&
diff --git a/dir.c b/dir.c
index 65c3e681b..4541f9e14 100644
--- a/dir.c
+++ b/dir.c
@@ -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 f46d40e4a..ef6d560e1 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
diff --git a/graph.c b/graph.c
index 064900770..8b9049dd2 100644
--- a/graph.c
+++ b/graph.c
@@ -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 de4e32f94..323399d16 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 d32720944..b7ff1ada3 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)
diff --git a/object.c b/object.c
index 67d9a9e22..e680d881a 100644
--- a/object.c
+++ b/object.c
@@ -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 6bc7c9403..1b7ebd8d7 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 e4365b00d..17252d231 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)
diff --git a/strbuf.h b/strbuf.h
index 2262b1268..cf1b5409e 100644
--- a/strbuf.h
+++ b/strbuf.h
@@ -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 5ee9211f9..99bdb16c8 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 08ea725de..48b55bfd2 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/t7800-difftool.sh b/t/t7800-difftool.sh
index aa0ef0259..25241f409 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
)
'