{"thread":{"id":"26423","subject":"[PATCH 0/8] git-p4 fixes and enhancements","startedAt":"2011-02-05T22:48:48Z","lastAt":"2011-02-08T23:26:06Z","messageCount":18,"participants":["Pete Wyckoff","Vitor Antunes","Junio C Hamano","Tor Arvid Lund"],"isPatch":true,"patchVersion":1,"patchTotal":8},"messages":[{"id":"160468","messageId":"20110205224848.GA30963@arf.padd.com","threadId":"26423","inReplyTo":null,"subject":"[PATCH 0/8] git-p4 fixes and enhancements","fromName":"Pete Wyckoff","fromEmail":"pw@padd.com","sentAt":"2011-02-05T22:48:48Z","receivedAt":"2011-02-05T22:48:48Z","isPatch":true,"sender":{"key":"pw@padd.com","avatar":null},"body":"I've collected a fair number of fixes and enhancements\nto git-p4, and finally cleaned them up to send upstream.\n\n      git-p4: test script\n      git-p4: fix key error for p4 problem\n      git-p4: add missing newline in initial import message\n      git-p4: accommodate new move/delete type in p4\n      git-p4: reinterpret confusing p4 message\n      git-p4: better message for \"git-p4 sync\" when not cloned\n      git-p4: decode p4 wildcard characters\n      git-p4: support clone --bare\n\nThe first one is interesting in that it adds a test for\ngit-p4.  I'd appreciate a careful review of this in\nparticular.\n\nThe other seven fix problems and add small features, with\ntest cases where it makes sense.\n\n\t\t-- Pete\n"},{"id":"160469","messageId":"20110205225105.GB30963@arf.padd.com","threadId":"26423","inReplyTo":"20110205224848.GA30963@arf.padd.com","subject":"[PATCH 1/8] git-p4: test script","fromName":"Pete Wyckoff","fromEmail":"pw@padd.com","sentAt":"2011-02-05T22:51:05Z","receivedAt":"2011-02-05T22:51:05Z","isPatch":true,"sender":{"key":"pw@padd.com","avatar":null},"body":"Add a basic test script for git-p4.\n\nSigned-off-by: Pete Wyckoff <pw@padd.com>\n---\n t/t9800-git-p4.sh |   62 +++++++++++++++++++++++++++++++++++++++++++++++++++++\n 1 files changed, 62 insertions(+), 0 deletions(-)\n create mode 100755 t/t9800-git-p4.sh\n\ndiff --git a/t/t9800-git-p4.sh b/t/t9800-git-p4.sh\nnew file mode 100755\nindex 0000000..f4956b7\n--- /dev/null\n+++ b/t/t9800-git-p4.sh\n@@ -0,0 +1,62 @@\n+#!/bin/sh\n+\n+test_description='git-p4 tests'\n+\n+. ./test-lib.sh\n+\n+p4 -h >/dev/null 2>&1\n+retc=$?\n+p4d -h >/dev/null 2>&1\n+retd=$?\n+if test $retc -ne 0 -o $retd -ne 0\n+then\n+\tskip_all='skipping git-p4 tests; no p4 or p4d'\n+\ttest_done\n+fi\n+\n+GITP4=$GIT_BUILD_DIR/contrib/fast-import/git-p4\n+P4DPORT=10669\n+\n+db=\"$TRASH_DIRECTORY/db\"\n+cli=\"$TRASH_DIRECTORY/cli\"\n+git=\"$TRASH_DIRECTORY/git\"\n+\n+test_debug 'echo p4d -q -d -r \"$db\" -p $P4DPORT'\n+test_expect_success setup '\n+\tmkdir -p \"$db\" &&\n+\tp4d -q -d -r \"$db\" -p $P4DPORT &&\n+\t# wait for it to finish its initialization\n+\tsleep 1 &&\n+\tmkdir -p \"$cli\" &&\n+\tmkdir -p \"$git\" &&\n+\texport P4PORT=localhost:$P4DPORT\n+'\n+\n+test_expect_success 'add p4 files' '\n+\tcd \"$cli\" &&\n+\tp4 client -i <<-EOF &&\n+\tClient: client\n+\tDescription: client\n+\tRoot: $cli\n+\tView: //depot/... //client/...\n+\tEOF\n+\texport P4CLIENT=client &&\n+\techo file1 >file1 &&\n+\tp4 add file1 &&\n+\tp4 submit -d \"file1\" &&\n+\tcd \"$TRASH_DIRECTORY\"\n+'\n+\n+test_expect_success 'basic git-p4 clone' '\n+\t\"$GITP4\" clone --dest=\"$git\" //depot &&\n+\trm -rf \"$git\" && mkdir \"$git\"\n+'\n+\n+test_expect_success 'shutdown' '\n+\tpid=`pgrep -f p4d` &&\n+\ttest -n \"$pid\" &&\n+\ttest_debug \"ps wl `echo $pid`\" &&\n+\tkill $pid\n+'\n+\n+test_done\n-- \n1.7.2.3\n"},{"id":"160470","messageId":"20110205225121.GC30963@arf.padd.com","threadId":"26423","inReplyTo":"20110205224848.GA30963@arf.padd.com","subject":"[PATCH 2/8] git-p4: fix key error for p4 problem","fromName":"Pete Wyckoff","fromEmail":"pw@padd.com","sentAt":"2011-02-05T22:51:21Z","receivedAt":"2011-02-05T22:51:21Z","isPatch":true,"sender":{"key":"pw@padd.com","avatar":null},"body":"Some p4 failures result in an error, but the info['code'] is not\nset.  These include a bad p4 executable, or a core dump from p4,\nand other odd internal errors where p4 fails to generate proper\nmarshaled output.\n\nMake sure the info key exists before using it to avoid a python\ntraceback.\n\nSigned-off-by: Pete Wyckoff <pw@padd.com>\n---\n contrib/fast-import/git-p4 |    5 ++++-\n t/t9800-git-p4.sh          |   13 +++++++++++++\n 2 files changed, 17 insertions(+), 1 deletions(-)\n\ndiff --git a/contrib/fast-import/git-p4 b/contrib/fast-import/git-p4\nindex 04ce7e3..2fefea4 100755\n--- a/contrib/fast-import/git-p4\n+++ b/contrib/fast-import/git-p4\n@@ -1440,10 +1440,13 @@ class P4Sync(Command):\n                                            % (p, revision)\n                                            for p in self.depotPaths])):\n \n-            if info['code'] == 'error':\n+            if 'code' in info and info['code'] == 'error':\n                 sys.stderr.write(\"p4 returned an error: %s\\n\"\n                                  % info['data'])\n                 sys.exit(1)\n+            if 'p4ExitCode' in info:\n+                sys.stderr.write(\"p4 exitcode: %s\\n\" % info['p4ExitCode'])\n+                sys.exit(1)\n \n \n             change = int(info[\"change\"])\ndiff --git a/t/t9800-git-p4.sh b/t/t9800-git-p4.sh\nindex f4956b7..41e57bb 100755\n--- a/t/t9800-git-p4.sh\n+++ b/t/t9800-git-p4.sh\n@@ -52,6 +52,19 @@ test_expect_success 'basic git-p4 clone' '\n \trm -rf \"$git\" && mkdir \"$git\"\n '\n \n+test_expect_success 'exit when p4 fails to produce marshaled output' '\n+\tbadp4dir=\"$TRASH_DIRECTORY/badp4dir\" &&\n+\tmkdir -p \"$badp4dir\" &&\n+\tcat >\"$badp4dir\"/p4 <<-EOF &&\n+\t#!$SHELL_PATH\n+\texit 1\n+\tEOF\n+\tchmod 755 \"$badp4dir\"/p4 &&\n+\tPATH=\"$badp4dir:$PATH\" \"$GITP4\" clone --dest=\"$git\" //depot >errs 2>&1 ; retval=$? &&\n+\ttest $retval -eq 1 &&\n+\ttest_must_fail grep -q Traceback errs\n+'\n+\n test_expect_success 'shutdown' '\n \tpid=`pgrep -f p4d` &&\n \ttest -n \"$pid\" &&\n-- \n1.7.2.3\n"},{"id":"160471","messageId":"20110205225155.GD30963@arf.padd.com","threadId":"26423","inReplyTo":"20110205224848.GA30963@arf.padd.com","subject":"[PATCH 3/8] git-p4: add missing newline in initial import message","fromName":"Pete Wyckoff","fromEmail":"pw@padd.com","sentAt":"2011-02-05T22:51:55Z","receivedAt":"2011-02-05T22:51:55Z","isPatch":true,"sender":{"key":"pw@padd.com","avatar":null},"body":"The commit message looks wrong without the newline.\n\nSigned-off-by: Pete Wyckoff <pw@padd.com>\n---\n contrib/fast-import/git-p4 |    2 +-\n 1 files changed, 1 insertions(+), 1 deletions(-)\n\ndiff --git a/contrib/fast-import/git-p4 b/contrib/fast-import/git-p4\nindex 2fefea4..d2ba215 100755\n--- a/contrib/fast-import/git-p4\n+++ b/contrib/fast-import/git-p4\n@@ -1429,7 +1429,7 @@ class P4Sync(Command):\n         print \"Doing initial import of %s from revision %s into %s\" % (' '.join(self.depotPaths), revision, self.branch)\n \n         details = { \"user\" : \"git perforce import user\", \"time\" : int(time.time()) }\n-        details[\"desc\"] = (\"Initial import of %s from the state at revision %s\"\n+        details[\"desc\"] = (\"Initial import of %s from the state at revision %s\\n\"\n                            % (' '.join(self.depotPaths), revision))\n         details[\"change\"] = revision\n         newestRevision = 0\n-- \n1.7.2.3\n"},{"id":"160472","messageId":"20110205225206.GE30963@arf.padd.com","threadId":"26423","inReplyTo":"20110205224848.GA30963@arf.padd.com","subject":"[PATCH 4/8] git-p4: accommodate new move/delete type in p4","fromName":"Pete Wyckoff","fromEmail":"pw@padd.com","sentAt":"2011-02-05T22:52:06Z","receivedAt":"2011-02-05T22:52:06Z","isPatch":true,"sender":{"key":"pw@padd.com","avatar":null},"body":"Change 562d53f (2010-11-21) recognized the new move/delete type\nfor git-p4 sync, but it can also show up in an initial clone and\nlabels output.  Instead of replicating this in three places,\nhoist the definition somewhere global.\n\nSigned-off-by: Pete Wyckoff <pw@padd.com>\n---\n contrib/fast-import/git-p4 |   12 +++++++-----\n 1 files changed, 7 insertions(+), 5 deletions(-)\n\ndiff --git a/contrib/fast-import/git-p4 b/contrib/fast-import/git-p4\nindex d2ba215..db19b17 100755\n--- a/contrib/fast-import/git-p4\n+++ b/contrib/fast-import/git-p4\n@@ -834,6 +834,8 @@ class P4Submit(Command):\n         return True\n \n class P4Sync(Command):\n+    delete_actions = ( \"delete\", \"move/delete\", \"purge\" )\n+\n     def __init__(self):\n         Command.__init__(self)\n         self.options = [\n@@ -1038,10 +1040,10 @@ class P4Sync(Command):\n \n             if includeFile:\n                 filesForCommit.append(f)\n-                if f['action'] not in ('delete', 'move/delete', 'purge'):\n-                    filesToRead.append(f)\n-                else:\n+                if f['action'] in self.delete_actions:\n                     filesToDelete.append(f)\n+                else:\n+                    filesToRead.append(f)\n \n         # deleted files...\n         for f in filesToDelete:\n@@ -1127,7 +1129,7 @@ class P4Sync(Command):\n \n                 cleanedFiles = {}\n                 for info in files:\n-                    if info[\"action\"] in (\"delete\", \"purge\"):\n+                    if info[\"action\"] in self.delete_actions:\n                         continue\n                     cleanedFiles[info[\"depotFile\"]] = info[\"rev\"]\n \n@@ -1453,7 +1455,7 @@ class P4Sync(Command):\n             if change > newestRevision:\n                 newestRevision = change\n \n-            if info[\"action\"] in (\"delete\", \"purge\"):\n+            if info[\"action\"] in self.delete_actions:\n                 # don't increase the file cnt, otherwise details[\"depotFile123\"] will have gaps!\n                 #fileCnt = fileCnt + 1\n                 continue\n-- \n1.7.2.3\n"},{"id":"160473","messageId":"20110205225214.GF30963@arf.padd.com","threadId":"26423","inReplyTo":"20110205224848.GA30963@arf.padd.com","subject":"[PATCH 5/8] git-p4: reinterpret confusing p4 message","fromName":"Pete Wyckoff","fromEmail":"pw@padd.com","sentAt":"2011-02-05T22:52:14Z","receivedAt":"2011-02-05T22:52:14Z","isPatch":true,"sender":{"key":"pw@padd.com","avatar":null},"body":"Error output will look like this:\n\nglom$ git p4 clone //deopt\nImporting from //deopt into .\nReinitialized existing Git repository in /tmp/x/.git/\nDoing initial import of //deopt from revision #head into refs/remotes/p4/master\np4 returned an error: //deopt/... - must refer to client glom.\n\nThis particular p4 error is misleading.\nPerhaps the depot path was misspelled.\nDepot path:  //deopt\n\nSigned-off-by: Pete Wyckoff <pw@padd.com>\n---\n contrib/fast-import/git-p4 |    4 ++++\n 1 files changed, 4 insertions(+), 0 deletions(-)\n\ndiff --git a/contrib/fast-import/git-p4 b/contrib/fast-import/git-p4\nindex db19b17..6b847c4 100755\n--- a/contrib/fast-import/git-p4\n+++ b/contrib/fast-import/git-p4\n@@ -1445,6 +1445,10 @@ class P4Sync(Command):\n             if 'code' in info and info['code'] == 'error':\n                 sys.stderr.write(\"p4 returned an error: %s\\n\"\n                                  % info['data'])\n+                if info['data'].find(\"must refer to client\") >= 0:\n+                    sys.stderr.write(\"This particular p4 error is misleading.\\n\")\n+                    sys.stderr.write(\"Perhaps the depot path was misspelled.\\n\");\n+                    sys.stderr.write(\"Depot path:  %s\\n\" % \" \".join(self.depotPaths))\n                 sys.exit(1)\n             if 'p4ExitCode' in info:\n                 sys.stderr.write(\"p4 exitcode: %s\\n\" % info['p4ExitCode'])\n-- \n1.7.2.3\n"},{"id":"160474","messageId":"20110205225224.GG30963@arf.padd.com","threadId":"26423","inReplyTo":"20110205224848.GA30963@arf.padd.com","subject":"[PATCH 6/8] git-p4: better message for \"git-p4 sync\" when not cloned","fromName":"Pete Wyckoff","fromEmail":"pw@padd.com","sentAt":"2011-02-05T22:52:24Z","receivedAt":"2011-02-05T22:52:24Z","isPatch":true,"sender":{"key":"pw@padd.com","avatar":null},"body":"A common error is to do \"git-p4 sync\" in a repository that\nwas not initialized by \"git-p4 clone\".  There will be no\np4 refs.  The error message in this case is a traceback\nfor an assertion, which is confusing.\n\nChange it instead to explain the likely problem.\n\nSigned-off-by: Pete Wyckoff <pw@padd.com>\n---\n contrib/fast-import/git-p4 |    2 ++\n 1 files changed, 2 insertions(+), 0 deletions(-)\n\ndiff --git a/contrib/fast-import/git-p4 b/contrib/fast-import/git-p4\nindex 6b847c4..04e6c3d 100755\n--- a/contrib/fast-import/git-p4\n+++ b/contrib/fast-import/git-p4\n@@ -1676,6 +1676,8 @@ class P4Sync(Command):\n \n                 changes.sort()\n             else:\n+                if not self.p4BranchesInGit:\n+                    die(\"No remote p4 branches.  Perhaps you never did \\\"git p4 clone\\\" in here.\");\n                 if self.verbose:\n                     print \"Getting p4 changes for %s...%s\" % (', '.join(self.depotPaths),\n                                                               self.changeRange)\n-- \n1.7.2.3\n"},{"id":"160475","messageId":"20110205225237.GH30963@arf.padd.com","threadId":"26423","inReplyTo":"20110205224848.GA30963@arf.padd.com","subject":"[PATCH 7/8] git-p4: decode p4 wildcard characters","fromName":"Pete Wyckoff","fromEmail":"pw@padd.com","sentAt":"2011-02-05T22:52:37Z","receivedAt":"2011-02-05T22:52:37Z","isPatch":true,"sender":{"key":"pw@padd.com","avatar":null},"body":"There are four wildcard characters in p4.  Files with these\ncharacters can be added to p4 repos using the \"-f\" option.\nThey are stored in %xx notation, and when checked out, p4\nconverts them back to normal.\n\nThis patch does the same thing when importing into git,\nconverting the four special characters.  Without this change,\nthe files appear with literal %xx in their names.\n\nSigned-off-by: Pete Wyckoff <pw@padd.com>\n---\n contrib/fast-import/git-p4 |   13 +++++++++++++\n t/t9800-git-p4.sh          |   22 ++++++++++++++++++++++\n 2 files changed, 35 insertions(+), 0 deletions(-)\n\ndiff --git a/contrib/fast-import/git-p4 b/contrib/fast-import/git-p4\nindex 04e6c3d..5b08cd6 100755\n--- a/contrib/fast-import/git-p4\n+++ b/contrib/fast-import/git-p4\n@@ -884,6 +884,18 @@ class P4Sync(Command):\n         if gitConfig(\"git-p4.syncFromOrigin\") == \"false\":\n             self.syncWithOrigin = False\n \n+    # The p4 wildcards are not allowed in filenames.  It complains\n+    # if you try to add them, but you can override with \"-f\", in\n+    # which case it translates them into %xx encoding.  Search for\n+    # and fix just these four characters.  Do % last so it does\n+    # not inadvertantly create new %-escapes.\n+    def wildcard_decode(self, path):\n+        path = path.replace(\"%23\", \"#\") \\\n+                   .replace(\"%2A\", \"*\") \\\n+                   .replace(\"%40\", \"@\") \\\n+                   .replace(\"%25\", \"%\")\n+        return path\n+\n     def extractFilesFromCommit(self, commit):\n         self.cloneExclude = [re.sub(r\"\\.\\.\\.$\", \"\", path)\n                              for path in self.cloneExclude]\n@@ -962,6 +974,7 @@ class P4Sync(Command):\n \t    return\n \n         relPath = self.stripRepoPath(file['depotFile'], self.branchPrefixes)\n+        relPath = self.wildcard_decode(relPath)\n         if verbose:\n             sys.stderr.write(\"%s\\n\" % relPath)\n \ndiff --git a/t/t9800-git-p4.sh b/t/t9800-git-p4.sh\nindex 41e57bb..72c38af 100755\n--- a/t/t9800-git-p4.sh\n+++ b/t/t9800-git-p4.sh\n@@ -65,6 +65,28 @@ test_expect_success 'exit when p4 fails to produce marshaled output' '\n \ttest_must_fail grep -q Traceback errs\n '\n \n+test_expect_success 'add p4 files with wildcards in the names' '\n+\tcd \"$cli\" &&\n+\techo file-wild-hash >file-wild#hash &&\n+\techo file-wild-star >file-wild\\*star &&\n+\techo file-wild-at >file-wild@at &&\n+\techo file-wild-percent >file-wild%percent &&\n+\tp4 add -f file-wild* &&\n+\tp4 submit -d \"file wildcards\" &&\n+\tcd \"$TRASH_DIRECTORY\"\n+'\n+\n+test_expect_success 'wildcard files git-p4 clone' '\n+\t\"$GITP4\" clone --dest=\"$git\" //depot &&\n+\tcd \"$git\" &&\n+\ttest -f file-wild#hash &&\n+\ttest -f file-wild\\*star &&\n+\ttest -f file-wild@at &&\n+\ttest -f file-wild%percent &&\n+\tcd \"$TRASH_DIRECTORY\" &&\n+\trm -rf \"$git\" && mkdir \"$git\"\n+'\n+\n test_expect_success 'shutdown' '\n \tpid=`pgrep -f p4d` &&\n \ttest -n \"$pid\" &&\n-- \n1.7.2.3\n"},{"id":"160476","messageId":"20110205225247.GI30963@arf.padd.com","threadId":"26423","inReplyTo":"20110205224848.GA30963@arf.padd.com","subject":"[PATCH 8/8] git-p4: support clone --bare","fromName":"Pete Wyckoff","fromEmail":"pw@padd.com","sentAt":"2011-02-05T22:52:47Z","receivedAt":"2011-02-05T22:52:47Z","isPatch":true,"sender":{"key":"pw@padd.com","avatar":null},"body":"Just like git clone --bare, build a .git directory but no\nchecked out files.\n\nSigned-off-by: Pete Wyckoff <pw@padd.com>\n---\n contrib/fast-import/git-p4 |   17 +++++++++++++----\n t/t9800-git-p4.sh          |   10 ++++++++++\n 2 files changed, 23 insertions(+), 4 deletions(-)\n\ndiff --git a/contrib/fast-import/git-p4 b/contrib/fast-import/git-p4\nindex 5b08cd6..efc5dce 100755\n--- a/contrib/fast-import/git-p4\n+++ b/contrib/fast-import/git-p4\n@@ -1771,10 +1771,13 @@ class P4Clone(P4Sync):\n                                  help=\"where to leave result of the clone\"),\n             optparse.make_option(\"-/\", dest=\"cloneExclude\",\n                                  action=\"append\", type=\"string\",\n-                                 help=\"exclude depot path\")\n+                                 help=\"exclude depot path\"),\n+            optparse.make_option(\"--bare\", dest=\"cloneBare\",\n+                                 action=\"store_true\", default=False),\n         ]\n         self.cloneDestination = None\n         self.needsGit = False\n+        self.cloneBare = False\n \n     # This is required for the \"append\" cloneExclude action\n     def ensure_value(self, attr, value):\n@@ -1814,11 +1817,16 @@ class P4Clone(P4Sync):\n             self.cloneDestination = self.defaultDestination(args)\n \n         print \"Importing from %s into %s\" % (', '.join(depotPaths), self.cloneDestination)\n+\n         if not os.path.exists(self.cloneDestination):\n             os.makedirs(self.cloneDestination)\n         chdir(self.cloneDestination)\n-        system(\"git init\")\n-        self.gitdir = os.getcwd() + \"/.git\"\n+\n+        init_cmd = [ \"git\", \"init\" ]\n+        if self.cloneBare:\n+            init_cmd.append(\"--bare\")\n+        subprocess.check_call(init_cmd)\n+\n         if not P4Sync.run(self, depotPaths):\n             return False\n         if self.branch != \"master\":\n@@ -1828,7 +1836,8 @@ class P4Clone(P4Sync):\n                 masterbranch = \"refs/heads/p4/master\"\n             if gitBranchExists(masterbranch):\n                 system(\"git branch master %s\" % masterbranch)\n-                system(\"git checkout -f\")\n+                if not self.cloneBare:\n+                    system(\"git checkout -f\")\n             else:\n                 print \"Could not detect main branch. No checkout/master branch created.\"\n \ndiff --git a/t/t9800-git-p4.sh b/t/t9800-git-p4.sh\nindex 72c38af..1e7639b 100755\n--- a/t/t9800-git-p4.sh\n+++ b/t/t9800-git-p4.sh\n@@ -87,6 +87,16 @@ test_expect_success 'wildcard files git-p4 clone' '\n \trm -rf \"$git\" && mkdir \"$git\"\n '\n \n+test_expect_success 'clone bare' '\n+\t\"$GITP4\" clone --dest=\"$git\" --bare //depot &&\n+\tcd \"$git\" &&\n+\ttest ! -d .git &&\n+\tbare=`git config --get core.bare` &&\n+\ttest \"$bare\" = true &&\n+\tcd \"$TRASH_DIRECTORY\" &&\n+\trm -rf \"$git\" && mkdir \"$git\"\n+'\n+\n test_expect_success 'shutdown' '\n \tpid=`pgrep -f p4d` &&\n \ttest -n \"$pid\" &&\n-- \n1.7.2.3\n"},{"id":"160506","messageId":"loom.20110206T185849-616@post.gmane.org","threadId":"26423","inReplyTo":"20110205225105.GB30963@arf.padd.com","subject":"Re: [PATCH 1/8] git-p4: test script","fromName":"Vitor Antunes","fromEmail":"vitor.hda@gmail.com","sentAt":"2011-02-06T18:00:25Z","receivedAt":"2011-02-06T18:00:25Z","isPatch":true,"sender":{"key":"vitor.hda@gmail.com","avatar":"https://avatars.githubusercontent.com/u/606876?v=4"},"body":"Hi Pete,\n\nKudos on this patch! I'm looking forward in having it accepted, so that I can\ncreate some test cases for my latest patches ;)\n\nThanks,\nVitor Antunes\n"},{"id":"160569","messageId":"7v1v3kwpm9.fsf@alter.siamese.dyndns.org","threadId":"26423","inReplyTo":"20110205225105.GB30963@arf.padd.com","subject":"Re: [PATCH 1/8] git-p4: test script","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-02-07T02:22:06Z","receivedAt":"2011-02-07T02:22:06Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Pete Wyckoff <pw@padd.com> writes:\n\n> Add a basic test script for git-p4.\n>\n> Signed-off-by: Pete Wyckoff <pw@padd.com>\n> ---\n>  t/t9800-git-p4.sh |   62 +++++++++++++++++++++++++++++++++++++++++++++++++++++\n>  1 files changed, 62 insertions(+), 0 deletions(-)\n>  create mode 100755 t/t9800-git-p4.sh\n>\n> diff --git a/t/t9800-git-p4.sh b/t/t9800-git-p4.sh\n> new file mode 100755\n> index 0000000..f4956b7\n> --- /dev/null\n> +++ b/t/t9800-git-p4.sh\n> @@ -0,0 +1,62 @@\n> +#!/bin/sh\n> +\n> +test_description='git-p4 tests'\n> +\n> +. ./test-lib.sh\n> +\n> +p4 -h >/dev/null 2>&1\n> +retc=$?\n> +p4d -h >/dev/null 2>&1\n> +retd=$?\n> +if test $retc -ne 0 -o $retd -ne 0\n> +then\n\nUse of two global variables with short names makes me feel \"yeek!\".\n\n\t(p4 -h && p4d -h) >/dev/null 2>/dev/null ||\n\t{\n\t\t...\n                test_done\n\t}\n\n> +GITP4=$GIT_BUILD_DIR/contrib/fast-import/git-p4\n> +P4DPORT=10669\n> +\n> +db=\"$TRASH_DIRECTORY/db\"\n> +cli=\"$TRASH_DIRECTORY/cli\"\n> +git=\"$TRASH_DIRECTORY/git\"\n> +\n> +test_debug 'echo p4d -q -d -r \"$db\" -p $P4DPORT'\n> +test_expect_success setup '\n> +\tmkdir -p \"$db\" &&\n> +\tp4d -q -d -r \"$db\" -p $P4DPORT &&\n> +\t# wait for it to finish its initialization\n> +\tsleep 1 &&\n\nIs there a guarantee that \"1\" is sufficiently long for everybody?\n\nOtherwise this will be a flaky test that sometimes passes and sometimes\ndoesn't, which we try to avoid.\n\nIf the answer is \"empirically 1 second is sufficient for 99.9% of people\",\nthen I would have to guess that it is 0.8 second too long for majority of\npeople, in which case I would like to see us try harder to make it both\nreliable and efficient.\n\nIsn't there a \"noop\" command a client can issue against a working server\nthat fails when the server is not ready (or waits until the server becomes\nready)?\n"},{"id":"160653","messageId":"20110207222623.GB19851@arf.padd.com","threadId":"26423","inReplyTo":"7v1v3kwpm9.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH 1/8] git-p4: test script","fromName":"Pete Wyckoff","fromEmail":"pw@padd.com","sentAt":"2011-02-07T22:26:23Z","receivedAt":"2011-02-07T22:26:23Z","isPatch":true,"sender":{"key":"pw@padd.com","avatar":null},"body":"gitster@pobox.com wrote on Sun, 06 Feb 2011 18:22 -0800:\n> Pete Wyckoff <pw@padd.com> writes:\n[..]\n> Use of two global variables with short names makes me feel \"yeek!\".\n> \n> \t(p4 -h && p4d -h) >/dev/null 2>/dev/null ||\n> \t{\n> \t\t...\n>                 test_done\n> \t}\n\nMuch nicer.  Thanks.\n\n> > +\tp4d -q -d -r \"$db\" -p $P4DPORT &&\n> > +\t# wait for it to finish its initialization\n> > +\tsleep 1 &&\n> \n> Is there a guarantee that \"1\" is sufficiently long for everybody?\n> \n> Otherwise this will be a flaky test that sometimes passes and sometimes\n> doesn't, which we try to avoid.\n> \n> If the answer is \"empirically 1 second is sufficient for 99.9% of people\",\n> then I would have to guess that it is 0.8 second too long for majority of\n> people, in which case I would like to see us try harder to make it both\n> reliable and efficient.\n> \n> Isn't there a \"noop\" command a client can issue against a working server\n> that fails when the server is not ready (or waits until the server becomes\n> ready)?\n\nThere is a noop (\"p4 info\") that I can use to test.  But turns\nout I was wrong in even needing to sleep or wait for the \"info\"\ntest to complete.  In trying to get it to race, I found that p4d\nis well-behaved.  Strace confirms that it does bind/listen before\ndaemonizing.  So that sleep can be removed.\n\nI'll wait a while in case other comments come in, then send the\nupdated series to you.\n\n\t\t-- Pete\n"},{"id":"160683","messageId":"AANLkTikAqDNwGbFfZ=kNyJ4rxdTmesaOmtPYmM3bLf_6@mail.gmail.com","threadId":"26423","inReplyTo":"20110205225155.GD30963@arf.padd.com","subject":"Re: [PATCH 3/8] git-p4: add missing newline in initial import message","fromName":"Tor Arvid Lund","fromEmail":"torarvid@gmail.com","sentAt":"2011-02-08T08:48:50Z","receivedAt":"2011-02-08T08:48:50Z","isPatch":true,"sender":{"key":"torarvid@gmail.com","avatar":"https://avatars.githubusercontent.com/u/439758?v=4"},"body":"On Sat, Feb 5, 2011 at 11:51 PM, Pete Wyckoff <pw@padd.com> wrote:\n> The commit message looks wrong without the newline.\n>\n> Signed-off-by: Pete Wyckoff <pw@padd.com>\n\nAcked-By: Tor Arvid Lund <torarvid@gmail.com>\n\n> ---\n>  contrib/fast-import/git-p4 |    2 +-\n>  1 files changed, 1 insertions(+), 1 deletions(-)\n>\n> diff --git a/contrib/fast-import/git-p4 b/contrib/fast-import/git-p4\n> index 2fefea4..d2ba215 100755\n> --- a/contrib/fast-import/git-p4\n> +++ b/contrib/fast-import/git-p4\n> @@ -1429,7 +1429,7 @@ class P4Sync(Command):\n>         print \"Doing initial import of %s from revision %s into %s\" % (' '.join(self.depotPaths), revision, self.branch)\n>\n>         details = { \"user\" : \"git perforce import user\", \"time\" : int(time.time()) }\n> -        details[\"desc\"] = (\"Initial import of %s from the state at revision %s\"\n> +        details[\"desc\"] = (\"Initial import of %s from the state at revision %s\\n\"\n>                            % (' '.join(self.depotPaths), revision))\n>         details[\"change\"] = revision\n>         newestRevision = 0\n> --\n> 1.7.2.3\n>\n> --\n> To unsubscribe from this list: send the line \"unsubscribe git\" in\n> the body of a message to majordomo@vger.kernel.org\n> More majordomo info at  http://vger.kernel.org/majordomo-info.html\n>\n"},{"id":"160684","messageId":"AANLkTimr3uZQZGo_POvFc_GMj_h0uRXpv8V9vSEydXPB@mail.gmail.com","threadId":"26423","inReplyTo":"20110205225206.GE30963@arf.padd.com","subject":"Re: [PATCH 4/8] git-p4: accommodate new move/delete type in p4","fromName":"Tor Arvid Lund","fromEmail":"torarvid@gmail.com","sentAt":"2011-02-08T08:52:49Z","receivedAt":"2011-02-08T08:52:49Z","isPatch":true,"sender":{"key":"torarvid@gmail.com","avatar":"https://avatars.githubusercontent.com/u/439758?v=4"},"body":"On Sat, Feb 5, 2011 at 11:52 PM, Pete Wyckoff <pw@padd.com> wrote:\n> Change 562d53f (2010-11-21) recognized the new move/delete type\n> for git-p4 sync, but it can also show up in an initial clone and\n> labels output.  Instead of replicating this in three places,\n> hoist the definition somewhere global.\n>\n> Signed-off-by: Pete Wyckoff <pw@padd.com>\n\nAcked-By: Tor Arvid Lund <torarvid@gmail.com>\n\n> ---\n>  contrib/fast-import/git-p4 |   12 +++++++-----\n>  1 files changed, 7 insertions(+), 5 deletions(-)\n>\n> diff --git a/contrib/fast-import/git-p4 b/contrib/fast-import/git-p4\n> index d2ba215..db19b17 100755\n> --- a/contrib/fast-import/git-p4\n> +++ b/contrib/fast-import/git-p4\n> @@ -834,6 +834,8 @@ class P4Submit(Command):\n>         return True\n>\n>  class P4Sync(Command):\n> +    delete_actions = ( \"delete\", \"move/delete\", \"purge\" )\n> +\n>     def __init__(self):\n>         Command.__init__(self)\n>         self.options = [\n> @@ -1038,10 +1040,10 @@ class P4Sync(Command):\n>\n>             if includeFile:\n>                 filesForCommit.append(f)\n> -                if f['action'] not in ('delete', 'move/delete', 'purge'):\n> -                    filesToRead.append(f)\n> -                else:\n> +                if f['action'] in self.delete_actions:\n>                     filesToDelete.append(f)\n> +                else:\n> +                    filesToRead.append(f)\n>\n>         # deleted files...\n>         for f in filesToDelete:\n> @@ -1127,7 +1129,7 @@ class P4Sync(Command):\n>\n>                 cleanedFiles = {}\n>                 for info in files:\n> -                    if info[\"action\"] in (\"delete\", \"purge\"):\n> +                    if info[\"action\"] in self.delete_actions:\n>                         continue\n>                     cleanedFiles[info[\"depotFile\"]] = info[\"rev\"]\n>\n> @@ -1453,7 +1455,7 @@ class P4Sync(Command):\n>             if change > newestRevision:\n>                 newestRevision = change\n>\n> -            if info[\"action\"] in (\"delete\", \"purge\"):\n> +            if info[\"action\"] in self.delete_actions:\n>                 # don't increase the file cnt, otherwise details[\"depotFile123\"] will have gaps!\n>                 #fileCnt = fileCnt + 1\n>                 continue\n> --\n> 1.7.2.3\n>\n> --\n> To unsubscribe from this list: send the line \"unsubscribe git\" in\n> the body of a message to majordomo@vger.kernel.org\n> More majordomo info at  http://vger.kernel.org/majordomo-info.html\n>\n"},{"id":"160685","messageId":"AANLkTi=m9JM=L2E0pjZQr6ycrPnprA4ptTVQD+LYbX5S@mail.gmail.com","threadId":"26423","inReplyTo":"20110205225224.GG30963@arf.padd.com","subject":"Re: [PATCH 6/8] git-p4: better message for \"git-p4 sync\" when not cloned","fromName":"Tor Arvid Lund","fromEmail":"torarvid@gmail.com","sentAt":"2011-02-08T08:55:26Z","receivedAt":"2011-02-08T08:55:26Z","isPatch":true,"sender":{"key":"torarvid@gmail.com","avatar":"https://avatars.githubusercontent.com/u/439758?v=4"},"body":"On Sat, Feb 5, 2011 at 11:52 PM, Pete Wyckoff <pw@padd.com> wrote:\n> A common error is to do \"git-p4 sync\" in a repository that\n> was not initialized by \"git-p4 clone\".  There will be no\n> p4 refs.  The error message in this case is a traceback\n> for an assertion, which is confusing.\n>\n> Change it instead to explain the likely problem.\n>\n> Signed-off-by: Pete Wyckoff <pw@padd.com>\n\nAcked-By: Tor Arvid Lund <torarvid@gmail.com>\n\n> ---\n>  contrib/fast-import/git-p4 |    2 ++\n>  1 files changed, 2 insertions(+), 0 deletions(-)\n>\n> diff --git a/contrib/fast-import/git-p4 b/contrib/fast-import/git-p4\n> index 6b847c4..04e6c3d 100755\n> --- a/contrib/fast-import/git-p4\n> +++ b/contrib/fast-import/git-p4\n> @@ -1676,6 +1676,8 @@ class P4Sync(Command):\n>\n>                 changes.sort()\n>             else:\n> +                if not self.p4BranchesInGit:\n> +                    die(\"No remote p4 branches.  Perhaps you never did \\\"git p4 clone\\\" in here.\");\n>                 if self.verbose:\n>                     print \"Getting p4 changes for %s...%s\" % (', '.join(self.depotPaths),\n>                                                               self.changeRange)\n> --\n> 1.7.2.3\n>\n> --\n> To unsubscribe from this list: send the line \"unsubscribe git\" in\n> the body of a message to majordomo@vger.kernel.org\n> More majordomo info at  http://vger.kernel.org/majordomo-info.html\n>\n"},{"id":"160686","messageId":"AANLkTi=Gah9yeYYnHPZ2Z6-OZQ2-CU5Kub=o5SqWAXht@mail.gmail.com","threadId":"26423","inReplyTo":"20110205225237.GH30963@arf.padd.com","subject":"Re: [PATCH 7/8] git-p4: decode p4 wildcard characters","fromName":"Tor Arvid Lund","fromEmail":"torarvid@gmail.com","sentAt":"2011-02-08T09:09:42Z","receivedAt":"2011-02-08T09:09:42Z","isPatch":true,"sender":{"key":"torarvid@gmail.com","avatar":"https://avatars.githubusercontent.com/u/439758?v=4"},"body":"On Sat, Feb 5, 2011 at 11:52 PM, Pete Wyckoff <pw@padd.com> wrote:\n> There are four wildcard characters in p4.  Files with these\n> characters can be added to p4 repos using the \"-f\" option.\n> They are stored in %xx notation, and when checked out, p4\n> converts them back to normal.\n>\n> This patch does the same thing when importing into git,\n> converting the four special characters.  Without this change,\n> the files appear with literal %xx in their names.\n>\n> Signed-off-by: Pete Wyckoff <pw@padd.com>\n> ---\n>  contrib/fast-import/git-p4 |   13 +++++++++++++\n>  t/t9800-git-p4.sh          |   22 ++++++++++++++++++++++\n>  2 files changed, 35 insertions(+), 0 deletions(-)\n>\n> diff --git a/contrib/fast-import/git-p4 b/contrib/fast-import/git-p4\n> index 04e6c3d..5b08cd6 100755\n> --- a/contrib/fast-import/git-p4\n> +++ b/contrib/fast-import/git-p4\n> @@ -884,6 +884,18 @@ class P4Sync(Command):\n>         if gitConfig(\"git-p4.syncFromOrigin\") == \"false\":\n>             self.syncWithOrigin = False\n>\n> +    # The p4 wildcards are not allowed in filenames.  It complains\n> +    # if you try to add them, but you can override with \"-f\", in\n> +    # which case it translates them into %xx encoding.  Search for\n> +    # and fix just these four characters.  Do % last so it does\n> +    # not inadvertantly create new %-escapes.\n> +    def wildcard_decode(self, path):\n> +        path = path.replace(\"%23\", \"#\") \\\n> +                   .replace(\"%2A\", \"*\") \\\n\nThis probably works fine on UNIX platforms, but the asterisk '*'\ncharacter is not allowed in windows filenames. I don't really know\nwhat perforce does in that scenario. Does it make the most sense to\njust keep the %2A in the filename if we are running on windows (??)\n\n    -- Tor Arvid\n\n> +                   .replace(\"%40\", \"@\") \\\n> +                   .replace(\"%25\", \"%\")\n> +        return path\n> +\n>     def extractFilesFromCommit(self, commit):\n>         self.cloneExclude = [re.sub(r\"\\.\\.\\.$\", \"\", path)\n>                              for path in self.cloneExclude]\n> @@ -962,6 +974,7 @@ class P4Sync(Command):\n>            return\n>\n>         relPath = self.stripRepoPath(file['depotFile'], self.branchPrefixes)\n> +        relPath = self.wildcard_decode(relPath)\n>         if verbose:\n>             sys.stderr.write(\"%s\\n\" % relPath)\n>\n> diff --git a/t/t9800-git-p4.sh b/t/t9800-git-p4.sh\n> index 41e57bb..72c38af 100755\n> --- a/t/t9800-git-p4.sh\n> +++ b/t/t9800-git-p4.sh\n> @@ -65,6 +65,28 @@ test_expect_success 'exit when p4 fails to produce marshaled output' '\n>        test_must_fail grep -q Traceback errs\n>  '\n>\n> +test_expect_success 'add p4 files with wildcards in the names' '\n> +       cd \"$cli\" &&\n> +       echo file-wild-hash >file-wild#hash &&\n> +       echo file-wild-star >file-wild\\*star &&\n> +       echo file-wild-at >file-wild@at &&\n> +       echo file-wild-percent >file-wild%percent &&\n> +       p4 add -f file-wild* &&\n> +       p4 submit -d \"file wildcards\" &&\n> +       cd \"$TRASH_DIRECTORY\"\n> +'\n> +\n> +test_expect_success 'wildcard files git-p4 clone' '\n> +       \"$GITP4\" clone --dest=\"$git\" //depot &&\n> +       cd \"$git\" &&\n> +       test -f file-wild#hash &&\n> +       test -f file-wild\\*star &&\n> +       test -f file-wild@at &&\n> +       test -f file-wild%percent &&\n> +       cd \"$TRASH_DIRECTORY\" &&\n> +       rm -rf \"$git\" && mkdir \"$git\"\n> +'\n> +\n>  test_expect_success 'shutdown' '\n>        pid=`pgrep -f p4d` &&\n>        test -n \"$pid\" &&\n> --\n> 1.7.2.3\n>\n> --\n> To unsubscribe from this list: send the line \"unsubscribe git\" in\n> the body of a message to majordomo@vger.kernel.org\n> More majordomo info at  http://vger.kernel.org/majordomo-info.html\n>\n"},{"id":"160687","messageId":"AANLkTinmttwtgF+RdG7Sr9aMi=awKeWZnHVME+9Z_Np+@mail.gmail.com","threadId":"26423","inReplyTo":"20110205225247.GI30963@arf.padd.com","subject":"Re: [PATCH 8/8] git-p4: support clone --bare","fromName":"Tor Arvid Lund","fromEmail":"torarvid@gmail.com","sentAt":"2011-02-08T09:18:13Z","receivedAt":"2011-02-08T09:18:13Z","isPatch":true,"sender":{"key":"torarvid@gmail.com","avatar":"https://avatars.githubusercontent.com/u/439758?v=4"},"body":"On Sat, Feb 5, 2011 at 11:52 PM, Pete Wyckoff <pw@padd.com> wrote:\n> Just like git clone --bare, build a .git directory but no\n> checked out files.\n>\n> Signed-off-by: Pete Wyckoff <pw@padd.com>\n\nAcked-By: Tor Arvid Lund <torarvid@gmail.com>\n\n> ---\n>  contrib/fast-import/git-p4 |   17 +++++++++++++----\n>  t/t9800-git-p4.sh          |   10 ++++++++++\n>  2 files changed, 23 insertions(+), 4 deletions(-)\n>\n> diff --git a/contrib/fast-import/git-p4 b/contrib/fast-import/git-p4\n> index 5b08cd6..efc5dce 100755\n> --- a/contrib/fast-import/git-p4\n> +++ b/contrib/fast-import/git-p4\n> @@ -1771,10 +1771,13 @@ class P4Clone(P4Sync):\n>                                  help=\"where to leave result of the clone\"),\n>             optparse.make_option(\"-/\", dest=\"cloneExclude\",\n>                                  action=\"append\", type=\"string\",\n> -                                 help=\"exclude depot path\")\n> +                                 help=\"exclude depot path\"),\n> +            optparse.make_option(\"--bare\", dest=\"cloneBare\",\n> +                                 action=\"store_true\", default=False),\n>         ]\n>         self.cloneDestination = None\n>         self.needsGit = False\n> +        self.cloneBare = False\n>\n>     # This is required for the \"append\" cloneExclude action\n>     def ensure_value(self, attr, value):\n> @@ -1814,11 +1817,16 @@ class P4Clone(P4Sync):\n>             self.cloneDestination = self.defaultDestination(args)\n>\n>         print \"Importing from %s into %s\" % (', '.join(depotPaths), self.cloneDestination)\n> +\n>         if not os.path.exists(self.cloneDestination):\n>             os.makedirs(self.cloneDestination)\n>         chdir(self.cloneDestination)\n> -        system(\"git init\")\n> -        self.gitdir = os.getcwd() + \"/.git\"\n> +\n> +        init_cmd = [ \"git\", \"init\" ]\n> +        if self.cloneBare:\n> +            init_cmd.append(\"--bare\")\n> +        subprocess.check_call(init_cmd)\n> +\n>         if not P4Sync.run(self, depotPaths):\n>             return False\n>         if self.branch != \"master\":\n> @@ -1828,7 +1836,8 @@ class P4Clone(P4Sync):\n>                 masterbranch = \"refs/heads/p4/master\"\n>             if gitBranchExists(masterbranch):\n>                 system(\"git branch master %s\" % masterbranch)\n> -                system(\"git checkout -f\")\n> +                if not self.cloneBare:\n> +                    system(\"git checkout -f\")\n>             else:\n>                 print \"Could not detect main branch. No checkout/master branch created.\"\n>\n> diff --git a/t/t9800-git-p4.sh b/t/t9800-git-p4.sh\n> index 72c38af..1e7639b 100755\n> --- a/t/t9800-git-p4.sh\n> +++ b/t/t9800-git-p4.sh\n> @@ -87,6 +87,16 @@ test_expect_success 'wildcard files git-p4 clone' '\n>        rm -rf \"$git\" && mkdir \"$git\"\n>  '\n>\n> +test_expect_success 'clone bare' '\n> +       \"$GITP4\" clone --dest=\"$git\" --bare //depot &&\n> +       cd \"$git\" &&\n> +       test ! -d .git &&\n> +       bare=`git config --get core.bare` &&\n> +       test \"$bare\" = true &&\n> +       cd \"$TRASH_DIRECTORY\" &&\n> +       rm -rf \"$git\" && mkdir \"$git\"\n> +'\n> +\n>  test_expect_success 'shutdown' '\n>        pid=`pgrep -f p4d` &&\n>        test -n \"$pid\" &&\n> --\n> 1.7.2.3\n>\n> --\n> To unsubscribe from this list: send the line \"unsubscribe git\" in\n> the body of a message to majordomo@vger.kernel.org\n> More majordomo info at  http://vger.kernel.org/majordomo-info.html\n>\n"},{"id":"160717","messageId":"20110208232606.GA32491@arf.padd.com","threadId":"26423","inReplyTo":"AANLkTi=Gah9yeYYnHPZ2Z6-OZQ2-CU5Kub=o5SqWAXht@mail.gmail.com","subject":"Re: [PATCH 7/8] git-p4: decode p4 wildcard characters","fromName":"Pete Wyckoff","fromEmail":"pw@padd.com","sentAt":"2011-02-08T23:26:06Z","receivedAt":"2011-02-08T23:26:06Z","isPatch":true,"sender":{"key":"pw@padd.com","avatar":null},"body":"torarvid@gmail.com wrote on Tue, 08 Feb 2011 10:09 +0100:\n> On Sat, Feb 5, 2011 at 11:52 PM, Pete Wyckoff <pw@padd.com> wrote:\n> > +    # The p4 wildcards are not allowed in filenames.  It complains\n> > +    # if you try to add them, but you can override with \"-f\", in\n> > +    # which case it translates them into %xx encoding.  Search for\n> > +    # and fix just these four characters.  Do % last so it does\n> > +    # not inadvertantly create new %-escapes.\n> > +    def wildcard_decode(self, path):\n> > +        path = path.replace(\"%23\", \"#\") \\\n> > +                   .replace(\"%2A\", \"*\") \\\n> \n> This probably works fine on UNIX platforms, but the asterisk '*'\n> character is not allowed in windows filenames. I don't really know\n> what perforce does in that scenario. Does it make the most sense to\n> just keep the %2A in the filename if we are running on windows (??)\n\nI changed it to do the \"*\" translation if not self.isWindows, so\n%2A will remain in the filename.  Good that you noticed it.\n\nJust for giggles, I found a windows VM to test perforce on.\nBuilt two files with different wildcards on a unix box, then\npointed a windows client at it:\n\nC:\\DOCUME~1\\ADMINI~1\\DESKTOP>set P4PORT=192.168.2.1:1666\n\nC:\\DOCUME~1\\ADMINI~1\\DESKTOP>p4 files //depot/...\n//depot/file%25percent#1 - add change 1 (binary)\n//depot/file%2Astar#1 - add change 1 (binary)\n\nC:\\DOCUME~1\\ADMINI~1\\DESKTOP>p4 client\nClient soulfree saved.\n\nC:\\DOCUME~1\\ADMINI~1\\DESKTOP>p4 sync\n//depot/file%25percent#1 - added as c:\\Documents and Settings\\Administrator\\Desktop\\file%percent\n//depot/file%2Astar#1 - added as c:\\Documents and Settings\\Administrator\\Desktop\\file*star\nopen for write: c:\\Documents and Settings\\Administrator\\Desktop\\file*star: The filename, directory name, or volume label syntax is incorrect.\n\nAnd only the one file was synced to the windows client.  So \"*\" is not\nwell handled in perforce on windows anyway.\n\nDocs are not helpful:\n\nhttp://www.perforce.com/perforce/doc.current/manuals/cmdref/o.fspecs.html#1041962\n\nFor git, leaving a %2A in a filename is better than an error, I believe.\n\nThanks for the other acks.\n\n\t\t-- Pete\n"}]}