git-p4: fix multi-path changelist empty commits

When importing from multiple perforce paths - we may attempt to import a changelist that contains files from two (or more) of these depot paths. Currently, this results in multiple git commits - one containing the changes, and the other(s) as empty commit(s). This behavior was introduced in commit 1f90a64891 ("git-p4: reduce number of server queries for fetches", 2015-12-19). Reproduction Steps: 1. Have a git repo cloned from a perforce repo using multiple depot paths (e.g. //depot/foo and //depot/bar). 2. Submit a single change to the perforce repo that makes changes in both //depot/foo and //depot/bar. 3. Run "git p4 sync" to sync the change from #2. Change is synced as multiple commits, one for each depot path that was affected. Using a set, instead of a list inside p4ChangesForPaths() ensures that each changelist is unique to the returned list, and therefore only a single commit is generated for each changelist. Reported-by: James Farwell <jfarwell@vmware.com> Signed-off-by: George Vanburgh <gvanburgh@bloomberg.net> Reviewed-by: Luke Diamand <luke@diamand.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>

George Vanburgh committed Dec 17, 2016 at 22:11 UTC 9943e5b9799336460ecbbeb86e544cc4a1ad1254
2 files changed +23 -3
git-p4.py
+2 -2
@@ -822,7 +822,7 @@ def p4ChangesForPaths(depotPaths, changeRange, requestedBlockSize):
822 die("cannot use --changes-block-size with non-numeric revisions")
823 block_size = None
824
825 - changes = []
825 + changes = set()
826
827 # Retrieve changes a block at a time, to prevent running
828 # into a MaxResults/MaxScanRows error from the server.
@@ -841,7 +841,7 @@ def p4ChangesForPaths(depotPaths, changeRange, requestedBlockSize):
841
842 # Insert changes in chronological order
843 for line in reversed(p4_read_pipe_lines(cmd)):
844 - changes.append(int(line.split(" ")[1]))
844 + changes.add(int(line.split(" ")[1]))
845
846 if not block_size:
847 break
t/t9800-git-p4-basic.sh
+21 -1
@@ -131,6 +131,26 @@ test_expect_success 'clone two dirs, @all, conflicting files' '
131 )
132 '
133
134 +test_expect_success 'clone two dirs, each edited by submit, single git commit' '
135 + (
136 + cd "$cli" &&
137 + echo sub1/f4 >sub1/f4 &&
138 + p4 add sub1/f4 &&
139 + echo sub2/f4 >sub2/f4 &&
140 + p4 add sub2/f4 &&
141 + p4 submit -d "sub1/f4 and sub2/f4"
142 + ) &&
143 + git p4 clone --dest="$git" //depot/sub1@all //depot/sub2@all &&
144 + test_when_finished cleanup_git &&
145 + (
146 + cd "$git" &&
147 + git ls-files >lines &&
148 + test_line_count = 4 lines &&
149 + git log --oneline p4/master >lines &&
150 + test_line_count = 5 lines
151 + )
152 +'
153 +
154 revision_ranges="2000/01/01,#head \
155 1,2080/01/01 \
156 2000/01/01,2080/01/01 \
@@ -147,7 +167,7 @@ test_expect_success 'clone using non-numeric revision ranges' '
167 (
168 cd "$git" &&
169 git ls-files >lines &&
150 - test_line_count = 6 lines
170 + test_line_count = 8 lines
171 )
172 done
173 '