{"thread":{"id":"14274","subject":"Re: PATCH: Allow ':/<oneline prefix>' notation to specify a specific file","startedAt":"2008-07-03T11:05:21Z","lastAt":"2008-07-03T11:05:21Z","messageCount":1,"participants":["Eric Raible"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"82108","messageId":"279b37b20807030405s8212daarcd4d0083cc2df03e@mail.gmail.com","threadId":"14274","inReplyTo":null,"subject":"Re: PATCH: Allow ':/<oneline prefix>' notation to specify a specific file","fromName":"Eric Raible","fromEmail":"raible@gmail.com","sentAt":"2008-07-03T11:05:21Z","receivedAt":"2008-07-03T11:05:21Z","isPatch":false,"sender":{"key":"raible@gmail.com","avatar":null},"body":"On Thu, Jul 3, 2008 at 2:20 AM, Junio C Hamano <gitster@pobox.com> wrote:\n> So when you have \":/A:B:C\", you first try to look for string \"A:B:C\", and\n> then when it fails try \"A:B\" and look for path C?\n\nExactly.  And as you pointed out it doesn't break existing usage by design.\n\n>  (1) An obvious micro-optimization. Check if \"A:B:C\" is a rev, and if and\n>     only if it fails, run strrchr() to find fallback point;\n\nDone.  This version is more careful about return values as well.\n\n>  (2) When you do not find either \"A:B:C\" nor \"A:B\", perhaps try \"A\" and\n>     find \"B:C\" as a path in it?  IOW, you may want to fallback more than\n>     once;\n>  (3) If you are given \":/A~20\" or \":/A^2\", perhaps you would want to do\n>     something similar?\n\nI agree these are nice but get_sha1_oneline() is time-consuming as is\nand I'm not familiar enough with the code to attempt a complete\nrefactorization.\n\nAnd without refactoring get_sha1_oneline() would need to be called\nrepeated for each ~, ^, or : (working backward) until it succeeds.\n\nI'll leave it to Johannes to refactor get_sha1_oneline to handle the\n\":/A~20\" or \":/A^2\" cases if he chooses to, as it's currently beyond\nmy git-fu.\n\nAn alternative suggested by Peff:\n\t:/ should stop eating text at the first ':', and allow '\\:' for\n\ta literal colon and '\\\\' for a literal backslash.\n\nis arguably better because it's completely unambiguous and allows\nfor a simpler implementation but it's not backwards compatible.\nI'd be willing to come up with patch for that if people agree that\nit's worth it.\n\nPlease note that the commit message uses the current subject,\nso if this is applied it should be kept consistent.\n\n- Eric\n\n----- 8< -----\n\nAlthough the rev-parse documentation claims that the tree-ish:path/to/file\nsyntax is applicable to all tree-ish forms this is not so when using the\n:/ \"oneline prefix\" syntax introduced in v1.5.0.1-227-g28a4d94.\n\nFor instance, to see the file changed by this patch one could say:\n\tgit show \":/Allow ':/<oneline prefix>'\":sha1_name.c\n\nNote that this should but doesn't handle ~ and ^, so it will fail when\ntrying to show the parent of this commit message by using\n\tgit show \":/Allow ':/<oneline prefix>'\"^\n\nSigned-off-by: Eric Raible <raible@gmail.com>\n---\n sha1_name.c |   16 ++++++++++++++--\n 1 files changed, 14 insertions(+), 2 deletions(-)\n\ndiff --git a/sha1_name.c b/sha1_name.c\nindex b0b2167..415b4ce 100644\n--- a/sha1_name.c\n+++ b/sha1_name.c\n@@ -697,8 +697,20 @@ int get_sha1_with_mode(const char *name, unsigned\nchar *sha1, unsigned *mode)\n \t\tint stage = 0;\n \t\tstruct cache_entry *ce;\n \t\tint pos;\n-\t\tif (namelen > 2 && name[1] == '/')\n-\t\t\treturn get_sha1_oneline(name + 2, sha1);\n+\t\tif (namelen > 2 && name[1] == '/') {\n+\t\t\tchar *copy, *colon;\n+\t\t\tname += 2;\n+\t\t\tret = get_sha1_oneline(name, sha1);\n+\t\t\tif (!ret || !(colon = strrchr(name, ':')))\n+\t\t\t\treturn ret;\n+\t\t\tcopy = xstrdup(name);\n+\t\t\tcopy[colon - name] = '\\0';\n+\t\t\tret = get_sha1_oneline(copy, sha1);\n+\t\t\tif (!ret)\n+\t\t\t\tret = get_tree_entry(sha1, colon+1, sha1, mode);\n+\t\t\tfree(copy);\n+\t\t\treturn ret;\n+\t\t}\n \t\tif (namelen < 3 ||\n \t\t    name[2] != ':' ||\n \t\t    name[1] < '0' || '3' < name[1])\n-- \n1.5.6.1.1356.g3885.dirty\n"}]}