Skip to content

Commit 5d6f093

Browse files
author
Junio C Hamano
committed
revision.c: allow injecting revision parameters after setup_revisions().
setup_revisions() wants to get all the parameters at once and then postprocesses the resulting revs structure after it is done with them. This code structure is a bit cumbersome to deal with efficiently when we want to inject revision parameters from the side (e.g. read from standard input). Fortunately, the nature of this postprocessing is not affected by revision parameters; they are affected only by flags. So it is Ok to do add_object() after the it returns. This splits out the code that deals with the revision parameter out of the main loop of setup_revisions(), so that we can later call it from elsewhere after it returns. Signed-off-by: Junio C Hamano <junkio@cox.net>
1 parent 0caea90 commit 5d6f093

File tree

2 files changed

+87
-74
lines changed

2 files changed

+87
-74
lines changed

revision.c

Lines changed: 85 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -592,6 +592,85 @@ static void prepare_show_merge(struct rev_info *revs)
592592
revs->prune_data = prune;
593593
}
594594

595+
int handle_revision_arg(const char *arg, struct rev_info *revs,
596+
int flags,
597+
int cant_be_filename)
598+
{
599+
char *dotdot;
600+
struct object *object;
601+
unsigned char sha1[20];
602+
int local_flags;
603+
604+
dotdot = strstr(arg, "..");
605+
if (dotdot) {
606+
unsigned char from_sha1[20];
607+
const char *next = dotdot + 2;
608+
const char *this = arg;
609+
int symmetric = *next == '.';
610+
unsigned int flags_exclude = flags ^ UNINTERESTING;
611+
612+
*dotdot = 0;
613+
next += symmetric;
614+
615+
if (!*next)
616+
next = "HEAD";
617+
if (dotdot == arg)
618+
this = "HEAD";
619+
if (!get_sha1(this, from_sha1) &&
620+
!get_sha1(next, sha1)) {
621+
struct commit *a, *b;
622+
struct commit_list *exclude;
623+
624+
a = lookup_commit_reference(from_sha1);
625+
b = lookup_commit_reference(sha1);
626+
if (!a || !b) {
627+
die(symmetric ?
628+
"Invalid symmetric difference expression %s...%s" :
629+
"Invalid revision range %s..%s",
630+
arg, next);
631+
}
632+
633+
if (!cant_be_filename) {
634+
*dotdot = '.';
635+
verify_non_filename(revs->prefix, arg);
636+
}
637+
638+
if (symmetric) {
639+
exclude = get_merge_bases(a, b, 1);
640+
add_pending_commit_list(revs, exclude,
641+
flags_exclude);
642+
free_commit_list(exclude);
643+
a->object.flags |= flags;
644+
} else
645+
a->object.flags |= flags_exclude;
646+
b->object.flags |= flags;
647+
add_pending_object(revs, &a->object, this);
648+
add_pending_object(revs, &b->object, next);
649+
return 0;
650+
}
651+
*dotdot = '.';
652+
}
653+
dotdot = strstr(arg, "^@");
654+
if (dotdot && !dotdot[2]) {
655+
*dotdot = 0;
656+
if (add_parents_only(revs, arg, flags))
657+
return 0;
658+
*dotdot = '^';
659+
}
660+
local_flags = 0;
661+
if (*arg == '^') {
662+
local_flags = UNINTERESTING;
663+
arg++;
664+
}
665+
if (get_sha1(arg, sha1))
666+
return -1;
667+
if (!cant_be_filename)
668+
verify_non_filename(revs->prefix, arg);
669+
object = get_reference(revs, arg, sha1, flags ^ local_flags);
670+
add_pending_object(revs, object, arg);
671+
return 0;
672+
}
673+
595674
/*
596675
* Parse revision information, filling in the "rev_info" structure,
597676
* 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
620699

621700
flags = show_merge = 0;
622701
for (i = 1; i < argc; i++) {
623-
struct object *object;
624702
const char *arg = argv[i];
625-
unsigned char sha1[20];
626-
char *dotdot;
627-
int local_flags;
628-
629703
if (*arg == '-') {
630704
int opts;
631705
if (!strncmp(arg, "--max-count=", 12)) {
@@ -830,71 +904,10 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
830904
left++;
831905
continue;
832906
}
833-
dotdot = strstr(arg, "..");
834-
if (dotdot) {
835-
unsigned char from_sha1[20];
836-
const char *next = dotdot + 2;
837-
const char *this = arg;
838-
int symmetric = *next == '.';
839-
unsigned int flags_exclude = flags ^ UNINTERESTING;
840-
841-
*dotdot = 0;
842-
next += symmetric;
843-
844-
if (!*next)
845-
next = "HEAD";
846-
if (dotdot == arg)
847-
this = "HEAD";
848-
if (!get_sha1(this, from_sha1) &&
849-
!get_sha1(next, sha1)) {
850-
struct commit *a, *b;
851-
struct commit_list *exclude;
852-
853-
a = lookup_commit_reference(from_sha1);
854-
b = lookup_commit_reference(sha1);
855-
if (!a || !b) {
856-
die(symmetric ?
857-
"Invalid symmetric difference expression %s...%s" :
858-
"Invalid revision range %s..%s",
859-
arg, next);
860-
}
861-
862-
if (!seen_dashdash) {
863-
*dotdot = '.';
864-
verify_non_filename(revs->prefix, arg);
865-
}
866-
867-
if (symmetric) {
868-
exclude = get_merge_bases(a, b, 1);
869-
add_pending_commit_list(revs, exclude,
870-
flags_exclude);
871-
free_commit_list(exclude);
872-
a->object.flags |= flags;
873-
} else
874-
a->object.flags |= flags_exclude;
875-
b->object.flags |= flags;
876-
add_pending_object(revs, &a->object, this);
877-
add_pending_object(revs, &b->object, next);
878-
continue;
879-
}
880-
*dotdot = '.';
881-
}
882-
dotdot = strstr(arg, "^@");
883-
if (dotdot && !dotdot[2]) {
884-
*dotdot = 0;
885-
if (add_parents_only(revs, arg, flags))
886-
continue;
887-
*dotdot = '^';
888-
}
889-
local_flags = 0;
890-
if (*arg == '^') {
891-
local_flags = UNINTERESTING;
892-
arg++;
893-
}
894-
if (get_sha1(arg, sha1)) {
895-
int j;
896907

897-
if (seen_dashdash || local_flags)
908+
if (handle_revision_arg(arg, revs, flags, seen_dashdash)) {
909+
int j;
910+
if (seen_dashdash || *arg == '^')
898911
die("bad revision '%s'", arg);
899912

900913
/* If we didn't have a "--":
@@ -906,14 +919,12 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
906919
for (j = i; j < argc; j++)
907920
verify_filename(revs->prefix, argv[j]);
908921

909-
revs->prune_data = get_pathspec(revs->prefix, argv + i);
922+
revs->prune_data = get_pathspec(revs->prefix,
923+
argv + i);
910924
break;
911925
}
912-
if (!seen_dashdash)
913-
verify_non_filename(revs->prefix, arg);
914-
object = get_reference(revs, arg, sha1, flags ^ local_flags);
915-
add_pending_object(revs, object, arg);
916926
}
927+
917928
if (show_merge)
918929
prepare_show_merge(revs);
919930
if (def && !revs->pending.nr) {

revision.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ extern int rev_compare_tree(struct rev_info *, struct tree *t1, struct tree *t2)
9090

9191
extern void init_revisions(struct rev_info *revs, const char *prefix);
9292
extern int setup_revisions(int argc, const char **argv, struct rev_info *revs, const char *def);
93+
extern int handle_revision_arg(const char *arg, struct rev_info *revs,int flags,int cant_be_filename);
94+
9395
extern void prepare_revision_walk(struct rev_info *revs);
9496
extern struct commit *get_revision(struct rev_info *revs);
9597

0 commit comments

Comments
 (0)