Obey p4 views when using client spec
When using the p4 client spec, this attempts to obey the client's output preferences. For example, a view like //depot/foo/branch/... //client/branch/foo/... //depot/bar/branch/... //client/branch/bar/... will result in a directory layout in the git tree of branch/ branch/foo branch/bar p4 can do various other reordering that this change doesn't support, but we should detect it and at least fail nicely. Signed-off-by: Ian Wienand <ianw@vmware.com> Acked-by: Pete Wyckoff <pw@padd.com> Acked-by: Tor Arvid Lund <torarvid@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Ian Wienand committed
Feb 11, 2011 at 16:33 UTC
3952710bfaa46917fd0c3a9b29d076ec013d6b6a
2 files changed
+51
-4
contrib/fast-import/git-p4
+46
-4
@@ -910,6 +910,22 @@ class P4Sync(Command):
910
return files
911
912
def stripRepoPath(self, path, prefixes):
913
+ if self.useClientSpec:
914
+
915
+ # if using the client spec, we use the output directory
916
+ # specified in the client. For example, a view
917
+ # //depot/foo/branch/... //client/branch/foo/...
918
+ # will end up putting all foo/branch files into
919
+ # branch/foo/
920
+ for val in self.clientSpecDirs:
921
+ if path.startswith(val[0]):
922
+ # replace the depot path with the client path
923
+ path = path.replace(val[0], val[1][1])
924
+ # now strip out the client (//client/...)
925
+ path = re.sub("^(//[^/]+/)", '', path)
926
+ # the rest is all path
927
+ return path
928
+
929
if self.keepRepoPath:
930
prefixes = [re.sub("^(//[^/]+/).*", r'\1', prefixes[0])]
931
@@ -1032,7 +1048,7 @@ class P4Sync(Command):
1048
includeFile = True
1049
for val in self.clientSpecDirs:
1050
if f['path'].startswith(val[0]):
1035
- if val[1] <= 0:
1051
+ if val[1][0] <= 0:
1052
includeFile = False
1053
break
1054
@@ -1475,19 +1491,45 @@ class P4Sync(Command):
1491
for entry in specList:
1492
for k,v in entry.iteritems():
1493
if k.startswith("View"):
1494
+
1495
+ # p4 has these %%1 to %%9 arguments in specs to
1496
+ # reorder paths; which we can't handle (yet :)
1497
+ if re.match('%%\d', v) != None:
1498
+ print "Sorry, can't handle %%n arguments in client specs"
1499
+ sys.exit(1)
1500
+
1501
if v.startswith('"'):
1502
start = 1
1503
else:
1504
start = 0
1505
index = v.find("...")
1506
+
1507
+ # save the "client view"; i.e the RHS of the view
1508
+ # line that tells the client where to put the
1509
+ # files for this view.
1510
+ cv = v[index+3:].strip() # +3 to remove previous '...'
1511
+
1512
+ # if the client view doesn't end with a
1513
+ # ... wildcard, then we're going to mess up the
1514
+ # output directory, so fail gracefully.
1515
+ if not cv.endswith('...'):
1516
+ print 'Sorry, client view in "%s" needs to end with wildcard' % (k)
1517
+ sys.exit(1)
1518
+ cv=cv[:-3]
1519
+
1520
+ # now save the view; +index means included, -index
1521
+ # means it should be filtered out.
1522
v = v[start:index]
1523
if v.startswith("-"):
1524
v = v[1:]
1486
- temp[v] = -len(v)
1525
+ include = -len(v)
1526
else:
1488
- temp[v] = len(v)
1527
+ include = len(v)
1528
+
1529
+ temp[v] = (include, cv)
1530
+
1531
self.clientSpecDirs = temp.items()
1490
- self.clientSpecDirs.sort( lambda x, y: abs( y[1] ) - abs( x[1] ) )
1532
+ self.clientSpecDirs.sort( lambda x, y: abs( y[1][0] ) - abs( x[1][0] ) )
1533
1534
def run(self, args):
1535
self.depotPaths = []
contrib/fast-import/git-p4.txt
+5
@@ -191,6 +191,11 @@ git-p4.useclientspec
191
192
git config [--global] git-p4.useclientspec false
193
194
+The P4CLIENT environment variable should be correctly set for p4 to be
195
+able to find the relevant client. This client spec will be used to
196
+both filter the files cloned by git and set the directory layout as
197
+specified in the client (this implies --keep-path style semantics).
198
+
199
Implementation Details...
200
=========================
201