aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--revision.c159
-rw-r--r--revision.h2
2 files changed, 87 insertions, 74 deletions
diff --git a/revision.c b/revision.c
index b588f7487..db0168275 100644
--- a/revision.c
+++ b/revision.c
@@ -592,6 +592,85 @@ static void prepare_show_merge(struct rev_info *revs)
revs->prune_data = prune;
}
+int handle_revision_arg(const char *arg, struct rev_info *revs,
+ int flags,
+ int cant_be_filename)
+{
+ char *dotdot;
+ struct object *object;
+ unsigned char sha1[20];
+ int local_flags;
+
+ dotdot = strstr(arg, "..");
+ if (dotdot) {
+ unsigned char from_sha1[20];
+ const char *next = dotdot + 2;
+ const char *this = arg;
+ int symmetric = *next == '.';
+ unsigned int flags_exclude = flags ^ UNINTERESTING;
+
+ *dotdot = 0;
+ next += symmetric;
+
+ if (!*next)
+ next = "HEAD";
+ if (dotdot == arg)
+ this = "HEAD";
+ if (!get_sha1(this, from_sha1) &&
+ !get_sha1(next, sha1)) {
+ struct commit *a, *b;
+ struct commit_list *exclude;
+
+ a = lookup_commit_reference(from_sha1);
+ b = lookup_commit_reference(sha1);
+ if (!a || !b) {
+ die(symmetric ?
+ "Invalid symmetric difference expression %s...%s" :
+ "Invalid revision range %s..%s",
+ arg, next);
+ }
+
+ if (!cant_be_filename) {
+ *dotdot = '.';
+ verify_non_filename(revs->prefix, arg);
+ }
+
+ if (symmetric) {
+ exclude = get_merge_bases(a, b, 1);
+ add_pending_commit_list(revs, exclude,
+ flags_exclude);
+ free_commit_list(exclude);
+ a->object.flags |= flags;
+ } else
+ a->object.flags |= flags_exclude;
+ b->object.flags |= flags;
+ add_pending_object(revs, &a->object, this);
+ add_pending_object(revs, &b->object, next);
+ return 0;
+ }
+ *dotdot = '.';
+ }
+ dotdot = strstr(arg, "^@");
+ if (dotdot && !dotdot[2]) {
+ *dotdot = 0;
+ if (add_parents_only(revs, arg, flags))
+ return 0;
+ *dotdot = '^';
+ }
+ local_flags = 0;
+ if (*arg == '^') {
+ local_flags = UNINTERESTING;
+ arg++;
+ }
+ if (get_sha1(arg, sha1))
+ return -1;
+ if (!cant_be_filename)
+ verify_non_filename(revs->prefix, arg);
+ object = get_reference(revs, arg, sha1, flags ^ local_flags);
+ add_pending_object(revs, object, arg);
+ return 0;
+}
+
/*
* Parse revision information, filling in the "rev_info" structure,
* and removing the used arguments from the argument list.
@@ -620,12 +699,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
flags = show_merge = 0;
for (i = 1; i < argc; i++) {
- struct object *object;
const char *arg = argv[i];
- unsigned char sha1[20];
- char *dotdot;
- int local_flags;
-
if (*arg == '-') {
int opts;
if (!strncmp(arg, "--max-count=", 12)) {
@@ -830,71 +904,10 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
left++;
continue;
}
- dotdot = strstr(arg, "..");
- if (dotdot) {
- unsigned char from_sha1[20];
- const char *next = dotdot + 2;
- const char *this = arg;
- int symmetric = *next == '.';
- unsigned int flags_exclude = flags ^ UNINTERESTING;
-
- *dotdot = 0;
- next += symmetric;
-
- if (!*next)
- next = "HEAD";
- if (dotdot == arg)
- this = "HEAD";
- if (!get_sha1(this, from_sha1) &&
- !get_sha1(next, sha1)) {
- struct commit *a, *b;
- struct commit_list *exclude;
-
- a = lookup_commit_reference(from_sha1);
- b = lookup_commit_reference(sha1);
- if (!a || !b) {
- die(symmetric ?
- "Invalid symmetric difference expression %s...%s" :
- "Invalid revision range %s..%s",
- arg, next);
- }
-
- if (!seen_dashdash) {
- *dotdot = '.';
- verify_non_filename(revs->prefix, arg);
- }
-
- if (symmetric) {
- exclude = get_merge_bases(a, b, 1);
- add_pending_commit_list(revs, exclude,
- flags_exclude);
- free_commit_list(exclude);
- a->object.flags |= flags;
- } else
- a->object.flags |= flags_exclude;
- b->object.flags |= flags;
- add_pending_object(revs, &a->object, this);
- add_pending_object(revs, &b->object, next);
- continue;
- }
- *dotdot = '.';
- }
- dotdot = strstr(arg, "^@");
- if (dotdot && !dotdot[2]) {
- *dotdot = 0;
- if (add_parents_only(revs, arg, flags))
- continue;
- *dotdot = '^';
- }
- local_flags = 0;
- if (*arg == '^') {
- local_flags = UNINTERESTING;
- arg++;
- }
- if (get_sha1(arg, sha1)) {
- int j;
- if (seen_dashdash || local_flags)
+ if (handle_revision_arg(arg, revs, flags, seen_dashdash)) {
+ int j;
+ if (seen_dashdash || *arg == '^')
die("bad revision '%s'", arg);
/* If we didn't have a "--":
@@ -906,14 +919,12 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
for (j = i; j < argc; j++)
verify_filename(revs->prefix, argv[j]);
- revs->prune_data = get_pathspec(revs->prefix, argv + i);
+ revs->prune_data = get_pathspec(revs->prefix,
+ argv + i);
break;
}
- if (!seen_dashdash)
- verify_non_filename(revs->prefix, arg);
- object = get_reference(revs, arg, sha1, flags ^ local_flags);
- add_pending_object(revs, object, arg);
}
+
if (show_merge)
prepare_show_merge(revs);
if (def && !revs->pending.nr) {
diff --git a/revision.h b/revision.h
index d28978105..c1f71afe6 100644
--- a/revision.h
+++ b/revision.h
@@ -90,6 +90,8 @@ extern int rev_compare_tree(struct rev_info *, struct tree *t1, struct tree *t2)
extern void init_revisions(struct rev_info *revs, const char *prefix);
extern int setup_revisions(int argc, const char **argv, struct rev_info *revs, const char *def);
+extern int handle_revision_arg(const char *arg, struct rev_info *revs,int flags,int cant_be_filename);
+
extern void prepare_revision_walk(struct rev_info *revs);
extern struct commit *get_revision(struct rev_info *revs);