1
0
Fork 0
mirror of https://github.com/git/git.git synced 2024-11-17 22:44:49 +01:00

Merge branch 'lt/logopt' into next

* lt/logopt:
  Tentative built-in "git show"
  Built-in git-whatchanged.
  rev-list option parser fix.
  Split init_revisions() out of setup_revisions()
This commit is contained in:
Junio C Hamano 2006-04-16 00:52:55 -07:00
commit 43f934aa90
9 changed files with 286 additions and 340 deletions

View file

@ -45,6 +45,8 @@ enum cmit_fmt {
CMIT_FMT_FULL, CMIT_FMT_FULL,
CMIT_FMT_FULLER, CMIT_FMT_FULLER,
CMIT_FMT_ONELINE, CMIT_FMT_ONELINE,
CMIT_FMT_UNSPECIFIED,
}; };
extern enum cmit_fmt get_commit_format(const char *arg); extern enum cmit_fmt get_commit_format(const char *arg);

View file

@ -3,7 +3,7 @@
#include "commit.h" #include "commit.h"
#include "log-tree.h" #include "log-tree.h"
static struct log_tree_opt log_tree_opt; static struct rev_info log_tree_opt;
static int diff_tree_commit_sha1(const unsigned char *sha1) static int diff_tree_commit_sha1(const unsigned char *sha1)
{ {
@ -62,47 +62,20 @@ int main(int argc, const char **argv)
{ {
int nr_sha1; int nr_sha1;
char line[1000]; char line[1000];
unsigned char sha1[2][20]; struct object *tree1, *tree2;
const char *prefix = setup_git_directory(); static struct rev_info *opt = &log_tree_opt;
static struct log_tree_opt *opt = &log_tree_opt; struct object_list *list;
int read_stdin = 0; int read_stdin = 0;
git_config(git_diff_config); git_config(git_diff_config);
nr_sha1 = 0; nr_sha1 = 0;
init_log_tree_opt(opt); init_revisions(opt);
opt->abbrev = 0;
argc = setup_revisions(argc, argv, opt, NULL);
for (;;) { while (--argc > 0) {
int opt_cnt; const char *arg = *++argv;
const char *arg;
argv++;
argc--;
arg = *argv;
if (!arg)
break;
if (*arg != '-') {
if (nr_sha1 < 2 && !get_sha1(arg, sha1[nr_sha1])) {
nr_sha1++;
continue;
}
break;
}
opt_cnt = log_tree_opt_parse(opt, argv, argc);
if (opt_cnt < 0)
usage(diff_tree_usage);
else if (opt_cnt) {
argv += opt_cnt - 1;
argc -= opt_cnt - 1;
continue;
}
if (!strcmp(arg, "--")) {
argv++;
argc--;
break;
}
if (!strcmp(arg, "--stdin")) { if (!strcmp(arg, "--stdin")) {
read_stdin = 1; read_stdin = 1;
continue; continue;
@ -110,18 +83,36 @@ int main(int argc, const char **argv)
usage(diff_tree_usage); usage(diff_tree_usage);
} }
if (opt->combine_merges) /*
opt->ignore_merges = 0; * NOTE! "setup_revisions()" will have inserted the revisions
* it parsed in reverse order. So if you do
/* We can only do dense combined merges with diff output */ *
if (opt->dense_combined_merges) * git-diff-tree a b
opt->diffopt.output_format = DIFF_FORMAT_PATCH; *
* the commit list will be "b" -> "a" -> NULL, so we reverse
if (opt->diffopt.output_format == DIFF_FORMAT_PATCH) * the order of the objects if the first one is not marked
opt->diffopt.recursive = 1; * UNINTERESTING.
*/
diff_tree_setup_paths(get_pathspec(prefix, argv), &opt->diffopt); nr_sha1 = 0;
diff_setup_done(&opt->diffopt); list = opt->pending_objects;
if (list) {
nr_sha1++;
tree1 = list->item;
list = list->next;
if (list) {
nr_sha1++;
tree2 = tree1;
tree1 = list->item;
if (list->next)
usage(diff_tree_usage);
/* Switch them around if the second one was uninteresting.. */
if (tree2->flags & UNINTERESTING) {
struct object *tmp = tree2;
tree2 = tree1;
tree1 = tmp;
}
}
}
switch (nr_sha1) { switch (nr_sha1) {
case 0: case 0:
@ -129,10 +120,12 @@ int main(int argc, const char **argv)
usage(diff_tree_usage); usage(diff_tree_usage);
break; break;
case 1: case 1:
diff_tree_commit_sha1(sha1[0]); diff_tree_commit_sha1(tree1->sha1);
break; break;
case 2: case 2:
diff_tree_sha1(sha1[0], sha1[1], "", &opt->diffopt); diff_tree_sha1(tree1->sha1,
tree2->sha1,
"", &opt->diffopt);
log_tree_diff_flush(opt); log_tree_diff_flush(opt);
break; break;
} }

88
git.c
View file

@ -279,31 +279,28 @@ static int cmd_help(int argc, const char **argv, char **envp)
#define LOGSIZE (65536) #define LOGSIZE (65536)
static int cmd_log_wc(int argc, const char **argv, char **envp, static int cmd_log_wc(int argc, const char **argv, char **envp,
struct whatchanged_opt *wcopt) struct rev_info *rev)
{ {
struct commit *commit; struct commit *commit;
char *buf = xmalloc(LOGSIZE); char *buf = xmalloc(LOGSIZE);
const char *commit_prefix = "commit "; const char *commit_prefix = "commit ";
int shown = 0; int shown = 0;
struct rev_info *rev = &wcopt->revopt;
struct log_tree_opt *opt = &wcopt->logopt;
opt->commit_format = CMIT_FMT_DEFAULT; if (argc > 1)
wcopt->abbrev = DEFAULT_ABBREV; die("unrecognized argument: %s", argv[1]);
argc = parse_whatchanged_opt(argc, argv, wcopt); if (rev->commit_format == CMIT_FMT_ONELINE)
if (opt->commit_format == CMIT_FMT_ONELINE)
commit_prefix = ""; commit_prefix = "";
prepare_revision_walk(rev); prepare_revision_walk(rev);
setup_pager(); setup_pager();
while ((commit = get_revision(rev)) != NULL) { while ((commit = get_revision(rev)) != NULL) {
if (shown && wcopt->do_diff && if (shown && rev->diff &&
opt->commit_format != CMIT_FMT_ONELINE) rev->commit_format != CMIT_FMT_ONELINE)
putchar('\n'); putchar('\n');
fputs(commit_prefix, stdout); fputs(commit_prefix, stdout);
if (wcopt->abbrev_commit && wcopt->abbrev) if (rev->abbrev_commit && rev->abbrev)
fputs(find_unique_abbrev(commit->object.sha1, wcopt->abbrev), fputs(find_unique_abbrev(commit->object.sha1,
rev->abbrev),
stdout); stdout);
else else
fputs(sha1_to_hex(commit->object.sha1), stdout); fputs(sha1_to_hex(commit->object.sha1), stdout);
@ -326,16 +323,16 @@ static int cmd_log_wc(int argc, const char **argv, char **envp,
parents = parents->next) parents = parents->next)
parents->item->object.flags &= ~TMP_MARK; parents->item->object.flags &= ~TMP_MARK;
} }
if (opt->commit_format == CMIT_FMT_ONELINE) if (rev->commit_format == CMIT_FMT_ONELINE)
putchar(' '); putchar(' ');
else else
putchar('\n'); putchar('\n');
pretty_print_commit(opt->commit_format, commit, ~0, buf, pretty_print_commit(rev->commit_format, commit, ~0, buf,
LOGSIZE, wcopt->abbrev); LOGSIZE, rev->abbrev);
printf("%s\n", buf); printf("%s\n", buf);
if (wcopt->do_diff) { if (rev->diff) {
printf("---\n"); printf("--\n");
log_tree_commit(opt, commit); log_tree_commit(rev, commit);
} }
shown = 1; shown = 1;
free(commit->buffer); free(commit->buffer);
@ -345,38 +342,47 @@ static int cmd_log_wc(int argc, const char **argv, char **envp,
return 0; return 0;
} }
static int cmd_log(int ac, const char **av, char **ep) static int cmd_wc(int argc, const char **argv, char **envp)
{ {
struct whatchanged_opt wcopt; struct rev_info rev;
memset(&wcopt, 0, sizeof(wcopt)); init_revisions(&rev);
init_log_tree_opt(&wcopt.logopt); rev.abbrev = DEFAULT_ABBREV;
return cmd_log_wc(ac, av, ep, &wcopt); rev.no_commit_id = 1;
rev.commit_format = CMIT_FMT_DEFAULT;
rev.diff = 1;
rev.diffopt.recursive = 1;
argc = setup_revisions(argc, argv, &rev, "HEAD");
return cmd_log_wc(argc, argv, envp, &rev);
} }
static int cmd_whatchanged(int ac, const char **av, char **ep) static int cmd_show(int argc, const char **argv, char **envp)
{ {
struct whatchanged_opt wcopt; struct rev_info rev;
memset(&wcopt, 0, sizeof(wcopt)); init_revisions(&rev);
wcopt.do_diff = 1; rev.diff = 1;
init_log_tree_opt(&wcopt.logopt); rev.ignore_merges = 0;
wcopt.logopt.diffopt.recursive = 1; rev.combine_merges = 1;
return cmd_log_wc(ac, av, ep, &wcopt); rev.dense_combined_merges = 1;
rev.abbrev = DEFAULT_ABBREV;
rev.commit_format = CMIT_FMT_DEFAULT;
rev.diffopt.recursive = 1;
rev.no_walk = 1;
argc = setup_revisions(argc, argv, &rev, "HEAD");
return cmd_log_wc(argc, argv, envp, &rev);
} }
static int cmd_show(int ac, const char **av, char **ep) static int cmd_log(int argc, const char **argv, char **envp)
{ {
struct whatchanged_opt wcopt; struct rev_info rev;
memset(&wcopt, 0, sizeof(wcopt)); init_revisions(&rev);
wcopt.do_diff = 1; rev.abbrev = DEFAULT_ABBREV;
init_log_tree_opt(&wcopt.logopt); rev.no_commit_id = 1;
wcopt.logopt.ignore_merges = 0; rev.commit_format = CMIT_FMT_DEFAULT;
wcopt.logopt.combine_merges = 1; argc = setup_revisions(argc, argv, &rev, "HEAD");
wcopt.logopt.dense_combined_merges = 1; return cmd_log_wc(argc, argv, envp, &rev);
wcopt.logopt.diffopt.recursive = 1;
return cmd_log_wc(ac, av, ep, &wcopt);
} }
static void handle_internal_command(int argc, const char **argv, char **envp) static void handle_internal_command(int argc, const char **argv, char **envp)
@ -389,8 +395,8 @@ static void handle_internal_command(int argc, const char **argv, char **envp)
{ "version", cmd_version }, { "version", cmd_version },
{ "help", cmd_help }, { "help", cmd_help },
{ "log", cmd_log }, { "log", cmd_log },
{ "whatchanged", cmd_wc },
{ "show", cmd_show }, { "show", cmd_show },
{ "whatchanged", cmd_whatchanged },
}; };
int i; int i;

View file

@ -2498,6 +2498,7 @@ int main(int argc, char **argv)
commit_argv[3] = old_sha1_hex; commit_argv[3] = old_sha1_hex;
commit_argc++; commit_argc++;
} }
init_revisions(&revs);
setup_revisions(commit_argc, commit_argv, &revs, NULL); setup_revisions(commit_argc, commit_argv, &revs, NULL);
free(new_sha1_hex); free(new_sha1_hex);
if (old_sha1_hex) { if (old_sha1_hex) {

View file

@ -3,57 +3,7 @@
#include "commit.h" #include "commit.h"
#include "log-tree.h" #include "log-tree.h"
void init_log_tree_opt(struct log_tree_opt *opt) int log_tree_diff_flush(struct rev_info *opt)
{
memset(opt, 0, sizeof *opt);
opt->ignore_merges = 1;
opt->header_prefix = "";
opt->commit_format = CMIT_FMT_RAW;
diff_setup(&opt->diffopt);
}
int log_tree_opt_parse(struct log_tree_opt *opt, const char **av, int ac)
{
const char *arg;
int cnt = diff_opt_parse(&opt->diffopt, av, ac);
if (0 < cnt)
return cnt;
arg = *av;
if (!strcmp(arg, "-r"))
opt->diffopt.recursive = 1;
else if (!strcmp(arg, "-t")) {
opt->diffopt.recursive = 1;
opt->diffopt.tree_in_recursive = 1;
}
else if (!strcmp(arg, "-m"))
opt->ignore_merges = 0;
else if (!strcmp(arg, "-c"))
opt->combine_merges = 1;
else if (!strcmp(arg, "--cc")) {
opt->dense_combined_merges = 1;
opt->combine_merges = 1;
}
else if (!strcmp(arg, "-v")) {
opt->verbose_header = 1;
opt->header_prefix = "diff-tree ";
}
else if (!strncmp(arg, "--pretty", 8)) {
opt->verbose_header = 1;
opt->header_prefix = "diff-tree ";
opt->commit_format = get_commit_format(arg+8);
}
else if (!strcmp(arg, "--root"))
opt->show_root_diff = 1;
else if (!strcmp(arg, "--no-commit-id"))
opt->no_commit_id = 1;
else if (!strcmp(arg, "--always"))
opt->always_show_header = 1;
else
return 0;
return 1;
}
int log_tree_diff_flush(struct log_tree_opt *opt)
{ {
diffcore_std(&opt->diffopt); diffcore_std(&opt->diffopt);
if (diff_queue_is_empty()) { if (diff_queue_is_empty()) {
@ -73,7 +23,7 @@ int log_tree_diff_flush(struct log_tree_opt *opt)
return 1; return 1;
} }
static int diff_root_tree(struct log_tree_opt *opt, static int diff_root_tree(struct rev_info *opt,
const unsigned char *new, const char *base) const unsigned char *new, const char *base)
{ {
int retval; int retval;
@ -93,7 +43,7 @@ static int diff_root_tree(struct log_tree_opt *opt,
return retval; return retval;
} }
static const char *generate_header(struct log_tree_opt *opt, static const char *generate_header(struct rev_info *opt,
const unsigned char *commit_sha1, const unsigned char *commit_sha1,
const unsigned char *parent_sha1, const unsigned char *parent_sha1,
const struct commit *commit) const struct commit *commit)
@ -129,7 +79,7 @@ static const char *generate_header(struct log_tree_opt *opt,
return this_header; return this_header;
} }
static int do_diff_combined(struct log_tree_opt *opt, struct commit *commit) static int do_diff_combined(struct rev_info *opt, struct commit *commit)
{ {
unsigned const char *sha1 = commit->object.sha1; unsigned const char *sha1 = commit->object.sha1;
@ -142,7 +92,7 @@ static int do_diff_combined(struct log_tree_opt *opt, struct commit *commit)
return 0; return 0;
} }
int log_tree_commit(struct log_tree_opt *opt, struct commit *commit) int log_tree_commit(struct rev_info *opt, struct commit *commit)
{ {
struct commit_list *parents; struct commit_list *parents;
unsigned const char *sha1 = commit->object.sha1; unsigned const char *sha1 = commit->object.sha1;
@ -173,70 +123,3 @@ int log_tree_commit(struct log_tree_opt *opt, struct commit *commit)
} }
return 0; return 0;
} }
int parse_whatchanged_opt(int ac, const char **av, struct whatchanged_opt *wcopt)
{
struct rev_info *rev = &wcopt->revopt;
struct log_tree_opt *opt = &wcopt->logopt;
const char **unrecognized = av+1;
int left = 1;
ac = setup_revisions(ac, av, rev, "HEAD");
if (!strcmp(av[0], "show"))
rev->no_walk = 1;
while (1 < ac) {
const char *arg = av[1];
if (!strncmp(arg, "--pretty", 8)) {
opt->commit_format = get_commit_format(arg + 8);
}
else if (!strcmp(arg, "--no-abbrev")) {
wcopt->abbrev = 0;
}
else if (!strcmp(arg, "--abbrev")) {
wcopt->abbrev = DEFAULT_ABBREV;
}
else if (!strcmp(arg, "--abbrev-commit")) {
wcopt->abbrev_commit = 1;
}
else if (!strncmp(arg, "--abbrev=", 9)) {
wcopt->abbrev = strtoul(arg + 9, NULL, 10);
if (wcopt->abbrev && wcopt->abbrev < MINIMUM_ABBREV)
wcopt->abbrev = MINIMUM_ABBREV;
else if (40 < wcopt->abbrev)
wcopt->abbrev = 40;
}
else if (!strcmp(arg, "--full-diff")) {
wcopt->do_diff = 1;
wcopt->full_diff = 1;
}
else {
int cnt = log_tree_opt_parse(opt, av+1, ac-1);
if (0 < cnt) {
wcopt->do_diff = 1;
av += cnt;
ac -= cnt;
continue;
}
*unrecognized++ = arg;
left++;
}
ac--; av++;
}
if (wcopt->do_diff) {
opt->diffopt.abbrev = wcopt->abbrev;
opt->verbose_header = 0;
opt->always_show_header = 0;
opt->no_commit_id = 1;
if (opt->combine_merges)
opt->ignore_merges = 0;
if (opt->dense_combined_merges)
opt->diffopt.output_format = DIFF_FORMAT_PATCH;
if (opt->diffopt.output_format == DIFF_FORMAT_PATCH)
opt->diffopt.recursive = 1;
if (!wcopt->full_diff && rev->prune_data)
diff_tree_setup_paths(rev->prune_data, &opt->diffopt);
diff_setup_done(&opt->diffopt);
}
return left;
}

View file

@ -3,34 +3,9 @@
#include "revision.h" #include "revision.h"
struct log_tree_opt { void init_log_tree_opt(struct rev_info *);
struct diff_options diffopt; int log_tree_diff_flush(struct rev_info *);
int show_root_diff; int log_tree_commit(struct rev_info *, struct commit *);
int no_commit_id; int log_tree_opt_parse(struct rev_info *, const char **, int);
int verbose_header;
int ignore_merges;
int combine_merges;
int dense_combined_merges;
int always_show_header;
const char *header_prefix;
const char *header;
enum cmit_fmt commit_format;
};
void init_log_tree_opt(struct log_tree_opt *);
int log_tree_diff_flush(struct log_tree_opt *);
int log_tree_commit(struct log_tree_opt *, struct commit *);
int log_tree_opt_parse(struct log_tree_opt *, const char **, int);
struct whatchanged_opt {
struct rev_info revopt;
struct log_tree_opt logopt;
int abbrev;
int abbrev_commit;
int do_diff;
int full_diff;
};
int parse_whatchanged_opt(int, const char **, struct whatchanged_opt *);
#endif #endif

View file

@ -39,24 +39,20 @@ static const char rev_list_usage[] =
struct rev_info revs; struct rev_info revs;
static int bisect_list = 0; static int bisect_list = 0;
static int verbose_header = 0;
static int abbrev = DEFAULT_ABBREV;
static int abbrev_commit = 0;
static int show_timestamp = 0; static int show_timestamp = 0;
static int hdr_termination = 0; static int hdr_termination = 0;
static const char *commit_prefix = "";
static enum cmit_fmt commit_format = CMIT_FMT_RAW;
static void show_commit(struct commit *commit) static void show_commit(struct commit *commit)
{ {
if (show_timestamp) if (show_timestamp)
printf("%lu ", commit->date); printf("%lu ", commit->date);
if (commit_prefix[0]) if (*revs.header_prefix)
fputs(commit_prefix, stdout); fputs(revs.header_prefix, stdout);
if (commit->object.flags & BOUNDARY) if (commit->object.flags & BOUNDARY)
putchar('-'); putchar('-');
if (abbrev_commit && abbrev) if (revs.abbrev_commit && revs.abbrev)
fputs(find_unique_abbrev(commit->object.sha1, abbrev), stdout); fputs(find_unique_abbrev(commit->object.sha1, revs.abbrev),
stdout);
else else
fputs(sha1_to_hex(commit->object.sha1), stdout); fputs(sha1_to_hex(commit->object.sha1), stdout);
if (revs.parents) { if (revs.parents) {
@ -78,14 +74,16 @@ static void show_commit(struct commit *commit)
parents = parents->next) parents = parents->next)
parents->item->object.flags &= ~TMP_MARK; parents->item->object.flags &= ~TMP_MARK;
} }
if (commit_format == CMIT_FMT_ONELINE) if (revs.commit_format == CMIT_FMT_ONELINE)
putchar(' '); putchar(' ');
else else
putchar('\n'); putchar('\n');
if (verbose_header) { if (revs.verbose_header) {
static char pretty_header[16384]; static char pretty_header[16384];
pretty_print_commit(commit_format, commit, ~0, pretty_header, sizeof(pretty_header), abbrev); pretty_print_commit(revs.commit_format, commit, ~0,
pretty_header, sizeof(pretty_header),
revs.abbrev);
printf("%s%c", pretty_header, hdr_termination); printf("%s%c", pretty_header, hdr_termination);
} }
fflush(stdout); fflush(stdout);
@ -297,58 +295,16 @@ int main(int argc, const char **argv)
struct commit_list *list; struct commit_list *list;
int i; int i;
init_revisions(&revs);
revs.abbrev = 0;
revs.commit_format = CMIT_FMT_UNSPECIFIED;
argc = setup_revisions(argc, argv, &revs, NULL); argc = setup_revisions(argc, argv, &revs, NULL);
for (i = 1 ; i < argc; i++) { for (i = 1 ; i < argc; i++) {
const char *arg = argv[i]; const char *arg = argv[i];
/* accept -<digit>, like traditilnal "head" */
if ((*arg == '-') && isdigit(arg[1])) {
revs.max_count = atoi(arg + 1);
continue;
}
if (!strcmp(arg, "-n")) {
if (++i >= argc)
die("-n requires an argument");
revs.max_count = atoi(argv[i]);
continue;
}
if (!strncmp(arg,"-n",2)) {
revs.max_count = atoi(arg + 2);
continue;
}
if (!strcmp(arg, "--header")) { if (!strcmp(arg, "--header")) {
verbose_header = 1; revs.verbose_header = 1;
continue;
}
if (!strcmp(arg, "--no-abbrev")) {
abbrev = 0;
continue;
}
if (!strcmp(arg, "--abbrev")) {
abbrev = DEFAULT_ABBREV;
continue;
}
if (!strcmp(arg, "--abbrev-commit")) {
abbrev_commit = 1;
continue;
}
if (!strncmp(arg, "--abbrev=", 9)) {
abbrev = strtoul(arg + 9, NULL, 10);
if (abbrev && abbrev < MINIMUM_ABBREV)
abbrev = MINIMUM_ABBREV;
else if (40 < abbrev)
abbrev = 40;
continue;
}
if (!strncmp(arg, "--pretty", 8)) {
commit_format = get_commit_format(arg+8);
verbose_header = 1;
hdr_termination = '\n';
if (commit_format == CMIT_FMT_ONELINE)
commit_prefix = "";
else
commit_prefix = "commit ";
continue; continue;
} }
if (!strcmp(arg, "--timestamp")) { if (!strcmp(arg, "--timestamp")) {
@ -362,14 +318,24 @@ int main(int argc, const char **argv)
usage(rev_list_usage); usage(rev_list_usage);
} }
if (revs.commit_format != CMIT_FMT_UNSPECIFIED) {
/* The command line has a --pretty */
hdr_termination = '\n';
if (revs.commit_format == CMIT_FMT_ONELINE)
revs.header_prefix = "";
else
revs.header_prefix = "commit ";
}
list = revs.commits; list = revs.commits;
if (!list && if ((!list &&
(!(revs.tag_objects||revs.tree_objects||revs.blob_objects) && !revs.pending_objects)) (!(revs.tag_objects||revs.tree_objects||revs.blob_objects) &&
!revs.pending_objects)) ||
revs.diff)
usage(rev_list_usage); usage(rev_list_usage);
save_commit_buffer = verbose_header; save_commit_buffer = revs.verbose_header;
track_object_refs = 0; track_object_refs = 0;
if (bisect_list) if (bisect_list)
revs.limited = 1; revs.limited = 1;

View file

@ -116,21 +116,27 @@ static void add_pending_object(struct rev_info *revs, struct object *obj, const
add_object(obj, &revs->pending_objects, NULL, name); add_object(obj, &revs->pending_objects, NULL, name);
} }
static struct commit *get_commit_reference(struct rev_info *revs, const char *name, const unsigned char *sha1, unsigned int flags) static struct object *get_reference(struct rev_info *revs, const char *name, const unsigned char *sha1, unsigned int flags)
{ {
struct object *object; struct object *object;
object = parse_object(sha1); object = parse_object(sha1);
if (!object) if (!object)
die("bad object %s", name); die("bad object %s", name);
object->flags |= flags;
return object;
}
static struct commit *handle_commit(struct rev_info *revs, struct object *object, const char *name)
{
unsigned long flags = object->flags;
/* /*
* Tag object? Look what it points to.. * Tag object? Look what it points to..
*/ */
while (object->type == tag_type) { while (object->type == tag_type) {
struct tag *tag = (struct tag *) object; struct tag *tag = (struct tag *) object;
object->flags |= flags; if (revs->tag_objects && !(flags & UNINTERESTING))
if (revs->tag_objects && !(object->flags & UNINTERESTING))
add_pending_object(revs, object, tag->tag); add_pending_object(revs, object, tag->tag);
object = parse_object(tag->tagged->sha1); object = parse_object(tag->tagged->sha1);
if (!object) if (!object)
@ -143,7 +149,6 @@ static struct commit *get_commit_reference(struct rev_info *revs, const char *na
*/ */
if (object->type == commit_type) { if (object->type == commit_type) {
struct commit *commit = (struct commit *)object; struct commit *commit = (struct commit *)object;
object->flags |= flags;
if (parse_commit(commit) < 0) if (parse_commit(commit) < 0)
die("unable to parse commit %s", name); die("unable to parse commit %s", name);
if (flags & UNINTERESTING) { if (flags & UNINTERESTING) {
@ -241,7 +246,7 @@ int rev_compare_tree(struct rev_info *revs, struct tree *t1, struct tree *t2)
return REV_TREE_DIFFERENT; return REV_TREE_DIFFERENT;
tree_difference = REV_TREE_SAME; tree_difference = REV_TREE_SAME;
if (diff_tree_sha1(t1->object.sha1, t2->object.sha1, "", if (diff_tree_sha1(t1->object.sha1, t2->object.sha1, "",
&revs->diffopt) < 0) &revs->pruning) < 0)
return REV_TREE_DIFFERENT; return REV_TREE_DIFFERENT;
return tree_difference; return tree_difference;
} }
@ -264,7 +269,7 @@ int rev_same_tree_as_empty(struct rev_info *revs, struct tree *t1)
empty.size = 0; empty.size = 0;
tree_difference = 0; tree_difference = 0;
retval = diff_tree(&empty, &real, "", &revs->diffopt); retval = diff_tree(&empty, &real, "", &revs->pruning);
free(tree); free(tree);
return retval >= 0 && !tree_difference; return retval >= 0 && !tree_difference;
@ -454,21 +459,13 @@ static void limit_list(struct rev_info *revs)
revs->commits = newlist; revs->commits = newlist;
} }
static void add_one_commit(struct commit *commit, struct rev_info *revs)
{
if (!commit || (commit->object.flags & SEEN))
return;
commit->object.flags |= SEEN;
commit_list_insert(commit, &revs->commits);
}
static int all_flags; static int all_flags;
static struct rev_info *all_revs; static struct rev_info *all_revs;
static int handle_one_ref(const char *path, const unsigned char *sha1) static int handle_one_ref(const char *path, const unsigned char *sha1)
{ {
struct commit *commit = get_commit_reference(all_revs, path, sha1, all_flags); struct object *object = get_reference(all_revs, path, sha1, all_flags);
add_one_commit(commit, all_revs); add_pending_object(all_revs, object, "");
return 0; return 0;
} }
@ -482,9 +479,12 @@ static void handle_all(struct rev_info *revs, unsigned flags)
void init_revisions(struct rev_info *revs) void init_revisions(struct rev_info *revs)
{ {
memset(revs, 0, sizeof(*revs)); memset(revs, 0, sizeof(*revs));
revs->diffopt.recursive = 1;
revs->diffopt.add_remove = file_add_remove; revs->abbrev = DEFAULT_ABBREV;
revs->diffopt.change = file_change; revs->ignore_merges = 1;
revs->pruning.recursive = 1;
revs->pruning.add_remove = file_add_remove;
revs->pruning.change = file_change;
revs->lifo = 1; revs->lifo = 1;
revs->dense = 1; revs->dense = 1;
revs->prefix = setup_git_directory(); revs->prefix = setup_git_directory();
@ -497,6 +497,11 @@ void init_revisions(struct rev_info *revs)
revs->topo_setter = topo_sort_default_setter; revs->topo_setter = topo_sort_default_setter;
revs->topo_getter = topo_sort_default_getter; revs->topo_getter = topo_sort_default_getter;
revs->header_prefix = "";
revs->commit_format = CMIT_FMT_DEFAULT;
diff_setup(&revs->diffopt);
} }
/* /*
@ -512,8 +517,6 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
const char **unrecognized = argv + 1; const char **unrecognized = argv + 1;
int left = 1; int left = 1;
init_revisions(revs);
/* First, search for "--" */ /* First, search for "--" */
seen_dashdash = 0; seen_dashdash = 0;
for (i = 1; i < argc; i++) { for (i = 1; i < argc; i++) {
@ -529,13 +532,14 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
flags = 0; flags = 0;
for (i = 1; i < argc; i++) { for (i = 1; i < argc; i++) {
struct commit *commit; struct object *object;
const char *arg = argv[i]; const char *arg = argv[i];
unsigned char sha1[20]; unsigned char sha1[20];
char *dotdot; char *dotdot;
int local_flags; int local_flags;
if (*arg == '-') { if (*arg == '-') {
int opts;
if (!strncmp(arg, "--max-count=", 12)) { if (!strncmp(arg, "--max-count=", 12)) {
revs->max_count = atoi(arg + 12); revs->max_count = atoi(arg + 12);
continue; continue;
@ -643,6 +647,78 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
revs->unpacked = 1; revs->unpacked = 1;
continue; continue;
} }
if (!strcmp(arg, "-r")) {
revs->diff = 1;
revs->diffopt.recursive = 1;
continue;
}
if (!strcmp(arg, "-t")) {
revs->diff = 1;
revs->diffopt.recursive = 1;
revs->diffopt.tree_in_recursive = 1;
continue;
}
if (!strcmp(arg, "-m")) {
revs->ignore_merges = 0;
continue;
}
if (!strcmp(arg, "-c")) {
revs->diff = 1;
revs->combine_merges = 1;
continue;
}
if (!strcmp(arg, "--cc")) {
revs->diff = 1;
revs->dense_combined_merges = 1;
revs->combine_merges = 1;
continue;
}
if (!strcmp(arg, "-v")) {
revs->verbose_header = 1;
revs->header_prefix = "diff-tree ";
continue;
}
if (!strncmp(arg, "--pretty", 8)) {
revs->verbose_header = 1;
revs->header_prefix = "diff-tree ";
revs->commit_format = get_commit_format(arg+8);
continue;
}
if (!strcmp(arg, "--root")) {
revs->show_root_diff = 1;
continue;
}
if (!strcmp(arg, "--no-commit-id")) {
revs->no_commit_id = 1;
continue;
}
if (!strcmp(arg, "--always")) {
revs->always_show_header = 1;
continue;
}
if (!strcmp(arg, "--no-abbrev")) {
revs->abbrev = 0;
continue;
}
if (!strcmp(arg, "--abbrev")) {
revs->abbrev = DEFAULT_ABBREV;
continue;
}
if (!strcmp(arg, "--abbrev-commit")) {
revs->abbrev_commit = 1;
continue;
}
if (!strcmp(arg, "--full-diff")) {
revs->diff = 1;
revs->full_diff = 1;
continue;
}
opts = diff_opt_parse(&revs->diffopt, argv+i, argc-i);
if (opts > 0) {
revs->diff = 1;
i += opts - 1;
continue;
}
*unrecognized++ = arg; *unrecognized++ = arg;
left++; left++;
continue; continue;
@ -659,15 +735,15 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
this = "HEAD"; this = "HEAD";
if (!get_sha1(this, from_sha1) && if (!get_sha1(this, from_sha1) &&
!get_sha1(next, sha1)) { !get_sha1(next, sha1)) {
struct commit *exclude; struct object *exclude;
struct commit *include; struct object *include;
exclude = get_commit_reference(revs, this, from_sha1, flags ^ UNINTERESTING); exclude = get_reference(revs, this, from_sha1, flags ^ UNINTERESTING);
include = get_commit_reference(revs, next, sha1, flags); include = get_reference(revs, next, sha1, flags);
if (!exclude || !include) if (!exclude || !include)
die("Invalid revision range %s..%s", arg, next); die("Invalid revision range %s..%s", arg, next);
add_one_commit(exclude, revs); add_pending_object(revs, exclude, this);
add_one_commit(include, revs); add_pending_object(revs, include, next);
continue; continue;
} }
*dotdot = '.'; *dotdot = '.';
@ -692,34 +768,59 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
revs->prune_data = get_pathspec(revs->prefix, argv + i); revs->prune_data = get_pathspec(revs->prefix, argv + i);
break; break;
} }
commit = get_commit_reference(revs, arg, sha1, flags ^ local_flags); object = get_reference(revs, arg, sha1, flags ^ local_flags);
add_one_commit(commit, revs); add_pending_object(revs, object, arg);
} }
if (def && !revs->commits) { if (def && !revs->pending_objects) {
unsigned char sha1[20]; unsigned char sha1[20];
struct commit *commit; struct object *object;
if (get_sha1(def, sha1) < 0) if (get_sha1(def, sha1) < 0)
die("bad default revision '%s'", def); die("bad default revision '%s'", def);
commit = get_commit_reference(revs, def, sha1, 0); object = get_reference(revs, def, sha1, 0);
add_one_commit(commit, revs); add_pending_object(revs, object, def);
} }
if (revs->topo_order || revs->unpacked) if (revs->topo_order || revs->unpacked)
revs->limited = 1; revs->limited = 1;
if (revs->prune_data) { if (revs->prune_data) {
diff_tree_setup_paths(revs->prune_data, &revs->diffopt); diff_tree_setup_paths(revs->prune_data, &revs->pruning);
revs->prune_fn = try_to_simplify_commit; revs->prune_fn = try_to_simplify_commit;
if (!revs->full_diff)
diff_tree_setup_paths(revs->prune_data, &revs->diffopt);
} }
if (revs->combine_merges) {
revs->ignore_merges = 0;
if (revs->dense_combined_merges)
revs->diffopt.output_format = DIFF_FORMAT_PATCH;
}
if (revs->diffopt.output_format == DIFF_FORMAT_PATCH)
revs->diffopt.recursive = 1;
revs->diffopt.abbrev = revs->abbrev;
diff_setup_done(&revs->diffopt);
return left; return left;
} }
void prepare_revision_walk(struct rev_info *revs) void prepare_revision_walk(struct rev_info *revs)
{ {
struct object_list *list;
list = revs->pending_objects;
revs->pending_objects = NULL;
while (list) {
struct commit *commit = handle_commit(revs, list->item, list->name);
if (commit) {
if (!(commit->object.flags & SEEN)) {
commit->object.flags |= SEEN;
insert_by_date(commit, &revs->commits);
}
}
list = list->next;
}
if (revs->no_walk) if (revs->no_walk)
return; return;
sort_by_date(&revs->commits);
if (revs->limited) if (revs->limited)
limit_list(revs); limit_list(revs);
if (revs->topo_order) if (revs->topo_order)

View file

@ -39,13 +39,32 @@ struct rev_info {
boundary:1, boundary:1,
parents:1; parents:1;
/* Diff flags */
unsigned int diff:1,
full_diff:1,
show_root_diff:1,
no_commit_id:1,
verbose_header:1,
ignore_merges:1,
combine_merges:1,
dense_combined_merges:1,
always_show_header:1;
/* Format info */
unsigned int abbrev_commit:1;
unsigned int abbrev;
enum cmit_fmt commit_format;
const char *header_prefix;
const char *header;
/* special limits */ /* special limits */
int max_count; int max_count;
unsigned long max_age; unsigned long max_age;
unsigned long min_age; unsigned long min_age;
/* paths limiting */ /* diff info for patches and for paths limiting */
struct diff_options diffopt; struct diff_options diffopt;
struct diff_options pruning;
topo_sort_set_fn_t topo_setter; topo_sort_set_fn_t topo_setter;
topo_sort_get_fn_t topo_getter; topo_sort_get_fn_t topo_getter;