From: Pete Wyckoff <pw@padd.com>
To: Sam Hocevar <sam@zoy.org>
Cc: git@vger.kernel.org
Subject: Re: git-p4 workflow suggestions?
Date: Tue, 17 Mar 2009 08:18:15 -0700 [thread overview]
Message-ID: <20090317151815.GA2451@padd.com> (raw)
In-Reply-To: <20090316180108.GE27280@zoy.org>
sam@zoy.org wrote on Mon, 16 Mar 2009 19:01 +0100:
> Yes, like this. More precisely:
>
> //work/framework/example/... //client/...
> //work/project1/src/... //client/src/...
> //work/project1/include/... //client/include/...
[..]
> My changes are extremely messy but I will refactor them as time goes.
> There is at least one other important thing my git-p4 does, which is not
> storing the whole commit in memory. Combined with the patches I sent
> last week to this list, it's the only way I can import the p4 repository
> we have at work. (See http://zoy.org/~sam/git/clumsily-hacked-git-p4)
Oh, that is, ahem, a bit site-specific. The looping over chunks in
the import phase is important, and other people have been thinking
about that. I'll ignore that aspect for now, though, and we'll see
if we can get the client-spec part worked out.
Can you take a look at the attached. Its goal is purely to allow
you to clone a complex spec like yours above. You may have to merge
this in with your perrformance changes.
Edit your ~/.gitconfig to add a section:
[git-p4]
useClientSpec = true
Then copy a good P4ENV from a p4 client that has a client spec
checked out as you like. git-p4 clone will do "p4 client -o",
reading that spec, and use the results to import, hopefully as
you have things laid out in the spec.
If this seems to work for you, we can figure out how to clean up
the patch so it can be used generally by people with and without
client specs.
-- Pete
---------
From 4a922efcef18e3bb740f88c31ed4d00fa66f4cce Mon Sep 17 00:00:00 2001
From: Pete Wyckoff <petew@netapp.com>
Date: Wed, 26 Nov 2008 12:28:09 -0500
Subject: [PATCH] honor git client spec
Destination directories for parts of the depot are specified in the
client spec. Use them as given. Also read the entire client spec to
figure out what to do.
---
contrib/fast-import/git-p4 | 110 ++++++++++++++++++++++++++++++++++---------
1 files changed, 87 insertions(+), 23 deletions(-)
diff --git a/contrib/fast-import/git-p4 b/contrib/fast-import/git-p4
index 332c7f8..d953a1e 100755
--- a/contrib/fast-import/git-p4
+++ b/contrib/fast-import/git-p4
@@ -451,6 +451,26 @@ def p4ChangesForPaths(depotPaths, changeRange):
changelist.sort()
return changelist
+#
+# Sort by number of slashes first: more specific at the top. Then
+# sort by alpha within a given number of path components.
+#
+def clientSortFunc(a, b):
+ asrc = a[0]
+ bsrc = b[0]
+ asrclen = asrc.count("/")
+ bsrclen = bsrc.count("/")
+ if asrclen > bsrclen:
+ return -1
+ elif asrclen < bsrclen:
+ return 1
+ elif asrc > bsrc:
+ return 1
+ elif asrc < bsrc:
+ return -1
+ else:
+ return 0
+
class Command:
def __init__(self):
self.usage = "usage: %prog [options]"
@@ -959,8 +979,9 @@ class P4Sync(Command):
includeFile = True
for val in self.clientSpecDirs:
if f['path'].startswith(val[0]):
- if val[1] <= 0:
+ if val[1] == '-':
includeFile = False
+ f['pathmap'] = val
break
if includeFile:
@@ -1056,7 +1077,12 @@ class P4Sync(Command):
print "\nfile %s is a strange apple file that forks. Ignoring!" % file['path']
continue
- relPath = self.stripRepoPath(file['path'], branchPrefixes)
+ if 'pathmap' in file:
+ relPath = file['pathmap'][1] + file['path'][len(file['pathmap'][0]):]
+ else:
+ relPath = self.stripRepoPath(file['path'], branchPrefixes)
+
+ print "path", file['path'], "->", relPath
if file["action"] in ("delete", "purge"):
self.gitStream.write("D %s\n" % relPath)
else:
@@ -1439,24 +1465,54 @@ class P4Sync(Command):
def getClientSpec(self):
- specList = p4CmdList( "client -o" )
+ specList = p4CmdList("client -o")
temp = {}
+ client = ""
+ for entry in specList:
+ for k,v in entry.iteritems():
+ if k.startswith("Client"):
+ client = v
+ print "client is", client
+ if not client:
+ sys.stderr.write("no client found\n")
+ sys.exit(1)
+ client = "//" + client + "/"
for entry in specList:
for k,v in entry.iteritems():
if k.startswith("View"):
- if v.startswith('"'):
- start = 1
- else:
- start = 0
- index = v.find("...")
- v = v[start:index]
- if v.startswith("-"):
- v = v[1:]
- temp[v] = -len(v)
- else:
- temp[v] = len(v)
- self.clientSpecDirs = temp.items()
- self.clientSpecDirs.sort( lambda x, y: abs( y[1] ) - abs( x[1] ) )
+ if v.startswith('"'):
+ v = v[1:]
+ if v.endswith('"'):
+ v = v[:-1]
+ d = v.split(" ");
+ if len(d) != 2:
+ sys.stderr.write( \
+ "expecting two fields in view, got: %s\n" % v)
+ sys.exit(1)
+ if not d[0].endswith("..."):
+ sys.stderr.write(\
+ "expecting trailing ..., got: %s\n" % d[0])
+ sys.exit(1)
+ d[0] = d[0][:-3]
+ if not d[1].endswith("..."):
+ sys.stderr.write(\
+ "expecting trailing ..., got: %s\n" % d[1])
+ sys.exit(1)
+ d[1] = d[1][:-3]
+ if not d[1].startswith(client):
+ sys.stderr.write(\
+ "expecting dest to start with %s, got: %s\n" % \
+ (client, d[1]))
+ sys.exit(1)
+ d[1] = d[1][len(client):]
+ # negated items do not appear in tree
+ if d[0].startswith("-"):
+ d[0] = d[0][1:]
+ d[1] = ""
+ temp[d[0]] = d[1]
+
+ self.clientSpecDirs = temp.items()
+ self.clientSpecDirs.sort(clientSortFunc)
def run(self, args):
self.depotPaths = []
@@ -1718,7 +1774,7 @@ class P4Clone(P4Sync):
def __init__(self):
P4Sync.__init__(self)
self.description = "Creates a new git repository and imports from Perforce into it"
- self.usage = "usage: %prog [options] //depot/path[@revRange]"
+ self.usage = "usage: %prog [options] [//depot/path[@revRange]]"
self.options += [
optparse.make_option("--destination", dest="cloneDestination",
action='store', default=None,
@@ -1746,18 +1802,26 @@ class P4Clone(P4Sync):
return os.path.split(depotDir)[1]
def run(self, args):
- if len(args) < 1:
- return False
-
if self.keepRepoPath and not self.cloneDestination:
sys.stderr.write("Must specify destination for --keep-path\n")
sys.exit(1)
depotPaths = args
- if not self.cloneDestination and len(depotPaths) > 1:
- self.cloneDestination = depotPaths[-1]
- depotPaths = depotPaths[:-1]
+ if gitConfig("git-p4.useclientspec") == "true":
+ if not os.path.exists("P4ENV"):
+ sys.stderr.write("Must copy P4ENV file from a valid client\n")
+ sys.exit(1)
+ self.getClientSpec()
+ if not depotPaths:
+ depotPaths = [p[0] for p in self.clientSpecDirs]
+ else:
+ if not depotPaths:
+ sys.stderr.write("Must specify depot path if no client spec\n")
+ sys.exit(1)
+
+ if not self.cloneDestination:
+ self.cloneDestination = "."
self.cloneExclude = ["/"+p for p in self.cloneExclude]
for p in depotPaths:
--
1.6.0.6
next prev parent reply other threads:[~2009-03-17 15:18 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-03-09 14:21 git-p4 workflow suggestions? Sam Hocevar
2009-03-10 7:15 ` Christian Couder
2009-03-10 9:57 ` Sam Hocevar
2009-03-11 7:03 ` Christian Couder
2009-03-11 12:58 ` Pete Wyckoff
2009-03-16 18:01 ` Sam Hocevar
2009-03-17 15:18 ` Pete Wyckoff [this message]
2009-03-20 10:31 ` Sam Hocevar
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20090317151815.GA2451@padd.com \
--to=pw@padd.com \
--cc=git@vger.kernel.org \
--cc=sam@zoy.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).