git-p4: don't exclude other files with same prefix

Make sure not to exclude files unintentionally if exclude paths are specified without a trailing /. I.e., don't exclude "//depot/file_dont_exclude" if run with "-//depot/file". Do this by ensuring that paths without a trailing "/" are only matched completely. Also, abort path search on the first match as a micro-optimization. Signed-off-by: Andrey Mazo <amazo@checkvideo.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Mazo, Andrey committed Apr 1, 2019 at 18:02 UTC a2bee10ad9ed4dc45c1f7da76f01388925b80212
2 files changed +16 -9
git-p4.py
+14 -7
@@ -2623,18 +2623,25 @@ class P4Sync(Command, P4UserMap):
2623 if self.verbose:
2624 print("checkpoint finished: " + out)
2625
2626 + def isPathWanted(self, path):
2627 + for p in self.cloneExclude:
2628 + if p.endswith("/"):
2629 + if p4PathStartsWith(path, p):
2630 + return False
2631 + # "-//depot/file1" without a trailing "/" should only exclude "file1", but not "file111" or "file1_dir/file2"
2632 + elif path.lower() == p.lower():
2633 + return False
2634 + for p in self.depotPaths:
2635 + if p4PathStartsWith(path, p):
2636 + return True
2637 + return False
2638 +
2639 def extractFilesFromCommit(self, commit, shelved=False, shelved_cl = 0):
2640 files = []
2641 fnum = 0
2642 while "depotFile%s" % fnum in commit:
2643 path = commit["depotFile%s" % fnum]
2631 -
2632 - if [p for p in self.cloneExclude
2633 - if p4PathStartsWith(path, p)]:
2634 - found = False
2635 - else:
2636 - found = [p for p in self.depotPaths
2637 - if p4PathStartsWith(path, p)]
2644 + found = self.isPathWanted(path)
2645 if not found:
2646 fnum = fnum + 1
2647 continue
t/t9817-git-p4-exclude.sh
+2 -2
@@ -53,7 +53,7 @@ test_expect_success 'clone, excluding part of repo' '
53 )
54 '
55
56 -test_expect_failure 'clone, excluding single file, no trailing /' '
56 +test_expect_success 'clone, excluding single file, no trailing /' '
57 test_when_finished cleanup_git &&
58 git p4 clone -//depot/discard_file --dest="$git" //depot/...@all &&
59 (
@@ -85,7 +85,7 @@ test_expect_success 'clone, then sync with exclude' '
85 )
86 '
87
88 -test_expect_failure 'clone, then sync with exclude, no trailing /' '
88 +test_expect_success 'clone, then sync with exclude, no trailing /' '
89 test_when_finished cleanup_git &&
90 git p4 clone -//depot/discard/... -//depot/discard_file --dest="$git" //depot/...@all &&
91 (