diff options
author | Vegard Nossum <vegard.nossum@oracle.com> | 2016-09-27 10:32:49 +0200 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2016-09-27 19:59:28 +0200 |
commit | 8779351dd7ee54c6ef2a7007670bad75a86edc75 (patch) | |
tree | 2810d463c6e0baef7f93889678334720156b797c /revision.c | |
parent | Start preparing for 2.10.1 (diff) | |
download | git-8779351dd7ee54c6ef2a7007670bad75a86edc75.tar.xz git-8779351dd7ee54c6ef2a7007670bad75a86edc75.zip |
revision: new rev^-n shorthand for rev^n..rev
"git log rev^..rev" is commonly used to show all work done on and merged
from a side branch. This patch introduces a shorthand "rev^-" for this
and additionally allows "rev^-$n" to mean "reachable from rev, excluding
what is reachable from the nth parent of rev". For example, for a
two-parent merge, you can use rev^-2 to get the set of commits which were
made to the main branch while the topic branch was prepared.
Signed-off-by: Vegard Nossum <vegard.nossum@oracle.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'revision.c')
-rw-r--r-- | revision.c | 34 |
1 files changed, 30 insertions, 4 deletions
diff --git a/revision.c b/revision.c index 8a29cb03c5..c141a398ac 100644 --- a/revision.c +++ b/revision.c @@ -1289,12 +1289,14 @@ void add_index_objects_to_pending(struct rev_info *revs, unsigned flags) } } -static int add_parents_only(struct rev_info *revs, const char *arg_, int flags) +static int add_parents_only(struct rev_info *revs, const char *arg_, int flags, + int exclude_parent) { unsigned char sha1[20]; struct object *it; struct commit *commit; struct commit_list *parents; + int parent_number; const char *arg = arg_; if (*arg == '^') { @@ -1316,7 +1318,15 @@ static int add_parents_only(struct rev_info *revs, const char *arg_, int flags) if (it->type != OBJ_COMMIT) return 0; commit = (struct commit *)it; - for (parents = commit->parents; parents; parents = parents->next) { + if (exclude_parent && + exclude_parent > commit_list_count(commit->parents)) + return 0; + for (parents = commit->parents, parent_number = 1; + parents; + parents = parents->next, parent_number++) { + if (exclude_parent && parent_number != exclude_parent) + continue; + it = &parents->item->object; it->flags |= flags; add_rev_cmdline(revs, it, arg_, REV_CMD_PARENTS_ONLY, flags); @@ -1519,17 +1529,33 @@ int handle_revision_arg(const char *arg_, struct rev_info *revs, int flags, unsi } *dotdot = '.'; } + dotdot = strstr(arg, "^@"); if (dotdot && !dotdot[2]) { *dotdot = 0; - if (add_parents_only(revs, arg, flags)) + if (add_parents_only(revs, arg, flags, 0)) return 0; *dotdot = '^'; } dotdot = strstr(arg, "^!"); if (dotdot && !dotdot[2]) { *dotdot = 0; - if (!add_parents_only(revs, arg, flags ^ (UNINTERESTING | BOTTOM))) + if (!add_parents_only(revs, arg, flags ^ (UNINTERESTING | BOTTOM), 0)) + *dotdot = '^'; + } + dotdot = strstr(arg, "^-"); + if (dotdot) { + int exclude_parent = 1; + + if (dotdot[2]) { + char *end; + exclude_parent = strtoul(dotdot + 2, &end, 10); + if (*end != '\0' || !exclude_parent) + return -1; + } + + *dotdot = 0; + if (!add_parents_only(revs, arg, flags ^ (UNINTERESTING | BOTTOM), exclude_parent)) *dotdot = '^'; } |