Merge branch 'jc/diff' into next
authorJunio C Hamano <junkio@cox.net>
Tue, 11 Apr 2006 21:34:53 +0000 (14:34 -0700)
committerJunio C Hamano <junkio@cox.net>
Tue, 11 Apr 2006 21:34:53 +0000 (14:34 -0700)
* jc/diff:
  blame and friends: adjust to multiple pathspec change.
  git log --full-diff
  tree-diff: do not assume we use only one pathspec

blame.c
diff-tree.c
diff.h
git.c
http-push.c
rev-list.c
revision.c
revision.h
tree-diff.c

diff --git a/blame.c b/blame.c
index 6730b10..07d2d27 100644 (file)
--- a/blame.c
+++ b/blame.c
@@ -508,25 +508,33 @@ static void process_commits(struct rev_info *rev, const char *path,
 static int compare_tree_path(struct rev_info* revs,
                             struct commit* c1, struct commit* c2)
 {
+       int ret;
        const char* paths[2];
        struct util_info* util = c2->object.util;
        paths[0] = util->pathname;
        paths[1] = NULL;
 
-       diff_tree_setup_paths(get_pathspec(revs->prefix, paths));
-       return rev_compare_tree(c1->tree, c2->tree);
+       diff_tree_setup_paths(get_pathspec(revs->prefix, paths),
+                             &revs->diffopt);
+       ret = rev_compare_tree(revs, c1->tree, c2->tree);
+       diff_tree_release_paths(&revs->diffopt);
+       return ret;
 }
 
 
 static int same_tree_as_empty_path(struct rev_info *revs, struct tree* t1,
                                   const char* path)
 {
+       int ret;
        const char* paths[2];
        paths[0] = path;
        paths[1] = NULL;
 
-       diff_tree_setup_paths(get_pathspec(revs->prefix, paths));
-       return rev_same_tree_as_empty(t1);
+       diff_tree_setup_paths(get_pathspec(revs->prefix, paths),
+                             &revs->diffopt);
+       ret = rev_same_tree_as_empty(revs, t1);
+       diff_tree_release_paths(&revs->diffopt);
+       return ret;
 }
 
 static const char* find_rename(struct commit* commit, struct commit* parent)
@@ -546,7 +554,7 @@ static const char* find_rename(struct commit* commit, struct commit* parent)
        diff_opts.recursive = 1;
        diff_opts.detect_rename = DIFF_DETECT_RENAME;
        paths[0] = NULL;
-       diff_tree_setup_paths(paths);
+       diff_tree_setup_paths(paths, &diff_opts);
        if (diff_setup_done(&diff_opts) < 0)
                die("diff_setup_done failed");
 
@@ -826,7 +834,7 @@ int main(int argc, const char **argv)
 
        args[0] = filename;
        args[1] = NULL;
-       diff_tree_setup_paths(args);
+       diff_tree_setup_paths(args, &rev.diffopt);
        prepare_revision_walk(&rev);
        process_commits(&rev, filename, &initial);
 
index 2a088d1..2b79dd0 100644 (file)
@@ -120,7 +120,7 @@ int main(int argc, const char **argv)
        if (opt->diffopt.output_format == DIFF_FORMAT_PATCH)
                opt->diffopt.recursive = 1;
 
-       diff_tree_setup_paths(get_pathspec(prefix, argv));
+       diff_tree_setup_paths(get_pathspec(prefix, argv), opt);
        diff_setup_done(&opt->diffopt);
 
        switch (nr_sha1) {
diff --git a/diff.h b/diff.h
index c5372b9..236095f 100644 (file)
--- a/diff.h
+++ b/diff.h
@@ -39,11 +39,15 @@ struct diff_options {
        int setup;
        int abbrev;
 
+       int nr_paths;
+       const char **paths;
+       int *pathlens;
        change_fn_t change;
        add_remove_fn_t add_remove;
 };
 
-extern void diff_tree_setup_paths(const char **paths);
+extern void diff_tree_setup_paths(const char **paths, struct diff_options *);
+extern void diff_tree_release_paths(struct diff_options *);
 extern int diff_tree(struct tree_desc *t1, struct tree_desc *t2,
                     const char *base, struct diff_options *opt);
 extern int diff_tree_sha1(const unsigned char *old, const unsigned char *new,
diff --git a/git.c b/git.c
index 8776088..5cb0d32 100644 (file)
--- a/git.c
+++ b/git.c
@@ -15,8 +15,8 @@
 
 #include "cache.h"
 #include "commit.h"
-#include "revision.h"
 #include "diff.h"
+#include "revision.h"
 #include "log-tree.h"
 
 #ifndef PATH_MAX
@@ -288,7 +288,9 @@ static int cmd_log(int argc, const char **argv, char **envp)
        int abbrev_commit = 0;
        const char *commit_prefix = "commit ";
        struct log_tree_opt opt;
+       int shown = 0;
        int do_diff = 0;
+       int full_diff = 0;
 
        init_log_tree_opt(&opt);
        argc = setup_revisions(argc, argv, &rev, "HEAD");
@@ -315,6 +317,10 @@ static int cmd_log(int argc, const char **argv, char **envp)
                        else if (40 < abbrev)
                                abbrev = 40;
                }
+               else if (!strcmp(arg, "--full-diff")) {
+                       do_diff = 1;
+                       full_diff = 1;
+               }
                else {
                        int cnt = log_tree_opt_parse(&opt, argv+1, argc-1);
                        if (0 < cnt) {
@@ -328,6 +334,7 @@ static int cmd_log(int argc, const char **argv, char **envp)
 
                argc--; argv++;
        }
+
        if (do_diff) {
                opt.diffopt.abbrev = abbrev;
                opt.verbose_header = 0;
@@ -339,12 +346,16 @@ static int cmd_log(int argc, const char **argv, char **envp)
                        opt.diffopt.output_format = DIFF_FORMAT_PATCH;
                if (opt.diffopt.output_format == DIFF_FORMAT_PATCH)
                        opt.diffopt.recursive = 1;
+               if (!full_diff && rev.prune_data)
+                       diff_tree_setup_paths(rev.prune_data, &opt.diffopt);
                diff_setup_done(&opt.diffopt);
        }
 
        prepare_revision_walk(&rev);
        setup_pager();
        while ((commit = get_revision(&rev)) != NULL) {
+               if (commit_format != CMIT_FMT_ONELINE && shown)
+                       putchar('\n');
                fputs(commit_prefix, stdout);
                if (abbrev_commit && abbrev)
                        fputs(find_unique_abbrev(commit->object.sha1, abbrev),
@@ -377,9 +388,9 @@ static int cmd_log(int argc, const char **argv, char **envp)
                pretty_print_commit(commit_format, commit, ~0, buf,
                                    LOGSIZE, abbrev);
                printf("%s\n", buf);
-
                if (do_diff)
                        log_tree_commit(&opt, commit);
+               shown = 1;
        }
        free(buf);
        return 0;
index 994ee90..19a0f77 100644 (file)
@@ -6,6 +6,7 @@
 #include "blob.h"
 #include "http.h"
 #include "refs.h"
+#include "diff.h"
 #include "revision.h"
 #include "exec_cmd.h"
 
index 359195b..963707a 100644 (file)
@@ -5,6 +5,7 @@
 #include "tree.h"
 #include "blob.h"
 #include "tree-walk.h"
+#include "diff.h"
 #include "revision.h"
 
 /* bits #0-6 in revision.h */
index fe26562..0505f3f 100644 (file)
@@ -233,25 +233,20 @@ static void file_change(struct diff_options *options,
        tree_difference = REV_TREE_DIFFERENT;
 }
 
-static struct diff_options diff_opt = {
-       .recursive = 1,
-       .add_remove = file_add_remove,
-       .change = file_change,
-};
-
-int rev_compare_tree(struct tree *t1, struct tree *t2)
+int rev_compare_tree(struct rev_info *revs, struct tree *t1, struct tree *t2)
 {
        if (!t1)
                return REV_TREE_NEW;
        if (!t2)
                return REV_TREE_DIFFERENT;
        tree_difference = REV_TREE_SAME;
-       if (diff_tree_sha1(t1->object.sha1, t2->object.sha1, "", &diff_opt) < 0)
+       if (diff_tree_sha1(t1->object.sha1, t2->object.sha1, "",
+                          &revs->diffopt) < 0)
                return REV_TREE_DIFFERENT;
        return tree_difference;
 }
 
-int rev_same_tree_as_empty(struct tree *t1)
+int rev_same_tree_as_empty(struct rev_info *revs, struct tree *t1)
 {
        int retval;
        void *tree;
@@ -269,7 +264,7 @@ int rev_same_tree_as_empty(struct tree *t1)
        empty.size = 0;
 
        tree_difference = 0;
-       retval = diff_tree(&empty, &real, "", &diff_opt);
+       retval = diff_tree(&empty, &real, "", &revs->diffopt);
        free(tree);
 
        return retval >= 0 && !tree_difference;
@@ -284,7 +279,7 @@ static void try_to_simplify_commit(struct rev_info *revs, struct commit *commit)
                return;
 
        if (!commit->parents) {
-               if (!rev_same_tree_as_empty(commit->tree))
+               if (!rev_same_tree_as_empty(revs, commit->tree))
                        commit->object.flags |= TREECHANGE;
                return;
        }
@@ -294,7 +289,7 @@ static void try_to_simplify_commit(struct rev_info *revs, struct commit *commit)
                struct commit *p = parent->item;
 
                parse_commit(p);
-               switch (rev_compare_tree(p->tree, commit->tree)) {
+               switch (rev_compare_tree(revs, p->tree, commit->tree)) {
                case REV_TREE_SAME:
                        if (p->object.flags & UNINTERESTING) {
                                /* Even if a merge with an uninteresting
@@ -312,7 +307,7 @@ static void try_to_simplify_commit(struct rev_info *revs, struct commit *commit)
 
                case REV_TREE_NEW:
                        if (revs->remove_empty_trees &&
-                           rev_same_tree_as_empty(p->tree)) {
+                           rev_same_tree_as_empty(revs, p->tree)) {
                                /* We are adding all the specified
                                 * paths from this parent, so the
                                 * history beyond this parent is not
@@ -484,6 +479,9 @@ 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->lifo = 1;
        revs->dense = 1;
        revs->prefix = setup_git_directory();
@@ -707,7 +705,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
                revs->limited = 1;
 
        if (revs->prune_data) {
-               diff_tree_setup_paths(revs->prune_data);
+               diff_tree_setup_paths(revs->prune_data, &revs->diffopt);
                revs->prune_fn = try_to_simplify_commit;
        }
 
index 83d28d5..8970b57 100644 (file)
@@ -43,6 +43,9 @@ struct rev_info {
        unsigned long max_age;
        unsigned long min_age;
 
+       /* paths limiting */
+       struct diff_options diffopt;
+
        topo_sort_set_fn_t topo_setter;
        topo_sort_get_fn_t topo_getter;
 };
@@ -52,8 +55,8 @@ struct rev_info {
 #define REV_TREE_DIFFERENT     2
 
 /* revision.c */
-extern int rev_same_tree_as_empty(struct tree *t1);
-extern int rev_compare_tree(struct tree *t1, struct tree *t2);
+extern int rev_same_tree_as_empty(struct rev_info *, struct tree *t1);
+extern int rev_compare_tree(struct rev_info *, struct tree *t1, struct tree *t2);
 
 extern void init_revisions(struct rev_info *revs);
 extern int setup_revisions(int argc, const char **argv, struct rev_info *revs, const char *def);
index 701fbba..1cdf8aa 100644 (file)
@@ -5,11 +5,6 @@
 #include "diff.h"
 #include "tree.h"
 
-// What paths are we interested in?
-static int nr_paths = 0;
-static const char **paths = NULL;
-static int *pathlens = NULL;
-
 static char *malloc_base(const char *base, const char *path, int pathlen)
 {
        int baselen = strlen(base);
@@ -72,14 +67,14 @@ static int compare_tree_entry(struct tree_desc *t1, struct tree_desc *t2, const
        return 0;
 }
 
-static int interesting(struct tree_desc *desc, const char *base)
+static int interesting(struct tree_desc *desc, const char *base, struct diff_options *opt)
 {
        const char *path;
        unsigned mode;
        int i;
        int baselen, pathlen;
 
-       if (!nr_paths)
+       if (!opt->nr_paths)
                return 1;
 
        (void)tree_entry_extract(desc, &path, &mode);
@@ -87,9 +82,9 @@ static int interesting(struct tree_desc *desc, const char *base)
        pathlen = strlen(path);
        baselen = strlen(base);
 
-       for (i=0; i < nr_paths; i++) {
-               const char *match = paths[i];
-               int matchlen = pathlens[i];
+       for (i=0; i < opt->nr_paths; i++) {
+               const char *match = opt->paths[i];
+               int matchlen = opt->pathlens[i];
 
                if (baselen >= matchlen) {
                        /* If it doesn't match, move along... */
@@ -129,7 +124,7 @@ static int interesting(struct tree_desc *desc, const char *base)
 static void show_tree(struct diff_options *opt, const char *prefix, struct tree_desc *desc, const char *base)
 {
        while (desc->size) {
-               if (interesting(desc, base))
+               if (interesting(desc, base, opt))
                        show_entry(opt, prefix, desc, base);
                update_tree_entry(desc);
        }
@@ -167,11 +162,11 @@ static int show_entry(struct diff_options *opt, const char *prefix, struct tree_
 int diff_tree(struct tree_desc *t1, struct tree_desc *t2, const char *base, struct diff_options *opt)
 {
        while (t1->size | t2->size) {
-               if (nr_paths && t1->size && !interesting(t1, base)) {
+               if (opt->nr_paths && t1->size && !interesting(t1, base, opt)) {
                        update_tree_entry(t1);
                        continue;
                }
-               if (nr_paths && t2->size && !interesting(t2, base)) {
+               if (opt->nr_paths && t2->size && !interesting(t2, base, opt)) {
                        update_tree_entry(t2);
                        continue;
                }
@@ -229,19 +224,28 @@ static int count_paths(const char **paths)
        return i;
 }
 
-void diff_tree_setup_paths(const char **p)
+void diff_tree_release_paths(struct diff_options *opt)
 {
+       free(opt->pathlens);
+}
+
+void diff_tree_setup_paths(const char **p, struct diff_options *opt)
+{
+       opt->nr_paths = 0;
+       opt->pathlens = NULL;
+       opt->paths = NULL;
+
        if (p) {
                int i;
 
-               paths = p;
-               nr_paths = count_paths(paths);
-               if (nr_paths == 0) {
-                       pathlens = NULL;
+               opt->paths = p;
+               opt->nr_paths = count_paths(p);
+               if (opt->nr_paths == 0) {
+                       opt->pathlens = NULL;
                        return;
                }
-               pathlens = xmalloc(nr_paths * sizeof(int));
-               for (i=0; i<nr_paths; i++)
-                       pathlens[i] = strlen(paths[i]);
+               opt->pathlens = xmalloc(opt->nr_paths * sizeof(int));
+               for (i=0; i < opt->nr_paths; i++)
+                       opt->pathlens[i] = strlen(p[i]);
        }
 }