{"thread":{"id":"12698","subject":"Fix tree mode of the file list for files containing curly brackets","startedAt":"2008-03-14T21:49:04Z","lastAt":"2008-04-27T16:51:56Z","messageCount":5,"participants":["Alex Riesen","Paul Mackerras"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"72146","messageId":"20080314214904.GA5914@steel.home","threadId":"12698","inReplyTo":null,"subject":"Fix tree mode of the file list for files containing curly brackets","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2008-03-14T21:49:04Z","receivedAt":"2008-03-14T21:49:04Z","isPatch":false,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"As far as I could understand the online documentation the [lindex ...]\nthing expects an array, which a string produced by git-ls-tree is not.\nSo [split ...] it first, to get a real Tcl string-array.\n\nFor instance:\n\n    $ git init\n    $ date >file\n    $ git add . && git commit -m1\n    $ git mv file '{a-b}.a.b'\n    $ git commit -m2\n    $ gitk\n\nNow switch the file list from \"Patch\" to \"Tree\":\n\n    list element in braces followed by \".a.b\" instead of space\n    list element in braces followed by \".a.b\" instead of space\n\twhile executing\n    \"lindex $line 1\"\n\t(procedure \"gettreeline\" line 9)\n\tinvoked from within\n    \"gettreeline file11 4b155a05282eeccd7c8fd381b22ed442efde2850\"\n\t(\"eval\" body line 1)\n\tinvoked from within\n    \"eval $script\"\n\t(procedure \"dorunq\" line 9)\n\tinvoked from within\n    \"dorunq\"\n\t(\"after\" script)\n\nSigned-off-by: Alex Riesen <raa.lkml@gmail.com>\n\n--\n\nMy workaround for the problem was the patch attached, but as I know\nnext to nothing of Tcl, I suspect it is at least incomplete (there\ncould be other places with the same problem).\n\ndiff --git a/gitk-git/gitk b/gitk-git/gitk\nindex f1f21e9..3368148 100644\n--- a/gitk-git/gitk\n+++ b/gitk-git/gitk\n@@ -4946,14 +4946,10 @@ proc gettreeline {gtf id} {\n \tif {$diffids eq $nullid} {\n \t    set fname $line\n \t} else {\n-\t    if {$diffids ne $nullid2 && [lindex $line 1] ne \"blob\"} continue\n-\t    set i [string first \"\\t\" $line]\n-\t    if {$i < 0} continue\n-\t    set sha1 [lindex $line 2]\n-\t    set fname [string range $line [expr {$i+1}] end]\n-\t    if {[string index $fname 0] eq \"\\\"\"} {\n-\t\tset fname [lindex $fname 0]\n-\t    }\n+\t    set la [split \"$line\" \" \\t\"]\n+\t    if {$diffids ne $nullid2 && [lindex $la 1] ne \"blob\"} continue\n+\t    set sha1 [lindex $la 2]\n+\t    set fname [lindex $la 3]\n \t    lappend treeidlist($id) $sha1\n \t}\n \tlappend treefilelist($id) $fname\n"},{"id":"72147","messageId":"20080314215841.GB5914@steel.home","threadId":"12698","inReplyTo":"20080314214904.GA5914@steel.home","subject":"[PATCH] Fix tree mode of the file list for files containing curly brackets","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2008-03-14T21:58:41Z","receivedAt":"2008-03-14T21:58:41Z","isPatch":true,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"As far as I could understand the online documentation the [lindex ...]\nthing expects an array, which a string produced by git-ls-tree is not.\nSo [split ...] it first, to get a real Tcl string-array.\n\nFor instance:\n\n    $ git init\n    $ date >file\n    $ git add . && git commit -m1\n    $ git mv file '{a-b}.a.b'\n    $ git commit -m2\n    $ git mv file '{a-b}.a.b{'\n    $ git commit -m3\n    $ git mv file '{a-b}.a .b{'\n    $ git commit -m4\n    $ gitk\n\nNow switch the file list from \"Patch\" to \"Tree\":\n\n    list element in braces followed by \".a.b\" instead of space\n    list element in braces followed by \".a.b\" instead of space\n\twhile executing\n    \"lindex $line 1\"\n\t(procedure \"gettreeline\" line 9)\n\tinvoked from within\n    \"gettreeline file11 4b155a05282eeccd7c8fd381b22ed442efde2850\"\n\t(\"eval\" body line 1)\n\tinvoked from within\n    \"eval $script\"\n\t(procedure \"dorunq\" line 9)\n\tinvoked from within\n    \"dorunq\"\n\t(\"after\" script)\n\nSigned-off-by: Alex Riesen <raa.lkml@gmail.com>\n---\nAlex Riesen, Fri, Mar 14, 2008 22:49:04 +0100:\n> +\t    set la [split \"$line\" \" \\t\"]\n> +\t    if {$diffids ne $nullid2 && [lindex $la 1] ne \"blob\"} continue\n> +\t    set sha1 [lindex $la 2]\n> +\t    set fname [lindex $la 3]\n\nAnd, as I actually do know nothing about Tcl, it does not work for\nfiles with spaces. The last lindex is obviuosly wrong, it breaks names\nwith whitespaces.\n\n gitk-git/gitk |   12 ++++--------\n 1 files changed, 4 insertions(+), 8 deletions(-)\n\ndiff --git a/gitk-git/gitk b/gitk-git/gitk\nindex f1f21e9..b3a57be 100644\n--- a/gitk-git/gitk\n+++ b/gitk-git/gitk\n@@ -4946,14 +4946,10 @@ proc gettreeline {gtf id} {\n \tif {$diffids eq $nullid} {\n \t    set fname $line\n \t} else {\n-\t    if {$diffids ne $nullid2 && [lindex $line 1] ne \"blob\"} continue\n-\t    set i [string first \"\\t\" $line]\n-\t    if {$i < 0} continue\n-\t    set sha1 [lindex $line 2]\n-\t    set fname [string range $line [expr {$i+1}] end]\n-\t    if {[string index $fname 0] eq \"\\\"\"} {\n-\t\tset fname [lindex $fname 0]\n-\t    }\n+\t    set la [split \"$line\" \" \"]\n+\t    if {$diffids ne $nullid2 && [lindex $la 1] ne \"blob\"} continue\n+\t    set sha1 [lindex $la 2]\n+\t    set fname [lindex [split \"$line\" \"\\t\"] 1]\n \t    lappend treeidlist($id) $sha1\n \t}\n \tlappend treefilelist($id) $fname\n-- \n1.5.4.4.578.g182d\n"},{"id":"75284","messageId":"20080427105700.GA28896@steel.home","threadId":"12698","inReplyTo":"20080314214904.GA5914@steel.home","subject":"[RESEND] [PATCH] Fix tree mode of the file list for files containing curly brackets","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2008-04-27T10:57:00Z","receivedAt":"2008-04-27T10:57:00Z","isPatch":true,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"As far as I could understand the online documentation the [lindex ...]\nthing expects an array, which a string produced by git-ls-tree is not.\nSo [split ...] it first, to get a real Tcl string-array.\n\nFor instance:\n\n    $ git init\n    $ date >file\n    $ git add . && git commit -m1\n    $ git mv file '{a-b}.a.b'\n    $ git commit -m2\n    $ git mv file '{a-b}.a.b{'\n    $ git commit -m3\n    $ git mv file '{a-b}.a .b{'\n    $ git commit -m4\n    $ gitk\n\nNow switch the file list from \"Patch\" to \"Tree\":\n\n    list element in braces followed by \".a.b\" instead of space\n    list element in braces followed by \".a.b\" instead of space\n\twhile executing\n    \"lindex $line 1\"\n\t(procedure \"gettreeline\" line 9)\n\tinvoked from within\n    \"gettreeline file11 4b155a05282eeccd7c8fd381b22ed442efde2850\"\n\t(\"eval\" body line 1)\n\tinvoked from within\n    \"eval $script\"\n\t(procedure \"dorunq\" line 9)\n\tinvoked from within\n    \"dorunq\"\n\t(\"after\" script)\n\nSigned-off-by: Alex Riesen <raa.lkml@gmail.com>\n---\nAlex Riesen, Fri, Mar 14, 2008 22:49:04 +0100:\n> +\t    set la [split \"$line\" \" \\t\"]\n> +\t    if {$diffids ne $nullid2 && [lindex $la 1] ne \"blob\"} continue\n> +\t    set sha1 [lindex $la 2]\n> +\t    set fname [lindex $la 3]\n\nAnd, as I actually do know nothing about Tcl, it does not work for\nfiles with spaces. The last lindex is obviuosly wrong, it breaks names\nwith whitespaces.\n\nI rebased the patch on current master.\n\n gitk-git/gitk |   12 ++++--------\n 1 files changed, 4 insertions(+), 8 deletions(-)\n\ndiff --git a/gitk-git/gitk b/gitk-git/gitk\nindex 9a4d9c4..5599878 100644\n--- a/gitk-git/gitk\n+++ b/gitk-git/gitk\n@@ -4992,14 +4992,10 @@ proc gettreeline {gtf id} {\n \tif {$diffids eq $nullid} {\n \t    set fname $line\n \t} else {\n-\t    if {$diffids ne $nullid2 && [lindex $line 1] ne \"blob\"} continue\n-\t    set i [string first \"\\t\" $line]\n-\t    if {$i < 0} continue\n-\t    set sha1 [lindex $line 2]\n-\t    set fname [string range $line [expr {$i+1}] end]\n-\t    if {[string index $fname 0] eq \"\\\"\"} {\n-\t\tset fname [lindex $fname 0]\n-\t    }\n+\t    set la [split \"$line\" \" \\t\"]\n+\t    if {$diffids ne $nullid2 && [lindex $la 1] ne \"blob\"} continue\n+\t    set sha1 [lindex $la 2]\n+\t    set fname [lindex [split \"$line\" \"\\t\"] 1]\n \t    lappend treeidlist($id) $sha1\n \t}\n \tlappend treefilelist($id) $fname\n"},{"id":"75290","messageId":"18452.26961.14738.430774@cargo.ozlabs.ibm.com","threadId":"12698","inReplyTo":"20080427105700.GA28896@steel.home","subject":"Re: [RESEND] [PATCH] Fix tree mode of the file list for files containing curly brackets","fromName":"Paul Mackerras","fromEmail":"paulus@samba.org","sentAt":"2008-04-27T11:53:53Z","receivedAt":"2008-04-27T11:53:53Z","isPatch":true,"sender":{"key":"paulus@samba.org","avatar":"https://avatars.githubusercontent.com/u/1606439?v=4"},"body":"Alex Riesen writes:\n\n> As far as I could understand the online documentation the [lindex ...]\n> thing expects an array, which a string produced by git-ls-tree is not.\n> So [split ...] it first, to get a real Tcl string-array.\n\nUnfortunately that will do the wrong thing if the filename contains a\ntab character.  I think the right thing is to split the line textually\nat the tab, then treat the first part as a list (which will be OK\nsince it consists of words without special characters, separated by\nspaces), and the second part as the filename.  That is what I was\ntrying to do anyway, but I forgot to strip off the part after the tab,\nwhich is why lindex got unhappy with it.  Here's the patch I'm about\nto commit.\n\nPaul.\n\ndiff --git a/gitk-git/gitk b/gitk-git/gitk\nindex 9a4d9c4..da685aa 100644\n--- a/gitk-git/gitk\n+++ b/gitk-git/gitk\n@@ -4992,11 +4992,12 @@ proc gettreeline {gtf id} {\n \tif {$diffids eq $nullid} {\n \t    set fname $line\n \t} else {\n-\t    if {$diffids ne $nullid2 && [lindex $line 1] ne \"blob\"} continue\n \t    set i [string first \"\\t\" $line]\n \t    if {$i < 0} continue\n-\t    set sha1 [lindex $line 2]\n \t    set fname [string range $line [expr {$i+1}] end]\n+\t    set line [string range $line 0 [expr {$i-1}]]\n+\t    if {$diffids ne $nullid2 && [lindex $line 1] ne \"blob\"} continue\n+\t    set sha1 [lindex $line 2]\n \t    if {[string index $fname 0] eq \"\\\"\"} {\n \t\tset fname [lindex $fname 0]\n \t    }\n"},{"id":"75300","messageId":"20080427165156.GA3828@steel.home","threadId":"12698","inReplyTo":"18452.26961.14738.430774@cargo.ozlabs.ibm.com","subject":"Re: [RESEND] [PATCH] Fix tree mode of the file list for files containing curly brackets","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2008-04-27T16:51:56Z","receivedAt":"2008-04-27T16:51:56Z","isPatch":true,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"Paul Mackerras, Sun, Apr 27, 2008 13:53:53 +0200:\n> Alex Riesen writes:\n> \n> > As far as I could understand the online documentation the [lindex ...]\n> > thing expects an array, which a string produced by git-ls-tree is not.\n> > So [split ...] it first, to get a real Tcl string-array.\n> \n> Unfortunately that will do the wrong thing if the filename contains a\n> tab character.  I think the right thing is to split the line textually\n> at the tab, then treat the first part as a list (which will be OK\n> since it consists of words without special characters, separated by\n> spaces), and the second part as the filename.  That is what I was\n> trying to do anyway, but I forgot to strip off the part after the tab,\n> which is why lindex got unhappy with it.  Here's the patch I'm about\n> to commit.\n> \n\nFWIW, it does the right thing for me:\n\n    $ git init\n    Initialized empty Git repository in .git/\n    $ >a\n    $ git add .\n    $ gci -m.\n    Created initial commit 86ee2fa: .\n     0 files changed, 0 insertions(+), 0 deletions(-)\n     create mode 100644 a\n    $ git mv a ' { b } '\n    $ gci -m.\n    Created commit 2a90dc5: .\n     1 files changed, 0 insertions(+), 0 deletions(-)\n     rename a =>  { b }  (100%)\n    $ gitk\n    $ happy\n    The program 'happy' is currently not installed.  You can install it by typing:\n    sudo apt-get install happy\n    bash: happy: command not found\n"}]}