Merge branch 'cb/maint-ls-files-error-report' into maint
authorJunio C Hamano <gitster@pobox.com>
Fri, 23 Sep 2011 21:30:49 +0000 (14:30 -0700)
committerJunio C Hamano <gitster@pobox.com>
Fri, 23 Sep 2011 21:30:49 +0000 (14:30 -0700)
* cb/maint-ls-files-error-report:
t3005: do not assume a particular order of stdout and stderr of git-ls-files
ls-files: fix pathspec display on error

builtin/checkout.c
builtin/commit.c
builtin/ls-files.c
cache.h
quote.c
t/t3005-ls-files-relative.sh [new file with mode: 0755]
index ca855d716ccab1d1209638193e2f52e901acfba0..4c20dae34d2fc095195d91adae0af26087306277 100644 (file)
@@ -201,7 +201,7 @@ static int checkout_merged(int pos, struct checkout *state)
 }
 
 static int checkout_paths(struct tree *source_tree, const char **pathspec,
-                         struct checkout_opts *opts)
+                         const char *prefix, struct checkout_opts *opts)
 {
        int pos;
        struct checkout state;
@@ -231,7 +231,7 @@ static int checkout_paths(struct tree *source_tree, const char **pathspec,
                match_pathspec(pathspec, ce->name, ce_namelen(ce), 0, ps_matched);
        }
 
-       if (report_path_error(ps_matched, pathspec, 0))
+       if (report_path_error(ps_matched, pathspec, prefix))
                return 1;
 
        /* "checkout -m path" to recreate conflicted state */
@@ -1063,7 +1063,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
                if (1 < !!opts.writeout_stage + !!opts.force + !!opts.merge)
                        die(_("git checkout: --ours/--theirs, --force and --merge are incompatible when\nchecking out of the index."));
 
-               return checkout_paths(source_tree, pathspec, &opts);
+               return checkout_paths(source_tree, pathspec, prefix, &opts);
        }
 
        if (patch_mode)
index e1af9b19f0be71484ae9341762dc2bf89cabb70c..9679a99f9902583094ddc1e31d44d119203482a9 100644 (file)
@@ -272,7 +272,7 @@ static int list_paths(struct string_list *list, const char *with_tree,
                        item->util = item; /* better a valid pointer than a fake one */
        }
 
-       return report_path_error(m, pattern, prefix ? strlen(prefix) : 0);
+       return report_path_error(m, pattern, prefix);
 }
 
 static void add_remove_files(struct string_list *list)
index 15701233e29b240cfa1abdb56bd489306e74c677..468bb13c81b960ac5c9ad5b37cca3ac37b6ef5c0 100644 (file)
@@ -388,11 +388,13 @@ void overlay_tree_on_cache(const char *tree_name, const char *prefix)
        }
 }
 
-int report_path_error(const char *ps_matched, const char **pathspec, int prefix_len)
+int report_path_error(const char *ps_matched, const char **pathspec, const char *prefix)
 {
        /*
         * Make sure all pathspec matched; otherwise it is an error.
         */
+       struct strbuf sb = STRBUF_INIT;
+       const char *name;
        int num, errors = 0;
        for (num = 0; pathspec[num]; num++) {
                int other, found_dup;
@@ -417,10 +419,12 @@ int report_path_error(const char *ps_matched, const char **pathspec, int prefix_
                if (found_dup)
                        continue;
 
+               name = quote_path_relative(pathspec[num], -1, &sb, prefix);
                error("pathspec '%s' did not match any file(s) known to git.",
-                     pathspec[num] + prefix_len);
+                     name);
                errors++;
        }
+       strbuf_release(&sb);
        return errors;
 }
 
@@ -611,7 +615,7 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)
 
        if (ps_matched) {
                int bad;
-               bad = report_path_error(ps_matched, pathspec, prefix_len);
+               bad = report_path_error(ps_matched, pathspec, prefix);
                if (bad)
                        fprintf(stderr, "Did you forget to 'git add'?\n");
 
diff --git a/cache.h b/cache.h
index e494bdcda77678c971ab810151e0d5ecfe89c447..6b24c252ef5c8d56b06cf0f00934fc79e46f022c 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -1189,7 +1189,7 @@ extern int ws_blank_line(const char *line, int len, unsigned ws_rule);
 #define ws_tab_width(rule)     ((rule) & WS_TAB_WIDTH_MASK)
 
 /* ls-files */
-int report_path_error(const char *ps_matched, const char **pathspec, int prefix_offset);
+int report_path_error(const char *ps_matched, const char **pathspec, const char *prefix);
 void overlay_tree_on_cache(const char *tree_name, const char *prefix);
 
 char *alias_lookup(const char *alias);
diff --git a/quote.c b/quote.c
index 63d3b018183abc05a5231dfd7e134dd7394f7a9b..532fd3b7b7a0c7b6766a7af742b0c7362f307221 100644 (file)
--- a/quote.c
+++ b/quote.c
@@ -325,8 +325,12 @@ static const char *path_relative(const char *in, int len,
 
        if (len < 0)
                len = strlen(in);
-       if (prefix && prefix_len < 0)
-               prefix_len = strlen(prefix);
+       if (prefix_len < 0) {
+               if (prefix)
+                       prefix_len = strlen(prefix);
+               else
+                       prefix_len = 0;
+       }
 
        off = 0;
        i = 0;
diff --git a/t/t3005-ls-files-relative.sh b/t/t3005-ls-files-relative.sh
new file mode 100755 (executable)
index 0000000..3778694
--- /dev/null
@@ -0,0 +1,72 @@
+#!/bin/sh
+
+test_description='ls-files tests with relative paths
+
+This test runs git ls-files with various relative path arguments.
+'
+
+. ./test-lib.sh
+
+new_line='
+'
+sq=\'
+
+test_expect_success 'prepare' '
+       : >never-mind-me &&
+       git add never-mind-me &&
+       mkdir top &&
+       (
+               cd top &&
+               mkdir sub &&
+               x="x xa xbc xdef xghij xklmno" &&
+               y=$(echo "$x" | tr x y) &&
+               touch $x &&
+               touch $y &&
+               cd sub &&
+               git add ../x*
+       )
+'
+
+test_expect_success 'ls-files with mixed levels' '
+       (
+               cd top/sub &&
+               cat >expect <<-EOF &&
+               ../../never-mind-me
+               ../x
+               EOF
+               git ls-files $(cat expect) >actual &&
+               test_cmp expect actual
+       )
+'
+
+test_expect_success 'ls-files -c' '
+       (
+               cd top/sub &&
+               for f in ../y*
+               do
+                       echo "error: pathspec $sq$f$sq did not match any file(s) known to git."
+               done >expect.err &&
+               echo "Did you forget to ${sq}git add${sq}?" >>expect.err &&
+               ls ../x* >expect.out &&
+               test_must_fail git ls-files -c --error-unmatch ../[xy]* >actual.out 2>actual.err &&
+               test_cmp expect.out actual.out &&
+               test_cmp expect.err actual.err
+       )
+'
+
+test_expect_success 'ls-files -o' '
+       (
+               cd top/sub &&
+               for f in ../x*
+               do
+                       echo "error: pathspec $sq$f$sq did not match any file(s) known to git."
+               done >expect.err &&
+               echo "Did you forget to ${sq}git add${sq}?" >>expect.err &&
+               ls ../y* >expect.out &&
+               test_must_fail git ls-files -o --error-unmatch ../[xy]* >actual.out 2>actual.err &&
+               test_cmp expect.out actual.out &&
+               test_cmp expect.err actual.err
+       )
+'
+
+test_done