git-p4: reduce number of server queries for fetches

When fetching changes from a depot using a full client spec, there is no need to perform as many queries as there are top-level paths in the client spec. Instead we query all changes in chronological order, also getting rid of the need to sort the results and remove duplicates. Signed-off-by: Sam Hocevar <sam@hocevar.net> Signed-off-by: Luke Diamand <luke@diamand.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Sam Hocevar committed Dec 19, 2015 at 09:39 UTC 1f90a64891ed83e172cbf605890044dba8315073
2 files changed +22 -24
git-p4.py
+21 -23
@@ -822,39 +822,37 @@ def p4ChangesForPaths(depotPaths, changeRange, requestedBlockSize):
822 die("cannot use --changes-block-size with non-numeric revisions")
823 block_size = None
824
825 - # Accumulate change numbers in a dictionary to avoid duplicates
826 - changes = {}
825 + changes = []
826
828 - for p in depotPaths:
829 - # Retrieve changes a block at a time, to prevent running
830 - # into a MaxResults/MaxScanRows error from the server.
827 + # Retrieve changes a block at a time, to prevent running
828 + # into a MaxResults/MaxScanRows error from the server.
829
832 - while True:
833 - cmd = ['changes']
830 + while True:
831 + cmd = ['changes']
832
835 - if block_size:
836 - end = min(changeEnd, changeStart + block_size)
837 - revisionRange = "%d,%d" % (changeStart, end)
838 - else:
839 - revisionRange = "%s,%s" % (changeStart, changeEnd)
833 + if block_size:
834 + end = min(changeEnd, changeStart + block_size)
835 + revisionRange = "%d,%d" % (changeStart, end)
836 + else:
837 + revisionRange = "%s,%s" % (changeStart, changeEnd)
838
839 + for p in depotPaths:
840 cmd += ["%s...@%s" % (p, revisionRange)]
841
843 - for line in p4_read_pipe_lines(cmd):
844 - changeNum = int(line.split(" ")[1])
845 - changes[changeNum] = True
842 + # Insert changes in chronological order
843 + for line in reversed(p4_read_pipe_lines(cmd)):
844 + changes.append(int(line.split(" ")[1]))
845
847 - if not block_size:
848 - break
846 + if not block_size:
847 + break
848
850 - if end >= changeEnd:
851 - break
849 + if end >= changeEnd:
850 + break
851
853 - changeStart = end + 1
852 + changeStart = end + 1
853
855 - changelist = changes.keys()
856 - changelist.sort()
857 - return changelist
854 + changes = sorted(changes)
855 + return changes
856
857 def p4PathStartsWith(path, prefix):
858 # This method tries to remedy a potential mixed-case issue:
t/t9818-git-p4-block.sh
+1 -1
@@ -128,7 +128,7 @@ test_expect_success 'Create a repo with multiple depot paths' '
128 done
129 '
130
131 -test_expect_failure 'Clone repo with multiple depot paths' '
131 +test_expect_success 'Clone repo with multiple depot paths' '
132 (
133 cd "$git" &&
134 git p4 clone --changes-block-size=4 //depot/pathA@all //depot/pathB@all \