summaryrefslogtreecommitdiff
path: root/revision.c
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2016-10-06 21:53:10 (GMT)
committerJunio C Hamano <gitster@pobox.com>2016-10-06 21:53:10 (GMT)
commit8c98a68981177013dfa0380968b57a1a37a45539 (patch)
tree916cefe551cd89da661008e2f294cddd4746ef38 /revision.c
parent66c22ba6fbe0724ecce3d82611ff0ec5c2b0255f (diff)
parent8779351dd7ee54c6ef2a7007670bad75a86edc75 (diff)
downloadgit-8c98a68981177013dfa0380968b57a1a37a45539.zip
git-8c98a68981177013dfa0380968b57a1a37a45539.tar.gz
git-8c98a68981177013dfa0380968b57a1a37a45539.tar.bz2
Merge branch 'vn/revision-shorthand-for-side-branch-log'
"git log rev^..rev" is an often-used revision range specification to show what was done on a side branch merged at rev. This has gained a short-hand "rev^-1". In general "rev^-$n" is the same as "^rev^$n rev", i.e. what has happened on other branches while the history leading to nth parent was looking the other way. * vn/revision-shorthand-for-side-branch-log: revision: new rev^-n shorthand for rev^n..rev
Diffstat (limited to 'revision.c')
-rw-r--r--revision.c34
1 files changed, 30 insertions, 4 deletions
diff --git a/revision.c b/revision.c
index 969b3d1..b37dbec 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 = '^';
}