{"thread":{"id":"26444","subject":"[PATCH] Teach git-p4 to ignore case in perforce filenames if configured.","startedAt":"2011-02-08T11:11:39Z","lastAt":"2011-02-11T12:22:53Z","messageCount":2,"participants":["Tor Arvid Lund","Pete Wyckoff"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"160694","messageId":"1297163499-18776-1-git-send-email-torarvid@gmail.com","threadId":"26444","inReplyTo":null,"subject":"[PATCH] Teach git-p4 to ignore case in perforce filenames if configured.","fromName":"Tor Arvid Lund","fromEmail":"torarvid@gmail.com","sentAt":"2011-02-08T11:11:39Z","receivedAt":"2011-02-08T11:11:39Z","isPatch":true,"sender":{"key":"torarvid@gmail.com","avatar":"https://avatars.githubusercontent.com/u/439758?v=4"},"body":"When files are added to perforce, the path to that file has whichever case\nconfiguration that exists on the machine of the user who added the file.\nWhat does that mean? It means that when Alice adds a file\n\n//depot/DirA/FileA.txt\n\n... and Bob adds:\n\n//depot/dirA/FileB.txt\n\n... we may or may not get a problem. If a user sets the config variable\ngit-p4.ignorecase to \"true\", we will consider //depot/DirA and //depot/dirA\nto be the same directory.\n---\n contrib/fast-import/git-p4     |   22 ++++++++++++++--------\n contrib/fast-import/git-p4.txt |   12 ++++++++++++\n 2 files changed, 26 insertions(+), 8 deletions(-)\n\ndiff --git a/contrib/fast-import/git-p4 b/contrib/fast-import/git-p4\nindex 04ce7e3..ca3cea0 100755\n--- a/contrib/fast-import/git-p4\n+++ b/contrib/fast-import/git-p4\n@@ -452,6 +452,12 @@ def p4ChangesForPaths(depotPaths, changeRange):\n     changelist.sort()\n     return changelist\n \n+def p4PathStartsWith(path, prefix):\n+    ignorecase = gitConfig(\"git-p4.ignorecase\").lower()\n+    if ignorecase in [\"true\", \"yes\", \"1\"]:\n+        return path.lower().startswith(prefix.lower())\n+    return path.startswith(prefix)\n+\n class Command:\n     def __init__(self):\n         self.usage = \"usage: %prog [options]\"\n@@ -599,7 +605,7 @@ class P4Submit(Command):\n                     lastTab = path.rfind(\"\\t\")\n                     if lastTab != -1:\n                         path = path[:lastTab]\n-                        if not path.startswith(self.depotPath):\n+                        if not p4PathStartsWith(path, self.depotPath):\n                             continue\n                 else:\n                     inFilesSection = False\n@@ -891,11 +897,11 @@ class P4Sync(Command):\n             path =  commit[\"depotFile%s\" % fnum]\n \n             if [p for p in self.cloneExclude\n-                if path.startswith (p)]:\n+                if p4PathStartsWith(path, p)]:\n                 found = False\n             else:\n                 found = [p for p in self.depotPaths\n-                         if path.startswith (p)]\n+                         if p4PathStartsWith(path, p)]\n             if not found:\n                 fnum = fnum + 1\n                 continue\n@@ -914,7 +920,7 @@ class P4Sync(Command):\n             prefixes = [re.sub(\"^(//[^/]+/).*\", r'\\1', prefixes[0])]\n \n         for p in prefixes:\n-            if path.startswith(p):\n+            if p4PathStartsWith(path, p):\n                 path = path[len(p):]\n \n         return path\n@@ -925,7 +931,7 @@ class P4Sync(Command):\n         while commit.has_key(\"depotFile%s\" % fnum):\n             path =  commit[\"depotFile%s\" % fnum]\n             found = [p for p in self.depotPaths\n-                     if path.startswith (p)]\n+                     if p4PathStartsWith(path, p)]\n             if not found:\n                 fnum = fnum + 1\n                 continue\n@@ -1031,7 +1037,7 @@ class P4Sync(Command):\n         for f in files:\n             includeFile = True\n             for val in self.clientSpecDirs:\n-                if f['path'].startswith(val[0]):\n+                if p4PathStartsWith(f['path'], val[0]):\n                     if val[1] <= 0:\n                         includeFile = False\n                     break\n@@ -1077,7 +1083,7 @@ class P4Sync(Command):\n         # create a commit.\n         new_files = []\n         for f in files:\n-            if [p for p in branchPrefixes if f['path'].startswith(p)]:\n+            if [p for p in branchPrefixes if p4PathStartsWith(f['path'], p)]:\n                 new_files.append (f)\n             else:\n                 sys.stderr.write(\"Ignoring file outside of prefix: %s\\n\" % path)\n@@ -1241,7 +1247,7 @@ class P4Sync(Command):\n                 source = paths[0]\n                 destination = paths[1]\n                 ## HACK\n-                if source.startswith(self.depotPaths[0]) and destination.startswith(self.depotPaths[0]):\n+                if p4PathStartsWith(source, self.depotPaths[0]) and p4PathStartsWith(destination, self.depotPaths[0]):\n                     source = source[len(self.depotPaths[0]):-4]\n                     destination = destination[len(self.depotPaths[0]):-4]\n \ndiff --git a/contrib/fast-import/git-p4.txt b/contrib/fast-import/git-p4.txt\nindex 49b3359..bf7904a 100644\n--- a/contrib/fast-import/git-p4.txt\n+++ b/contrib/fast-import/git-p4.txt\n@@ -191,6 +191,18 @@ git-p4.useclientspec\n \n   git config [--global] git-p4.useclientspec false\n \n+git-p4.ignorecase\n+\n+If this variable is set to 'true' (or 'yes' or '1'), perforce paths like:\n+\n+//depot/Path/\n+//depot/path/\n+//dePoT/PATH/\n+\n+will all be considered to be the same directory.\n+\n+  git config [--global] git-p4.ignorecase false\n+\n Implementation Details...\n =========================\n \n-- \n1.7.3.1.68.g06779.dirty\n"},{"id":"160893","messageId":"20110211122253.GA14662@mew.padd.com","threadId":"26444","inReplyTo":"1297163499-18776-1-git-send-email-torarvid@gmail.com","subject":"Re: [PATCH] Teach git-p4 to ignore case in perforce filenames if configured.","fromName":"Pete Wyckoff","fromEmail":"pw@padd.com","sentAt":"2011-02-11T12:22:53Z","receivedAt":"2011-02-11T12:22:53Z","isPatch":true,"sender":{"key":"pw@padd.com","avatar":null},"body":"torarvid@gmail.com wrote on Tue, 08 Feb 2011 12:11 +0100:\n> When files are added to perforce, the path to that file has whichever case\n> configuration that exists on the machine of the user who added the file.\n> What does that mean? It means that when Alice adds a file\n> \n> //depot/DirA/FileA.txt\n> \n> ... and Bob adds:\n> \n> //depot/dirA/FileB.txt\n> \n> ... we may or may not get a problem. If a user sets the config variable\n> git-p4.ignorecase to \"true\", we will consider //depot/DirA and //depot/dirA\n> to be the same directory.\n\nThat's horrid.  Seriously?  A and B can both generate mixed-case\npaths, but with a different mix?\n\nIf it's all just cast to lower, does it make sense to use\ncore.ignorecase for this?\n\n> ---\n>  contrib/fast-import/git-p4     |   22 ++++++++++++++--------\n>  contrib/fast-import/git-p4.txt |   12 ++++++++++++\n>  2 files changed, 26 insertions(+), 8 deletions(-)\n> \n> diff --git a/contrib/fast-import/git-p4 b/contrib/fast-import/git-p4\n> index 04ce7e3..ca3cea0 100755\n> --- a/contrib/fast-import/git-p4\n> +++ b/contrib/fast-import/git-p4\n> @@ -452,6 +452,12 @@ def p4ChangesForPaths(depotPaths, changeRange):\n>      changelist.sort()\n>      return changelist\n>  \n> +def p4PathStartsWith(path, prefix):\n> +    ignorecase = gitConfig(\"git-p4.ignorecase\").lower()\n> +    if ignorecase in [\"true\", \"yes\", \"1\"]:\n> +        return path.lower().startswith(prefix.lower())\n> +    return path.startswith(prefix)\n\ngit config --bool will always return \"true\" or \"false\" (or \"\").\nI think we should start looking for \"true\" that rather than\nchecking for all four possible versions of true (+ \"on\").\n\nCan you put a comment in this function explaining the mixed-case\nproblem?  When reading the code, it's easier than searching\nthrough the doc to learn about it.\n\nRest of patch looks fine.\n\n\t\t-- Pete\n"}]}