From 68b28593899d528d4b59e7eb07cc37b85012376a Mon Sep 17 00:00:00 2001 From: Pete Wyckoff Date: Sat, 19 Feb 2011 08:17:55 -0500 Subject: git-p4: fix key error for p4 problem Some p4 failures result in an error, but the info['code'] is not set. These include a bad p4 executable, or a core dump from p4, and other odd internal errors where p4 fails to generate proper marshaled output. Make sure the info key exists before using it to avoid a python traceback. Signed-off-by: Pete Wyckoff Signed-off-by: Junio C Hamano --- contrib/fast-import/git-p4 | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'contrib') diff --git a/contrib/fast-import/git-p4 b/contrib/fast-import/git-p4 index 04ce7e3b0..2fefea4de 100755 --- a/contrib/fast-import/git-p4 +++ b/contrib/fast-import/git-p4 @@ -1440,10 +1440,13 @@ class P4Sync(Command): % (p, revision) for p in self.depotPaths])): - if info['code'] == 'error': + if 'code' in info and info['code'] == 'error': sys.stderr.write("p4 returned an error: %s\n" % info['data']) sys.exit(1) + if 'p4ExitCode' in info: + sys.stderr.write("p4 exitcode: %s\n" % info['p4ExitCode']) + sys.exit(1) change = int(info["change"]) -- cgit v1.2.1 From 1494fcbb75299eb16cfb9817aea591f3f2dcdfed Mon Sep 17 00:00:00 2001 From: Pete Wyckoff Date: Sat, 19 Feb 2011 08:17:56 -0500 Subject: git-p4: add missing newline in initial import message Signed-off-by: Pete Wyckoff Acked-By: Tor Arvid Lund Signed-off-by: Junio C Hamano --- contrib/fast-import/git-p4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'contrib') diff --git a/contrib/fast-import/git-p4 b/contrib/fast-import/git-p4 index 2fefea4de..d2ba21568 100755 --- a/contrib/fast-import/git-p4 +++ b/contrib/fast-import/git-p4 @@ -1429,7 +1429,7 @@ class P4Sync(Command): print "Doing initial import of %s from revision %s into %s" % (' '.join(self.depotPaths), revision, self.branch) details = { "user" : "git perforce import user", "time" : int(time.time()) } - details["desc"] = ("Initial import of %s from the state at revision %s" + details["desc"] = ("Initial import of %s from the state at revision %s\n" % (' '.join(self.depotPaths), revision)) details["change"] = revision newestRevision = 0 -- cgit v1.2.1 From 56c093451c7b2b485b194943ea071aca4e74733d Mon Sep 17 00:00:00 2001 From: Pete Wyckoff Date: Sat, 19 Feb 2011 08:17:57 -0500 Subject: git-p4: accommodate new move/delete type in p4 562d53f (git-p4: Fix sync errors due to new server version, 2010-01-21) taught git-p4 sync to recognize the new move/delete type, but this type can also show up in an initial clone and labels output. Instead of replicating the support in three places, hoist the definition somewhere global. Signed-off-by: Pete Wyckoff Acked-By: Tor Arvid Lund Signed-off-by: Junio C Hamano --- contrib/fast-import/git-p4 | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'contrib') diff --git a/contrib/fast-import/git-p4 b/contrib/fast-import/git-p4 index d2ba21568..db19b1778 100755 --- a/contrib/fast-import/git-p4 +++ b/contrib/fast-import/git-p4 @@ -834,6 +834,8 @@ class P4Submit(Command): return True class P4Sync(Command): + delete_actions = ( "delete", "move/delete", "purge" ) + def __init__(self): Command.__init__(self) self.options = [ @@ -1038,10 +1040,10 @@ class P4Sync(Command): if includeFile: filesForCommit.append(f) - if f['action'] not in ('delete', 'move/delete', 'purge'): - filesToRead.append(f) - else: + if f['action'] in self.delete_actions: filesToDelete.append(f) + else: + filesToRead.append(f) # deleted files... for f in filesToDelete: @@ -1127,7 +1129,7 @@ class P4Sync(Command): cleanedFiles = {} for info in files: - if info["action"] in ("delete", "purge"): + if info["action"] in self.delete_actions: continue cleanedFiles[info["depotFile"]] = info["rev"] @@ -1453,7 +1455,7 @@ class P4Sync(Command): if change > newestRevision: newestRevision = change - if info["action"] in ("delete", "purge"): + if info["action"] in self.delete_actions: # don't increase the file cnt, otherwise details["depotFile123"] will have gaps! #fileCnt = fileCnt + 1 continue -- cgit v1.2.1 From d88e707f17ddcf3f789ec7fb1eb33121cecdcd67 Mon Sep 17 00:00:00 2001 From: Pete Wyckoff Date: Sat, 19 Feb 2011 08:17:58 -0500 Subject: git-p4: reinterpret confusing p4 message Error output will look like this: glom$ git p4 clone //deopt Importing from //deopt into . Reinitialized existing Git repository in /tmp/x/.git/ Doing initial import of //deopt from revision #head into refs/remotes/p4/master p4 returned an error: //deopt/... - must refer to client glom. This particular p4 error is misleading. Perhaps the depot path was misspelled. Depot path: //deopt Signed-off-by: Pete Wyckoff Signed-off-by: Junio C Hamano --- contrib/fast-import/git-p4 | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'contrib') diff --git a/contrib/fast-import/git-p4 b/contrib/fast-import/git-p4 index db19b1778..6b847c4cb 100755 --- a/contrib/fast-import/git-p4 +++ b/contrib/fast-import/git-p4 @@ -1445,6 +1445,10 @@ class P4Sync(Command): if 'code' in info and info['code'] == 'error': sys.stderr.write("p4 returned an error: %s\n" % info['data']) + if info['data'].find("must refer to client") >= 0: + sys.stderr.write("This particular p4 error is misleading.\n") + sys.stderr.write("Perhaps the depot path was misspelled.\n"); + sys.stderr.write("Depot path: %s\n" % " ".join(self.depotPaths)) sys.exit(1) if 'p4ExitCode' in info: sys.stderr.write("p4 exitcode: %s\n" % info['p4ExitCode']) -- cgit v1.2.1 From e32e00dc88948a730b8b1f3b8129f30c313713e7 Mon Sep 17 00:00:00 2001 From: Pete Wyckoff Date: Sat, 19 Feb 2011 08:17:59 -0500 Subject: git-p4: better message for "git-p4 sync" when not cloned A common error is to do "git-p4 sync" in a repository that was not initialized by "git-p4 clone". There will be no p4 refs. The error message in this case is a traceback for an assertion, which is confusing. Change it instead to explain the likely problem. Signed-off-by: Pete Wyckoff Acked-By: Tor Arvid Lund Signed-off-by: Junio C Hamano --- contrib/fast-import/git-p4 | 2 ++ 1 file changed, 2 insertions(+) (limited to 'contrib') diff --git a/contrib/fast-import/git-p4 b/contrib/fast-import/git-p4 index 6b847c4cb..04e6c3dcb 100755 --- a/contrib/fast-import/git-p4 +++ b/contrib/fast-import/git-p4 @@ -1676,6 +1676,8 @@ class P4Sync(Command): changes.sort() else: + if not self.p4BranchesInGit: + die("No remote p4 branches. Perhaps you never did \"git p4 clone\" in here."); if self.verbose: print "Getting p4 changes for %s...%s" % (', '.join(self.depotPaths), self.changeRange) -- cgit v1.2.1 From 084f6306d4b7b27a5d12236e808604220b8b3e3f Mon Sep 17 00:00:00 2001 From: Pete Wyckoff Date: Sat, 19 Feb 2011 08:18:00 -0500 Subject: git-p4: decode p4 wildcard characters There are four wildcard characters in p4. Files with these characters can be added to p4 repos using the "-f" option. They are stored in %xx notation, and when checked out, p4 converts them back to normal. This patch does the same thing when importing into git, converting the four special characters. Without this change, the files appear with literal %xx in their names. Be careful not to produce "*" in filenames on windows. That will fail. Signed-off-by: Pete Wyckoff Signed-off-by: Junio C Hamano --- contrib/fast-import/git-p4 | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'contrib') diff --git a/contrib/fast-import/git-p4 b/contrib/fast-import/git-p4 index 04e6c3dcb..98597d372 100755 --- a/contrib/fast-import/git-p4 +++ b/contrib/fast-import/git-p4 @@ -884,6 +884,23 @@ class P4Sync(Command): if gitConfig("git-p4.syncFromOrigin") == "false": self.syncWithOrigin = False + # + # P4 wildcards are not allowed in filenames. P4 complains + # if you simply add them, but you can force it with "-f", in + # which case it translates them into %xx encoding internally. + # Search for and fix just these four characters. Do % last so + # that fixing it does not inadvertently create new %-escapes. + # + def wildcard_decode(self, path): + # Cannot have * in a filename in windows; untested as to + # what p4 would do in such a case. + if not self.isWindows: + path = path.replace("%2A", "*") + path = path.replace("%23", "#") \ + .replace("%40", "@") \ + .replace("%25", "%") + return path + def extractFilesFromCommit(self, commit): self.cloneExclude = [re.sub(r"\.\.\.$", "", path) for path in self.cloneExclude] @@ -962,6 +979,7 @@ class P4Sync(Command): return relPath = self.stripRepoPath(file['depotFile'], self.branchPrefixes) + relPath = self.wildcard_decode(relPath) if verbose: sys.stderr.write("%s\n" % relPath) -- cgit v1.2.1 From 382000769477ed0666e99d01c21df64df9ba0911 Mon Sep 17 00:00:00 2001 From: Pete Wyckoff Date: Sat, 19 Feb 2011 08:18:01 -0500 Subject: git-p4: support clone --bare Just like git clone --bare, build a .git directory but no checked out files. Signed-off-by: Pete Wyckoff Acked-By: Tor Arvid Lund Signed-off-by: Junio C Hamano --- contrib/fast-import/git-p4 | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'contrib') diff --git a/contrib/fast-import/git-p4 b/contrib/fast-import/git-p4 index 98597d372..725af7599 100755 --- a/contrib/fast-import/git-p4 +++ b/contrib/fast-import/git-p4 @@ -1776,10 +1776,13 @@ class P4Clone(P4Sync): help="where to leave result of the clone"), optparse.make_option("-/", dest="cloneExclude", action="append", type="string", - help="exclude depot path") + help="exclude depot path"), + optparse.make_option("--bare", dest="cloneBare", + action="store_true", default=False), ] self.cloneDestination = None self.needsGit = False + self.cloneBare = False # This is required for the "append" cloneExclude action def ensure_value(self, attr, value): @@ -1819,11 +1822,16 @@ class P4Clone(P4Sync): self.cloneDestination = self.defaultDestination(args) print "Importing from %s into %s" % (', '.join(depotPaths), self.cloneDestination) + if not os.path.exists(self.cloneDestination): os.makedirs(self.cloneDestination) chdir(self.cloneDestination) - system("git init") - self.gitdir = os.getcwd() + "/.git" + + init_cmd = [ "git", "init" ] + if self.cloneBare: + init_cmd.append("--bare") + subprocess.check_call(init_cmd) + if not P4Sync.run(self, depotPaths): return False if self.branch != "master": @@ -1833,7 +1841,8 @@ class P4Clone(P4Sync): masterbranch = "refs/heads/p4/master" if gitBranchExists(masterbranch): system("git branch master %s" % masterbranch) - system("git checkout -f") + if not self.cloneBare: + system("git checkout -f") else: print "Could not detect main branch. No checkout/master branch created." -- cgit v1.2.1