From 470faf96544c1844ad775c695dfa370fe0ef3756 Mon Sep 17 00:00:00 2001 From: Thomas Gummerer Date: Wed, 11 Dec 2013 10:58:42 +0100 Subject: diff: move no-index detection to builtin/diff.c Currently the --no-index option is parsed in diff_no_index(). Move the detection if a no-index diff should be executed to builtin/diff.c, where we can use it for executing diff_no_index() conditionally. This will also allow us to execute other operations conditionally, which will be done in the next patch. There are no functional changes. Helped-by: Jonathan Nieder Signed-off-by: Thomas Gummerer Signed-off-by: Junio C Hamano --- builtin/diff.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 3 deletions(-) (limited to 'builtin/diff.c') diff --git a/builtin/diff.c b/builtin/diff.c index adb93a9efa..da69e4a3c8 100644 --- a/builtin/diff.c +++ b/builtin/diff.c @@ -16,6 +16,9 @@ #include "submodule.h" #include "sha1-array.h" +#define DIFF_NO_INDEX_EXPLICIT 1 +#define DIFF_NO_INDEX_IMPLICIT 2 + struct blobinfo { unsigned char sha1[20]; const char *name; @@ -257,7 +260,7 @@ int cmd_diff(int argc, const char **argv, const char *prefix) int blobs = 0, paths = 0; const char *path = NULL; struct blobinfo blob[2]; - int nongit; + int nongit = 0, no_index = 0; int result = 0; /* @@ -283,14 +286,57 @@ int cmd_diff(int argc, const char **argv, const char *prefix) * Other cases are errors. */ + /* Were we asked to do --no-index explicitly? */ + for (i = 1; i < argc; i++) { + if (!strcmp(argv[i], "--")) { + i++; + break; + } + if (!strcmp(argv[i], "--no-index")) + no_index = DIFF_NO_INDEX_EXPLICIT; + if (argv[i][0] != '-') + break; + } + prefix = setup_git_directory_gently(&nongit); + /* + * Treat git diff with at least one path outside of the + * repo the same as if the command would have been executed + * outside of a git repository. In this case it behaves + * the same way as "git diff --no-index ", which acts + * as a colourful "diff" replacement. + */ + if (nongit || ((argc == i + 2) && + (!path_inside_repo(prefix, argv[i]) || + !path_inside_repo(prefix, argv[i + 1])))) + no_index = DIFF_NO_INDEX_IMPLICIT; + gitmodules_config(); git_config(git_diff_ui_config, NULL); init_revisions(&rev, prefix); - /* If this is a no-index diff, just run it and exit there. */ - diff_no_index(&rev, argc, argv, nongit, prefix); + if (no_index) { + if (argc != i + 2) { + if (no_index == DIFF_NO_INDEX_IMPLICIT) { + /* + * There was no --no-index and there were not two + * paths. It is possible that the user intended + * to do an inside-repository operation. + */ + fprintf(stderr, "Not a git repository\n"); + fprintf(stderr, + "To compare two paths outside a working tree:\n"); + } + /* Give the usage message for non-repository usage and exit. */ + usagef("git diff %s ", + no_index == DIFF_NO_INDEX_EXPLICIT ? + "--no-index" : "[--no-index]"); + + } + /* If this is a no-index diff, just run it and exit there. */ + diff_no_index(&rev, argc, argv, prefix); + } /* Otherwise, we are doing the usual "git" diff */ rev.diffopt.skip_stat_unmatch = !!diff_auto_refresh_index; -- cgit v1.2.1 From 6df5762db354ca55a0cf77451d06b332b7de0b82 Mon Sep 17 00:00:00 2001 From: Thomas Gummerer Date: Wed, 11 Dec 2013 10:58:43 +0100 Subject: diff: don't read index when --no-index is given git diff --no-index ... currently reads the index, during setup, when calling gitmodules_config(). This results in worse performance when the index is not actually needed. This patch avoids calling gitmodules_config() when the --no-index option is given. The times for executing "git diff --no-index" in the WebKit repository are improved as follows: Test HEAD~3 HEAD ------------------------------------------------------------------ 4001.1: diff --no-index 0.24(0.15+0.09) 0.01(0.00+0.00) -95.8% An additional improvement of this patch is that "git diff --no-index" no longer breaks when the index file is corrupt, which makes it possible to use it for investigating the broken repository. To improve the possible usage as investigation tool for broken repositories, setup_git_directory_gently() is also not called when the --no-index option is given. Also add a test to guard against future breakages, and a performance test to show the improvements. Signed-off-by: Thomas Gummerer Signed-off-by: Junio C Hamano --- builtin/diff.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'builtin/diff.c') diff --git a/builtin/diff.c b/builtin/diff.c index da69e4a3c8..ea1dd65a2f 100644 --- a/builtin/diff.c +++ b/builtin/diff.c @@ -298,7 +298,9 @@ int cmd_diff(int argc, const char **argv, const char *prefix) break; } - prefix = setup_git_directory_gently(&nongit); + if (!no_index) + prefix = setup_git_directory_gently(&nongit); + /* * Treat git diff with at least one path outside of the * repo the same as if the command would have been executed @@ -311,7 +313,8 @@ int cmd_diff(int argc, const char **argv, const char *prefix) !path_inside_repo(prefix, argv[i + 1])))) no_index = DIFF_NO_INDEX_IMPLICIT; - gitmodules_config(); + if (!no_index) + gitmodules_config(); git_config(git_diff_ui_config, NULL); init_revisions(&rev, prefix); -- cgit v1.2.1 From aad90e85f8e6368533aa30c072b8e2bd7adafa53 Mon Sep 17 00:00:00 2001 From: Thomas Gummerer Date: Mon, 16 Dec 2013 21:19:24 +0100 Subject: diff: avoid some nesting Avoid some nesting in builtin/diff.c, to make the code easier to read. There are no functional changes. Helped-by: Jonathan Nieder Signed-off-by: Thomas Gummerer Signed-off-by: Junio C Hamano --- builtin/diff.c | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) (limited to 'builtin/diff.c') diff --git a/builtin/diff.c b/builtin/diff.c index ea1dd65a2f..24d6271625 100644 --- a/builtin/diff.c +++ b/builtin/diff.c @@ -319,27 +319,26 @@ int cmd_diff(int argc, const char **argv, const char *prefix) init_revisions(&rev, prefix); - if (no_index) { - if (argc != i + 2) { - if (no_index == DIFF_NO_INDEX_IMPLICIT) { - /* - * There was no --no-index and there were not two - * paths. It is possible that the user intended - * to do an inside-repository operation. - */ - fprintf(stderr, "Not a git repository\n"); - fprintf(stderr, - "To compare two paths outside a working tree:\n"); - } - /* Give the usage message for non-repository usage and exit. */ - usagef("git diff %s ", - no_index == DIFF_NO_INDEX_EXPLICIT ? - "--no-index" : "[--no-index]"); - + if (no_index && argc != i + 2) { + if (no_index == DIFF_NO_INDEX_IMPLICIT) { + /* + * There was no --no-index and there were not two + * paths. It is possible that the user intended + * to do an inside-repository operation. + */ + fprintf(stderr, "Not a git repository\n"); + fprintf(stderr, + "To compare two paths outside a working tree:\n"); } + /* Give the usage message for non-repository usage and exit. */ + usagef("git diff %s ", + no_index == DIFF_NO_INDEX_EXPLICIT ? + "--no-index" : "[--no-index]"); + + } + if (no_index) /* If this is a no-index diff, just run it and exit there. */ diff_no_index(&rev, argc, argv, prefix); - } /* Otherwise, we are doing the usual "git" diff */ rev.diffopt.skip_stat_unmatch = !!diff_auto_refresh_index; -- cgit v1.2.1