summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLibravatar Junio C Hamano <junkio@cox.net>2006-04-16 00:52:55 -0700
committerLibravatar Junio C Hamano <junkio@cox.net>2006-04-16 01:02:33 -0700
commit43f934aa9078b6a82cc43c7d4efc9a048b7fed60 (patch)
treeb779c03cc7268f21cb5370cd7f1d1f4b47f58033
parentMerge branch 'js/diffstat' into next (diff)
parentTentative built-in "git show" (diff)
downloadtgif-43f934aa9078b6a82cc43c7d4efc9a048b7fed60.tar.xz
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()
-rw-r--r--commit.h2
-rw-r--r--diff-tree.c93
-rw-r--r--git.c94
-rw-r--r--http-push.c1
-rw-r--r--log-tree.c127
-rw-r--r--log-tree.h33
-rw-r--r--rev-list.c88
-rw-r--r--revision.c173
-rw-r--r--revision.h21
9 files changed, 289 insertions, 343 deletions
diff --git a/commit.h b/commit.h
index 918c9ab5e4..de142afe73 100644
--- a/commit.h
+++ b/commit.h
@@ -45,6 +45,8 @@ enum cmit_fmt {
CMIT_FMT_FULL,
CMIT_FMT_FULLER,
CMIT_FMT_ONELINE,
+
+ CMIT_FMT_UNSPECIFIED,
};
extern enum cmit_fmt get_commit_format(const char *arg);
diff --git a/diff-tree.c b/diff-tree.c
index 7015b06c7f..e578798537 100644
--- a/diff-tree.c
+++ b/diff-tree.c
@@ -3,7 +3,7 @@
#include "commit.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)
{
@@ -62,47 +62,20 @@ int main(int argc, const char **argv)
{
int nr_sha1;
char line[1000];
- unsigned char sha1[2][20];
- const char *prefix = setup_git_directory();
- static struct log_tree_opt *opt = &log_tree_opt;
+ struct object *tree1, *tree2;
+ static struct rev_info *opt = &log_tree_opt;
+ struct object_list *list;
int read_stdin = 0;
git_config(git_diff_config);
nr_sha1 = 0;
- init_log_tree_opt(opt);
+ init_revisions(opt);
+ opt->abbrev = 0;
+ argc = setup_revisions(argc, argv, opt, NULL);
- for (;;) {
- int opt_cnt;
- const char *arg;
+ while (--argc > 0) {
+ const char *arg = *++argv;
- 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")) {
read_stdin = 1;
continue;
@@ -110,18 +83,36 @@ int main(int argc, const char **argv)
usage(diff_tree_usage);
}
- if (opt->combine_merges)
- opt->ignore_merges = 0;
-
- /* We can only do dense combined merges with diff output */
- if (opt->dense_combined_merges)
- opt->diffopt.output_format = DIFF_FORMAT_PATCH;
-
- if (opt->diffopt.output_format == DIFF_FORMAT_PATCH)
- opt->diffopt.recursive = 1;
-
- diff_tree_setup_paths(get_pathspec(prefix, argv), &opt->diffopt);
- diff_setup_done(&opt->diffopt);
+ /*
+ * NOTE! "setup_revisions()" will have inserted the revisions
+ * it parsed in reverse order. So if you do
+ *
+ * git-diff-tree a b
+ *
+ * the commit list will be "b" -> "a" -> NULL, so we reverse
+ * the order of the objects if the first one is not marked
+ * UNINTERESTING.
+ */
+ nr_sha1 = 0;
+ 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) {
case 0:
@@ -129,10 +120,12 @@ int main(int argc, const char **argv)
usage(diff_tree_usage);
break;
case 1:
- diff_tree_commit_sha1(sha1[0]);
+ diff_tree_commit_sha1(tree1->sha1);
break;
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);
break;
}
diff --git a/git.c b/git.c
index 2e0ae5e58e..239b26adfd 100644
--- a/git.c
+++ b/git.c
@@ -279,31 +279,28 @@ static int cmd_help(int argc, const char **argv, char **envp)
#define LOGSIZE (65536)
static int cmd_log_wc(int argc, const char **argv, char **envp,
- struct whatchanged_opt *wcopt)
+ struct rev_info *rev)
{
struct commit *commit;
char *buf = xmalloc(LOGSIZE);
const char *commit_prefix = "commit ";
int shown = 0;
- struct rev_info *rev = &wcopt->revopt;
- struct log_tree_opt *opt = &wcopt->logopt;
- opt->commit_format = CMIT_FMT_DEFAULT;
- wcopt->abbrev = DEFAULT_ABBREV;
- argc = parse_whatchanged_opt(argc, argv, wcopt);
-
- if (opt->commit_format == CMIT_FMT_ONELINE)
+ if (argc > 1)
+ die("unrecognized argument: %s", argv[1]);
+ if (rev->commit_format == CMIT_FMT_ONELINE)
commit_prefix = "";
prepare_revision_walk(rev);
setup_pager();
while ((commit = get_revision(rev)) != NULL) {
- if (shown && wcopt->do_diff &&
- opt->commit_format != CMIT_FMT_ONELINE)
+ if (shown && rev->diff &&
+ rev->commit_format != CMIT_FMT_ONELINE)
putchar('\n');
fputs(commit_prefix, stdout);
- if (wcopt->abbrev_commit && wcopt->abbrev)
- fputs(find_unique_abbrev(commit->object.sha1, wcopt->abbrev),
+ if (rev->abbrev_commit && rev->abbrev)
+ fputs(find_unique_abbrev(commit->object.sha1,
+ rev->abbrev),
stdout);
else
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->item->object.flags &= ~TMP_MARK;
}
- if (opt->commit_format == CMIT_FMT_ONELINE)
+ if (rev->commit_format == CMIT_FMT_ONELINE)
putchar(' ');
else
putchar('\n');
- pretty_print_commit(opt->commit_format, commit, ~0, buf,
- LOGSIZE, wcopt->abbrev);
+ pretty_print_commit(rev->commit_format, commit, ~0, buf,
+ LOGSIZE, rev->abbrev);
printf("%s\n", buf);
- if (wcopt->do_diff) {
- printf("---\n");
- log_tree_commit(opt, commit);
+ if (rev->diff) {
+ printf("--\n");
+ log_tree_commit(rev, commit);
}
shown = 1;
free(commit->buffer);
@@ -345,38 +342,47 @@ static int cmd_log_wc(int argc, const char **argv, char **envp,
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;
-
- memset(&wcopt, 0, sizeof(wcopt));
- init_log_tree_opt(&wcopt.logopt);
- return cmd_log_wc(ac, av, ep, &wcopt);
+ struct rev_info rev;
+
+ init_revisions(&rev);
+ rev.abbrev = DEFAULT_ABBREV;
+ 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;
-
- memset(&wcopt, 0, sizeof(wcopt));
- wcopt.do_diff = 1;
- init_log_tree_opt(&wcopt.logopt);
- wcopt.logopt.diffopt.recursive = 1;
- return cmd_log_wc(ac, av, ep, &wcopt);
+ struct rev_info rev;
+
+ init_revisions(&rev);
+ rev.diff = 1;
+ rev.ignore_merges = 0;
+ rev.combine_merges = 1;
+ 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;
-
- memset(&wcopt, 0, sizeof(wcopt));
- wcopt.do_diff = 1;
- init_log_tree_opt(&wcopt.logopt);
- wcopt.logopt.ignore_merges = 0;
- wcopt.logopt.combine_merges = 1;
- wcopt.logopt.dense_combined_merges = 1;
- wcopt.logopt.diffopt.recursive = 1;
- return cmd_log_wc(ac, av, ep, &wcopt);
+ struct rev_info rev;
+
+ init_revisions(&rev);
+ rev.abbrev = DEFAULT_ABBREV;
+ rev.no_commit_id = 1;
+ rev.commit_format = CMIT_FMT_DEFAULT;
+ argc = setup_revisions(argc, argv, &rev, "HEAD");
+ return cmd_log_wc(argc, argv, envp, &rev);
}
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 },
{ "help", cmd_help },
{ "log", cmd_log },
+ { "whatchanged", cmd_wc },
{ "show", cmd_show },
- { "whatchanged", cmd_whatchanged },
};
int i;
diff --git a/http-push.c b/http-push.c
index 19a0f772e7..4a9dcf2bf6 100644
--- a/http-push.c
+++ b/http-push.c
@@ -2498,6 +2498,7 @@ int main(int argc, char **argv)
commit_argv[3] = old_sha1_hex;
commit_argc++;
}
+ init_revisions(&revs);
setup_revisions(commit_argc, commit_argv, &revs, NULL);
free(new_sha1_hex);
if (old_sha1_hex) {
diff --git a/log-tree.c b/log-tree.c
index 17e976a637..04a68e0f57 100644
--- a/log-tree.c
+++ b/log-tree.c
@@ -3,57 +3,7 @@
#include "commit.h"
#include "log-tree.h"
-void init_log_tree_opt(struct log_tree_opt *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)
+int log_tree_diff_flush(struct rev_info *opt)
{
diffcore_std(&opt->diffopt);
if (diff_queue_is_empty()) {
@@ -73,7 +23,7 @@ int log_tree_diff_flush(struct log_tree_opt *opt)
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)
{
int retval;
@@ -93,7 +43,7 @@ static int diff_root_tree(struct log_tree_opt *opt,
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 *parent_sha1,
const struct commit *commit)
@@ -129,7 +79,7 @@ static const char *generate_header(struct log_tree_opt *opt,
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;
@@ -142,7 +92,7 @@ static int do_diff_combined(struct log_tree_opt *opt, struct commit *commit)
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;
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;
}
-
-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;
-}
diff --git a/log-tree.h b/log-tree.h
index 8d8f6f1458..91a909be73 100644
--- a/log-tree.h
+++ b/log-tree.h
@@ -3,34 +3,9 @@
#include "revision.h"
-struct log_tree_opt {
- struct diff_options diffopt;
- int show_root_diff;
- int no_commit_id;
- 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 *);
+void init_log_tree_opt(struct rev_info *);
+int log_tree_diff_flush(struct rev_info *);
+int log_tree_commit(struct rev_info *, struct commit *);
+int log_tree_opt_parse(struct rev_info *, const char **, int);
#endif
diff --git a/rev-list.c b/rev-list.c
index cb67b399fc..33741ebbc4 100644
--- a/rev-list.c
+++ b/rev-list.c
@@ -39,24 +39,20 @@ static const char rev_list_usage[] =
struct rev_info revs;
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 hdr_termination = 0;
-static const char *commit_prefix = "";
-static enum cmit_fmt commit_format = CMIT_FMT_RAW;
static void show_commit(struct commit *commit)
{
if (show_timestamp)
printf("%lu ", commit->date);
- if (commit_prefix[0])
- fputs(commit_prefix, stdout);
+ if (*revs.header_prefix)
+ fputs(revs.header_prefix, stdout);
if (commit->object.flags & BOUNDARY)
putchar('-');
- if (abbrev_commit && abbrev)
- fputs(find_unique_abbrev(commit->object.sha1, abbrev), stdout);
+ if (revs.abbrev_commit && revs.abbrev)
+ fputs(find_unique_abbrev(commit->object.sha1, revs.abbrev),
+ stdout);
else
fputs(sha1_to_hex(commit->object.sha1), stdout);
if (revs.parents) {
@@ -78,14 +74,16 @@ static void show_commit(struct commit *commit)
parents = parents->next)
parents->item->object.flags &= ~TMP_MARK;
}
- if (commit_format == CMIT_FMT_ONELINE)
+ if (revs.commit_format == CMIT_FMT_ONELINE)
putchar(' ');
else
putchar('\n');
- if (verbose_header) {
+ if (revs.verbose_header) {
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);
}
fflush(stdout);
@@ -297,58 +295,16 @@ int main(int argc, const char **argv)
struct commit_list *list;
int i;
+ init_revisions(&revs);
+ revs.abbrev = 0;
+ revs.commit_format = CMIT_FMT_UNSPECIFIED;
argc = setup_revisions(argc, argv, &revs, NULL);
for (i = 1 ; i < argc; 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")) {
- 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 ";
+ revs.verbose_header = 1;
continue;
}
if (!strcmp(arg, "--timestamp")) {
@@ -362,14 +318,24 @@ int main(int argc, const char **argv)
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;
- if (!list &&
- (!(revs.tag_objects||revs.tree_objects||revs.blob_objects) && !revs.pending_objects))
+ if ((!list &&
+ (!(revs.tag_objects||revs.tree_objects||revs.blob_objects) &&
+ !revs.pending_objects)) ||
+ revs.diff)
usage(rev_list_usage);
- save_commit_buffer = verbose_header;
+ save_commit_buffer = revs.verbose_header;
track_object_refs = 0;
if (bisect_list)
revs.limited = 1;
diff --git a/revision.c b/revision.c
index 0c3c392fde..f8fb028855 100644
--- a/revision.c
+++ b/revision.c
@@ -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);
}
-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;
object = parse_object(sha1);
if (!object)
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..
*/
while (object->type == tag_type) {
struct tag *tag = (struct tag *) object;
- object->flags |= flags;
- if (revs->tag_objects && !(object->flags & UNINTERESTING))
+ if (revs->tag_objects && !(flags & UNINTERESTING))
add_pending_object(revs, object, tag->tag);
object = parse_object(tag->tagged->sha1);
if (!object)
@@ -143,7 +149,6 @@ static struct commit *get_commit_reference(struct rev_info *revs, const char *na
*/
if (object->type == commit_type) {
struct commit *commit = (struct commit *)object;
- object->flags |= flags;
if (parse_commit(commit) < 0)
die("unable to parse commit %s", name);
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;
tree_difference = REV_TREE_SAME;
if (diff_tree_sha1(t1->object.sha1, t2->object.sha1, "",
- &revs->diffopt) < 0)
+ &revs->pruning) < 0)
return REV_TREE_DIFFERENT;
return tree_difference;
}
@@ -264,7 +269,7 @@ int rev_same_tree_as_empty(struct rev_info *revs, struct tree *t1)
empty.size = 0;
tree_difference = 0;
- retval = diff_tree(&empty, &real, "", &revs->diffopt);
+ retval = diff_tree(&empty, &real, "", &revs->pruning);
free(tree);
return retval >= 0 && !tree_difference;
@@ -454,21 +459,13 @@ static void limit_list(struct rev_info *revs)
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 struct rev_info *all_revs;
static int handle_one_ref(const char *path, const unsigned char *sha1)
{
- struct commit *commit = get_commit_reference(all_revs, path, sha1, all_flags);
- add_one_commit(commit, all_revs);
+ struct object *object = get_reference(all_revs, path, sha1, all_flags);
+ add_pending_object(all_revs, object, "");
return 0;
}
@@ -482,9 +479,12 @@ static void handle_all(struct rev_info *revs, unsigned flags)
void init_revisions(struct rev_info *revs)
{
memset(revs, 0, sizeof(*revs));
- revs->diffopt.recursive = 1;
- revs->diffopt.add_remove = file_add_remove;
- revs->diffopt.change = file_change;
+
+ revs->abbrev = DEFAULT_ABBREV;
+ revs->ignore_merges = 1;
+ revs->pruning.recursive = 1;
+ revs->pruning.add_remove = file_add_remove;
+ revs->pruning.change = file_change;
revs->lifo = 1;
revs->dense = 1;
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_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;
int left = 1;
- init_revisions(revs);
-
/* First, search for "--" */
seen_dashdash = 0;
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;
for (i = 1; i < argc; i++) {
- struct commit *commit;
+ 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)) {
revs->max_count = atoi(arg + 12);
continue;
@@ -643,6 +647,78 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
revs->unpacked = 1;
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;
left++;
continue;
@@ -659,15 +735,15 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
this = "HEAD";
if (!get_sha1(this, from_sha1) &&
!get_sha1(next, sha1)) {
- struct commit *exclude;
- struct commit *include;
+ struct object *exclude;
+ struct object *include;
- exclude = get_commit_reference(revs, this, from_sha1, flags ^ UNINTERESTING);
- include = get_commit_reference(revs, next, sha1, flags);
+ exclude = get_reference(revs, this, from_sha1, flags ^ UNINTERESTING);
+ include = get_reference(revs, next, sha1, flags);
if (!exclude || !include)
die("Invalid revision range %s..%s", arg, next);
- add_one_commit(exclude, revs);
- add_one_commit(include, revs);
+ add_pending_object(revs, exclude, this);
+ add_pending_object(revs, include, next);
continue;
}
*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);
break;
}
- commit = get_commit_reference(revs, arg, sha1, flags ^ local_flags);
- add_one_commit(commit, revs);
+ object = get_reference(revs, arg, sha1, flags ^ local_flags);
+ add_pending_object(revs, object, arg);
}
- if (def && !revs->commits) {
+ if (def && !revs->pending_objects) {
unsigned char sha1[20];
- struct commit *commit;
+ struct object *object;
if (get_sha1(def, sha1) < 0)
die("bad default revision '%s'", def);
- commit = get_commit_reference(revs, def, sha1, 0);
- add_one_commit(commit, revs);
+ object = get_reference(revs, def, sha1, 0);
+ add_pending_object(revs, object, def);
}
if (revs->topo_order || revs->unpacked)
revs->limited = 1;
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;
+ 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;
}
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)
return;
- sort_by_date(&revs->commits);
if (revs->limited)
limit_list(revs);
if (revs->topo_order)
diff --git a/revision.h b/revision.h
index ff2a13ea87..7b854866b2 100644
--- a/revision.h
+++ b/revision.h
@@ -39,13 +39,32 @@ struct rev_info {
boundary: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 */
int max_count;
unsigned long max_age;
unsigned long min_age;
- /* paths limiting */
+ /* diff info for patches and for paths limiting */
struct diff_options diffopt;
+ struct diff_options pruning;
topo_sort_set_fn_t topo_setter;
topo_sort_get_fn_t topo_getter;