While at there, move exit() back to the caller. It's easier to see the
flow that way than burying it in diff-no-index.c

Signed-off-by: Nguyễn Thái Ngọc Duy <pclo...@gmail.com>
---
 builtin/diff.c           | 21 +++--------------
 diff-no-index.c          | 49 ++++++++++++++++++++++++----------------
 diff.h                   |  3 ++-
 t/t4053-diff-no-index.sh |  3 +--
 4 files changed, 35 insertions(+), 41 deletions(-)

diff --git a/builtin/diff.c b/builtin/diff.c
index f0393bba23..52dc3e136f 100644
--- a/builtin/diff.c
+++ b/builtin/diff.c
@@ -320,26 +320,11 @@ int cmd_diff(int argc, const char **argv, const char 
*prefix)
 
        repo_init_revisions(the_repository, &rev, prefix);
 
-       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 <path> <path>",
-                      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(the_repository, &rev, argc, argv);
+               exit(diff_no_index(the_repository, &rev,
+                                  no_index == DIFF_NO_INDEX_IMPLICIT,
+                                  argc, argv));
 
        /* Otherwise, we are doing the usual "git" diff */
        rev.diffopt.skip_stat_unmatch = !!diff_auto_refresh_index;
diff --git a/diff-no-index.c b/diff-no-index.c
index 9414e922d1..a879f45862 100644
--- a/diff-no-index.c
+++ b/diff-no-index.c
@@ -14,6 +14,7 @@
 #include "revision.h"
 #include "log-tree.h"
 #include "builtin.h"
+#include "parse-options.h"
 #include "string-list.h"
 #include "dir.h"
 
@@ -233,35 +234,43 @@ static void fixup_paths(const char **path, struct strbuf 
*replacement)
        }
 }
 
-void diff_no_index(struct repository *r,
-                  struct rev_info *revs,
-                  int argc, const char **argv)
+static const char * const diff_no_index_usage[] = {
+       N_("git diff --no-index [<options>] <path> <path>"),
+       NULL
+};
+
+int diff_no_index(struct repository *r,
+                 struct rev_info *revs,
+                 int implicit_no_index,
+                 int argc, const char **argv)
 {
-       int i;
+       int i, no_index;
        const char *paths[2];
        struct strbuf replacement = STRBUF_INIT;
        const char *prefix = revs->prefix;
+       struct option no_index_options[] = {
+               OPT_BOOL_F(0, "no-index", &no_index, "",
+                          PARSE_OPT_NONEG | PARSE_OPT_HIDDEN),
+               OPT_END(),
+       };
+       struct option *options;
 
        /*
         * FIXME: --no-index should not look at index and we should be
         * able to pass NULL repo. Maybe later.
         */
        repo_diff_setup(r, &revs->diffopt);
-       for (i = 1; i < argc - 2; ) {
-               int j;
-               if (!strcmp(argv[i], "--no-index"))
-                       i++;
-               else if (!strcmp(argv[i], "--"))
-                       i++;
-               else {
-                       j = diff_opt_parse(&revs->diffopt, argv + i, argc - i,
-                                          revs->prefix);
-                       if (j <= 0)
-                               die("invalid diff option/value: %s", argv[i]);
-                       i += j;
-               }
+       options = parse_options_concat(no_index_options,
+                                      revs->diffopt.parseopts);
+       argc = parse_options(argc, argv, revs->prefix, options,
+                            diff_no_index_usage, 0);
+       if (argc != 2) {
+               if (implicit_no_index)
+                       warning(_("Not a git repository. Use --no-index to "
+                                 "compare two paths outside a working tree"));
+               usage_with_options(diff_no_index_usage, options);
        }
-
+       FREE_AND_NULL(options);
        for (i = 0; i < 2; i++) {
                const char *p = argv[argc - 2 + i];
                if (!strcmp(p, "-"))
@@ -293,7 +302,7 @@ void diff_no_index(struct repository *r,
        revs->diffopt.flags.exit_with_status = 1;
 
        if (queue_diff(&revs->diffopt, paths[0], paths[1]))
-               exit(1);
+               return 1;
        diff_set_mnemonic_prefix(&revs->diffopt, "1/", "2/");
        diffcore_std(&revs->diffopt);
        diff_flush(&revs->diffopt);
@@ -304,5 +313,5 @@ void diff_no_index(struct repository *r,
         * The return code for --no-index imitates diff(1):
         * 0 = no changes, 1 = changes, else error
         */
-       exit(diff_result_code(&revs->diffopt, 0));
+       return diff_result_code(&revs->diffopt, 0);
 }
diff --git a/diff.h b/diff.h
index d9ad73f0e1..03c6afda22 100644
--- a/diff.h
+++ b/diff.h
@@ -437,7 +437,8 @@ int diff_flush_patch_id(struct diff_options *, struct 
object_id *, int);
 
 int diff_result_code(struct diff_options *, int);
 
-void diff_no_index(struct repository *, struct rev_info *, int, const char **);
+int diff_no_index(struct repository *, struct rev_info *,
+                 int implicit_no_index, int, const char **);
 
 int index_differs_from(struct repository *r, const char *def,
                       const struct diff_flags *flags,
diff --git a/t/t4053-diff-no-index.sh b/t/t4053-diff-no-index.sh
index 6e0dd6f9e5..fb25cdb789 100755
--- a/t/t4053-diff-no-index.sh
+++ b/t/t4053-diff-no-index.sh
@@ -50,8 +50,7 @@ test_expect_success 'git diff --no-index executed outside 
repo gives correct err
                export GIT_CEILING_DIRECTORIES &&
                cd non/git &&
                test_must_fail git diff --no-index a 2>actual.err &&
-               echo "usage: git diff --no-index <path> <path>" >expect.err &&
-               test_cmp expect.err actual.err
+               test_i18ngrep "usage: git diff --no-index" actual.err
        )
 '
 
-- 
2.21.0.548.gd3c7d92dc2

Reply via email to