{"thread":{"id":"30358","subject":"[PATCH 1/4] git p4: bring back files in deleted client directory","startedAt":"2012-04-30T00:57:13Z","lastAt":"2012-04-30T21:56:09Z","messageCount":10,"participants":["Pete Wyckoff","Luke Diamand"],"isPatch":true,"patchVersion":1,"patchTotal":4},"messages":[{"id":"190266","messageId":"1335747437-24034-1-git-send-email-pw@padd.com","threadId":"30358","inReplyTo":null,"subject":"[PATCH 0/4] git p4 submit fixes","fromName":"Pete Wyckoff","fromEmail":"pw@padd.com","sentAt":"2012-04-30T00:57:13Z","receivedAt":"2012-04-30T00:57:13Z","isPatch":true,"sender":{"key":"pw@padd.com","avatar":null},"body":"These patches fix some issues associated with submit.  They add a\ngood chunk of basic testing for the submit path as well.\nThe last patch was sent to the list back in February, if it\nlooks familiar.\n\nPete Wyckoff (4):\n  git p4: bring back files in deleted client directory\n  git p4: test submit\n  git p4: fix writable file after rename or copy\n  git p4: submit files with wildcards\n\n git-p4.py                     |   96 +++++++++++++++++++++++++------------\n t/t9800-git-p4-basic.sh       |  106 +++++++++++++++++++++++++++++++++++++++++\n t/t9807-git-p4-submit.sh      |  101 ++++++++++++++++++++++++++++++++++++++-\n t/t9809-git-p4-client-view.sh |   40 ++++++++++++++--\n 4 files changed, 308 insertions(+), 35 deletions(-)\n\n-- \n1.7.10.366.g90ade\n"},{"id":"190265","messageId":"1335747437-24034-2-git-send-email-pw@padd.com","threadId":"30358","inReplyTo":"1335747437-24034-1-git-send-email-pw@padd.com","subject":"[PATCH 1/4] git p4: bring back files in deleted client directory","fromName":"Pete Wyckoff","fromEmail":"pw@padd.com","sentAt":"2012-04-30T00:57:14Z","receivedAt":"2012-04-30T00:57:14Z","isPatch":true,"sender":{"key":"pw@padd.com","avatar":null},"body":"The code to auto-create the client directory, added in 0591cfa\n(git-p4: ensure submit clientPath exists before chdir,\n2011-12-09), works when the client directory never existed.\n\nBut if the directory is summarily removed without telling p4,\nthe sync operation will not bring back all the files.  Always\ndo \"sync -f\" if the client directory is newly created.\n\nReported-by: Gary Gibbons <ggibbons@perforce.com>\nSigned-off-by: Pete Wyckoff <pw@padd.com>\n---\n git-p4.py                |   12 +++++++++---\n t/t9807-git-p4-submit.sh |    7 +++++--\n 2 files changed, 14 insertions(+), 5 deletions(-)\n\ndiff --git a/git-p4.py b/git-p4.py\nindex f910d5a..a2eba5d 100755\n--- a/git-p4.py\n+++ b/git-p4.py\n@@ -133,8 +133,8 @@ def p4_system(cmd):\n def p4_integrate(src, dest):\n     p4_system([\"integrate\", \"-Dt\", src, dest])\n \n-def p4_sync(path):\n-    p4_system([\"sync\", path])\n+def p4_sync(f, *options):\n+    p4_system([\"sync\"] + list(options) + [f])\n \n def p4_add(f):\n     p4_system([\"add\", f])\n@@ -1279,12 +1279,18 @@ class P4Submit(Command, P4UserMap):\n         self.oldWorkingDirectory = os.getcwd()\n \n         # ensure the clientPath exists\n+        new_client_dir = False\n         if not os.path.exists(self.clientPath):\n+            new_client_dir = True\n             os.makedirs(self.clientPath)\n \n         chdir(self.clientPath)\n         print \"Synchronizing p4 checkout...\"\n-        p4_sync(\"...\")\n+        if new_client_dir:\n+            # old one was destroyed, and maybe nobody told p4\n+            p4_sync(\"...\", \"-f\")\n+        else:\n+            p4_sync(\"...\")\n         self.check()\n \n         commits = []\ndiff --git a/t/t9807-git-p4-submit.sh b/t/t9807-git-p4-submit.sh\nindex 1541716..2d7dc27 100755\n--- a/t/t9807-git-p4-submit.sh\n+++ b/t/t9807-git-p4-submit.sh\n@@ -28,6 +28,11 @@ test_expect_success 'submit with no client dir' '\n \t\trm -rf \"$cli\" &&\n \t\tgit config git-p4.skipSubmitEdit true &&\n \t\tgit p4 submit\n+\t) &&\n+\t(\n+\t\tcd \"$cli\" &&\n+\t\ttest_path_is_file file1 &&\n+\t\ttest_path_is_file file2\n \t)\n '\n \n@@ -44,7 +49,6 @@ test_expect_success 'submit --origin' '\n \t) &&\n \t(\n \t\tcd \"$cli\" &&\n-\t\tp4 sync &&\n \t\ttest_path_is_missing \"file3.t\" &&\n \t\ttest_path_is_file \"file4.t\"\n \t)\n@@ -79,7 +83,6 @@ test_expect_success 'submit with master branch name from argv' '\n \t) &&\n \t(\n \t\tcd \"$cli\" &&\n-\t\tp4 sync &&\n \t\ttest_path_is_file \"file6.t\" &&\n \t\ttest_path_is_missing \"file7.t\"\n \t)\n-- \n1.7.10.366.g90ade\n"},{"id":"190267","messageId":"1335747437-24034-3-git-send-email-pw@padd.com","threadId":"30358","inReplyTo":"1335747437-24034-1-git-send-email-pw@padd.com","subject":"[PATCH 2/4] git p4: test submit","fromName":"Pete Wyckoff","fromEmail":"pw@padd.com","sentAt":"2012-04-30T00:57:15Z","receivedAt":"2012-04-30T00:57:15Z","isPatch":true,"sender":{"key":"pw@padd.com","avatar":null},"body":"Try each of the five diff patterns that might happen during submit.\n\nSigned-off-by: Pete Wyckoff <pw@padd.com>\n---\n t/t9807-git-p4-submit.sh |   92 ++++++++++++++++++++++++++++++++++++++++++++++\n 1 file changed, 92 insertions(+)\n\ndiff --git a/t/t9807-git-p4-submit.sh b/t/t9807-git-p4-submit.sh\nindex 2d7dc27..a2499ee 100755\n--- a/t/t9807-git-p4-submit.sh\n+++ b/t/t9807-git-p4-submit.sh\n@@ -88,6 +88,98 @@ test_expect_success 'submit with master branch name from argv' '\n \t)\n '\n \n+#\n+# Basic submit tests, the five handled cases\n+#\n+\n+test_expect_success 'submit modify' '\n+\ttest_when_finished cleanup_git &&\n+\tgit p4 clone --dest=\"$git\" //depot &&\n+\t(\n+\t\tcd \"$git\" &&\n+\t\tgit config git-p4.skipSubmitEdit true &&\n+\t\techo line >>file1 &&\n+\t\tgit add file1 &&\n+\t\tgit commit -m file1 &&\n+\t\tgit p4 submit\n+\t) &&\n+\t(\n+\t\tcd \"$cli\" &&\n+\t\ttest_path_is_file file1 &&\n+\t\ttest_line_count = 2 file1\n+\t)\n+'\n+\n+test_expect_success 'submit add' '\n+\ttest_when_finished cleanup_git &&\n+\tgit p4 clone --dest=\"$git\" //depot &&\n+\t(\n+\t\tcd \"$git\" &&\n+\t\tgit config git-p4.skipSubmitEdit true &&\n+\t\techo file13 >file13 &&\n+\t\tgit add file13 &&\n+\t\tgit commit -m file13 &&\n+\t\tgit p4 submit\n+\t) &&\n+\t(\n+\t\tcd \"$cli\" &&\n+\t\ttest_path_is_file file13\n+\t)\n+'\n+\n+test_expect_success 'submit delete' '\n+\ttest_when_finished cleanup_git &&\n+\tgit p4 clone --dest=\"$git\" //depot &&\n+\t(\n+\t\tcd \"$git\" &&\n+\t\tgit config git-p4.skipSubmitEdit true &&\n+\t\tgit rm file4.t &&\n+\t\tgit commit -m \"delete file4.t\" &&\n+\t\tgit p4 submit\n+\t) &&\n+\t(\n+\t\tcd \"$cli\" &&\n+\t\ttest_path_is_missing file4.t\n+\t)\n+'\n+\n+test_expect_success 'submit copy' '\n+\ttest_when_finished cleanup_git &&\n+\tgit p4 clone --dest=\"$git\" //depot &&\n+\t(\n+\t\tcd \"$git\" &&\n+\t\tgit config git-p4.skipSubmitEdit true &&\n+\t\tgit config git-p4.detectCopies true &&\n+\t\tgit config git-p4.detectCopiesHarder true &&\n+\t\tcp file5.t file5.ta &&\n+\t\tgit add file5.ta &&\n+\t\tgit commit -m \"copy to file5.ta\" &&\n+\t\tgit p4 submit\n+\t) &&\n+\t(\n+\t\tcd \"$cli\" &&\n+\t\ttest_path_is_file file5.ta\n+\t)\n+'\n+\n+test_expect_success 'submit rename' '\n+\ttest_when_finished cleanup_git &&\n+\tgit p4 clone --dest=\"$git\" //depot &&\n+\t(\n+\t\tcd \"$git\" &&\n+\t\tgit config git-p4.skipSubmitEdit true &&\n+\t\tgit config git-p4.detectRenames true &&\n+\t\tgit mv file6.t file6.ta &&\n+\t\tgit commit -m \"rename file6.t to file6.ta\" &&\n+\t\tgit p4 submit\n+\t) &&\n+\t(\n+\t\tcd \"$cli\" &&\n+\t\ttest_path_is_missing file6.t &&\n+\t\ttest_path_is_file file6.ta\n+\t)\n+'\n+\n test_expect_success 'kill p4d' '\n \tkill_p4d\n '\n-- \n1.7.10.366.g90ade\n"},{"id":"190268","messageId":"1335747437-24034-4-git-send-email-pw@padd.com","threadId":"30358","inReplyTo":"1335747437-24034-1-git-send-email-pw@padd.com","subject":"[PATCH 3/4] git p4: fix writable file after rename or copy","fromName":"Pete Wyckoff","fromEmail":"pw@padd.com","sentAt":"2012-04-30T00:57:16Z","receivedAt":"2012-04-30T00:57:16Z","isPatch":true,"sender":{"key":"pw@padd.com","avatar":null},"body":"The way rename works is with a \"p4 integrate\", optionally\nfollowed by a \"p4 edit\" if the change is not a 100% rename.\nContents are generated by applying a patch, not doing a file\nsystem rename.  Copy is similar.\n\nIn this case, p4 does not fix the permissions back to read-only.\nMake sure this happens by calling \"p4 sync -f\".\n\nSigned-off-by: Pete Wyckoff <pw@padd.com>\n---\n git-p4.py                     |   12 ++++++++++++\n t/t9807-git-p4-submit.sh      |    6 ++++--\n t/t9809-git-p4-client-view.sh |    7 ++++---\n 3 files changed, 20 insertions(+), 5 deletions(-)\n\ndiff --git a/git-p4.py b/git-p4.py\nindex a2eba5d..888e3e7 100755\n--- a/git-p4.py\n+++ b/git-p4.py\n@@ -1021,6 +1021,7 @@ class P4Submit(Command, P4UserMap):\n         filesToAdd = set()\n         filesToDelete = set()\n         editedFiles = set()\n+        pureRenameCopy = set()\n         filesToChangeExecBit = {}\n \n         for line in diff:\n@@ -1044,10 +1045,13 @@ class P4Submit(Command, P4UserMap):\n             elif modifier == \"C\":\n                 src, dest = diff['src'], diff['dst']\n                 p4_integrate(src, dest)\n+                pureRenameCopy.add(dest)\n                 if diff['src_sha1'] != diff['dst_sha1']:\n                     p4_edit(dest)\n+                    pureRenameCopy.discard(dest)\n                 if isModeExecChanged(diff['src_mode'], diff['dst_mode']):\n                     p4_edit(dest)\n+                    pureRenameCopy.discard(dest)\n                     filesToChangeExecBit[dest] = diff['dst_mode']\n                 os.unlink(dest)\n                 editedFiles.add(dest)\n@@ -1056,6 +1060,8 @@ class P4Submit(Command, P4UserMap):\n                 p4_integrate(src, dest)\n                 if diff['src_sha1'] != diff['dst_sha1']:\n                     p4_edit(dest)\n+                else:\n+                    pureRenameCopy.add(dest)\n                 if isModeExecChanged(diff['src_mode'], diff['dst_mode']):\n                     p4_edit(dest)\n                     filesToChangeExecBit[dest] = diff['dst_mode']\n@@ -1209,6 +1215,12 @@ class P4Submit(Command, P4UserMap):\n                         # unmarshalled.\n                         changelist = self.lastP4Changelist()\n                         self.modifyChangelistUser(changelist, p4User)\n+\n+                # The rename/copy happened by applying a patch that created a\n+                # new file.  This leaves it writable, which confuses p4.\n+                for f in pureRenameCopy:\n+                    p4_sync(f, \"-f\")\n+\n             else:\n                 # skip this patch\n                 print \"Submission cancelled, undoing p4 changes.\"\ndiff --git a/t/t9807-git-p4-submit.sh b/t/t9807-git-p4-submit.sh\nindex a2499ee..f23b4c3 100755\n--- a/t/t9807-git-p4-submit.sh\n+++ b/t/t9807-git-p4-submit.sh\n@@ -158,7 +158,8 @@ test_expect_success 'submit copy' '\n \t) &&\n \t(\n \t\tcd \"$cli\" &&\n-\t\ttest_path_is_file file5.ta\n+\t\ttest_path_is_file file5.ta &&\n+\t\ttest ! -w file5.ta\n \t)\n '\n \n@@ -176,7 +177,8 @@ test_expect_success 'submit rename' '\n \t(\n \t\tcd \"$cli\" &&\n \t\ttest_path_is_missing file6.t &&\n-\t\ttest_path_is_file file6.ta\n+\t\ttest_path_is_file file6.ta &&\n+\t\ttest ! -w file6.ta\n \t)\n '\n \ndiff --git a/t/t9809-git-p4-client-view.sh b/t/t9809-git-p4-client-view.sh\nindex 796b02c..43ed1fe 100755\n--- a/t/t9809-git-p4-client-view.sh\n+++ b/t/t9809-git-p4-client-view.sh\n@@ -349,7 +349,8 @@ test_expect_success 'subdir clone, submit copy' '\n \t) &&\n \t(\n \t\tcd \"$cli\" &&\n-\t\ttest_path_is_file dir1/file11a\n+\t\ttest_path_is_file dir1/file11a &&\n+\t\ttest ! -w dir1/file11a\n \t)\n '\n \n@@ -368,14 +369,14 @@ test_expect_success 'subdir clone, submit rename' '\n \t(\n \t\tcd \"$cli\" &&\n \t\ttest_path_is_missing dir1/file13 &&\n-\t\ttest_path_is_file dir1/file13a\n+\t\ttest_path_is_file dir1/file13a &&\n+\t\ttest ! -w dir1/file13a\n \t)\n '\n \n test_expect_success 'reinit depot' '\n \t(\n \t\tcd \"$cli\" &&\n-\t\tp4 sync -f &&\n \t\trm files &&\n \t\tp4 delete */* &&\n \t\tp4 submit -d \"delete all files\" &&\n-- \n1.7.10.366.g90ade\n"},{"id":"190269","messageId":"1335747437-24034-5-git-send-email-pw@padd.com","threadId":"30358","inReplyTo":"1335747437-24034-1-git-send-email-pw@padd.com","subject":"[PATCH 4/4] git p4: submit files with wildcards","fromName":"Pete Wyckoff","fromEmail":"pw@padd.com","sentAt":"2012-04-30T00:57:17Z","receivedAt":"2012-04-30T00:57:17Z","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.  They\nare stored in %xx notation, and when checked out, p4 converts\nthem back to normal.\n\nWhen adding files with wildcards in git, the submit path must\nbe careful to use the encoded names in some places, and it\nmust use \"-f\" to add them.  All other p4 commands that operate\non the client directory expect encoded filenames as arguments.\n\nSupport for wildcards in the clone/sync path was added in\n084f630 (git-p4: decode p4 wildcard characters, 2011-02-19),\nbut that change did not handle the submit path.\n\nThere was a problem with wildcards in the sync path too.  Commit\n084f630 (git-p4: decode p4 wildcard characters, 2011-02-19)\nhandled files with p4 wildcards that were added or modified in\np4.  Do this for deleted files, and also in branch detection\nchecks, too.\n\nReported-by: Luke Diamand <luke@diamand.org>\nSigned-off-by: Pete Wyckoff <pw@padd.com>\n---\n git-p4.py                     |   74 +++++++++++++++++-----------\n t/t9800-git-p4-basic.sh       |  106 +++++++++++++++++++++++++++++++++++++++++\n t/t9809-git-p4-client-view.sh |   33 +++++++++++++\n 3 files changed, 185 insertions(+), 28 deletions(-)\n\ndiff --git a/git-p4.py b/git-p4.py\nindex 888e3e7..5afd501 100755\n--- a/git-p4.py\n+++ b/git-p4.py\n@@ -131,25 +131,29 @@ def p4_system(cmd):\n     subprocess.check_call(real_cmd, shell=expand)\n \n def p4_integrate(src, dest):\n-    p4_system([\"integrate\", \"-Dt\", src, dest])\n+    p4_system([\"integrate\", \"-Dt\", wildcard_encode(src), wildcard_encode(dest)])\n \n def p4_sync(f, *options):\n-    p4_system([\"sync\"] + list(options) + [f])\n+    p4_system([\"sync\"] + list(options) + [wildcard_encode(f)])\n \n def p4_add(f):\n-    p4_system([\"add\", f])\n+    # forcibly add file names with wildcards\n+    if wildcard_present(f):\n+        p4_system([\"add\", \"-f\", f])\n+    else:\n+        p4_system([\"add\", f])\n \n def p4_delete(f):\n-    p4_system([\"delete\", f])\n+    p4_system([\"delete\", wildcard_encode(f)])\n \n def p4_edit(f):\n-    p4_system([\"edit\", f])\n+    p4_system([\"edit\", wildcard_encode(f)])\n \n def p4_revert(f):\n-    p4_system([\"revert\", f])\n+    p4_system([\"revert\", wildcard_encode(f)])\n \n-def p4_reopen(type, file):\n-    p4_system([\"reopen\", \"-t\", type, file])\n+def p4_reopen(type, f):\n+    p4_system([\"reopen\", \"-t\", type, wildcard_encode(f)])\n \n #\n # Canonicalize the p4 type and return a tuple of the\n@@ -246,7 +250,7 @@ def setP4ExecBit(file, mode):\n def getP4OpenedType(file):\n     # Returns the perforce file type for the given file.\n \n-    result = p4_read_pipe([\"opened\", file])\n+    result = p4_read_pipe([\"opened\", wildcard_encode(file)])\n     match = re.match(\".*\\((.+)\\)\\r?$\", result)\n     if match:\n         return match.group(1)\n@@ -636,6 +640,34 @@ def getClientRoot():\n \n     return entry[\"Root\"]\n \n+#\n+# P4 wildcards are not allowed in filenames.  P4 complains\n+# if you simply add them, but you can force it with \"-f\", in\n+# which case it translates them into %xx encoding internally.\n+#\n+def wildcard_decode(path):\n+    # Search for and fix just these four characters.  Do % last so\n+    # that fixing it does not inadvertently create new %-escapes.\n+    # Cannot have * in a filename in windows; untested as to\n+    # what p4 would do in such a case.\n+    if not platform.system() == \"Windows\":\n+        path = path.replace(\"%2A\", \"*\")\n+    path = path.replace(\"%23\", \"#\") \\\n+               .replace(\"%40\", \"@\") \\\n+               .replace(\"%25\", \"%\")\n+    return path\n+\n+def wildcard_encode(path):\n+    # do % first to avoid double-encoding the %s introduced here\n+    path = path.replace(\"%\", \"%25\") \\\n+               .replace(\"*\", \"%2A\") \\\n+               .replace(\"#\", \"%23\") \\\n+               .replace(\"@\", \"%40\")\n+    return path\n+\n+def wildcard_present(path):\n+    return path.translate(None, \"*#@%\") != path\n+\n class Command:\n     def __init__(self):\n         self.usage = \"usage: %prog [options]\"\n@@ -1170,7 +1202,8 @@ class P4Submit(Command, P4UserMap):\n                 del(os.environ[\"P4DIFF\"])\n             diff = \"\"\n             for editedFile in editedFiles:\n-                diff += p4_read_pipe(['diff', '-du', editedFile])\n+                diff += p4_read_pipe(['diff', '-du',\n+                                      wildcard_encode(editedFile)])\n \n             newdiff = \"\"\n             for newFile in filesToAdd:\n@@ -1605,23 +1638,6 @@ class P4Sync(Command, P4UserMap):\n         if gitConfig(\"git-p4.syncFromOrigin\") == \"false\":\n             self.syncWithOrigin = False\n \n-    #\n-    # P4 wildcards are not allowed in filenames.  P4 complains\n-    # if you simply add them, but you can force it with \"-f\", in\n-    # which case it translates them into %xx encoding internally.\n-    # Search for and fix just these four characters.  Do % last so\n-    # that fixing it does not inadvertently create new %-escapes.\n-    #\n-    def wildcard_decode(self, path):\n-        # Cannot have * in a filename in windows; untested as to\n-        # what p4 would do in such a case.\n-        if not self.isWindows:\n-            path = path.replace(\"%2A\", \"*\")\n-        path = path.replace(\"%23\", \"#\") \\\n-                   .replace(\"%40\", \"@\") \\\n-                   .replace(\"%25\", \"%\")\n-        return path\n-\n     # Force a checkpoint in fast-import and wait for it to finish\n     def checkpoint(self):\n         self.gitStream.write(\"checkpoint\\n\\n\")\n@@ -1689,6 +1705,7 @@ class P4Sync(Command, P4UserMap):\n             fnum = fnum + 1\n \n             relPath = self.stripRepoPath(path, self.depotPaths)\n+            relPath = wildcard_decode(relPath)\n \n             for branch in self.knownBranches.keys():\n \n@@ -1706,7 +1723,7 @@ class P4Sync(Command, P4UserMap):\n \n     def streamOneP4File(self, file, contents):\n         relPath = self.stripRepoPath(file['depotFile'], self.branchPrefixes)\n-        relPath = self.wildcard_decode(relPath)\n+        relPath = wildcard_decode(relPath)\n         if verbose:\n             sys.stderr.write(\"%s\\n\" % relPath)\n \n@@ -1775,6 +1792,7 @@ class P4Sync(Command, P4UserMap):\n \n     def streamOneP4Deletion(self, file):\n         relPath = self.stripRepoPath(file['path'], self.branchPrefixes)\n+        relPath = wildcard_decode(relPath)\n         if verbose:\n             sys.stderr.write(\"delete %s\\n\" % relPath)\n         self.gitStream.write(\"D %s\\n\" % relPath)\ndiff --git a/t/t9800-git-p4-basic.sh b/t/t9800-git-p4-basic.sh\nindex 13be144..0223fcf 100755\n--- a/t/t9800-git-p4-basic.sh\n+++ b/t/t9800-git-p4-basic.sh\n@@ -163,6 +163,112 @@ test_expect_success 'wildcard files git p4 clone' '\n \t)\n '\n \n+test_expect_success 'wildcard files submit back to p4, add' '\n+\ttest_when_finished cleanup_git &&\n+\tgit p4 clone --dest=\"$git\" //depot &&\n+\t(\n+\t\tcd \"$git\" &&\n+\t\techo git-wild-hash >git-wild#hash &&\n+\t\techo git-wild-star >git-wild\\*star &&\n+\t\techo git-wild-at >git-wild@at &&\n+\t\techo git-wild-percent >git-wild%percent &&\n+\t\tgit add git-wild* &&\n+\t\tgit commit -m \"add some wildcard filenames\" &&\n+\t\tgit config git-p4.skipSubmitEdit true &&\n+\t\tgit p4 submit\n+\t) &&\n+\t(\n+\t\tcd \"$cli\" &&\n+\t\ttest_path_is_file git-wild#hash &&\n+\t\ttest_path_is_file git-wild\\*star &&\n+\t\ttest_path_is_file git-wild@at &&\n+\t\ttest_path_is_file git-wild%percent\n+\t)\n+'\n+\n+test_expect_success 'wildcard files submit back to p4, modify' '\n+\ttest_when_finished cleanup_git &&\n+\tgit p4 clone --dest=\"$git\" //depot &&\n+\t(\n+\t\tcd \"$git\" &&\n+\t\techo new-line >>git-wild#hash &&\n+\t\techo new-line >>git-wild\\*star &&\n+\t\techo new-line >>git-wild@at &&\n+\t\techo new-line >>git-wild%percent &&\n+\t\tgit add git-wild* &&\n+\t\tgit commit -m \"modify the wildcard files\" &&\n+\t\tgit config git-p4.skipSubmitEdit true &&\n+\t\tgit p4 submit\n+\t) &&\n+\t(\n+\t\tcd \"$cli\" &&\n+\t\ttest_line_count = 2 git-wild#hash &&\n+\t\ttest_line_count = 2 git-wild\\*star &&\n+\t\ttest_line_count = 2 git-wild@at &&\n+\t\ttest_line_count = 2 git-wild%percent\n+\t)\n+'\n+\n+test_expect_success 'wildcard files submit back to p4, copy' '\n+\ttest_when_finished cleanup_git &&\n+\tgit p4 clone --dest=\"$git\" //depot &&\n+\t(\n+\t\tcd \"$git\" &&\n+\t\tcp file2 git-wild-cp#hash &&\n+\t\tgit add git-wild-cp#hash &&\n+\t\tcp git-wild\\*star file-wild-3 &&\n+\t\tgit add file-wild-3 &&\n+\t\tgit commit -m \"wildcard copies\" &&\n+\t\tgit config git-p4.detectCopies true &&\n+\t\tgit config git-p4.detectCopiesHarder true &&\n+\t\tgit config git-p4.skipSubmitEdit true &&\n+\t\tgit p4 submit\n+\t) &&\n+\t(\n+\t\tcd \"$cli\" &&\n+\t\ttest_path_is_file git-wild-cp#hash &&\n+\t\ttest_path_is_file file-wild-3\n+\t)\n+'\n+\n+test_expect_success 'wildcard files submit back to p4, rename' '\n+\ttest_when_finished cleanup_git &&\n+\tgit p4 clone --dest=\"$git\" //depot &&\n+\t(\n+\t\tcd \"$git\" &&\n+\t\tgit mv git-wild@at file-wild-4 &&\n+\t\tgit mv file-wild-3 git-wild-cp%percent &&\n+\t\tgit commit -m \"wildcard renames\" &&\n+\t\tgit config git-p4.detectRenames true &&\n+\t\tgit config git-p4.skipSubmitEdit true &&\n+\t\tgit p4 submit\n+\t) &&\n+\t(\n+\t\tcd \"$cli\" &&\n+\t\ttest_path_is_missing git-wild@at &&\n+\t\ttest_path_is_file git-wild-cp%percent\n+\t)\n+'\n+\n+test_expect_success 'wildcard files submit back to p4, delete' '\n+\ttest_when_finished cleanup_git &&\n+\tgit p4 clone --dest=\"$git\" //depot &&\n+\t(\n+\t\tcd \"$git\" &&\n+\t\tgit rm git-wild* &&\n+\t\tgit commit -m \"delete the wildcard files\" &&\n+\t\tgit config git-p4.skipSubmitEdit true &&\n+\t\tgit p4 submit\n+\t) &&\n+\t(\n+\t\tcd \"$cli\" &&\n+\t\ttest_path_is_missing git-wild#hash &&\n+\t\ttest_path_is_missing git-wild\\*star &&\n+\t\ttest_path_is_missing git-wild@at &&\n+\t\ttest_path_is_missing git-wild%percent\n+\t)\n+'\n+\n test_expect_success 'clone bare' '\n \tgit p4 clone --dest=\"$git\" --bare //depot &&\n \ttest_when_finished cleanup_git &&\ndiff --git a/t/t9809-git-p4-client-view.sh b/t/t9809-git-p4-client-view.sh\nindex 43ed1fe..7d993ef 100755\n--- a/t/t9809-git-p4-client-view.sh\n+++ b/t/t9809-git-p4-client-view.sh\n@@ -374,6 +374,39 @@ test_expect_success 'subdir clone, submit rename' '\n \t)\n '\n \n+# see t9800 for the non-client-spec case, and the rest of the wildcard tests\n+test_expect_success 'wildcard files submit back to p4, client-spec case' '\n+\tclient_view \"//depot/... //client/...\" &&\n+\ttest_when_finished cleanup_git &&\n+\tgit p4 clone --use-client-spec --dest=\"$git\" //depot/dir1 &&\n+\t(\n+\t\tcd \"$git\" &&\n+\t\techo git-wild-hash >dir1/git-wild#hash &&\n+\t\techo git-wild-star >dir1/git-wild\\*star &&\n+\t\techo git-wild-at >dir1/git-wild@at &&\n+\t\techo git-wild-percent >dir1/git-wild%percent &&\n+\t\tgit add dir1/git-wild* &&\n+\t\tgit commit -m \"add some wildcard filenames\" &&\n+\t\tgit config git-p4.skipSubmitEditCheck true &&\n+\t\tgit p4 submit\n+\t) &&\n+\t(\n+\t\tcd \"$cli\" &&\n+\t\ttest_path_is_file dir1/git-wild#hash &&\n+\t\ttest_path_is_file dir1/git-wild\\*star &&\n+\t\ttest_path_is_file dir1/git-wild@at &&\n+\t\ttest_path_is_file dir1/git-wild%percent\n+\t) &&\n+\t(\n+\t\t# delete these carefully, cannot just do \"p4 delete\"\n+\t\t# on files with wildcards; but git-p4 knows how\n+\t\tcd \"$git\" &&\n+\t\tgit rm dir1/git-wild* &&\n+\t\tgit commit -m \"clean up the wildcards\" &&\n+\t\tgit p4 submit\n+\t)\n+'\n+\n test_expect_success 'reinit depot' '\n \t(\n \t\tcd \"$cli\" &&\n-- \n1.7.10.366.g90ade\n"},{"id":"190281","messageId":"4F9E376B.1000107@diamand.org","threadId":"30358","inReplyTo":"1335747437-24034-2-git-send-email-pw@padd.com","subject":"Re: [PATCH 1/4] git p4: bring back files in deleted client directory","fromName":"Luke Diamand","fromEmail":"luke@diamand.org","sentAt":"2012-04-30T06:55:39Z","receivedAt":"2012-04-30T06:55:39Z","isPatch":true,"sender":{"key":"luke@diamand.org","avatar":"https://avatars.githubusercontent.com/u/5330967?v=4"},"body":"On 30/04/12 01:57, Pete Wyckoff wrote:\n> The code to auto-create the client directory, added in 0591cfa\n> (git-p4: ensure submit clientPath exists before chdir,\n> 2011-12-09), works when the client directory never existed.\n>\n> But if the directory is summarily removed without telling p4,\n> the sync operation will not bring back all the files.  Always\n> do \"sync -f\" if the client directory is newly created.\n\nI'm possibly missing something obvious here, but \n./t9807-git-p4-submit.sh fails with this change.\n\nRebasing the current branch onto remotes/p4/master\nFirst, rewinding head to replay your work on top of it...\nFile file1 doesn't exist. file1\nnot ok - 3 submit with no client dir\n\nLuke\n"},{"id":"190296","messageId":"20120430123650.GB25045@padd.com","threadId":"30358","inReplyTo":"4F9E376B.1000107@diamand.org","subject":"Re: [PATCH 1/4] git p4: bring back files in deleted client directory","fromName":"Pete Wyckoff","fromEmail":"pw@padd.com","sentAt":"2012-04-30T12:36:50Z","receivedAt":"2012-04-30T12:36:50Z","isPatch":true,"sender":{"key":"pw@padd.com","avatar":null},"body":"luke@diamand.org wrote on Mon, 30 Apr 2012 07:55 +0100:\n> On 30/04/12 01:57, Pete Wyckoff wrote:\n> >The code to auto-create the client directory, added in 0591cfa\n> >(git-p4: ensure submit clientPath exists before chdir,\n> >2011-12-09), works when the client directory never existed.\n> >\n> >But if the directory is summarily removed without telling p4,\n> >the sync operation will not bring back all the files.  Always\n> >do \"sync -f\" if the client directory is newly created.\n> \n> I'm possibly missing something obvious here, but\n> ./t9807-git-p4-submit.sh fails with this change.\n> \n> Rebasing the current branch onto remotes/p4/master\n> First, rewinding head to replay your work on top of it...\n> File file1 doesn't exist. file1\n> not ok - 3 submit with no client dir\n\nI can't figure it out.  Will you help debug a bit?  Something\nlike this maybe.\n\ndiff --git a/t/t9807-git-p4-submit.sh b/t/t9807-git-p4-submit.sh\nindex f23b4c3..e98cc5e 100755\n--- a/t/t9807-git-p4-submit.sh\n+++ b/t/t9807-git-p4-submit.sh\n@@ -31,6 +31,7 @@ test_expect_success 'submit with no client dir' '\n \t) &&\n \t(\n \t\tcd \"$cli\" &&\n+\t\tpwd && ls -la && p4 sync && ls -la &&\n \t\ttest_path_is_file file1 &&\n \t\ttest_path_is_file file2\n \t)\n\nAnd if the other \"submit modify\" etc. tests don't work, it\ncould be fallout from this one.  Deleting \"$cli\" is perhaps\nat fault:  permissions, ... ?\n\nOr somehow I completely broke things.\n\nI'll try with a newer version of p4, to see if there's a\ndependency there.\n\nThanks for checking!\n\n\t\t-- Pete\n"},{"id":"190326","messageId":"4F9EDB34.5090103@diamand.org","threadId":"30358","inReplyTo":"20120430123650.GB25045@padd.com","subject":"Re: [PATCH 1/4] git p4: bring back files in deleted client directory","fromName":"Luke Diamand","fromEmail":"luke@diamand.org","sentAt":"2012-04-30T18:34:28Z","receivedAt":"2012-04-30T18:34:28Z","isPatch":true,"sender":{"key":"luke@diamand.org","avatar":"https://avatars.githubusercontent.com/u/5330967?v=4"},"body":"On 30/04/12 13:36, Pete Wyckoff wrote:\n> luke@diamand.org wrote on Mon, 30 Apr 2012 07:55 +0100:\n>>\n>> Rebasing the current branch onto remotes/p4/master\n>> First, rewinding head to replay your work on top of it...\n>> File file1 doesn't exist. file1\n>> not ok - 3 submit with no client dir\n>\n> I can't figure it out.  Will you help debug a bit?  Something\n> like this maybe.\n\nUser error.\n\n% cp git-p4.py git-p4\n\nThen it works fine.\n\nIs there a way to get lib-git-p4.sh to check this?\n\nThanks\nLuke\n"},{"id":"190328","messageId":"4F9EDB48.6030301@diamand.org","threadId":"30358","inReplyTo":"1335747437-24034-5-git-send-email-pw@padd.com","subject":"Re: [PATCH 4/4] git p4: submit files with wildcards","fromName":"Luke Diamand","fromEmail":"luke@diamand.org","sentAt":"2012-04-30T18:34:48Z","receivedAt":"2012-04-30T18:34:48Z","isPatch":true,"sender":{"key":"luke@diamand.org","avatar":"https://avatars.githubusercontent.com/u/5330967?v=4"},"body":"On 30/04/12 01:57, Pete Wyckoff wrote:\n> There are four wildcard characters in p4.  Files with these\n> characters can be added to p4 repos using the \"-f\" option.  They\n> are stored in %xx notation, and when checked out, p4 converts\n> them back to normal.\n>\n> When adding files with wildcards in git, the submit path must\n> be careful to use the encoded names in some places, and it\n> must use \"-f\" to add them.  All other p4 commands that operate\n> on the client directory expect encoded filenames as arguments.\n>\n> Support for wildcards in the clone/sync path was added in\n> 084f630 (git-p4: decode p4 wildcard characters, 2011-02-19),\n> but that change did not handle the submit path.\n>\n> There was a problem with wildcards in the sync path too.  Commit\n> 084f630 (git-p4: decode p4 wildcard characters, 2011-02-19)\n> handled files with p4 wildcards that were added or modified in\n> p4.  Do this for deleted files, and also in branch detection\n> checks, too.\n\nAck, thanks for fixing this. The other changes look fine as well.\n\n>\n> Reported-by: Luke Diamand<luke@diamand.org>\n> Signed-off-by: Pete Wyckoff<pw@padd.com>\n> ---\n>   git-p4.py                     |   74 +++++++++++++++++-----------\n>   t/t9800-git-p4-basic.sh       |  106 +++++++++++++++++++++++++++++++++++++++++\n>   t/t9809-git-p4-client-view.sh |   33 +++++++++++++\n>   3 files changed, 185 insertions(+), 28 deletions(-)\n>\n> diff --git a/git-p4.py b/git-p4.py\n> index 888e3e7..5afd501 100755\n> --- a/git-p4.py\n> +++ b/git-p4.py\n> @@ -131,25 +131,29 @@ def p4_system(cmd):\n>       subprocess.check_call(real_cmd, shell=expand)\n>\n>   def p4_integrate(src, dest):\n> -    p4_system([\"integrate\", \"-Dt\", src, dest])\n> +    p4_system([\"integrate\", \"-Dt\", wildcard_encode(src), wildcard_encode(dest)])\n>\n>   def p4_sync(f, *options):\n> -    p4_system([\"sync\"] + list(options) + [f])\n> +    p4_system([\"sync\"] + list(options) + [wildcard_encode(f)])\n>\n>   def p4_add(f):\n> -    p4_system([\"add\", f])\n> +    # forcibly add file names with wildcards\n> +    if wildcard_present(f):\n> +        p4_system([\"add\", \"-f\", f])\n> +    else:\n> +        p4_system([\"add\", f])\n>\n>   def p4_delete(f):\n> -    p4_system([\"delete\", f])\n> +    p4_system([\"delete\", wildcard_encode(f)])\n>\n>   def p4_edit(f):\n> -    p4_system([\"edit\", f])\n> +    p4_system([\"edit\", wildcard_encode(f)])\n>\n>   def p4_revert(f):\n> -    p4_system([\"revert\", f])\n> +    p4_system([\"revert\", wildcard_encode(f)])\n>\n> -def p4_reopen(type, file):\n> -    p4_system([\"reopen\", \"-t\", type, file])\n> +def p4_reopen(type, f):\n> +    p4_system([\"reopen\", \"-t\", type, wildcard_encode(f)])\n>\n>   #\n>   # Canonicalize the p4 type and return a tuple of the\n> @@ -246,7 +250,7 @@ def setP4ExecBit(file, mode):\n>   def getP4OpenedType(file):\n>       # Returns the perforce file type for the given file.\n>\n> -    result = p4_read_pipe([\"opened\", file])\n> +    result = p4_read_pipe([\"opened\", wildcard_encode(file)])\n>       match = re.match(\".*\\((.+)\\)\\r?$\", result)\n>       if match:\n>           return match.group(1)\n> @@ -636,6 +640,34 @@ def getClientRoot():\n>\n>       return entry[\"Root\"]\n>\n> +#\n> +# P4 wildcards are not allowed in filenames.  P4 complains\n> +# if you simply add them, but you can force it with \"-f\", in\n> +# which case it translates them into %xx encoding internally.\n> +#\n> +def wildcard_decode(path):\n> +    # Search for and fix just these four characters.  Do % last so\n> +    # that fixing it does not inadvertently create new %-escapes.\n> +    # Cannot have * in a filename in windows; untested as to\n> +    # what p4 would do in such a case.\n> +    if not platform.system() == \"Windows\":\n> +        path = path.replace(\"%2A\", \"*\")\n> +    path = path.replace(\"%23\", \"#\") \\\n> +               .replace(\"%40\", \"@\") \\\n> +               .replace(\"%25\", \"%\")\n> +    return path\n> +\n> +def wildcard_encode(path):\n> +    # do % first to avoid double-encoding the %s introduced here\n> +    path = path.replace(\"%\", \"%25\") \\\n> +               .replace(\"*\", \"%2A\") \\\n> +               .replace(\"#\", \"%23\") \\\n> +               .replace(\"@\", \"%40\")\n> +    return path\n> +\n> +def wildcard_present(path):\n> +    return path.translate(None, \"*#@%\") != path\n> +\n>   class Command:\n>       def __init__(self):\n>           self.usage = \"usage: %prog [options]\"\n> @@ -1170,7 +1202,8 @@ class P4Submit(Command, P4UserMap):\n>                   del(os.environ[\"P4DIFF\"])\n>               diff = \"\"\n>               for editedFile in editedFiles:\n> -                diff += p4_read_pipe(['diff', '-du', editedFile])\n> +                diff += p4_read_pipe(['diff', '-du',\n> +                                      wildcard_encode(editedFile)])\n>\n>               newdiff = \"\"\n>               for newFile in filesToAdd:\n> @@ -1605,23 +1638,6 @@ class P4Sync(Command, P4UserMap):\n>           if gitConfig(\"git-p4.syncFromOrigin\") == \"false\":\n>               self.syncWithOrigin = False\n>\n> -    #\n> -    # P4 wildcards are not allowed in filenames.  P4 complains\n> -    # if you simply add them, but you can force it with \"-f\", in\n> -    # which case it translates them into %xx encoding internally.\n> -    # Search for and fix just these four characters.  Do % last so\n> -    # that fixing it does not inadvertently create new %-escapes.\n> -    #\n> -    def wildcard_decode(self, path):\n> -        # Cannot have * in a filename in windows; untested as to\n> -        # what p4 would do in such a case.\n> -        if not self.isWindows:\n> -            path = path.replace(\"%2A\", \"*\")\n> -        path = path.replace(\"%23\", \"#\") \\\n> -                   .replace(\"%40\", \"@\") \\\n> -                   .replace(\"%25\", \"%\")\n> -        return path\n> -\n>       # Force a checkpoint in fast-import and wait for it to finish\n>       def checkpoint(self):\n>           self.gitStream.write(\"checkpoint\\n\\n\")\n> @@ -1689,6 +1705,7 @@ class P4Sync(Command, P4UserMap):\n>               fnum = fnum + 1\n>\n>               relPath = self.stripRepoPath(path, self.depotPaths)\n> +            relPath = wildcard_decode(relPath)\n>\n>               for branch in self.knownBranches.keys():\n>\n> @@ -1706,7 +1723,7 @@ class P4Sync(Command, P4UserMap):\n>\n>       def streamOneP4File(self, file, contents):\n>           relPath = self.stripRepoPath(file['depotFile'], self.branchPrefixes)\n> -        relPath = self.wildcard_decode(relPath)\n> +        relPath = wildcard_decode(relPath)\n>           if verbose:\n>               sys.stderr.write(\"%s\\n\" % relPath)\n>\n> @@ -1775,6 +1792,7 @@ class P4Sync(Command, P4UserMap):\n>\n>       def streamOneP4Deletion(self, file):\n>           relPath = self.stripRepoPath(file['path'], self.branchPrefixes)\n> +        relPath = wildcard_decode(relPath)\n>           if verbose:\n>               sys.stderr.write(\"delete %s\\n\" % relPath)\n>           self.gitStream.write(\"D %s\\n\" % relPath)\n> diff --git a/t/t9800-git-p4-basic.sh b/t/t9800-git-p4-basic.sh\n> index 13be144..0223fcf 100755\n> --- a/t/t9800-git-p4-basic.sh\n> +++ b/t/t9800-git-p4-basic.sh\n> @@ -163,6 +163,112 @@ test_expect_success 'wildcard files git p4 clone' '\n>   \t)\n>   '\n>\n> +test_expect_success 'wildcard files submit back to p4, add' '\n> +\ttest_when_finished cleanup_git&&\n> +\tgit p4 clone --dest=\"$git\" //depot&&\n> +\t(\n> +\t\tcd \"$git\"&&\n> +\t\techo git-wild-hash>git-wild#hash&&\n> +\t\techo git-wild-star>git-wild\\*star&&\n> +\t\techo git-wild-at>git-wild@at&&\n> +\t\techo git-wild-percent>git-wild%percent&&\n> +\t\tgit add git-wild*&&\n> +\t\tgit commit -m \"add some wildcard filenames\"&&\n> +\t\tgit config git-p4.skipSubmitEdit true&&\n> +\t\tgit p4 submit\n> +\t)&&\n> +\t(\n> +\t\tcd \"$cli\"&&\n> +\t\ttest_path_is_file git-wild#hash&&\n> +\t\ttest_path_is_file git-wild\\*star&&\n> +\t\ttest_path_is_file git-wild@at&&\n> +\t\ttest_path_is_file git-wild%percent\n> +\t)\n> +'\n> +\n> +test_expect_success 'wildcard files submit back to p4, modify' '\n> +\ttest_when_finished cleanup_git&&\n> +\tgit p4 clone --dest=\"$git\" //depot&&\n> +\t(\n> +\t\tcd \"$git\"&&\n> +\t\techo new-line>>git-wild#hash&&\n> +\t\techo new-line>>git-wild\\*star&&\n> +\t\techo new-line>>git-wild@at&&\n> +\t\techo new-line>>git-wild%percent&&\n> +\t\tgit add git-wild*&&\n> +\t\tgit commit -m \"modify the wildcard files\"&&\n> +\t\tgit config git-p4.skipSubmitEdit true&&\n> +\t\tgit p4 submit\n> +\t)&&\n> +\t(\n> +\t\tcd \"$cli\"&&\n> +\t\ttest_line_count = 2 git-wild#hash&&\n> +\t\ttest_line_count = 2 git-wild\\*star&&\n> +\t\ttest_line_count = 2 git-wild@at&&\n> +\t\ttest_line_count = 2 git-wild%percent\n> +\t)\n> +'\n> +\n> +test_expect_success 'wildcard files submit back to p4, copy' '\n> +\ttest_when_finished cleanup_git&&\n> +\tgit p4 clone --dest=\"$git\" //depot&&\n> +\t(\n> +\t\tcd \"$git\"&&\n> +\t\tcp file2 git-wild-cp#hash&&\n> +\t\tgit add git-wild-cp#hash&&\n> +\t\tcp git-wild\\*star file-wild-3&&\n> +\t\tgit add file-wild-3&&\n> +\t\tgit commit -m \"wildcard copies\"&&\n> +\t\tgit config git-p4.detectCopies true&&\n> +\t\tgit config git-p4.detectCopiesHarder true&&\n> +\t\tgit config git-p4.skipSubmitEdit true&&\n> +\t\tgit p4 submit\n> +\t)&&\n> +\t(\n> +\t\tcd \"$cli\"&&\n> +\t\ttest_path_is_file git-wild-cp#hash&&\n> +\t\ttest_path_is_file file-wild-3\n> +\t)\n> +'\n> +\n> +test_expect_success 'wildcard files submit back to p4, rename' '\n> +\ttest_when_finished cleanup_git&&\n> +\tgit p4 clone --dest=\"$git\" //depot&&\n> +\t(\n> +\t\tcd \"$git\"&&\n> +\t\tgit mv git-wild@at file-wild-4&&\n> +\t\tgit mv file-wild-3 git-wild-cp%percent&&\n> +\t\tgit commit -m \"wildcard renames\"&&\n> +\t\tgit config git-p4.detectRenames true&&\n> +\t\tgit config git-p4.skipSubmitEdit true&&\n> +\t\tgit p4 submit\n> +\t)&&\n> +\t(\n> +\t\tcd \"$cli\"&&\n> +\t\ttest_path_is_missing git-wild@at&&\n> +\t\ttest_path_is_file git-wild-cp%percent\n> +\t)\n> +'\n> +\n> +test_expect_success 'wildcard files submit back to p4, delete' '\n> +\ttest_when_finished cleanup_git&&\n> +\tgit p4 clone --dest=\"$git\" //depot&&\n> +\t(\n> +\t\tcd \"$git\"&&\n> +\t\tgit rm git-wild*&&\n> +\t\tgit commit -m \"delete the wildcard files\"&&\n> +\t\tgit config git-p4.skipSubmitEdit true&&\n> +\t\tgit p4 submit\n> +\t)&&\n> +\t(\n> +\t\tcd \"$cli\"&&\n> +\t\ttest_path_is_missing git-wild#hash&&\n> +\t\ttest_path_is_missing git-wild\\*star&&\n> +\t\ttest_path_is_missing git-wild@at&&\n> +\t\ttest_path_is_missing git-wild%percent\n> +\t)\n> +'\n> +\n>   test_expect_success 'clone bare' '\n>   \tgit p4 clone --dest=\"$git\" --bare //depot&&\n>   \ttest_when_finished cleanup_git&&\n> diff --git a/t/t9809-git-p4-client-view.sh b/t/t9809-git-p4-client-view.sh\n> index 43ed1fe..7d993ef 100755\n> --- a/t/t9809-git-p4-client-view.sh\n> +++ b/t/t9809-git-p4-client-view.sh\n> @@ -374,6 +374,39 @@ test_expect_success 'subdir clone, submit rename' '\n>   \t)\n>   '\n>\n> +# see t9800 for the non-client-spec case, and the rest of the wildcard tests\n> +test_expect_success 'wildcard files submit back to p4, client-spec case' '\n> +\tclient_view \"//depot/... //client/...\"&&\n> +\ttest_when_finished cleanup_git&&\n> +\tgit p4 clone --use-client-spec --dest=\"$git\" //depot/dir1&&\n> +\t(\n> +\t\tcd \"$git\"&&\n> +\t\techo git-wild-hash>dir1/git-wild#hash&&\n> +\t\techo git-wild-star>dir1/git-wild\\*star&&\n> +\t\techo git-wild-at>dir1/git-wild@at&&\n> +\t\techo git-wild-percent>dir1/git-wild%percent&&\n> +\t\tgit add dir1/git-wild*&&\n> +\t\tgit commit -m \"add some wildcard filenames\"&&\n> +\t\tgit config git-p4.skipSubmitEditCheck true&&\n> +\t\tgit p4 submit\n> +\t)&&\n> +\t(\n> +\t\tcd \"$cli\"&&\n> +\t\ttest_path_is_file dir1/git-wild#hash&&\n> +\t\ttest_path_is_file dir1/git-wild\\*star&&\n> +\t\ttest_path_is_file dir1/git-wild@at&&\n> +\t\ttest_path_is_file dir1/git-wild%percent\n> +\t)&&\n> +\t(\n> +\t\t# delete these carefully, cannot just do \"p4 delete\"\n> +\t\t# on files with wildcards; but git-p4 knows how\n> +\t\tcd \"$git\"&&\n> +\t\tgit rm dir1/git-wild*&&\n> +\t\tgit commit -m \"clean up the wildcards\"&&\n> +\t\tgit p4 submit\n> +\t)\n> +'\n> +\n>   test_expect_success 'reinit depot' '\n>   \t(\n>   \t\tcd \"$cli\"&&\n"},{"id":"190350","messageId":"20120430215609.GA22615@padd.com","threadId":"30358","inReplyTo":"4F9EDB34.5090103@diamand.org","subject":"Re: [PATCH 1/4] git p4: bring back files in deleted client directory","fromName":"Pete Wyckoff","fromEmail":"pw@padd.com","sentAt":"2012-04-30T21:56:09Z","receivedAt":"2012-04-30T21:56:09Z","isPatch":true,"sender":{"key":"pw@padd.com","avatar":null},"body":"luke@diamand.org wrote on Mon, 30 Apr 2012 19:34 +0100:\n> On 30/04/12 13:36, Pete Wyckoff wrote:\n> >luke@diamand.org wrote on Mon, 30 Apr 2012 07:55 +0100:\n> >>\n> >>Rebasing the current branch onto remotes/p4/master\n> >>First, rewinding head to replay your work on top of it...\n> >>File file1 doesn't exist. file1\n> >>not ok - 3 submit with no client dir\n> >\n> >I can't figure it out.  Will you help debug a bit?  Something\n> >like this maybe.\n> \n> User error.\n> \n> % cp git-p4.py git-p4\n> \n> Then it works fine.\n\nWhew.  I caught myself forgetting to build a couple\nof times too.\n\n\"make git-p4\" is a bit more official.\n\n> Is there a way to get lib-git-p4.sh to check this?\n\nThis does seem appealing, but I'm not sure if it will be\nattractive to everybody else.\n\nMy thought pattern of what to put in lib-git-p4.sh\nwent like:\n\n    test git-p4.py -nt git-p4 && {\n\techo \"You must make git-p4\" >&2\n\texit 1\n    }\n\nto\n\n    test git-p4.py -nt git-p4 && {\n\techo \"Making git-p4\" >&2\n\tmake git-p4\n    }\n\nto\n\n    make git-p4\n\nto\n\n    make\n\nand that's when I realized that everybody else has\nthe same problem too.  Somehow they've gotten used\nto rebuilding before rerunning the tests.  I suspect\nthat we should get used to it too.\n\nThat said, it would have saved me some head scratching\non a few occasions.\n\n\t\t-- Pete\n"}]}