diff options
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 969b3d149f..b37dbec378 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 = '^'; } |