Pathspec in "git log -p <pathspec>" is used for both commit pruning and diff generation. If --full-diff is given, then diff pathspec is reset to generate complete diff. This patch gives more control to diff generation. The first pathspec in "git log -p -- <pathspec> -- <pathspec>" is used as commit pruning as usual. The second one is used for diff generation. So --full-diff now is essentially "git log -p -- <pathspec> --". This form requires specifying "--" twice. If a file name happens to be "--", it may be misunderstood as the second "--" marker. This is an unfortunate consequence for this syntax. Users can still use "./--" or similar to workaround this. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@xxxxxxxxx> --- Version 2. Now it looks more acceptable. Documentation/git-log.txt | 9 +++++++-- revision.c | 28 +++++++++++++++++++++++++--- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/Documentation/git-log.txt b/Documentation/git-log.txt index 249fc87..8e00dbc 100644 --- a/Documentation/git-log.txt +++ b/Documentation/git-log.txt @@ -9,7 +9,7 @@ git-log - Show commit logs SYNOPSIS -------- [verse] -'git log' [<options>] [<since>..<until>] [[\--] <path>...] +'git log' [<options>] [<since>..<until>] [[\--] <path>... [\-- <path>...]] DESCRIPTION ----------- @@ -52,11 +52,12 @@ OPTIONS commit was reached. --full-diff:: - Without this flag, "git log -p <path>..." shows commits that + Without this flag, `git log -p <path>...` shows commits that touch the specified paths, and diffs about the same specified paths. With this, the full diff is shown for commits that touch the specified paths; this means that "<path>..." limits only commits, and doesn't limit diff for those commits. + It is equivalent to `git log -p \-- <path>... \--`. + Note that this affects all diff-based output types, e.g. those produced by --stat etc. @@ -76,6 +77,10 @@ produced by --stat etc. + To prevent confusion with options and branch names, paths may need to be prefixed with "\-- " to separate them from options or refnames. ++ +If the second "\--" is found, the following pathspec is used to limit +diff generation. Note that this affects all diff-based output types, +e.g. those produced by --stat etc. include::rev-list-options.txt[] diff --git a/revision.c b/revision.c index 8764dde..f560647 100644 --- a/revision.c +++ b/revision.c @@ -1682,20 +1682,37 @@ static int handle_revision_pseudo_opt(const char *submodule, */ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct setup_revision_opt *opt) { - int i, flags, left, seen_dashdash, read_from_stdin, got_rev_arg = 0; + int i, flags, left, read_from_stdin, got_rev_arg = 0; + int seen_dashdash, seen_second_dashdash; struct cmdline_pathspec prune_data; + struct cmdline_pathspec diff_data; const char *submodule = NULL; memset(&prune_data, 0, sizeof(prune_data)); + memset(&diff_data, 0, sizeof(diff_data)); if (opt) submodule = opt->submodule; /* First, search for "--" */ - seen_dashdash = 0; + seen_dashdash = seen_second_dashdash = 0; for (i = 1; i < argc; i++) { + int i2; const char *arg = argv[i]; if (strcmp(arg, "--")) continue; + + /* Search for second "--" */ + for (i2 = i + 1; i2 < argc; i2++) { + const char *arg = argv[i2]; + if (strcmp(arg, "--")) + continue; + argv[i2] = NULL; + if (argv[i2 + 1]) + append_prune_data(&diff_data, argv + i2 + 1); + seen_second_dashdash = 1; + break; + } + argv[i] = NULL; argc = i; if (argv[i + 1]) @@ -1817,7 +1834,12 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s /* Can't prune commits with rename following: the paths change.. */ if (!DIFF_OPT_TST(&revs->diffopt, FOLLOW_RENAMES)) revs->prune = 1; - if (!revs->full_diff) + if (seen_second_dashdash) { + ALLOC_GROW(diff_data.path, diff_data.nr+1, diff_data.alloc); + diff_data.path[diff_data.nr++] = NULL; + diff_tree_setup_paths(diff_data.path, &revs->diffopt); + } + else if (!revs->full_diff) diff_tree_setup_paths(revs->prune_data.raw, &revs->diffopt); } if (revs->combine_merges) -- 1.7.4.74.g639db -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html