From 81b50f3ce40bfdd66e5d967bf82be001039a9a98 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 22 Feb 2010 08:42:18 -0800 Subject: Move 'builtin-*' into a 'builtin/' subdirectory This shrinks the top-level directory a bit, and makes it much more pleasant to use auto-completion on the thing. Instead of [torvalds@nehalem git]$ em buil Display all 180 possibilities? (y or n) [torvalds@nehalem git]$ em builtin-sh builtin-shortlog.c builtin-show-branch.c builtin-show-ref.c builtin-shortlog.o builtin-show-branch.o builtin-show-ref.o [torvalds@nehalem git]$ em builtin-shor builtin-shortlog.c builtin-shortlog.o [torvalds@nehalem git]$ em builtin-shortlog.c you get [torvalds@nehalem git]$ em buil [type] builtin/ builtin.h [torvalds@nehalem git]$ em builtin [auto-completes to] [torvalds@nehalem git]$ em builtin/sh [type] shortlog.c shortlog.o show-branch.c show-branch.o show-ref.c show-ref.o [torvalds@nehalem git]$ em builtin/sho [auto-completes to] [torvalds@nehalem git]$ em builtin/shor [type] shortlog.c shortlog.o [torvalds@nehalem git]$ em builtin/shortlog.c which doesn't seem all that different, but not having that annoying break in "Display all 180 possibilities?" is quite a relief. NOTE! If you do this in a clean tree (no object files etc), or using an editor that has auto-completion rules that ignores '*.o' files, you won't see that annoying 'Display all 180 possibilities?' message - it will just show the choices instead. I think bash has some cut-off around 100 choices or something. So the reason I see this is that I'm using an odd editory, and thus don't have the rules to cut down on auto-completion. But you can simulate that by using 'ls' instead, or something similar. Signed-off-by: Linus Torvalds Signed-off-by: Junio C Hamano --- builtin/diff-tree.c | 170 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 170 insertions(+) create mode 100644 builtin/diff-tree.c (limited to 'builtin/diff-tree.c') diff --git a/builtin/diff-tree.c b/builtin/diff-tree.c new file mode 100644 index 0000000000..2380c21951 --- /dev/null +++ b/builtin/diff-tree.c @@ -0,0 +1,170 @@ +#include "cache.h" +#include "diff.h" +#include "commit.h" +#include "log-tree.h" +#include "builtin.h" + +static struct rev_info log_tree_opt; + +static int diff_tree_commit_sha1(const unsigned char *sha1) +{ + struct commit *commit = lookup_commit_reference(sha1); + if (!commit) + return -1; + return log_tree_commit(&log_tree_opt, commit); +} + +/* Diff one or more commits. */ +static int stdin_diff_commit(struct commit *commit, char *line, int len) +{ + unsigned char sha1[20]; + if (isspace(line[40]) && !get_sha1_hex(line+41, sha1)) { + /* Graft the fake parents locally to the commit */ + int pos = 41; + struct commit_list **pptr, *parents; + + /* Free the real parent list */ + for (parents = commit->parents; parents; ) { + struct commit_list *tmp = parents->next; + free(parents); + parents = tmp; + } + commit->parents = NULL; + pptr = &(commit->parents); + while (line[pos] && !get_sha1_hex(line + pos, sha1)) { + struct commit *parent = lookup_commit(sha1); + if (parent) { + pptr = &commit_list_insert(parent, pptr)->next; + } + pos += 41; + } + } + return log_tree_commit(&log_tree_opt, commit); +} + +/* Diff two trees. */ +static int stdin_diff_trees(struct tree *tree1, char *line, int len) +{ + unsigned char sha1[20]; + struct tree *tree2; + if (len != 82 || !isspace(line[40]) || get_sha1_hex(line + 41, sha1)) + return error("Need exactly two trees, separated by a space"); + tree2 = lookup_tree(sha1); + if (!tree2 || parse_tree(tree2)) + return -1; + printf("%s %s\n", sha1_to_hex(tree1->object.sha1), + sha1_to_hex(tree2->object.sha1)); + diff_tree_sha1(tree1->object.sha1, tree2->object.sha1, + "", &log_tree_opt.diffopt); + log_tree_diff_flush(&log_tree_opt); + return 0; +} + +static int diff_tree_stdin(char *line) +{ + int len = strlen(line); + unsigned char sha1[20]; + struct object *obj; + + if (!len || line[len-1] != '\n') + return -1; + line[len-1] = 0; + if (get_sha1_hex(line, sha1)) + return -1; + obj = lookup_unknown_object(sha1); + if (!obj || !obj->parsed) + obj = parse_object(sha1); + if (!obj) + return -1; + if (obj->type == OBJ_COMMIT) + return stdin_diff_commit((struct commit *)obj, line, len); + if (obj->type == OBJ_TREE) + return stdin_diff_trees((struct tree *)obj, line, len); + error("Object %s is a %s, not a commit or tree", + sha1_to_hex(sha1), typename(obj->type)); + return -1; +} + +static const char diff_tree_usage[] = +"git diff-tree [--stdin] [-m] [-c] [--cc] [-s] [-v] [--pretty] [-t] [-r] [--root] " +"[] [] [...]\n" +" -r diff recursively\n" +" --root include the initial commit as diff against /dev/null\n" +COMMON_DIFF_OPTIONS_HELP; + +int cmd_diff_tree(int argc, const char **argv, const char *prefix) +{ + int nr_sha1; + char line[1000]; + struct object *tree1, *tree2; + static struct rev_info *opt = &log_tree_opt; + int read_stdin = 0; + + init_revisions(opt, prefix); + git_config(git_diff_basic_config, NULL); /* no "diff" UI options */ + opt->abbrev = 0; + opt->diff = 1; + opt->disable_stdin = 1; + argc = setup_revisions(argc, argv, opt, NULL); + + while (--argc > 0) { + const char *arg = *++argv; + + if (!strcmp(arg, "--stdin")) { + read_stdin = 1; + continue; + } + usage(diff_tree_usage); + } + + if (!opt->diffopt.output_format) + opt->diffopt.output_format = DIFF_FORMAT_RAW; + + /* + * NOTE! We expect "a ^b" to be equal to "a..b", so we + * reverse the order of the objects if the second one + * is marked UNINTERESTING. + */ + nr_sha1 = opt->pending.nr; + switch (nr_sha1) { + case 0: + if (!read_stdin) + usage(diff_tree_usage); + break; + case 1: + tree1 = opt->pending.objects[0].item; + diff_tree_commit_sha1(tree1->sha1); + break; + case 2: + tree1 = opt->pending.objects[0].item; + tree2 = opt->pending.objects[1].item; + if (tree2->flags & UNINTERESTING) { + struct object *tmp = tree2; + tree2 = tree1; + tree1 = tmp; + } + diff_tree_sha1(tree1->sha1, + tree2->sha1, + "", &opt->diffopt); + log_tree_diff_flush(opt); + break; + } + + if (read_stdin) { + if (opt->diffopt.detect_rename) + opt->diffopt.setup |= (DIFF_SETUP_USE_SIZE_CACHE | + DIFF_SETUP_USE_CACHE); + while (fgets(line, sizeof(line), stdin)) { + unsigned char sha1[20]; + + if (get_sha1_hex(line, sha1)) { + fputs(line, stdout); + fflush(stdout); + } + else + diff_tree_stdin(line); + } + } + + return diff_result_code(&opt->diffopt, 0); +} -- cgit v1.2.3 From 302ad7a9930a34413418b6436f96826070367647 Mon Sep 17 00:00:00 2001 From: Jens Lehmann Date: Fri, 6 Aug 2010 00:40:48 +0200 Subject: Submodules: Use "ignore" settings from .gitmodules too for diff and status The .gitmodules file is parsed for "submodule..ignore" entries before looking for them in .git/config. Thus settings found in .git/config will override those from .gitmodules, thereby allowing the local developer to ignore settings given by the remote side while also letting upstream set defaults for those users who don't have special needs. Signed-off-by: Jens Lehmann Signed-off-by: Junio C Hamano --- builtin/diff-tree.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'builtin/diff-tree.c') diff --git a/builtin/diff-tree.c b/builtin/diff-tree.c index 3c78bda566..0d2a3e9fa2 100644 --- a/builtin/diff-tree.c +++ b/builtin/diff-tree.c @@ -3,6 +3,7 @@ #include "commit.h" #include "log-tree.h" #include "builtin.h" +#include "submodule.h" static struct rev_info log_tree_opt; @@ -112,6 +113,7 @@ int cmd_diff_tree(int argc, const char **argv, const char *prefix) int read_stdin = 0; init_revisions(opt, prefix); + gitmodules_config(); git_config(git_diff_basic_config, NULL); /* no "diff" UI options */ opt->abbrev = 0; opt->diff = 1; -- cgit v1.2.3 From f31027c99cb2ec4eb7ad8d1ebc7f0e20fef4bd1d Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Thu, 6 Jan 2011 13:50:06 -0800 Subject: diffcore-rename: fall back to -C when -C -C busts the rename limit When there are too many paths in the project, the number of rename source candidates "git diff -C -C" finds will exceed the rename detection limit, and no inexact rename detection is performed. We however could fall back to "git diff -C" if the number of modified paths is sufficiently small. Signed-off-by: Junio C Hamano --- builtin/diff-tree.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'builtin/diff-tree.c') diff --git a/builtin/diff-tree.c b/builtin/diff-tree.c index 0d2a3e9fa2..be6417d166 100644 --- a/builtin/diff-tree.c +++ b/builtin/diff-tree.c @@ -163,6 +163,9 @@ int cmd_diff_tree(int argc, const char **argv, const char *prefix) } if (read_stdin) { + int saved_nrl = 0; + int saved_dcctc = 0; + if (opt->diffopt.detect_rename) opt->diffopt.setup |= (DIFF_SETUP_USE_SIZE_CACHE | DIFF_SETUP_USE_CACHE); @@ -173,9 +176,16 @@ int cmd_diff_tree(int argc, const char **argv, const char *prefix) fputs(line, stdout); fflush(stdout); } - else + else { diff_tree_stdin(line); + if (saved_nrl < opt->diffopt.needed_rename_limit) + saved_nrl = opt->diffopt.needed_rename_limit; + if (opt->diffopt.degraded_cc_to_c) + saved_dcctc = 1; + } } + opt->diffopt.degraded_cc_to_c = saved_dcctc; + opt->diffopt.needed_rename_limit = saved_nrl; } return diff_result_code(&opt->diffopt, 0); -- cgit v1.2.3