{"thread":{"id":"49570","subject":"[PATCHv2 0/3] git-p4: improved unshelving - small fixes","startedAt":"2018-10-15T11:14:26Z","lastAt":"2018-10-24T11:51:31Z","messageCount":6,"participants":["Luke Diamand","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"360513","messageId":"20181015111408.17618-1-luke@diamand.org","threadId":"49570","inReplyTo":null,"subject":"[PATCHv2 0/3] git-p4: improved unshelving - small fixes","fromName":"Luke Diamand","fromEmail":"luke@diamand.org","sentAt":"2018-10-15T11:14:05Z","receivedAt":"2018-10-15T11:14:26Z","isPatch":false,"sender":{"key":"luke@diamand.org","avatar":"https://avatars.githubusercontent.com/u/5330967?v=4"},"body":"This is the same as my earlier patch other than fixing the\ndocumentation to reflect the change to the destination branch,\nas noticed by Junio.\n\nLuke Diamand (3):\n  git-p4: do not fail in verbose mode for missing 'fileSize' key\n  git-p4: unshelve into refs/remotes/p4-unshelved, not\n    refs/remotes/p4/unshelved\n  git-p4: fully support unshelving changelists\n\n Documentation/git-p4.txt | 10 ++---\n git-p4.py                | 90 +++++++++++++++++++++++-----------------\n t/t9832-unshelve.sh      | 75 ++++++++++++++++++++++++++-------\n 3 files changed, 117 insertions(+), 58 deletions(-)\n\n-- \n2.19.1.331.gae0ed827e6\n\n"},{"id":"360514","messageId":"20181015111408.17618-2-luke@diamand.org","threadId":"49570","inReplyTo":"20181015111408.17618-1-luke@diamand.org","subject":"[PATCHv2 1/3] git-p4: do not fail in verbose mode for missing 'fileSize' key","fromName":"Luke Diamand","fromEmail":"luke@diamand.org","sentAt":"2018-10-15T11:14:06Z","receivedAt":"2018-10-15T11:14:29Z","isPatch":false,"sender":{"key":"luke@diamand.org","avatar":"https://avatars.githubusercontent.com/u/5330967?v=4"},"body":"If deleting or moving a file, sometimes P4 doesn't report the file size.\n\nThe code handles this just fine but some logging crashes. Stop this\nhappening.\n\nThere was some earlier discussion on the list about this:\n\nhttps://public-inbox.org/git/xmqq1sqpp1vv.fsf@gitster.mtv.corp.google.com/\n\nSigned-off-by: Luke Diamand <luke@diamand.org>\n---\n git-p4.py | 5 ++++-\n 1 file changed, 4 insertions(+), 1 deletion(-)\n\ndiff --git a/git-p4.py b/git-p4.py\nindex 7fab255584..5701bad06a 100755\n--- a/git-p4.py\n+++ b/git-p4.py\n@@ -2775,7 +2775,10 @@ def streamOneP4File(self, file, contents):\n         relPath = self.stripRepoPath(file['depotFile'], self.branchPrefixes)\n         relPath = self.encodeWithUTF8(relPath)\n         if verbose:\n-            size = int(self.stream_file['fileSize'])\n+            if 'fileSize' in self.stream_file:\n+                size = int(self.stream_file['fileSize'])\n+            else:\n+                size = 0 # deleted files don't get a fileSize apparently\n             sys.stdout.write('\\r%s --> %s (%i MB)\\n' % (file['depotFile'], relPath, size/1024/1024))\n             sys.stdout.flush()\n \n-- \n2.19.1.331.gae0ed827e6\n\n"},{"id":"360515","messageId":"20181015111408.17618-3-luke@diamand.org","threadId":"49570","inReplyTo":"20181015111408.17618-1-luke@diamand.org","subject":"[PATCHv2 2/3] git-p4: unshelve into refs/remotes/p4-unshelved, not refs/remotes/p4/unshelved","fromName":"Luke Diamand","fromEmail":"luke@diamand.org","sentAt":"2018-10-15T11:14:07Z","receivedAt":"2018-10-15T11:14:29Z","isPatch":false,"sender":{"key":"luke@diamand.org","avatar":"https://avatars.githubusercontent.com/u/5330967?v=4"},"body":"The branch detection code looks for branches under refs/remotes/p4/...\nand can end up getting confused if there are unshelved changes in\nthere as well. This happens in the function p4BranchesInGit().\n\nInstead, put the unshelved changes into refs/remotes/p4-unshelved/<N>.\n\nSigned-off-by: Luke Diamand <luke@diamand.org>\n---\n Documentation/git-p4.txt | 6 +++---\n git-p4.py                | 3 ++-\n t/t9832-unshelve.sh      | 6 +++---\n 3 files changed, 8 insertions(+), 7 deletions(-)\n\ndiff --git a/Documentation/git-p4.txt b/Documentation/git-p4.txt\nindex 41780a5aa9..6c0017e36e 100644\n--- a/Documentation/git-p4.txt\n+++ b/Documentation/git-p4.txt\n@@ -174,7 +174,7 @@ $ git p4 submit --update-shelve 1234 --update-shelve 2345\n Unshelve\n ~~~~~~~~\n Unshelving will take a shelved P4 changelist, and produce the equivalent git commit\n-in the branch refs/remotes/p4/unshelved/<changelist>.\n+in the branch refs/remotes/p4-unshelved/<changelist>.\n \n The git commit is created relative to the current origin revision (HEAD by default).\n If the shelved changelist's parent revisions differ, git-p4 will refuse to unshelve;\n@@ -182,13 +182,13 @@ you need to be unshelving onto an equivalent tree.\n \n The origin revision can be changed with the \"--origin\" option.\n \n-If the target branch in refs/remotes/p4/unshelved already exists, the old one will\n+If the target branch in refs/remotes/p4-unshelved already exists, the old one will\n be renamed.\n \n ----\n $ git p4 sync\n $ git p4 unshelve 12345\n-$ git show refs/remotes/p4/unshelved/12345\n+$ git show p4-unshelved/12345\n <submit more changes via p4 to the same files>\n $ git p4 unshelve 12345\n <refuses to unshelve until git is in sync with p4 again>\ndiff --git a/git-p4.py b/git-p4.py\nindex 5701bad06a..76c18a22e9 100755\n--- a/git-p4.py\n+++ b/git-p4.py\n@@ -3956,7 +3956,8 @@ def __init__(self):\n         ]\n         self.verbose = False\n         self.noCommit = False\n-        self.destbranch = \"refs/remotes/p4/unshelved\"\n+        self.destbranch = \"refs/remotes/p4-unshelved\"\n+        self.origin = \"p4/master\"\n \n     def renameBranch(self, branch_name):\n         \"\"\" Rename the existing branch to branch_name.N\ndiff --git a/t/t9832-unshelve.sh b/t/t9832-unshelve.sh\nindex 48ec7679b8..c3d15ceea8 100755\n--- a/t/t9832-unshelve.sh\n+++ b/t/t9832-unshelve.sh\n@@ -54,8 +54,8 @@ EOF\n \t\tcd \"$git\" &&\n \t\tchange=$(last_shelved_change) &&\n \t\tgit p4 unshelve $change &&\n-\t\tgit show refs/remotes/p4/unshelved/$change | grep -q \"Further description\" &&\n-\t\tgit cherry-pick refs/remotes/p4/unshelved/$change &&\n+\t\tgit show refs/remotes/p4-unshelved/$change | grep -q \"Further description\" &&\n+\t\tgit cherry-pick refs/remotes/p4-unshelved/$change &&\n \t\ttest_path_is_file file2 &&\n \t\ttest_cmp file1 \"$cli\"/file1 &&\n \t\ttest_cmp file2 \"$cli\"/file2 &&\n@@ -88,7 +88,7 @@ EOF\n \t\tcd \"$git\" &&\n \t\tchange=$(last_shelved_change) &&\n \t\tgit p4 unshelve $change &&\n-\t\tgit diff refs/remotes/p4/unshelved/$change.0 refs/remotes/p4/unshelved/$change | grep -q file3\n+\t\tgit diff refs/remotes/p4-unshelved/$change.0 refs/remotes/p4-unshelved/$change | grep -q file3\n \t)\n '\n \n-- \n2.19.1.331.gae0ed827e6\n\n"},{"id":"360516","messageId":"20181015111408.17618-4-luke@diamand.org","threadId":"49570","inReplyTo":"20181015111408.17618-1-luke@diamand.org","subject":"[PATCHv2 3/3] git-p4: fully support unshelving changelists","fromName":"Luke Diamand","fromEmail":"luke@diamand.org","sentAt":"2018-10-15T11:14:08Z","receivedAt":"2018-10-15T11:14:33Z","isPatch":false,"sender":{"key":"luke@diamand.org","avatar":"https://avatars.githubusercontent.com/u/5330967?v=4"},"body":"The previous git-p4 unshelve support would check for changes\nin Perforce to the files being unshelved since the original\nshelve, and would complain if any were found.\n\nThis was to ensure that the user wouldn't end up with both the\nshelved change delta, and some deltas from other changes in their\ngit commit.\n\ne.g. given fileA:\n      the\n      quick\n      brown\n      fox\n\n  change1: s/the/The/   <- p4 shelve this change\n  change2: s/fox/Fox/   <- p4 submit this change\n  git p4 unshelve 1     <- FAIL\n\nThis change teaches the P4Unshelve class to always create a parent\ncommit which matches the P4 tree (for the files being unshelved) at\nthe point prior to the P4 shelve being created (which is reported\nin the p4 description for a shelved changelist).\n\nThat then means git-p4 can always create a git commit matching the\nP4 shelve that was originally created, without any extra deltas.\n\nThe user might still need to use the --origin option though - there\nis no way for git-p4 to work out the versions of all of the other\n*unchanged* files in the shelve, since this information is not recorded\nby Perforce.\n\nAdditionally this fixes handling of shelved 'move' operations.\n\nSigned-off-by: Luke Diamand <luke@diamand.org>\n---\n Documentation/git-p4.txt |  4 +-\n git-p4.py                | 84 +++++++++++++++++++++++-----------------\n t/t9832-unshelve.sh      | 69 ++++++++++++++++++++++++++-------\n 3 files changed, 106 insertions(+), 51 deletions(-)\n\ndiff --git a/Documentation/git-p4.txt b/Documentation/git-p4.txt\nindex 6c0017e36e..f0a0280954 100644\n--- a/Documentation/git-p4.txt\n+++ b/Documentation/git-p4.txt\n@@ -177,8 +177,8 @@ Unshelving will take a shelved P4 changelist, and produce the equivalent git com\n in the branch refs/remotes/p4-unshelved/<changelist>.\n \n The git commit is created relative to the current origin revision (HEAD by default).\n-If the shelved changelist's parent revisions differ, git-p4 will refuse to unshelve;\n-you need to be unshelving onto an equivalent tree.\n+A parent commit is created based on the origin, and then the unshelve commit is\n+created based on that.\n \n The origin revision can be changed with the \"--origin\" option.\n \ndiff --git a/git-p4.py b/git-p4.py\nindex 76c18a22e9..1998c3e141 100755\n--- a/git-p4.py\n+++ b/git-p4.py\n@@ -1306,6 +1306,9 @@ def processContent(self, git_mode, relPath, contents):\n             return LargeFileSystem.processContent(self, git_mode, relPath, contents)\n \n class Command:\n+    delete_actions = ( \"delete\", \"move/delete\", \"purge\" )\n+    add_actions = ( \"add\", \"move/add\" )\n+\n     def __init__(self):\n         self.usage = \"usage: %prog [options]\"\n         self.needsGit = True\n@@ -2524,7 +2527,6 @@ def map_in_client(self, depot_path):\n         return \"\"\n \n class P4Sync(Command, P4UserMap):\n-    delete_actions = ( \"delete\", \"move/delete\", \"purge\" )\n \n     def __init__(self):\n         Command.__init__(self)\n@@ -2612,20 +2614,7 @@ def checkpoint(self):\n         if self.verbose:\n             print(\"checkpoint finished: \" + out)\n \n-    def cmp_shelved(self, path, filerev, revision):\n-        \"\"\" Determine if a path at revision #filerev is the same as the file\n-            at revision @revision for a shelved changelist. If they don't match,\n-            unshelving won't be safe (we will get other changes mixed in).\n-\n-            This is comparing the revision that the shelved changelist is *based* on, not\n-            the shelved changelist itself.\n-        \"\"\"\n-        ret = p4Cmd([\"diff2\", \"{0}#{1}\".format(path, filerev), \"{0}@{1}\".format(path, revision)])\n-        if verbose:\n-            print(\"p4 diff2 path %s filerev %s revision %s => %s\" % (path, filerev, revision, ret))\n-        return ret[\"status\"] == \"identical\"\n-\n-    def extractFilesFromCommit(self, commit, shelved=False, shelved_cl = 0, origin_revision = 0):\n+    def extractFilesFromCommit(self, commit, shelved=False, shelved_cl = 0):\n         self.cloneExclude = [re.sub(r\"\\.\\.\\.$\", \"\", path)\n                              for path in self.cloneExclude]\n         files = []\n@@ -2650,17 +2639,6 @@ def extractFilesFromCommit(self, commit, shelved=False, shelved_cl = 0, origin_r\n             file[\"type\"] = commit[\"type%s\" % fnum]\n             if shelved:\n                 file[\"shelved_cl\"] = int(shelved_cl)\n-\n-                # For shelved changelists, check that the revision of each file that the\n-                # shelve was based on matches the revision that we are using for the\n-                # starting point for git-fast-import (self.initialParent). Otherwise\n-                # the resulting diff will contain deltas from multiple commits.\n-\n-                if file[\"action\"] != \"add\" and \\\n-                    not self.cmp_shelved(path, file[\"rev\"], origin_revision):\n-                    sys.exit(\"change {0} not based on {1} for {2}, cannot unshelve\".format(\n-                        commit[\"change\"], self.initialParent, path))\n-\n             files.append(file)\n             fnum = fnum + 1\n         return files\n@@ -3032,7 +3010,7 @@ def hasBranchPrefix(self, path):\n             print('Ignoring file outside of prefix: {0}'.format(path))\n         return hasPrefix\n \n-    def commit(self, details, files, branch, parent = \"\"):\n+    def commit(self, details, files, branch, parent = \"\", allow_empty=False):\n         epoch = details[\"time\"]\n         author = details[\"user\"]\n         jobs = self.extractJobsFromCommit(details)\n@@ -3046,7 +3024,10 @@ def commit(self, details, files, branch, parent = \"\"):\n         files = [f for f in files\n             if self.inClientSpec(f['path']) and self.hasBranchPrefix(f['path'])]\n \n-        if not files and not gitConfigBool('git-p4.keepEmptyCommits'):\n+        if gitConfigBool('git-p4.keepEmptyCommits'):\n+            allow_empty = True\n+\n+        if not files and not allow_empty:\n             print('Ignoring revision {0} as it would produce an empty commit.'\n                 .format(details['change']))\n             return\n@@ -3387,10 +3368,10 @@ def searchParent(self, parent, branch, target):\n         else:\n             return None\n \n-    def importChanges(self, changes, shelved=False, origin_revision=0):\n+    def importChanges(self, changes, origin_revision=0):\n         cnt = 1\n         for change in changes:\n-            description = p4_describe(change, shelved)\n+            description = p4_describe(change)\n             self.updateOptionDict(description)\n \n             if not self.silent:\n@@ -3460,7 +3441,7 @@ def importChanges(self, changes, shelved=False, origin_revision=0):\n                                 print(\"Parent of %s not found. Committing into head of %s\" % (branch, parent))\n                             self.commit(description, filesForCommit, branch, parent)\n                 else:\n-                    files = self.extractFilesFromCommit(description, shelved, change, origin_revision)\n+                    files = self.extractFilesFromCommit(description)\n                     self.commit(description, files, self.branch,\n                                 self.initialParent)\n                     # only needed once, to connect to the previous commit\n@@ -3957,7 +3938,6 @@ def __init__(self):\n         self.verbose = False\n         self.noCommit = False\n         self.destbranch = \"refs/remotes/p4-unshelved\"\n-        self.origin = \"p4/master\"\n \n     def renameBranch(self, branch_name):\n         \"\"\" Rename the existing branch to branch_name.N\n@@ -3989,6 +3969,32 @@ def findLastP4Revision(self, starting_point):\n \n         sys.exit(\"could not find git-p4 commits in {0}\".format(self.origin))\n \n+    def createShelveParent(self, change, branch_name, sync, origin):\n+        \"\"\" Create a commit matching the parent of the shelved changelist 'change'\n+        \"\"\"\n+        parent_description = p4_describe(change, shelved=True)\n+        parent_description['desc'] = 'parent for shelved changelist {}\\n'.format(change)\n+        files = sync.extractFilesFromCommit(parent_description, shelved=False, shelved_cl=change)\n+\n+        parent_files = []\n+        for f in files:\n+            # if it was added in the shelved changelist, it won't exist in the parent\n+            if f['action'] in self.add_actions:\n+                continue\n+\n+            # if it was deleted in the shelved changelist it must not be deleted\n+            # in the parent - we might even need to create it if the origin branch\n+            # does not have it\n+            if f['action'] in self.delete_actions:\n+                f['action'] = 'add'\n+\n+            parent_files.append(f)\n+\n+        sync.commit(parent_description, parent_files, branch_name,\n+                parent=origin, allow_empty=True)\n+        print(\"created parent commit for {0} based on {1} in {2}\".format(\n+            change, self.origin, branch_name))\n+\n     def run(self, args):\n         if len(args) != 1:\n             return False\n@@ -3998,9 +4004,8 @@ def run(self, args):\n \n         sync = P4Sync()\n         changes = args\n-        sync.initialParent = self.origin\n \n-        # use the first change in the list to construct the branch to unshelve into\n+        # only one change at a time\n         change = changes[0]\n \n         # if the target branch already exists, rename it\n@@ -4013,14 +4018,21 @@ def run(self, args):\n         sync.suppress_meta_comment = True\n \n         settings = self.findLastP4Revision(self.origin)\n-        origin_revision = settings['change']\n         sync.depotPaths = settings['depot-paths']\n         sync.branchPrefixes = sync.depotPaths\n \n         sync.openStreams()\n         sync.loadUserMapFromCache()\n         sync.silent = True\n-        sync.importChanges(changes, shelved=True, origin_revision=origin_revision)\n+\n+        # create a commit for the parent of the shelved changelist\n+        self.createShelveParent(change, branch_name, sync, self.origin)\n+\n+        # create the commit for the shelved changelist itself\n+        description = p4_describe(change, True)\n+        files = sync.extractFilesFromCommit(description, True, change)\n+\n+        sync.commit(description, files, branch_name, \"\")\n         sync.closeStreams()\n \n         print(\"unshelved changelist {0} into {1}\".format(change, branch_name))\ndiff --git a/t/t9832-unshelve.sh b/t/t9832-unshelve.sh\nindex c3d15ceea8..41c09f11f4 100755\n--- a/t/t9832-unshelve.sh\n+++ b/t/t9832-unshelve.sh\n@@ -19,8 +19,10 @@ test_expect_success 'init depot' '\n \t\tp4 add file1 &&\n \t\tp4 submit -d \"change 1\" &&\n \t\t: >file_to_delete &&\n+\t\t: >file_to_move &&\n \t\tp4 add file_to_delete &&\n-\t\tp4 submit -d \"file to delete\"\n+\t\tp4 add file_to_move &&\n+\t\tp4 submit -d \"add files to delete\"\n \t)\n '\n \n@@ -36,6 +38,8 @@ test_expect_success 'create shelved changelist' '\n \t\techo \"new file\" >file2 &&\n \t\tp4 add file2 &&\n \t\tp4 delete file_to_delete &&\n+\t\tp4 edit file_to_move &&\n+\t\tp4 move file_to_move moved_file &&\n \t\tp4 opened &&\n \t\tp4 shelve -i <<EOF\n Change: new\n@@ -47,6 +51,8 @@ Files:\n \t//depot/file1\n \t//depot/file2\n \t//depot/file_to_delete\n+\t//depot/file_to_move\n+\t//depot/moved_file\n EOF\n \n \t) &&\n@@ -59,7 +65,9 @@ EOF\n \t\ttest_path_is_file file2 &&\n \t\ttest_cmp file1 \"$cli\"/file1 &&\n \t\ttest_cmp file2 \"$cli\"/file2 &&\n-\t\ttest_path_is_missing file_to_delete\n+\t\ttest_path_is_missing file_to_delete &&\n+\t\ttest_path_is_missing file_to_move &&\n+\t\ttest_path_is_file moved_file\n \t)\n '\n \n@@ -92,6 +100,18 @@ EOF\n \t)\n '\n \n+shelve_one_file () {\n+\tdescription=\"Change to be unshelved\" &&\n+\tfile=\"$1\" &&\n+\tp4 shelve -i <<EOF\n+Change: new\n+Description:\n+\t$description\n+Files:\n+\t$file\n+EOF\n+}\n+\n # This is the tricky case where the shelved changelist base revision doesn't\n # match git-p4's idea of the base revision\n #\n@@ -108,29 +128,52 @@ test_expect_success 'create shelved changelist based on p4 change ahead of p4/ma\n \t\tp4 submit -d \"change:foo\" &&\n \t\tp4 edit file1 &&\n \t\techo \"bar\" >>file1 &&\n-\t\tp4 shelve -i <<EOF &&\n-Change: new\n-Description:\n-\tChange to be unshelved\n-Files:\n-\t//depot/file1\n-EOF\n+\t\tshelve_one_file //depot/file1 &&\n \t\tchange=$(last_shelved_change) &&\n-\t\tp4 describe -S $change | grep -q \"Change to be unshelved\"\n+\t\tp4 describe -S $change >out.txt &&\n+\t\tgrep -q \"Change to be unshelved\" out.txt\n \t)\n '\n \n-# Now try to unshelve it. git-p4 should refuse to do so.\n+# Now try to unshelve it.\n test_expect_success 'try to unshelve the change' '\n \ttest_when_finished cleanup_git &&\n \t(\n \t\tchange=$(last_shelved_change) &&\n \t\tcd \"$git\" &&\n-\t\ttest_must_fail git p4 unshelve $change 2>out.txt &&\n-\t\tgrep -q \"cannot unshelve\" out.txt\n+\t\tgit p4 unshelve $change >out.txt &&\n+\t\tgrep -q \"unshelved changelist $change\" out.txt\n \t)\n '\n \n+# Specify the origin. Create 2 unrelated files, and check that\n+# we only get the one in HEAD~, not the one in HEAD.\n+\n+test_expect_success 'unshelve specifying the origin' '\n+\t(\n+\t\tcd \"$cli\" &&\n+\t\t: >unrelated_file0 &&\n+\t\tp4 add unrelated_file0 &&\n+\t\tp4 submit -d \"unrelated\" &&\n+\t\t: >unrelated_file1 &&\n+\t\tp4 add unrelated_file1 &&\n+\t\tp4 submit -d \"unrelated\" &&\n+\t\t: >file_to_shelve &&\n+\t\tp4 add file_to_shelve &&\n+\t\tshelve_one_file //depot/file_to_shelve\n+\t) &&\n+\ttest_when_finished cleanup_git &&\n+\tgit p4 clone --dest=\"$git\" //depot/@all &&\n+\t(\n+\t\tcd \"$git\" &&\n+\t\tchange=$(last_shelved_change) &&\n+\t\tgit p4 unshelve --origin HEAD~ $change &&\n+\t\tgit checkout refs/remotes/p4-unshelved/$change &&\n+\t\ttest_path_is_file unrelated_file0 &&\n+\t\ttest_path_is_missing unrelated_file1 &&\n+\t\ttest_path_is_file file_to_shelve\n+\t)\n+'\n test_expect_success 'kill p4d' '\n \tkill_p4d\n '\n-- \n2.19.1.331.gae0ed827e6\n\n"},{"id":"360576","messageId":"xmqqtvlm1pon.fsf@gitster-ct.c.googlers.com","threadId":"49570","inReplyTo":"20181015111408.17618-1-luke@diamand.org","subject":"Re: [PATCHv2 0/3] git-p4: improved unshelving - small fixes","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2018-10-16T04:27:36Z","receivedAt":"2018-10-16T04:27:41Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Luke Diamand <luke@diamand.org> writes:\n\n> This is the same as my earlier patch other than fixing the\n> documentation to reflect the change to the destination branch,\n> as noticed by Junio.\n\nAlso you set up when-finished driver for clean-up before running\nclone, which I think is a good change, too.\n\nWill replace.  Thanks.\n\n>\n> Luke Diamand (3):\n>   git-p4: do not fail in verbose mode for missing 'fileSize' key\n>   git-p4: unshelve into refs/remotes/p4-unshelved, not\n>     refs/remotes/p4/unshelved\n>   git-p4: fully support unshelving changelists\n>\n>  Documentation/git-p4.txt | 10 ++---\n>  git-p4.py                | 90 +++++++++++++++++++++++-----------------\n>  t/t9832-unshelve.sh      | 75 ++++++++++++++++++++++++++-------\n>  3 files changed, 117 insertions(+), 58 deletions(-)\n"},{"id":"361406","messageId":"CAE5ih7867GCao1NWDvmcaVnui5QUYf-uMfFNhH6Zh0zztMBhuA@mail.gmail.com","threadId":"49570","inReplyTo":"xmqqtvlm1pon.fsf@gitster-ct.c.googlers.com","subject":"Re: [PATCHv2 0/3] git-p4: improved unshelving - small fixes","fromName":"Luke Diamand","fromEmail":"luke@diamand.org","sentAt":"2018-10-24T11:51:17Z","receivedAt":"2018-10-24T11:51:31Z","isPatch":false,"sender":{"key":"luke@diamand.org","avatar":"https://avatars.githubusercontent.com/u/5330967?v=4"},"body":"On Tue, 16 Oct 2018 at 05:27, Junio C Hamano <gitster@pobox.com> wrote:\n>\n> Luke Diamand <luke@diamand.org> writes:\n>\n> > This is the same as my earlier patch other than fixing the\n> > documentation to reflect the change to the destination branch,\n> > as noticed by Junio.\n>\n> Also you set up when-finished driver for clean-up before running\n> clone, which I think is a good change, too.\n>\n> Will replace.  Thanks.\n\nAt the moment the parent commit file revisions are constructed by\np4-printing the relevant files at the required version. That's because\nit's easy to do - I can just make use of the existing infrastructure\nfor grabbing P4 changes.\n\nHowever, in most cases we will already have these files present in the\ngit repo - it's just that we don't know where. I think it ought to be\npossible to look at the revisions of each file, and then search\nthrough the git revision history for that file to find the magic\ncomment marker that git-p4 inserts (which has the P4 changelist\nembedded in it) and then use that - rather than going back to the\nPerforce depot.\n\nIn most cases that ought to be quite a bit faster, especially for large files.\n\nFor now I'm not proposing to do this as it's quite a bit more work\n(this isn't really my day job!) and for the typical use case (at least\nthe ones I encounter) the performance of unshelving isn't really that\nimportant - the fact that it does it at all is quite amazing.\n\nBut anyway, if someone somewhere finds that git-p4 unshelve\nperformance is too slow, then that's the change to make.\n\nLuke\n"}]}