* Re: [PATCH] allow pathspec to end with a slash
@ 2005-05-31 15:32 Linus Torvalds
2005-05-31 20:08 ` Junio C Hamano
` (3 more replies)
0 siblings, 4 replies; 12+ messages in thread
From: Linus Torvalds @ 2005-05-31 15:32 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Git Mailing List
Junio,
pathspec is still subtly broken.
Just removing the slash at the end is not the right thing to do, since
that means that
git-diff-files drivers/char/
will trigger on a _file_ "drivers/char", even though the spec makes it
unambiguous that the user only wants to see stuff under that directory.
Again, git-diff-tree gets this right (not to say that it always did - I
had to fix "interesting()" several times, exactly because it's not that
simple).
Linus
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] allow pathspec to end with a slash
2005-05-31 15:32 [PATCH] allow pathspec to end with a slash Linus Torvalds
@ 2005-05-31 20:08 ` Junio C Hamano
2005-05-31 21:47 ` [PATCH 1/2] diff: consolidate test helper script pieces Junio C Hamano
` (2 subsequent siblings)
3 siblings, 0 replies; 12+ messages in thread
From: Junio C Hamano @ 2005-05-31 20:08 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Git Mailing List
Do you want the same for git-ls-tree as well? That is, when
you have drivers/char as a blob in the tree, should
git-ls-tree $tree drivers/char/
show nothing?
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 1/2] diff: consolidate test helper script pieces.
2005-05-31 15:32 [PATCH] allow pathspec to end with a slash Linus Torvalds
2005-05-31 20:08 ` Junio C Hamano
@ 2005-05-31 21:47 ` Junio C Hamano
2005-05-31 21:48 ` [PATCH 2/2] diff: Fix trailing slash handling Junio C Hamano
2005-05-31 21:49 ` [PATCH] ls-tree: remove trailing slashes properly Junio C Hamano
3 siblings, 0 replies; 12+ messages in thread
From: Junio C Hamano @ 2005-05-31 21:47 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Git Mailing List
There were duplicate script pieces to help comparing diff
output, which this patch consolidates into the t/diff-lib.sh
library.
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
*** The next one is to fix the pathspec, whose test relies on
*** this cleanup.
t/diff-lib.sh | 35 +++++++++++++++++++++++++++++++++++
t/t4003-diff-rename-1.sh | 9 +--------
t/t4005-diff-rename-2.sh | 23 +----------------------
t/t4007-rename-3.sh | 15 +--------------
t/t4008-diff-break-rewrite.sh | 15 +--------------
t/t4009-diff-rename-4.sh | 29 ++++-------------------------
6 files changed, 43 insertions(+), 83 deletions(-)
diff --git a/t/diff-lib.sh b/t/diff-lib.sh
new file mode 100644
--- /dev/null
+++ b/t/diff-lib.sh
@@ -0,0 +1,35 @@
+:
+
+_x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
+_x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40"
+sanitize_diff_raw='/^:/s/ '"$_x40"' '"$_x40"' \([A-Z]\)[0-9]* / X X \1# /'
+compare_diff_raw () {
+ # When heuristics are improved, the score numbers would change.
+ # Ignore them while comparing.
+ # Also we do not check SHA1 hash generation in this test, which
+ # is a job for t0000-basic.sh
+
+ sed -e "$sanitize_diff_raw" <"$1" >.tmp-1
+ sed -e "$sanitize_diff_raw" <"$2" >.tmp-2
+ diff -u .tmp-1 .tmp-2 && rm -f .tmp-1 .tmp-2
+}
+
+sanitize_diff_raw_z='/^:/s/ '"$_x40"' '"$_x40"' \([A-Z]\)[0-9]*$/ X X \1#/'
+compare_diff_raw_z () {
+ # When heuristics are improved, the score numbers would change.
+ # Ignore them while comparing.
+ # Also we do not check SHA1 hash generation in this test, which
+ # is a job for t0000-basic.sh
+
+ tr '\0' '\012' <"$1" | sed -e "$sanitize_diff_raw_z" >.tmp-1
+ tr '\0' '\012' <"$2" | sed -e "$sanitize_diff_raw_z" >.tmp-2
+ diff -u .tmp-1 .tmp-2 && rm -f .tmp-1 .tmp-2
+}
+
+compare_diff_patch () {
+ # When heuristics are improved, the score numbers would change.
+ # Ignore them while comparing.
+ sed -e '/^[dis]*imilarity index [0-9]*%$/d' <"$1" >.tmp-1
+ sed -e '/^[dis]*imilarity index [0-9]*%$/d' <"$2" >.tmp-2
+ diff -u .tmp-1 .tmp-2 && rm -f .tmp-1 .tmp-2
+}
diff --git a/t/t4003-diff-rename-1.sh b/t/t4003-diff-rename-1.sh
--- a/t/t4003-diff-rename-1.sh
+++ b/t/t4003-diff-rename-1.sh
@@ -7,14 +7,7 @@ test_description='More rename detection
'
. ./test-lib.sh
-
-compare_diff_patch () {
- # When heuristics are improved, the score numbers would change.
- # Ignore them while comparing.
- sed -e '/^similarity index [0-9]*%$/d' <"$1" >.tmp-1
- sed -e '/^similarity index [0-9]*%$/d' <"$2" >.tmp-2
- diff -u .tmp-1 .tmp-2 && rm -f .tmp-1 .tmp-2
-}
+. ../diff-lib.sh ;# test-lib chdir's into trash
test_expect_success \
'prepare reference tree' \
diff --git a/t/t4005-diff-rename-2.sh b/t/t4005-diff-rename-2.sh
--- a/t/t4005-diff-rename-2.sh
+++ b/t/t4005-diff-rename-2.sh
@@ -7,28 +7,7 @@ test_description='Same rename detection
'
. ./test-lib.sh
-
-_x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
-_x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40"
-sanitize_diff_raw='s/ '"$_x40"' '"$_x40"' \([A-Z]\)[0-9]* / X X \1# /'
-compare_diff_raw () {
- # When heuristics are improved, the score numbers would change.
- # Ignore them while comparing.
- # Also we do not check SHA1 hash generation in this test, which
- # is a job for t0000-basic.sh
-
- sed -e "$sanitize_diff_raw" <"$1" >.tmp-1
- sed -e "$sanitize_diff_raw" <"$2" >.tmp-2
- diff -u .tmp-1 .tmp-2 && rm -f .tmp-1 .tmp-2
-}
-
-compare_diff_patch () {
- # When heuristics are improved, the score numbers would change.
- # Ignore them while comparing.
- sed -e '/^similarity index [0-9]*%$/d' <"$1" >.tmp-1
- sed -e '/^similarity index [0-9]*%$/d' <"$2" >.tmp-2
- diff -u .tmp-1 .tmp-2 && rm -f .tmp-1 .tmp-2
-}
+. ../diff-lib.sh ;# test-lib chdir's into trash
test_expect_success \
'prepare reference tree' \
diff --git a/t/t4007-rename-3.sh b/t/t4007-rename-3.sh
--- a/t/t4007-rename-3.sh
+++ b/t/t4007-rename-3.sh
@@ -7,20 +7,7 @@ test_description='Rename interaction wit
'
. ./test-lib.sh
-
-_x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
-_x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40"
-sanitize_diff_raw='s/ '"$_x40"' '"$_x40"' \([A-Z]\)[0-9]* / X X \1# /'
-compare_diff_raw () {
- # When heuristics are improved, the score numbers would change.
- # Ignore them while comparing.
- # Also we do not check SHA1 hash generation in this test, which
- # is a job for t0000-basic.sh
-
- sed -e "$sanitize_diff_raw" <"$1" >.tmp-1
- sed -e "$sanitize_diff_raw" <"$2" >.tmp-2
- diff -u .tmp-1 .tmp-2 && rm -f .tmp-1 .tmp-2
-}
+. ../diff-lib.sh ;# test-lib chdir's into trash
test_expect_success \
'prepare reference tree' \
diff --git a/t/t4008-diff-break-rewrite.sh b/t/t4008-diff-break-rewrite.sh
--- a/t/t4008-diff-break-rewrite.sh
+++ b/t/t4008-diff-break-rewrite.sh
@@ -22,20 +22,7 @@ four changes in total.
Further, with -B and -M together, these should turn into two renames.
'
. ./test-lib.sh
-
-_x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
-_x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40"
-sanitize_diff_raw='s/ '"$_x40"' '"$_x40"' \([CDNR]\)[0-9]* / X X \1# /'
-compare_diff_raw () {
- # When heuristics are improved, the score numbers would change.
- # Ignore them while comparing.
- # Also we do not check SHA1 hash generation in this test, which
- # is a job for t0000-basic.sh
-
- sed -e "$sanitize_diff_raw" <"$1" >.tmp-1
- sed -e "$sanitize_diff_raw" <"$2" >.tmp-2
- diff -u .tmp-1 .tmp-2 && rm -f .tmp-1 .tmp-2
-}
+. ../diff-lib.sh ;# test-lib chdir's into trash
test_expect_success \
setup \
diff --git a/t/t4009-diff-rename-4.sh b/t/t4009-diff-rename-4.sh
--- a/t/t4009-diff-rename-4.sh
+++ b/t/t4009-diff-rename-4.sh
@@ -7,28 +7,7 @@ test_description='Same rename detection
'
. ./test-lib.sh
-
-_x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
-_x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40"
-sanitize_diff_raw='/^:/s/ '"$_x40"' '"$_x40"' \([A-Z]\)[0-9]*$/ X X \1#/'
-compare_diff_raw () {
- # When heuristics are improved, the score numbers would change.
- # Ignore them while comparing.
- # Also we do not check SHA1 hash generation in this test, which
- # is a job for t0000-basic.sh
-
- tr '\0' '\012' <"$1" | sed -e "$sanitize_diff_raw" >.tmp-1
- tr '\0' '\012' <"$2" | sed -e "$sanitize_diff_raw" >.tmp-2
- diff -u .tmp-1 .tmp-2 && rm -f .tmp-1 .tmp-2
-}
-
-compare_diff_patch () {
- # When heuristics are improved, the score numbers would change.
- # Ignore them while comparing.
- sed -e '/^similarity index [0-9]*%$/d' <"$1" >.tmp-1
- sed -e '/^similarity index [0-9]*%$/d' <"$2" >.tmp-2
- diff -u .tmp-1 .tmp-2 && rm -f .tmp-1 .tmp-2
-}
+. ../diff-lib.sh ;# test-lib chdir's into trash
test_expect_success \
'prepare reference tree' \
@@ -63,7 +42,7 @@ EOF
test_expect_success \
'validate output from rename/copy detection (#1)' \
- 'compare_diff_raw current expected'
+ 'compare_diff_raw_z current expected'
# make sure diff-helper can grok it.
mv current diff-raw
@@ -120,7 +99,7 @@ EOF
test_expect_success \
'validate output from rename/copy detection (#2)' \
- 'compare_diff_raw current expected'
+ 'compare_diff_raw_z current expected'
# make sure diff-helper can grok it.
mv current diff-raw
@@ -173,7 +152,7 @@ EOF
test_expect_success \
'validate output from rename/copy detection (#3)' \
- 'compare_diff_raw current expected'
+ 'compare_diff_raw_z current expected'
# make sure diff-helper can grok it.
mv current diff-raw
------------
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 2/2] diff: Fix trailing slash handling.
2005-05-31 15:32 [PATCH] allow pathspec to end with a slash Linus Torvalds
2005-05-31 20:08 ` Junio C Hamano
2005-05-31 21:47 ` [PATCH 1/2] diff: consolidate test helper script pieces Junio C Hamano
@ 2005-05-31 21:48 ` Junio C Hamano
2005-05-31 21:49 ` [PATCH] ls-tree: remove trailing slashes properly Junio C Hamano
3 siblings, 0 replies; 12+ messages in thread
From: Junio C Hamano @ 2005-05-31 21:48 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Git Mailing List
When limiting the world to "drivers/char/", we should not
consider "drivers/char" which is not a directory.
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
t/t4010-diff-pathspec.sh | 65 ++++++++++++++++++++++++++++++++++++++++++++++
diffcore-pathspec.c | 60 +++++++++++++++++++++++++++++++++++++------
2 files changed, 117 insertions(+), 8 deletions(-)
diff --git a/t/t4010-diff-pathspec.sh b/t/t4010-diff-pathspec.sh
new file mode 100644
--- /dev/null
+++ b/t/t4010-diff-pathspec.sh
@@ -0,0 +1,65 @@
+#!/bin/sh
+#
+# Copyright (c) 2005 Junio C Hamano
+#
+
+test_description='Pathspec restrictions
+
+Prepare:
+ file0
+ path1/file1
+'
+. ./test-lib.sh
+. ../diff-lib.sh ;# test-lib chdir's into trash
+
+test_expect_success \
+ setup \
+ 'echo frotz >file0 &&
+ mkdir path1 &&
+ echo rezrov >path1/file1 &&
+ git-update-cache --add file0 path1/file1 &&
+ tree=`git-write-tree` &&
+ echo "$tree" &&
+ echo nitfol >file0 &&
+ echo yomin >path1/file1 &&
+ git-update-cache file0 path1/file1'
+
+cat >expected <<\EOF
+EOF
+test_expect_success \
+ 'limit to path should show nothing' \
+ 'git-diff-cache --cached $tree path >current &&
+ compare_diff_raw current expected'
+
+cat >expected <<\EOF
+:100644 100644 766498d93a4b06057a8e49d23f4068f1170ff38f 0a41e115ab61be0328a19b29f18cdcb49338d516 M path1/file1
+EOF
+test_expect_success \
+ 'limit to path1 should show path1/file1' \
+ 'git-diff-cache --cached $tree path1 >current &&
+ compare_diff_raw current expected'
+
+cat >expected <<\EOF
+:100644 100644 766498d93a4b06057a8e49d23f4068f1170ff38f 0a41e115ab61be0328a19b29f18cdcb49338d516 M path1/file1
+EOF
+test_expect_success \
+ 'limit to path1/ should show path1/file1' \
+ 'git-diff-cache --cached $tree path1/ >current &&
+ compare_diff_raw current expected'
+
+cat >expected <<\EOF
+:100644 100644 766498d93a4b06057a8e49d23f4068f1170ff38f 0a41e115ab61be0328a19b29f18cdcb49338d516 M file0
+EOF
+test_expect_success \
+ 'limit to file0 should show file0' \
+ 'git-diff-cache --cached $tree file0 >current &&
+ compare_diff_raw current expected'
+
+cat >expected <<\EOF
+EOF
+test_expect_success \
+ 'limit to file0/ should emit nothing.' \
+ 'git-diff-cache --cached $tree file0/ >current &&
+ compare_diff_raw current expected'
+
+test_done
diff --git a/diffcore-pathspec.c b/diffcore-pathspec.c
--- a/diffcore-pathspec.c
+++ b/diffcore-pathspec.c
@@ -8,9 +8,13 @@
struct path_spec {
const char *spec;
int len;
+ int reject_non_tree;
};
-static int matches_pathspec(const char *name, struct path_spec *s, int cnt)
+static int matches_pathspec(const char *name,
+ int obviously_non_tree,
+ struct path_spec *s,
+ int cnt)
{
int i;
int namelen;
@@ -21,10 +25,25 @@ static int matches_pathspec(const char *
namelen = strlen(name);
for (i = 0; i < cnt; i++) {
int len = s[i].len;
- if (! strncmp(s[i].spec, name, len) &&
- len <= namelen &&
- (name[len] == 0 || name[len] == '/'))
- return 1;
+ if (!strncmp(s[i].spec, name, len)) {
+ /* Leading part matches. */
+ if (len == namelen) {
+ /* Exact match: spec "drivers/char/"
+ * should not match against path
+ * "drivers/char".
+ */
+ if (s[i].reject_non_tree && obviously_non_tree)
+ continue;
+ return 1;
+ }
+ else if ((len < namelen) && name[len] == '/') {
+ /* Spec is leading path */
+ return 1;
+ }
+ /* otherwise, it is a false match of spec "abc"
+ * against path "abcdefg", so we continue.
+ */
+ }
}
return 0;
}
@@ -47,14 +66,39 @@ void diffcore_pathspec(const char **path
int l;
spec[i].spec = pathspec[i];
l = strlen(pathspec[i]);
- while (l > 0 && pathspec[i][l-1] == '/')
- l--;
+ if (l > 0 && pathspec[i][l-1] == '/') {
+ spec[i].reject_non_tree = 1;
+ while (l > 0 && pathspec[i][l-1] == '/')
+ l--;
+ }
spec[i].len = l;
}
for (i = 0; i < q->nr; i++) {
struct diff_filepair *p = q->queue[i];
- if (matches_pathspec(p->two->path, spec, speccnt))
+ int obviously_non_tree;
+#ifndef DIFF_TREE_CALLS_PATHSPEC
+ /*
+ * NOTE: This relies on the current behaviour of
+ * diff-tree which does not use diffcore-pathspec
+ * and we would not ever see "tree" objects
+ * in our input.
+ */
+ obviously_non_tree = 1;
+#else
+ if (DIFF_FILE_VALID(p->two))
+ obviously_non_tree = !S_ISDIR(p->two->mode);
+ else if (DIFF_FILE_VALID(p->one))
+ /* path is being deleted. is it a tree? */
+ obviously_non_tree = !S_ISDIR(p->one->mode);
+ else
+ /* path is unmerged, which comes from cache
+ * so it cannot be a tree
+ */
+ obviously_non_tree = 1;
+#endif
+ if (matches_pathspec(p->two->path, obviously_non_tree,
+ spec, speccnt))
diff_q(&outq, p);
else
diff_free_filepair(p);
------------
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH] ls-tree: remove trailing slashes properly.
2005-05-31 15:32 [PATCH] allow pathspec to end with a slash Linus Torvalds
` (2 preceding siblings ...)
2005-05-31 21:48 ` [PATCH 2/2] diff: Fix trailing slash handling Junio C Hamano
@ 2005-05-31 21:49 ` Junio C Hamano
2005-05-31 22:19 ` Linus Torvalds
3 siblings, 1 reply; 12+ messages in thread
From: Junio C Hamano @ 2005-05-31 21:49 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Git Mailing List
A typo prevented trailing slashes from being removed properly.
This fixes the problem that "drivers/char" which is a tree was
not shown when "drivers/char/" is given.
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
t/t3100-ls-tree-restrict.sh | 32 +++++++++++++++++++++++++++-----
ls-tree.c | 2 +-
2 files changed, 28 insertions(+), 6 deletions(-)
diff --git a/t/t3100-ls-tree-restrict.sh b/t/t3100-ls-tree-restrict.sh
--- a/t/t3100-ls-tree-restrict.sh
+++ b/t/t3100-ls-tree-restrict.sh
@@ -14,7 +14,7 @@ This test runs git-ls-tree with the foll
path2/baz/b - a file in a directory in a directory
The new path restriction code should do the right thing for path2 and
-path2/baz
+path2/baz. Also path0/ should snow nothing.
'
. ./test-lib.sh
@@ -63,7 +63,7 @@ EOF
test_output'
test_expect_success \
- 'ls-tree filtered' \
+ 'ls-tree filtered with path' \
'git-ls-tree $tree path >current &&
cat >expected <<\EOF &&
EOF
@@ -71,7 +71,7 @@ EOF
test_expect_success \
- 'ls-tree filtered' \
+ 'ls-tree filtered with path1 path0' \
'git-ls-tree $tree path1 path0 >current &&
cat >expected <<\EOF &&
120000 blob X path1
@@ -80,7 +80,7 @@ EOF
test_output'
test_expect_success \
- 'ls-tree filtered' \
+ 'ls-tree filtered with path2' \
'git-ls-tree $tree path2 >current &&
cat >expected <<\EOF &&
040000 tree X path2
@@ -91,7 +91,7 @@ EOF
test_output'
test_expect_success \
- 'ls-tree filtered' \
+ 'ls-tree filtered with path2/baz' \
'git-ls-tree $tree path2/baz >current &&
cat >expected <<\EOF &&
040000 tree X path2/baz
@@ -99,4 +99,26 @@ test_expect_success \
EOF
test_output'
+test_expect_success \
+ 'ls-tree filtered with path2' \
+ 'git-ls-tree $tree path2 >current &&
+ cat >expected <<\EOF &&
+040000 tree X path2
+040000 tree X path2/baz
+120000 blob X path2/bazbo
+100644 blob X path2/foo
+EOF
+ test_output'
+
+test_expect_success \
+ 'ls-tree filtered with path2/' \
+ 'git-ls-tree $tree path2/ >current &&
+ cat >expected <<\EOF &&
+040000 tree X path2
+040000 tree X path2/baz
+120000 blob X path2/bazbo
+100644 blob X path2/foo
+EOF
+ test_output'
+
test_done
diff --git a/ls-tree.c b/ls-tree.c
--- a/ls-tree.c
+++ b/ls-tree.c
@@ -201,7 +201,7 @@ static int list(char **path)
int err = 0;
for (i = 0; path[i]; i++) {
int len = strlen(path[i]);
- while (0 <= len && path[i][len] == '/')
+ while (0 < len && path[i][len-1] == '/')
len--;
err = err | list_one(path[i], path[i] + len);
}
------------
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] ls-tree: remove trailing slashes properly.
2005-05-31 21:49 ` [PATCH] ls-tree: remove trailing slashes properly Junio C Hamano
@ 2005-05-31 22:19 ` Linus Torvalds
2005-05-31 22:35 ` Junio C Hamano
` (2 more replies)
0 siblings, 3 replies; 12+ messages in thread
From: Linus Torvalds @ 2005-05-31 22:19 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Git Mailing List
On Tue, 31 May 2005, Junio C Hamano wrote:
>
> A typo prevented trailing slashes from being removed properly.
This is still wrong.
> This fixes the problem that "drivers/char" which is a tree was
> not shown when "drivers/char/" is given.
I sent an earlier email pointing out that removing trailing slashes is
_incorrect_, because it means that "drivers/char/" will match the _file_
"drivers/char", which is wrong.
IOW, the trailing slash should not be removed, it's the _test_ that is
wrong.
I just checked in a fix for this in diffcore-patchspec.c, I'd hope that
ls-tree could get it right too. Removing trailing slashes is a bandaid
that hides one bug by making it appear as a different bug.
Linus
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] ls-tree: remove trailing slashes properly.
2005-05-31 22:19 ` Linus Torvalds
@ 2005-05-31 22:35 ` Junio C Hamano
2005-05-31 23:18 ` [PATCH] ls-tree: handle trailing slashes in the pathspec properly Junio C Hamano
2005-05-31 23:22 ` [PATCH] ls-tree: remove trailing slashes properly Junio C Hamano
2 siblings, 0 replies; 12+ messages in thread
From: Junio C Hamano @ 2005-05-31 22:35 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Git Mailing List
>>>>> "LT" == Linus Torvalds <torvalds@osdl.org> writes:
LT> I just checked in a fix for this in diffcore-patchspec.c,
LT> I'd hope that ls-tree could get it right too. Removing
LT> trailing slashes is a bandaid that hides one bug by making
LT> it appear as a different bug.
Yes, I am aware of that problem but have not touched it; I sent
an earlier email about this to you. While I was waiting for
your response, I found that drivers/char/ does not even match
drivers/char tree, which is what the patch you are responding to
is about. Will look into it later.
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH] ls-tree: handle trailing slashes in the pathspec properly.
2005-05-31 22:19 ` Linus Torvalds
2005-05-31 22:35 ` Junio C Hamano
@ 2005-05-31 23:18 ` Junio C Hamano
2005-05-31 23:48 ` Linus Torvalds
2005-05-31 23:22 ` [PATCH] ls-tree: remove trailing slashes properly Junio C Hamano
2 siblings, 1 reply; 12+ messages in thread
From: Junio C Hamano @ 2005-05-31 23:18 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Git Mailing List
>>>>> "LT" == Linus Torvalds <torvalds@osdl.org> writes:
LT> I just checked in a fix for this in diffcore-patchspec.c, I'd hope that
LT> ls-tree could get it right too. Removing trailing slashes is a bandaid
LT> that hides one bug by making it appear as a different bug.
I take it to mean that you took my other patch for diffcore-pathspec.
Here is a fixed ls-tree, with a couple of new tests in an
existing test script, to catch this bug.
------------
This fixes one problem while avoiding the same mistake earlier
diffcore-pathspec had:
- "drivers/char" which is a tree was not shown given
"drivers/char/".
- "drivers/char" which is not a tree is not shown given
"drivers/char/".
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
ls-tree.c | 57 ++++++++++++++++++++++++++-----------------
t/t3100-ls-tree-restrict.sh | 39 ++++++++++++++++++++++++++----
2 files changed, 68 insertions(+), 28 deletions(-)
diff --git a/ls-tree.c b/ls-tree.c
--- a/ls-tree.c
+++ b/ls-tree.c
@@ -54,13 +54,22 @@ static int prepare_children(struct tree_
return 0;
}
-static struct tree_entry_list *find_entry_0(struct tree_entry_list *elem,
- const char *path,
- const char *path_end)
+static struct tree_entry_list *find_entry(const char *path,
+ const char *path_end,
+ int require_tree)
{
- const char *ep;
int len;
+ struct tree_entry_list *elem = &root_entry;
+ const char *ep;
+ if (path == path_end)
+ /* Special. This is the root level */
+ return elem;
+
+ /* Find tree element, descending from root, that
+ * corresponds to the named path, lazily expanding
+ * the tree if possible.
+ */
while (path < path_end) {
if (prepare_children(elem))
return NULL;
@@ -81,27 +90,25 @@ static struct tree_entry_list *find_entr
break;
elem = elem->next;
}
- if (path_end <= ep || !elem)
+ if (!elem)
+ return NULL;
+ if (path_end <= ep) {
+ /* elem matches the specified path. However,
+ * if the user said "drivers/char/" and
+ * elem is "drivers/char", _and_ it is not
+ * a tree, then we should reject, just like
+ * "/bin/ls -a ls-tree.c/" says "Not a directory".
+ */
+ if (require_tree && !elem->directory)
+ return NULL;
return elem;
+ }
while (*ep == '/' && ep < path_end)
ep++;
path = ep;
}
return NULL;
-}
-static struct tree_entry_list *find_entry(const char *path,
- const char *path_end)
-{
- /* Find tree element, descending from root, that
- * corresponds to the named path, lazily expanding
- * the tree if possible.
- */
- if (path == path_end) {
- /* Special. This is the root level */
- return &root_entry;
- }
- return find_entry_0(&root_entry, path, path_end);
}
static void show_entry_name(struct tree_entry_list *e)
@@ -180,10 +187,10 @@ static int show_entry(struct tree_entry_
return err;
}
-static int list_one(const char *path, const char *path_end)
+static int list_one(const char *path, const char *path_end, int require_tree)
{
int err = 0;
- struct tree_entry_list *e = find_entry(path, path_end);
+ struct tree_entry_list *e = find_entry(path, path_end, require_tree);
if (!e) {
/* traditionally ls-tree does not complain about
* missing path. We may change this later to match
@@ -201,9 +208,13 @@ static int list(char **path)
int err = 0;
for (i = 0; path[i]; i++) {
int len = strlen(path[i]);
- while (0 <= len && path[i][len] == '/')
- len--;
- err = err | list_one(path[i], path[i] + len);
+ int require_tree = 0;
+ if (0 < len && path[i][len-1] == '/') {
+ require_tree = 1;
+ while (0 < len && path[i][len-1] == '/')
+ len--;
+ }
+ err = err | list_one(path[i], path[i] + len, require_tree);
}
return err;
}
diff --git a/t/t3100-ls-tree-restrict.sh b/t/t3100-ls-tree-restrict.sh
--- a/t/t3100-ls-tree-restrict.sh
+++ b/t/t3100-ls-tree-restrict.sh
@@ -14,7 +14,7 @@ This test runs git-ls-tree with the foll
path2/baz/b - a file in a directory in a directory
The new path restriction code should do the right thing for path2 and
-path2/baz
+path2/baz. Also path0/ should snow nothing.
'
. ./test-lib.sh
@@ -63,7 +63,7 @@ EOF
test_output'
test_expect_success \
- 'ls-tree filtered' \
+ 'ls-tree filtered with path' \
'git-ls-tree $tree path >current &&
cat >expected <<\EOF &&
EOF
@@ -71,7 +71,7 @@ EOF
test_expect_success \
- 'ls-tree filtered' \
+ 'ls-tree filtered with path1 path0' \
'git-ls-tree $tree path1 path0 >current &&
cat >expected <<\EOF &&
120000 blob X path1
@@ -80,7 +80,14 @@ EOF
test_output'
test_expect_success \
- 'ls-tree filtered' \
+ 'ls-tree filtered with path0/' \
+ 'git-ls-tree $tree path0/ >current &&
+ cat >expected <<\EOF &&
+EOF
+ test_output'
+
+test_expect_success \
+ 'ls-tree filtered with path2' \
'git-ls-tree $tree path2 >current &&
cat >expected <<\EOF &&
040000 tree X path2
@@ -91,7 +98,7 @@ EOF
test_output'
test_expect_success \
- 'ls-tree filtered' \
+ 'ls-tree filtered with path2/baz' \
'git-ls-tree $tree path2/baz >current &&
cat >expected <<\EOF &&
040000 tree X path2/baz
@@ -99,4 +106,26 @@ test_expect_success \
EOF
test_output'
+test_expect_success \
+ 'ls-tree filtered with path2' \
+ 'git-ls-tree $tree path2 >current &&
+ cat >expected <<\EOF &&
+040000 tree X path2
+040000 tree X path2/baz
+120000 blob X path2/bazbo
+100644 blob X path2/foo
+EOF
+ test_output'
+
+test_expect_success \
+ 'ls-tree filtered with path2/' \
+ 'git-ls-tree $tree path2/ >current &&
+ cat >expected <<\EOF &&
+040000 tree X path2
+040000 tree X path2/baz
+120000 blob X path2/bazbo
+100644 blob X path2/foo
+EOF
+ test_output'
+
test_done
------------
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] ls-tree: remove trailing slashes properly.
2005-05-31 22:19 ` Linus Torvalds
2005-05-31 22:35 ` Junio C Hamano
2005-05-31 23:18 ` [PATCH] ls-tree: handle trailing slashes in the pathspec properly Junio C Hamano
@ 2005-05-31 23:22 ` Junio C Hamano
2 siblings, 0 replies; 12+ messages in thread
From: Junio C Hamano @ 2005-05-31 23:22 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Git Mailing List
Should we do the same for git-ls-files?
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] ls-tree: handle trailing slashes in the pathspec properly.
2005-05-31 23:18 ` [PATCH] ls-tree: handle trailing slashes in the pathspec properly Junio C Hamano
@ 2005-05-31 23:48 ` Linus Torvalds
2005-06-01 1:46 ` Junio C Hamano
0 siblings, 1 reply; 12+ messages in thread
From: Linus Torvalds @ 2005-05-31 23:48 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Git Mailing List
On Tue, 31 May 2005, Junio C Hamano wrote:
>
> I take it to mean that you took my other patch for diffcore-pathspec.
No, I did my own. Rather than add more code to handle '/' as a special
case, I just removed it all, and fixed the compare logic.
> Here is a fixed ls-tree, with a couple of new tests in an
> existing test script, to catch this bug.
You seem to think that '/' at the end is a special case, and it really
shouldn't be. It should just fall out as a natural special case of a
zero-sized name (which is, btw, the same natural special case that the
path of "" should have in &root_dir).
For some reason your ls-tree.c logic seems to think that zero-sized names
means "root entry", when the _natural_ thing to do is to pass in the "base
directory", and then a zero-sized name is that base.
IOW, it would make much more sense to have
list_one(struct tree_entry_list *tree, const char *name)
{
const char *slash = strchr(name, '/');
const char *next;
int len;
for (;;) {
if (!slash) {
len = strlen(name);
next = NULL;
} else {
len = slash - name;
next = slash+1;
}
newtree = tree;
if (len)
newtree = lookup(tree, name, len);
if (!next)
break;
tree = newtree;
name = next;
}
/* Ok, "newtree" is the last component */
show_entry(newtree);
}
and then call it with
list_one(&root_entry, full_path)
and notice how the cases of an empty path "" and "xxx//yy" and "xx/"
just fall out from the exact same logic - a zero-sized name is the same as
the directory it is in. No special cases for slashes or empty names.
Linus
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH] ls-tree: handle trailing slashes in the pathspec properly.
2005-05-31 23:48 ` Linus Torvalds
@ 2005-06-01 1:46 ` Junio C Hamano
2005-06-01 3:51 ` Linus Torvalds
0 siblings, 1 reply; 12+ messages in thread
From: Junio C Hamano @ 2005-06-01 1:46 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Git Mailing List
This fixes the problem with ls-tree which failed to show
"drivers/char" directory when the user asked for "drivers/char/"
from the command line. At the same time, if "drivers/char" were
a non directory, "drivers/char/" would not show it. This is
consistent with the way diffcore-pathspec has been recently
fixed.
This adds back the diffcore-pathspec test,dropped when my
earlier diffcore-pathspec fix was rejected.
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
*** OK, this is the third try (2 1/2nd to be exact). I love how
*** you always turn out to be right ;-). BTW could you limit
*** git-apply --stat output to 79 cols not 80?
ls-tree.c | 94 ++++++++++++++++++++++----------------------
t/t3100-ls-tree-restrict.sh | 39 ++++++++++++++++--
t/t4010-diff-pathspec.sh | 65 ++++++++++++++++++++++++++++++
3 files changed, 146 insertions(+), 52 deletions(-)
diff --git a/ls-tree.c b/ls-tree.c
--- a/ls-tree.c
+++ b/ls-tree.c
@@ -54,54 +54,58 @@ static int prepare_children(struct tree_
return 0;
}
-static struct tree_entry_list *find_entry_0(struct tree_entry_list *elem,
- const char *path,
- const char *path_end)
+static struct tree_entry_list *find_entry(const char *path)
{
- const char *ep;
+ const char *next, *slash;
int len;
+ struct tree_entry_list *elem = &root_entry;
- while (path < path_end) {
- if (prepare_children(elem))
- return NULL;
+ /* Find tree element, descending from root, that
+ * corresponds to the named path, lazily expanding
+ * the tree if possible.
+ */
- /* In elem->tree->entries, find the one that has name
- * that matches what is between path and ep.
+ while (path) {
+ /* The fact we still have path means that the caller
+ * wants us to make sure that elem at this point is a
+ * directory, and possibly descend into it. Even what
+ * is left is just trailing slashes, we loop back to
+ * here, and this call to prepare_children() will
+ * catch elem not being a tree. Nice.
*/
- elem = elem->item.tree->entries;
+ if (prepare_children(elem))
+ return NULL;
- ep = strchr(path, '/');
- if (!ep || path_end <= ep)
- ep = path_end;
- len = ep - path;
-
- while (elem) {
- if ((strlen(elem->name) == len) &&
- !strncmp(elem->name, path, len))
- break;
- elem = elem->next;
+ slash = strchr(path, '/');
+ if (!slash) {
+ len = strlen(path);
+ next = 0;
+ }
+ else {
+ next = slash + 1;
+ len = slash - path;
}
- if (path_end <= ep || !elem)
- return elem;
- while (*ep == '/' && ep < path_end)
- ep++;
- path = ep;
+ if (len) {
+ /* (len == 0) if the original path was "drivers/char/"
+ * and we have run already two rounds, having elem
+ * pointing at the drivers/char directory.
+ */
+ elem = elem->item.tree->entries;
+ while (elem) {
+ if ((strlen(elem->name) == len) &&
+ !strncmp(elem->name, path, len)) {
+ /* found */
+ break;
+ }
+ elem = elem->next;
+ }
+ if (!elem)
+ return NULL;
+ }
+ path = next;
}
- return NULL;
-}
-static struct tree_entry_list *find_entry(const char *path,
- const char *path_end)
-{
- /* Find tree element, descending from root, that
- * corresponds to the named path, lazily expanding
- * the tree if possible.
- */
- if (path == path_end) {
- /* Special. This is the root level */
- return &root_entry;
- }
- return find_entry_0(&root_entry, path, path_end);
+ return elem;
}
static void show_entry_name(struct tree_entry_list *e)
@@ -180,10 +184,10 @@ static int show_entry(struct tree_entry_
return err;
}
-static int list_one(const char *path, const char *path_end)
+static int list_one(const char *path)
{
int err = 0;
- struct tree_entry_list *e = find_entry(path, path_end);
+ struct tree_entry_list *e = find_entry(path);
if (!e) {
/* traditionally ls-tree does not complain about
* missing path. We may change this later to match
@@ -199,12 +203,8 @@ static int list(char **path)
{
int i;
int err = 0;
- for (i = 0; path[i]; i++) {
- int len = strlen(path[i]);
- while (0 <= len && path[i][len] == '/')
- len--;
- err = err | list_one(path[i], path[i] + len);
- }
+ for (i = 0; path[i]; i++)
+ err = err | list_one(path[i]);
return err;
}
diff --git a/t/t3100-ls-tree-restrict.sh b/t/t3100-ls-tree-restrict.sh
--- a/t/t3100-ls-tree-restrict.sh
+++ b/t/t3100-ls-tree-restrict.sh
@@ -14,7 +14,7 @@ This test runs git-ls-tree with the foll
path2/baz/b - a file in a directory in a directory
The new path restriction code should do the right thing for path2 and
-path2/baz
+path2/baz. Also path0/ should snow nothing.
'
. ./test-lib.sh
@@ -63,7 +63,7 @@ EOF
test_output'
test_expect_success \
- 'ls-tree filtered' \
+ 'ls-tree filtered with path' \
'git-ls-tree $tree path >current &&
cat >expected <<\EOF &&
EOF
@@ -71,7 +71,7 @@ EOF
test_expect_success \
- 'ls-tree filtered' \
+ 'ls-tree filtered with path1 path0' \
'git-ls-tree $tree path1 path0 >current &&
cat >expected <<\EOF &&
120000 blob X path1
@@ -80,7 +80,14 @@ EOF
test_output'
test_expect_success \
- 'ls-tree filtered' \
+ 'ls-tree filtered with path0/' \
+ 'git-ls-tree $tree path0/ >current &&
+ cat >expected <<\EOF &&
+EOF
+ test_output'
+
+test_expect_success \
+ 'ls-tree filtered with path2' \
'git-ls-tree $tree path2 >current &&
cat >expected <<\EOF &&
040000 tree X path2
@@ -91,7 +98,7 @@ EOF
test_output'
test_expect_success \
- 'ls-tree filtered' \
+ 'ls-tree filtered with path2/baz' \
'git-ls-tree $tree path2/baz >current &&
cat >expected <<\EOF &&
040000 tree X path2/baz
@@ -99,4 +106,26 @@ test_expect_success \
EOF
test_output'
+test_expect_success \
+ 'ls-tree filtered with path2' \
+ 'git-ls-tree $tree path2 >current &&
+ cat >expected <<\EOF &&
+040000 tree X path2
+040000 tree X path2/baz
+120000 blob X path2/bazbo
+100644 blob X path2/foo
+EOF
+ test_output'
+
+test_expect_success \
+ 'ls-tree filtered with path2/' \
+ 'git-ls-tree $tree path2/ >current &&
+ cat >expected <<\EOF &&
+040000 tree X path2
+040000 tree X path2/baz
+120000 blob X path2/bazbo
+100644 blob X path2/foo
+EOF
+ test_output'
+
test_done
diff --git a/t/t4010-diff-pathspec.sh b/t/t4010-diff-pathspec.sh
new file mode 100644
--- /dev/null
+++ b/t/t4010-diff-pathspec.sh
@@ -0,0 +1,65 @@
+#!/bin/sh
+#
+# Copyright (c) 2005 Junio C Hamano
+#
+
+test_description='Pathspec restrictions
+
+Prepare:
+ file0
+ path1/file1
+'
+. ./test-lib.sh
+. ../diff-lib.sh ;# test-lib chdir's into trash
+
+test_expect_success \
+ setup \
+ 'echo frotz >file0 &&
+ mkdir path1 &&
+ echo rezrov >path1/file1 &&
+ git-update-cache --add file0 path1/file1 &&
+ tree=`git-write-tree` &&
+ echo "$tree" &&
+ echo nitfol >file0 &&
+ echo yomin >path1/file1 &&
+ git-update-cache file0 path1/file1'
+
+cat >expected <<\EOF
+EOF
+test_expect_success \
+ 'limit to path should show nothing' \
+ 'git-diff-cache --cached $tree path >current &&
+ compare_diff_raw current expected'
+
+cat >expected <<\EOF
+:100644 100644 766498d93a4b06057a8e49d23f4068f1170ff38f 0a41e115ab61be0328a19b29f18cdcb49338d516 M path1/file1
+EOF
+test_expect_success \
+ 'limit to path1 should show path1/file1' \
+ 'git-diff-cache --cached $tree path1 >current &&
+ compare_diff_raw current expected'
+
+cat >expected <<\EOF
+:100644 100644 766498d93a4b06057a8e49d23f4068f1170ff38f 0a41e115ab61be0328a19b29f18cdcb49338d516 M path1/file1
+EOF
+test_expect_success \
+ 'limit to path1/ should show path1/file1' \
+ 'git-diff-cache --cached $tree path1/ >current &&
+ compare_diff_raw current expected'
+
+cat >expected <<\EOF
+:100644 100644 766498d93a4b06057a8e49d23f4068f1170ff38f 0a41e115ab61be0328a19b29f18cdcb49338d516 M file0
+EOF
+test_expect_success \
+ 'limit to file0 should show file0' \
+ 'git-diff-cache --cached $tree file0 >current &&
+ compare_diff_raw current expected'
+
+cat >expected <<\EOF
+EOF
+test_expect_success \
+ 'limit to file0/ should emit nothing.' \
+ 'git-diff-cache --cached $tree file0/ >current &&
+ compare_diff_raw current expected'
+
+test_done
------------
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] ls-tree: handle trailing slashes in the pathspec properly.
2005-06-01 1:46 ` Junio C Hamano
@ 2005-06-01 3:51 ` Linus Torvalds
0 siblings, 0 replies; 12+ messages in thread
From: Linus Torvalds @ 2005-06-01 3:51 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Git Mailing List
On Tue, 31 May 2005, Junio C Hamano wrote:
>
> BTW could you limit git-apply --stat output to 79 cols not 80?
Hmm, I thought I already did, but it turns out it could round up both
add/del, causing my 79 to be 80.
I think I fixed it.
Linus
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2005-06-01 3:46 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-05-31 15:32 [PATCH] allow pathspec to end with a slash Linus Torvalds
2005-05-31 20:08 ` Junio C Hamano
2005-05-31 21:47 ` [PATCH 1/2] diff: consolidate test helper script pieces Junio C Hamano
2005-05-31 21:48 ` [PATCH 2/2] diff: Fix trailing slash handling Junio C Hamano
2005-05-31 21:49 ` [PATCH] ls-tree: remove trailing slashes properly Junio C Hamano
2005-05-31 22:19 ` Linus Torvalds
2005-05-31 22:35 ` Junio C Hamano
2005-05-31 23:18 ` [PATCH] ls-tree: handle trailing slashes in the pathspec properly Junio C Hamano
2005-05-31 23:48 ` Linus Torvalds
2005-06-01 1:46 ` Junio C Hamano
2005-06-01 3:51 ` Linus Torvalds
2005-05-31 23:22 ` [PATCH] ls-tree: remove trailing slashes properly Junio C Hamano
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox