From: Eric Sunshine <hidden> Date: 2016-06-15 22:58:29
This series fixes a bug in dir.c which causes t3010 to fail [1] when
core.ignorecase is true. The problem is that
directory_exists_in_index(dirname,len) and
directory_exists_in_index_icase() behave differently if dirname[len] is
not a '/', even though this is beyond end-of-string. 2eac2a4cc4bdc8d7
(ls-files -k: a directory only can be killed if the index has a
non-directory; 2013-08-15) adds a caller which neglects to ensure that
the the required '/' is present, hence the failure.
I am not happy with the fix, which is too add a '/' after the last
character in dirname just at the call site introduced by
2eac2a4cc4bdc8d7.
The reason for my unhappiness is that directory_exists_in_index_icase()
makes the assumption, not only that it can access the character beyond
the end-of-string, but also that that character will unconditionally be
'/'. I presume that this was done for the sake of speed (existing
callers always had a '/' beyond end-of-string), but it feels like an
ugly wart. Since the required trailing '/' is purely an implementation
detail of directory_exists_in_index_icase(), and not of
directory_exists_in_index(), a cleaner fix would be for
directory_exists_in_index_icase() to add the '/' it needs, and not
expect the passed in dirname to have a '/' after its last character.
Unfortunately, such a fix would probably negate any optimization benefit
gained by the present implementation.
[1]: http://thread.gmane.org/gmane.comp.version-control.git/232727
Eric Sunshine (2):
t3103: demonstrate dir.c:treat_one_path() core.ignorecase failure
dir: test_one_path: fix inconsistent behavior due to missing '/'
dir.c | 12 +++++++++---
t/t3103-ls-tree-misc.sh | 15 +++++++++++++++
2 files changed, 24 insertions(+), 3 deletions(-)
--
1.8.4.rc4.529.g78818d7
From: Eric Sunshine <hidden> Date: 2016-06-15 22:58:29
2eac2a4cc4bdc8d7 (ls-files -k: a directory only can be killed if the
index has a non-directory; 2013-08-15) adds a caller of
directory_exists_in_index(dirname,len) which forgets to satisfy the
undocumented requirement that a '/' must be present at dirname[len]
(despite being past the end-of-string). This oversight leads to
incorrect behavior when core.ignorecase is true. Demonstrate this.
Signed-off-by: Eric Sunshine <redacted>
---
t/t3103-ls-tree-misc.sh | 15 +++++++++++++++
1 file changed, 15 insertions(+)
From: Eric Sunshine <hidden> Date: 2016-06-15 22:58:29
Although undocumented, directory_exists_in_index_icase(dirname,len)
unconditionally assumes the presence of a '/' at dirname[len] (despite
being past the end-of-string). Callers are expected to respect this
assumption by ensuring that a '/' is present beyond the last character
of the passed path. directory_exists_in_index(), on the other hand,
does not assume nor care about a trailing '/' beyond end-of-string.
2eac2a4cc4bdc8d7 (ls-files -k: a directory only can be killed if the
index has a non-directory; 2013-08-15) adds a caller which forgets to
ensure the trailing '/', thus leading to inconsistent behavior between
directory_exists_in_index() and directory_exists_in_index_icase()
depending upon the setting of core.ignorecase. Fix this problem.
This also fixes an initially-unnoticed failure in a t3010 test added by
3c56875176390eee (t3010: update to demonstrate "ls-files -k"
optimization pitfalls; 2013-08-15) when core.ignorecase is true.
Signed-off-by: Eric Sunshine <redacted>
---
dir.c | 12 +++++++++---
t/t3103-ls-tree-misc.sh | 2 +-
2 files changed, 10 insertions(+), 4 deletions(-)
From: Jonathan Nieder <hidden> Date: 2016-06-15 22:58:30
Eric Sunshine wrote:
Although undocumented, directory_exists_in_index_icase(dirname,len)
unconditionally assumes the presence of a '/' at dirname[len] (despite
being past the end-of-string). Callers are expected to respect
[...]
Fix this problem.
So, does this fix the problem by changing
directory_exists_in_index_icase() to be more liberal in what it
accepts, or callers to be more conservative in what they pass in?
Please forgive my laziness. I ask in order to save future readers the
time of digging into the code.
Thanks,
Jonathan
From: Eric Sunshine <hidden> Date: 2016-06-15 22:58:30
On Sun, Aug 25, 2013 at 2:00 AM, Jonathan Nieder [off-list ref] wrote:
Eric Sunshine wrote:
quoted
Although undocumented, directory_exists_in_index_icase(dirname,len)
unconditionally assumes the presence of a '/' at dirname[len] (despite
being past the end-of-string). Callers are expected to respect
[...]
quoted
Fix this problem.
So, does this fix the problem by changing
directory_exists_in_index_icase() to be more liberal in what it
accepts, or callers to be more conservative in what they pass in?
It places the onus upon the caller. As mentioned in the cover letter
[1], I was not happy with this solution. Junio felt likewise. A
follow-up series [2] fixes both directory_exists_in_index() and
directory_exists_in_index_icase() to be more liberal in what they
accept, relieving the caller of the burden. By the time that series
was posted, however, Junio and Peff had decided that a fix at a more
fundamental level would be better (a conclusion with which I agree,
but for which I do not yet have sufficient knowledge about git
internals to implement). In the meantime, as an interim bug fix, Junio
decided [3] to apply the patch to which you responded (but with an
updated commit message).
[1]: http://thread.gmane.org/gmane.comp.version-control.git/232796
[2]: http://thread.gmane.org/gmane.comp.version-control.git/232833
[3]: http://thread.gmane.org/gmane.comp.version-control.git/232833/focus=232837
Please forgive my laziness. I ask in order to save future readers the
time of digging into the code.