{"thread":{"id":"15568","subject":"[PATCH (GIT-GUI,GITK) 1/8] git-gui: Cleanup handling of the default encoding.","startedAt":"2008-09-17T21:07:31Z","lastAt":"2008-10-12T16:35:05Z","messageCount":44,"participants":["Alexander Gavrilov","Paul Mackerras","Dmitry Potapov","Johannes Sixt","Shawn O. Pearce","Jakub Narebski"],"isPatch":true,"patchVersion":1,"patchTotal":8},"messages":[{"id":"90967","messageId":"1221685659-476-1-git-send-email-angavrilov@gmail.com","threadId":"15568","inReplyTo":null,"subject":"[PATCH (GIT-GUI,GITK) 0/8] Encoding support in GUI","fromName":"Alexander Gavrilov","fromEmail":"angavrilov@gmail.com","sentAt":"2008-09-17T21:07:31Z","receivedAt":"2008-09-17T21:07:31Z","isPatch":true,"sender":{"key":"angavrilov@gmail.com","avatar":"https://avatars.githubusercontent.com/u/42666?v=4"},"body":"\nCurrently GUI tools don't provide any support for\nviewing files that contain non-ASCII characters. This set of\npatches addresses that issue. The git-gui part of the series\nis based on patches that are currently in the 'pu' branch\nof the git-gui repository.\n\n\nFile encoding can be specified in the following ways:\n\n1) It defaults to the current locale encoding.\n2) It can be overridden by setting the gui.encoding option.\n3) It can be further set on per-file basis by specifying\n   the 'encoding' attribute in gitattributes.\n4) Finally, git-gui allows directly selecting encodings\n   through a popup menu.\n\n\nThe last item is a necessity to compensate for the fact that\nnow staging/unstaging hunks would not work, if the selected\nencoding is incompatible with the actual data:\n\nWhile most single-byte character sets are mutually compatible,\nall multibyte encodings, including utf-8, have the concept\nof invalid byte sequences, and thus are not completely\nreversible. Because of this, git-gui won't be able to apply\nhunks that contain such sequences, and the user would have to\nspecify the encoding correctly, or fallback to ISO-8859-1.\n\n\nSince git apparently cannot work with filenames in non-locale\nencodings anyway, I did not try to do anything about it apart\nfrom fixing some obvious bugs.\n\nThere are also some bugs in handling of commit encodings in gitk,\nbut they are out of the scope of this series.\n\n\n\nGIT-GUI:\n\tgit-gui: Cleanup handling of the default encoding.\n\t---\n\tgit-gui.sh       |    1 +\n\tlib/blame.tcl    |    2 +-\n\tlib/diff.tcl     |   11 ++++++-----\n\tlib/encoding.tcl |   14 ++++++++++++++\n\tlib/option.tcl   |   24 ++++++++++++++++++++++++\n\t5 files changed, 46 insertions(+), 6 deletions(-)\n\n\tgit-gui: Add a menu of available encodings.\n\t---\n\tlib/encoding.tcl |  133 ++++++++++++++++++++++++++++++++++++++++++++++++++++-\n\tlib/option.tcl   |   13 +++++-\n\t2 files changed, 142 insertions(+), 4 deletions(-)\n\n\tgit-gui: Allow forcing display encoding for diffs using a submenu.\n\t---\n\tgit-gui.sh       |    8 ++++++++\n\tlib/diff.tcl     |    9 +++++++++\n\tlib/encoding.tcl |   29 +++++++++++++++++++++++++++--\n\t3 files changed, 44 insertions(+), 2 deletions(-)\n\n\tgit-gui: Optimize encoding name resolution using a lookup table.\n\t---\n\tlib/encoding.tcl |   82 +++++++++++++++++++++++++++++++++++-------------------\n\t1 files changed, 53 insertions(+), 29 deletions(-)\n\n\tgit-gui: Support the encoding menu in gui blame.\n\t---\n\tlib/blame.tcl |   17 +++++++++++++++++\n\t1 files changed, 17 insertions(+), 0 deletions(-)\n\n\nGITK:\n\tgitk: Port new encoding logic from git-gui.\n\t---\n\tgitk |   50 +++++++++++++++++++++++++++++++++++++++++++++++---\n\t1 files changed, 47 insertions(+), 3 deletions(-)\n\n\tgitk: Implement file contents encoding support.\n\t---\n\tgitk |   19 ++++++++++++++++---\n\t1 files changed, 16 insertions(+), 3 deletions(-)\n\n\tgitk: Support filenames in the locale encoding.\n\t---\n\tgitk |   16 +++++++++++-----\n\t1 files changed, 11 insertions(+), 5 deletions(-)\n"},{"id":"90966","messageId":"1221685659-476-2-git-send-email-angavrilov@gmail.com","threadId":"15568","inReplyTo":"1221685659-476-1-git-send-email-angavrilov@gmail.com","subject":"[PATCH (GIT-GUI,GITK) 1/8] git-gui: Cleanup handling of the default encoding.","fromName":"Alexander Gavrilov","fromEmail":"angavrilov@gmail.com","sentAt":"2008-09-17T21:07:32Z","receivedAt":"2008-09-17T21:07:32Z","isPatch":true,"sender":{"key":"angavrilov@gmail.com","avatar":"https://avatars.githubusercontent.com/u/42666?v=4"},"body":"- Make diffs and blame default to the system (locale)\n  encoding instead of hard-coding UTF-8.\n- Add a gui.encoding option to allow overriding it.\n- gitattributes still have the final word.\n\nThe rationale for this is Windows support:\n\n1) Windows people are accustomed to using legacy encodings\n   for text files. For many of them defaulting to utf-8\n   will be counter-intuitive.\n2) Windows doesn't support utf-8 locales, and switching\n   the system encoding is a real pain. Thus the option.\n\nThis patch also adds proper encoding conversion to Apply Hunk/Line.\n\nSigned-off-by: Alexander Gavrilov <angavrilov@gmail.com>\n---\n git-gui.sh       |    1 +\n lib/blame.tcl    |    2 +-\n lib/diff.tcl     |   11 ++++++-----\n lib/encoding.tcl |   14 ++++++++++++++\n lib/option.tcl   |   24 ++++++++++++++++++++++++\n 5 files changed, 46 insertions(+), 6 deletions(-)\n\ndiff --git a/git-gui.sh b/git-gui.sh\nindex 91457a2..444990b 100755\n--- a/git-gui.sh\n+++ b/git-gui.sh\n@@ -678,6 +678,7 @@ set default_config(merge.verbosity) 2\n set default_config(user.name) {}\n set default_config(user.email) {}\n \n+set default_config(gui.encoding) [encoding system]\n set default_config(gui.matchtrackingbranch) false\n set default_config(gui.pruneduringfetch) false\n set default_config(gui.trustmtime) false\ndiff --git a/lib/blame.tcl b/lib/blame.tcl\nindex 7535adb..84d55b5 100644\n--- a/lib/blame.tcl\n+++ b/lib/blame.tcl\n@@ -402,7 +402,7 @@ method _load {jump} {\n \tfconfigure $fd \\\n \t\t-blocking 0 \\\n \t\t-translation lf \\\n-\t\t-encoding [tcl_encoding [gitattr $path encoding UTF-8]]\n+\t\t-encoding [get_path_encoding $path]\n \tfileevent $fd readable [cb _read_file $fd $jump]\n \tset current_fd $fd\n }\ndiff --git a/lib/diff.tcl b/lib/diff.tcl\nindex b0ecfbc..8fefc5d 100644\n--- a/lib/diff.tcl\n+++ b/lib/diff.tcl\n@@ -164,11 +164,10 @@ proc show_other_diff {path w m scroll_pos} {\n \t\t\t\t\tset sz [string length $content]\n \t\t\t\t}\n \t\t\t\tfile {\n-\t\t\t\t\tset enc [gitattr $path encoding UTF-8]\n \t\t\t\t\tset fd [open $path r]\n \t\t\t\t\tfconfigure $fd \\\n \t\t\t\t\t\t-eofchar {} \\\n-\t\t\t\t\t\t-encoding [tcl_encoding $enc]\n+\t\t\t\t\t\t-encoding [get_path_encoding $path]\n \t\t\t\t\tset content [read $fd $max_sz]\n \t\t\t\t\tclose $fd\n \t\t\t\t\tset sz [file size $path]\n@@ -282,7 +281,7 @@ proc start_show_diff {scroll_pos {add_opts {}}} {\n \tset ::current_diff_inheader 1\n \tfconfigure $fd \\\n \t\t-blocking 0 \\\n-\t\t-encoding [tcl_encoding [gitattr $path encoding UTF-8]] \\\n+\t\t-encoding [get_path_encoding $path] \\\n \t\t-translation lf\n \tfileevent $fd readable [list read_diff $fd $scroll_pos]\n }\n@@ -435,8 +434,9 @@ proc apply_hunk {x y} {\n \t}\n \n \tif {[catch {\n+\t\tset enc [get_path_encoding $current_diff_path]\n \t\tset p [eval git_write $apply_cmd]\n-\t\tfconfigure $p -translation binary -encoding binary\n+\t\tfconfigure $p -translation binary -encoding $enc\n \t\tputs -nonewline $p $current_diff_header\n \t\tputs -nonewline $p [$ui_diff get $s_lno $e_lno]\n \t\tclose $p} err]} {\n@@ -604,8 +604,9 @@ proc apply_line {x y} {\n \tset patch \"@@ -$hln,$n +$hln,[eval expr $n $sign 1] @@\\n$patch\"\n \n \tif {[catch {\n+\t\tset enc [get_path_encoding $current_diff_path]\n \t\tset p [eval git_write $apply_cmd]\n-\t\tfconfigure $p -translation binary -encoding binary\n+\t\tfconfigure $p -translation binary -encoding $enc\n \t\tputs -nonewline $p $current_diff_header\n \t\tputs -nonewline $p $patch\n \t\tclose $p} err]} {\ndiff --git a/lib/encoding.tcl b/lib/encoding.tcl\nindex 7f06b0d..e186b0c 100644\n--- a/lib/encoding.tcl\n+++ b/lib/encoding.tcl\n@@ -274,3 +274,17 @@ proc tcl_encoding {enc} {\n     }\n     return {}\n }\n+\n+proc get_path_encoding {path} {\n+\tset tcl_enc [tcl_encoding [get_config gui.encoding]]\n+\tif {$tcl_enc eq {}} {\n+\t\tset tcl_enc [encoding system]\n+\t}\n+\tif {$path ne {}} {\n+\t\tset enc2 [tcl_encoding [gitattr $path encoding $tcl_enc]]\n+\t\tif {$enc2 ne {}} {\n+\t\t\tset tcl_enc $enc2\n+\t\t}\n+\t}\n+\treturn $tcl_enc\n+}\ndiff --git a/lib/option.tcl b/lib/option.tcl\nindex 9b865f6..40af44e 100644\n--- a/lib/option.tcl\n+++ b/lib/option.tcl\n@@ -1,6 +1,28 @@\n # git-gui options editor\n # Copyright (C) 2006, 2007 Shawn Pearce\n \n+proc config_check_encodings {} {\n+\tglobal repo_config_new global_config_new\n+\n+\tset enc $global_config_new(gui.encoding)\n+\tif {$enc eq {}} {\n+\t\tset global_config_new(gui.encoding) [encoding system]\n+\t} elseif {[tcl_encoding $enc] eq {}} {\n+\t\terror_popup [mc \"Invalid global encoding '%s'\" $enc]\n+\t\treturn 0\n+\t}\n+\n+\tset enc $repo_config_new(gui.encoding)\n+\tif {$enc eq {}} {\n+\t\tset repo_config_new(gui.encoding) [encoding system]\n+\t} elseif {[tcl_encoding $enc] eq {}} {\n+\t\terror_popup [mc \"Invalid repo encoding '%s'\" $enc]\n+\t\treturn 0\n+\t}\n+\n+\treturn 1\n+}\n+\n proc save_config {} {\n \tglobal default_config font_descs\n \tglobal repo_config global_config\n@@ -130,6 +152,7 @@ proc do_options {} {\n \t\t{i-1..99 gui.diffcontext {mc \"Number of Diff Context Lines\"}}\n \t\t{i-0..99 gui.commitmsgwidth {mc \"Commit Message Text Width\"}}\n \t\t{t gui.newbranchtemplate {mc \"New Branch Name Template\"}}\n+\t\t{t gui.encoding {mc \"Default File Contents Encoding\"}}\n \t\t} {\n \t\tset type [lindex $option 0]\n \t\tset name [lindex $option 1]\n@@ -275,6 +298,7 @@ proc do_restore_defaults {} {\n }\n \n proc do_save_config {w} {\n+\tif {![config_check_encodings]} return\n \tif {[catch {save_config} err]} {\n \t\terror_popup [strcat [mc \"Failed to completely save options:\"] \"\\n\\n$err\"]\n \t}\n-- \n1.6.0.20.g6148bc\n"},{"id":"90968","messageId":"1221685659-476-3-git-send-email-angavrilov@gmail.com","threadId":"15568","inReplyTo":"1221685659-476-2-git-send-email-angavrilov@gmail.com","subject":"[PATCH (GIT-GUI,GITK) 2/8] git-gui: Add a menu of available encodings.","fromName":"Alexander Gavrilov","fromEmail":"angavrilov@gmail.com","sentAt":"2008-09-17T21:07:33Z","receivedAt":"2008-09-17T21:07:33Z","isPatch":true,"sender":{"key":"angavrilov@gmail.com","avatar":"https://avatars.githubusercontent.com/u/42666?v=4"},"body":"To make encoding selection easier, add a menu that\nlists available encodings to the Options window.\n\nMenu structure is borrowed from Firefox.\n\nSigned-off-by: Alexander Gavrilov <angavrilov@gmail.com>\n---\n lib/encoding.tcl |  133 ++++++++++++++++++++++++++++++++++++++++++++++++++++-\n lib/option.tcl   |   13 +++++-\n 2 files changed, 142 insertions(+), 4 deletions(-)\n\ndiff --git a/lib/encoding.tcl b/lib/encoding.tcl\nindex e186b0c..2c1eda3 100644\n--- a/lib/encoding.tcl\n+++ b/lib/encoding.tcl\n@@ -206,7 +206,7 @@ set encoding_aliases {\n     { ISO-8859-16 iso-ir-226 ISO_8859-16:2001 ISO_8859-16 latin10 l10 }\n     { GBK CP936 MS936 windows-936 }\n     { JIS_Encoding csJISEncoding }\n-    { Shift_JIS MS_Kanji csShiftJIS }\n+    { Shift_JIS MS_Kanji csShiftJIS ShiftJIS Shift-JIS }\n     { Extended_UNIX_Code_Packed_Format_for_Japanese csEUCPkdFmtJapanese\n       EUC-JP }\n     { Extended_UNIX_Code_Fixed_Width_for_Japanese csEUCFixWidJapanese }\n@@ -240,6 +240,52 @@ set encoding_aliases {\n     { Big5 csBig5 }\n }\n \n+set encoding_groups {\n+    {\"\" \"\"\n+\t{\"Unicode\" UTF-8}\n+\t{\"Western\" ISO-8859-1}}\n+    {we \"West European\"\n+\t{\"Western\" ISO-8859-15 CP-437 CP-850 MacRoman CP-1252 Windows-1252}\n+\t{\"Celtic\" ISO-8859-14}\n+\t{\"Greek\" ISO-8859-14 ISO-8859-7 CP-737 CP-869 MacGreek CP-1253 Windows-1253}\n+\t{\"Icelandic\" MacIceland MacIcelandic CP-861}\n+\t{\"Nordic\" ISO-8859-10 CP-865}\n+\t{\"Portuguese\" CP-860}\n+\t{\"South European\" ISO-8859-3}}\n+    {ee \"East European\"\n+\t{\"Baltic\" CP-775 ISO-8859-4 ISO-8859-13 CP-1257 Windows-1257}\n+\t{\"Central European\" CP-852 ISO-8859-2 MacCE CP-1250 Windows-1250}\n+\t{\"Croatian\" MacCroatian}\n+\t{\"Cyrillic\" CP-855 ISO-8859-5 ISO-IR-111 KOI8-R MacCyrillic CP-1251 Windows-1251}\n+\t{\"Russian\" CP-866}\n+\t{\"Ukrainian\" KOI8-U MacUkraine MacUkrainian}\n+\t{\"Romanian\" ISO-8859-16 MacRomania MacRomanian}}\n+    {ea \"East Asian\"\n+\t{\"Generic\" ISO-2022}\n+\t{\"Chinese Simplified\" GB2312 GB1988 GB12345 GB2312-RAW GBK EUC-CN GB18030 HZ ISO-2022-CN}\n+\t{\"Chinese Traditional\" Big5 Big5-HKSCS EUC-TW CP-950}\n+\t{\"Japanese\" EUC-JP ISO-2022-JP Shift-JIS JIS-0212 JIS-0208 JIS-0201 CP-932 MacJapan}\n+\t{\"Korean\" EUC-KR UHC JOHAB ISO-2022-KR CP-949 KSC5601}}\n+    {sa \"SE & SW Asian\"\n+\t{\"Armenian\" ARMSCII-8}\n+\t{\"Georgian\" GEOSTD8}\n+\t{\"Thai\" TIS-620 ISO-8859-11 CP-874 Windows-874 MacThai}\n+\t{\"Turkish\" CP-857 CP857 ISO-8859-9 MacTurkish CP-1254 Windows-1254}\n+\t{\"Vietnamese\" TCVN VISCII VPS CP-1258 Windows-1258}\n+\t{\"Hindi\" MacDevanagari}\n+\t{\"Gujarati\" MacGujarati}\n+\t{\"Gurmukhi\" MacGurmukhi}}\n+    {me \"Middle Eastern\"\n+\t{\"Arabic\" ISO-8859-6 Windows-1256 CP-1256 CP-864 MacArabic}\n+\t{\"Farsi\" MacFarsi}\n+\t{\"Hebrew\" ISO-8859-8-I Windows-1255 CP-1255 ISO-8859-8 CP-862 MacHebrew}}\n+    {mi \"Misc\"\n+\t{\"7-bit\" ASCII}\n+\t{\"16-bit\" Unicode}\n+\t{\"Legacy\" CP-863 EBCDIC}\n+\t{\"Symbol\" Symbol Dingbats MacDingbats MacCentEuro}}\n+}\n+\n proc tcl_encoding {enc} {\n     global encoding_aliases\n     set names [encoding names]\n@@ -248,7 +294,7 @@ proc tcl_encoding {enc} {\n     set i [lsearch -exact $lcnames $enc]\n     if {$i < 0} {\n \t# look for \"isonnn\" instead of \"iso-nnn\" or \"iso_nnn\"\n-\tif {[regsub {^iso[-_]} $enc iso encx]} {\n+\tif {[regsub {^(iso|cp|ibm|jis)[-_]} $enc {\\1} encx]} {\n \t    set i [lsearch -exact $lcnames $encx]\n \t}\n     }\n@@ -260,7 +306,7 @@ proc tcl_encoding {enc} {\n \t    foreach e $ll {\n \t\tset i [lsearch -exact $lcnames $e]\n \t\tif {$i < 0} {\n-\t\t    if {[regsub {^iso[-_]} $e iso ex]} {\n+\t\t    if {[regsub {^(iso|cp|ibm|jis)[-_]} $e {\\1} ex]} {\n \t\t\tset i [lsearch -exact $lcnames $ex]\n \t\t    }\n \t\t}\n@@ -288,3 +334,84 @@ proc get_path_encoding {path} {\n \t}\n \treturn $tcl_enc\n }\n+\n+proc build_encoding_submenu {parent grp cmd} {\n+\tglobal used_encodings\n+\n+\tset mid [lindex $grp 0]\n+\tset gname [mc [lindex $grp 1]]\n+\n+\tset smenu {}\n+\tforeach subset [lrange $grp 2 end] {\n+\t\tset name [mc [lindex $subset 0]]\n+\n+\t\tforeach enc [lrange $subset 1 end] {\n+\t\t\tset tcl_enc [tcl_encoding $enc]\n+\t\t\tif {$tcl_enc eq {}} continue\n+\n+\t\t\tif {$smenu eq {}} {\n+\t\t\t\tif {$mid eq {}} {\n+\t\t\t\t\tset smenu $parent\n+\t\t\t\t} else {\n+\t\t\t\t\tset smenu \"$parent.$mid\"\n+\t\t\t\t\tmenu $smenu\n+\t\t\t\t\t$parent add cascade \\\n+\t\t\t\t\t\t-label $gname \\\n+\t\t\t\t\t\t-menu $smenu\n+\t\t\t\t}\n+\t\t\t}\n+\n+\t\t\tif {$name ne {}} {\n+\t\t\t\tset lbl \"$name ($enc)\"\n+\t\t\t} else {\n+\t\t\t\tset lbl $enc\n+\t\t\t}\n+\t\t\t$smenu add command \\\n+\t\t\t\t-label $lbl \\\n+\t\t\t\t-command [concat $cmd [list $tcl_enc]]\n+\n+\t\t\tlappend used_encodings $tcl_enc\n+\t\t}\n+\t}\n+}\n+\n+proc popup_btn_menu {m b} {\n+\ttk_popup $m [winfo pointerx $b] [winfo pointery $b]\n+}\n+\n+proc build_encoding_menu {emenu cmd {nodef 0}} {\n+\t$emenu configure -postcommand \\\n+\t\t[list do_build_encoding_menu $emenu $cmd $nodef]\n+}\n+\n+proc do_build_encoding_menu {emenu cmd {nodef 0}} {\n+\tglobal used_encodings encoding_groups\n+\n+\t$emenu configure -postcommand {}\n+\n+\tif {!$nodef} {\n+\t\t$emenu add command \\\n+\t\t\t-label [mc \"Default\"] \\\n+\t\t\t-command [concat $cmd [list {}]]\n+\t}\n+\tset sysenc [encoding system]\n+\t$emenu add command \\\n+\t\t-label [mc \"System (%s)\" $sysenc] \\\n+\t\t-command [concat $cmd [list $sysenc]]\n+\n+\t# Main encoding tree\n+\tset used_encodings [list identity]\n+\t$emenu add separator\n+\tforeach grp $encoding_groups {\n+\t\tbuild_encoding_submenu $emenu $grp $cmd\n+\t}\n+\n+\t# Add unclassified encodings\n+\tset unused_grp [list [mc Other]]\n+\tforeach enc [encoding names] {\n+\t\tif {[lsearch -exact $used_encodings $enc] < 0} {\n+\t\t\tlappend unused_grp $enc\n+\t\t}\n+\t}\n+\tbuild_encoding_submenu $emenu [list other [mc Other] $unused_grp] $cmd\n+}\ndiff --git a/lib/option.tcl b/lib/option.tcl\nindex 40af44e..c80c939 100644\n--- a/lib/option.tcl\n+++ b/lib/option.tcl\n@@ -152,7 +152,7 @@ proc do_options {} {\n \t\t{i-1..99 gui.diffcontext {mc \"Number of Diff Context Lines\"}}\n \t\t{i-0..99 gui.commitmsgwidth {mc \"Commit Message Text Width\"}}\n \t\t{t gui.newbranchtemplate {mc \"New Branch Name Template\"}}\n-\t\t{t gui.encoding {mc \"Default File Contents Encoding\"}}\n+\t\t{c gui.encoding {mc \"Default File Contents Encoding\"}}\n \t\t} {\n \t\tset type [lindex $option 0]\n \t\tset name [lindex $option 1]\n@@ -182,6 +182,7 @@ proc do_options {} {\n \t\t\t\tpack $w.$f.$optid.v -side right -anchor e -padx 5\n \t\t\t\tpack $w.$f.$optid -side top -anchor w -fill x\n \t\t\t}\n+\t\t\tc -\n \t\t\tt {\n \t\t\t\tframe $w.$f.$optid\n \t\t\t\tlabel $w.$f.$optid.l -text \"$text:\"\n@@ -194,6 +195,16 @@ proc do_options {} {\n \t\t\t\tpack $w.$f.$optid.v -side left -anchor w \\\n \t\t\t\t\t-fill x -expand 1 \\\n \t\t\t\t\t-padx 5\n+\t\t\t\tif {$type eq {c}} {\n+\t\t\t\t\tmenu $w.$f.$optid.m\n+\t\t\t\t\tbuild_encoding_menu $w.$f.$optid.m \\\n+\t\t\t\t\t\t[list set ${f}_config_new($name)] 1\n+\t\t\t\t\tbutton $w.$f.$optid.b \\\n+\t\t\t\t\t\t-text [mc \"Change\"] \\\n+\t\t\t\t\t\t-command [list popup_btn_menu \\\n+\t\t\t\t\t\t\t$w.$f.$optid.m $w.$f.$optid.b]\n+\t\t\t\t\tpack $w.$f.$optid.b -side left -anchor w\n+\t\t\t\t}\n \t\t\t\tpack $w.$f.$optid -side top -anchor w -fill x\n \t\t\t}\n \t\t\t}\n-- \n1.6.0.20.g6148bc\n"},{"id":"90971","messageId":"1221685659-476-4-git-send-email-angavrilov@gmail.com","threadId":"15568","inReplyTo":"1221685659-476-3-git-send-email-angavrilov@gmail.com","subject":"[PATCH (GIT-GUI,GITK) 3/8] git-gui: Allow forcing display encoding for diffs using a submenu.","fromName":"Alexander Gavrilov","fromEmail":"angavrilov@gmail.com","sentAt":"2008-09-17T21:07:34Z","receivedAt":"2008-09-17T21:07:34Z","isPatch":true,"sender":{"key":"angavrilov@gmail.com","avatar":"https://avatars.githubusercontent.com/u/42666?v=4"},"body":"Add a submenu to allow dynamically changing the encoding to use\nfor diffs. Encoding settings are remembered while git-gui runs.\nThe rules are:\n\n1) Encoding set for a specific file overrides gitattributes.\n2) Last explicitly set value of the encoding overrides gui.encoding\n\nSigned-off-by: Alexander Gavrilov <angavrilov@gmail.com>\n---\n git-gui.sh       |    8 ++++++++\n lib/diff.tcl     |    9 +++++++++\n lib/encoding.tcl |   29 +++++++++++++++++++++++++++--\n 3 files changed, 44 insertions(+), 2 deletions(-)\n\ndiff --git a/git-gui.sh b/git-gui.sh\nindex 444990b..3bbb4f1 100755\n--- a/git-gui.sh\n+++ b/git-gui.sh\n@@ -2937,6 +2937,14 @@ proc create_common_diff_popup {ctxm} {\n \t\t-command {incr_font_size font_diff 1}\n \tlappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]\n \t$ctxm add separator\n+\tset emenu $ctxm.enc\n+\tmenu $emenu\n+\tbuild_encoding_menu $emenu [list force_diff_encoding]\n+\t$ctxm add cascade \\\n+\t\t-label [mc \"Encoding\"] \\\n+\t\t-menu $emenu\n+\tlappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]\n+\t$ctxm add separator\n \t$ctxm add command -label [mc \"Options...\"] \\\n \t\t-command do_options\n }\ndiff --git a/lib/diff.tcl b/lib/diff.tcl\nindex 8fefc5d..b616296 100644\n--- a/lib/diff.tcl\n+++ b/lib/diff.tcl\n@@ -40,6 +40,15 @@ proc reshow_diff {} {\n \t}\n }\n \n+proc force_diff_encoding {enc} {\n+\tglobal current_diff_path\n+\t\n+\tif {$current_diff_path ne {}} {\n+\t\tforce_path_encoding $current_diff_path $enc\n+\t\treshow_diff\n+\t}\n+}\n+\n proc handle_empty_diff {} {\n \tglobal current_diff_path file_states file_lists\n \ndiff --git a/lib/encoding.tcl b/lib/encoding.tcl\nindex 2c1eda3..b2ee38c 100644\n--- a/lib/encoding.tcl\n+++ b/lib/encoding.tcl\n@@ -321,13 +321,38 @@ proc tcl_encoding {enc} {\n     return {}\n }\n \n+proc force_path_encoding {path enc} {\n+\tglobal path_encoding_overrides last_encoding_override\n+\n+\tset enc [tcl_encoding $enc]\n+\tif {$enc eq {}} {\n+\t\tcatch { unset last_encoding_override }\n+\t\tcatch { unset path_encoding_overrides($path) }\n+\t} else {\n+\t\tset last_encoding_override $enc\n+\t\tif {$path ne {}} {\n+\t\t\tset path_encoding_overrides($path) $enc\n+\t\t}\n+\t}\n+}\n+\n proc get_path_encoding {path} {\n-\tset tcl_enc [tcl_encoding [get_config gui.encoding]]\n+\tglobal path_encoding_overrides last_encoding_override\n+\n+\tif {[info exists last_encoding_override]} {\n+\t\tset tcl_enc $last_encoding_override\n+\t} else {\n+\t\tset tcl_enc [tcl_encoding [get_config gui.encoding]]\n+\t}\n \tif {$tcl_enc eq {}} {\n \t\tset tcl_enc [encoding system]\n \t}\n \tif {$path ne {}} {\n-\t\tset enc2 [tcl_encoding [gitattr $path encoding $tcl_enc]]\n+\t\tif {[info exists path_encoding_overrides($path)]} {\n+\t\t\tset enc2 $path_encoding_overrides($path)\n+\t\t} else {\n+\t\t\tset enc2 [tcl_encoding [gitattr $path encoding $tcl_enc]]\n+\t\t}\n \t\tif {$enc2 ne {}} {\n \t\t\tset tcl_enc $enc2\n \t\t}\n-- \n1.6.0.20.g6148bc\n"},{"id":"90973","messageId":"1221685659-476-5-git-send-email-angavrilov@gmail.com","threadId":"15568","inReplyTo":"1221685659-476-4-git-send-email-angavrilov@gmail.com","subject":"[PATCH (GIT-GUI,GITK) 4/8] git-gui: Optimize encoding name resolution using a lookup table.","fromName":"Alexander Gavrilov","fromEmail":"angavrilov@gmail.com","sentAt":"2008-09-17T21:07:35Z","receivedAt":"2008-09-17T21:07:35Z","isPatch":true,"sender":{"key":"angavrilov@gmail.com","avatar":"https://avatars.githubusercontent.com/u/42666?v=4"},"body":"Encoding menu construction does almost a hundred of encoding\nresolutions, which with the old implementation led to a\nsmall but noticeable delay.\n\nSigned-off-by: Alexander Gavrilov <angavrilov@gmail.com>\n---\n lib/encoding.tcl |   82 +++++++++++++++++++++++++++++++++++-------------------\n 1 files changed, 53 insertions(+), 29 deletions(-)\n\ndiff --git a/lib/encoding.tcl b/lib/encoding.tcl\nindex b2ee38c..32668fc 100644\n--- a/lib/encoding.tcl\n+++ b/lib/encoding.tcl\n@@ -286,39 +286,63 @@ set encoding_groups {\n \t{\"Symbol\" Symbol Dingbats MacDingbats MacCentEuro}}\n }\n \n+proc build_encoding_table {} {\n+\tglobal encoding_aliases encoding_lookup_table\n+\n+\t# Prepare the lookup list; cannot use lsort -nocase because\n+\t# of compatibility issues with older Tcl (e.g. in msysgit)\n+\tset names [list]\n+\tforeach item [encoding names] {\n+\t\tlappend names [list [string tolower $item] $item]\n+\t}\n+\tset names [lsort -ascii -index 0 $names]\n+\t# neither can we use lsearch -index\n+\tset lnames [list]\n+\tforeach item $names {\n+\t\tlappend lnames [lindex $item 0]\n+\t}\n+\n+\tforeach grp $encoding_aliases {\n+\t\tset target {}\n+\t\tforeach item $grp {\n+\t\t\tset i [lsearch -sorted -ascii $lnames \\\n+\t\t\t\t\t[string tolower $item]]\n+\t\t\tif {$i >= 0} {\n+\t\t\t\tset target [lindex $names $i 1]\n+\t\t\t\tbreak\n+\t\t\t}\n+\t\t}\n+\t\tif {$target eq {}} continue\n+\t\tforeach item $grp {\n+\t\t\tset encoding_lookup_table([string tolower $item]) $target\n+\t\t}\n+\t}\n+\n+\tforeach item $names {\n+\t\tset encoding_lookup_table([lindex $item 0]) [lindex $item 1]\n+\t}\n+}\n+\n proc tcl_encoding {enc} {\n-    global encoding_aliases\n-    set names [encoding names]\n-    set lcnames [string tolower $names]\n-    set enc [string tolower $enc]\n-    set i [lsearch -exact $lcnames $enc]\n-    if {$i < 0} {\n-\t# look for \"isonnn\" instead of \"iso-nnn\" or \"iso_nnn\"\n-\tif {[regsub {^(iso|cp|ibm|jis)[-_]} $enc {\\1} encx]} {\n-\t    set i [lsearch -exact $lcnames $encx]\n+\tglobal encoding_lookup_table\n+\tif {$enc eq {}} {\n+\t\treturn {}\n+\t}\n+\tif {![info exists encoding_lookup_table]} {\n+\t\tbuild_encoding_table\n \t}\n-    }\n-    if {$i < 0} {\n-\tforeach l $encoding_aliases {\n-\t    set ll [string tolower $l]\n-\t    if {[lsearch -exact $ll $enc] < 0} continue\n-\t    # look through the aliases for one that tcl knows about\n-\t    foreach e $ll {\n-\t\tset i [lsearch -exact $lcnames $e]\n-\t\tif {$i < 0} {\n-\t\t    if {[regsub {^(iso|cp|ibm|jis)[-_]} $e {\\1} ex]} {\n-\t\t\tset i [lsearch -exact $lcnames $ex]\n-\t\t    }\n+\tset enc [string tolower $enc]\n+\tif {![info exists encoding_lookup_table($enc)]} {\n+\t\t# look for \"isonnn\" instead of \"iso-nnn\" or \"iso_nnn\"\n+\t\tif {[regsub {^(iso|cp|ibm|jis)[-_]} $enc {\\1} encx]} {\n+\t\t\tset enc $encx\n \t\t}\n-\t\tif {$i >= 0} break\n-\t    }\n-\t    break\n \t}\n-    }\n-    if {$i >= 0} {\n-\treturn [lindex $names $i]\n-    }\n-    return {}\n+\tif {[info exists encoding_lookup_table($enc)]} {\n+\t\treturn $encoding_lookup_table($enc)\n+\t} else {\n+\t\treturn {}\n+\t}\n }\n \n proc force_path_encoding {path enc} {\n-- \n1.6.0.20.g6148bc\n"},{"id":"90972","messageId":"1221685659-476-6-git-send-email-angavrilov@gmail.com","threadId":"15568","inReplyTo":"1221685659-476-5-git-send-email-angavrilov@gmail.com","subject":"[PATCH (GIT-GUI,GITK) 5/8] git-gui: Support the encoding menu in gui blame.","fromName":"Alexander Gavrilov","fromEmail":"angavrilov@gmail.com","sentAt":"2008-09-17T21:07:36Z","receivedAt":"2008-09-17T21:07:36Z","isPatch":true,"sender":{"key":"angavrilov@gmail.com","avatar":"https://avatars.githubusercontent.com/u/42666?v=4"},"body":"Allow dynamically changing the encoding from the blame\nviewer as well.\n\nSigned-off-by: Alexander Gavrilov <angavrilov@gmail.com>\n---\n lib/blame.tcl |   17 +++++++++++++++++\n 1 files changed, 17 insertions(+), 0 deletions(-)\n\ndiff --git a/lib/blame.tcl b/lib/blame.tcl\nindex 84d55b5..eb61374 100644\n--- a/lib/blame.tcl\n+++ b/lib/blame.tcl\n@@ -256,9 +256,16 @@ constructor new {i_commit i_path i_jump} {\n \t$w.ctxm add command \\\n \t\t-label [mc \"Copy Commit\"] \\\n \t\t-command [cb _copycommit]\n+\t$w.ctxm add separator\n+\tmenu $w.ctxm.enc\n+\tbuild_encoding_menu $w.ctxm.enc [cb _setencoding]\n+\t$w.ctxm add cascade \\\n+\t\t-label [mc \"Encoding\"] \\\n+\t\t-menu $w.ctxm.enc\n \t$w.ctxm add command \\\n \t\t-label [mc \"Do Full Copy Detection\"] \\\n \t\t-command [cb _fullcopyblame]\n+\t$w.ctxm add separator\n \t$w.ctxm add command \\\n \t\t-label [mc \"Show History Context\"] \\\n \t\t-command [cb _gitkcommit]\n@@ -791,6 +798,16 @@ method _click {cur_w pos} {\n \t_showcommit $this $cur_w $lno\n }\n \n+method _setencoding {enc} {\n+\tforce_path_encoding $path $enc\n+\t_load $this [list \\\n+\t\t$highlight_column \\\n+\t\t$highlight_line \\\n+\t\t[lindex [$w_file xview] 0] \\\n+\t\t[lindex [$w_file yview] 0] \\\n+\t\t]\n+}\n+\n method _load_commit {cur_w cur_d pos} {\n \tupvar #0 $cur_d line_data\n \tset lno [lindex [split [$cur_w index $pos] .] 0]\n-- \n1.6.0.20.g6148bc\n"},{"id":"90970","messageId":"1221685659-476-7-git-send-email-angavrilov@gmail.com","threadId":"15568","inReplyTo":"1221685659-476-6-git-send-email-angavrilov@gmail.com","subject":"[PATCH (GIT-GUI,GITK) 6/8] gitk: Port new encoding logic from git-gui.","fromName":"Alexander Gavrilov","fromEmail":"angavrilov@gmail.com","sentAt":"2008-09-17T21:07:37Z","receivedAt":"2008-09-17T21:07:37Z","isPatch":true,"sender":{"key":"angavrilov@gmail.com","avatar":"https://avatars.githubusercontent.com/u/42666?v=4"},"body":"Add functions that implement the same logic for file\ncontents encoding as git-gui uses:\n\n- Defaults to the system encoding.\n- Overridden by setting the gui.encoding option.\n- Further overridden on per-file basis by gitattributes.\n\nAlso extends the range of supported encoding names.\n\nSigned-off-by: Alexander Gavrilov <angavrilov@gmail.com>\n---\n gitk |   50 +++++++++++++++++++++++++++++++++++++++++++++++---\n 1 files changed, 47 insertions(+), 3 deletions(-)\n\ndiff --git a/gitk b/gitk\nindex 546627f..b210f79 100755\n--- a/gitk\n+++ b/gitk\n@@ -9726,7 +9726,7 @@ set encoding_aliases {\n     { ISO-8859-16 iso-ir-226 ISO_8859-16:2001 ISO_8859-16 latin10 l10 }\n     { GBK CP936 MS936 windows-936 }\n     { JIS_Encoding csJISEncoding }\n-    { Shift_JIS MS_Kanji csShiftJIS }\n+    { Shift_JIS MS_Kanji csShiftJIS ShiftJIS Shift-JIS }\n     { Extended_UNIX_Code_Packed_Format_for_Japanese csEUCPkdFmtJapanese\n       EUC-JP }\n     { Extended_UNIX_Code_Fixed_Width_for_Japanese csEUCFixWidJapanese }\n@@ -9768,7 +9768,7 @@ proc tcl_encoding {enc} {\n     set i [lsearch -exact $lcnames $enc]\n     if {$i < 0} {\n \t# look for \"isonnn\" instead of \"iso-nnn\" or \"iso_nnn\"\n-\tif {[regsub {^iso[-_]} $enc iso encx]} {\n+\tif {[regsub {^(iso|cp|ibm|jis)[-_]} $enc {\\1} encx]} {\n \t    set i [lsearch -exact $lcnames $encx]\n \t}\n     }\n@@ -9780,7 +9780,7 @@ proc tcl_encoding {enc} {\n \t    foreach e $ll {\n \t\tset i [lsearch -exact $lcnames $e]\n \t\tif {$i < 0} {\n-\t\t    if {[regsub {^iso[-_]} $e iso ex]} {\n+\t\t    if {[regsub {^(iso|cp|ibm|jis)[-_]} $e {\\1} ex]} {\n \t\t\tset i [lsearch -exact $lcnames $ex]\n \t\t    }\n \t\t}\n@@ -9795,6 +9795,45 @@ proc tcl_encoding {enc} {\n     return {}\n }\n \n+proc gitattr {path attr default} {\n+\tif {[catch {set r [exec git check-attr $attr -- $path]}]} {\n+\t\tset r unspecified\n+\t} else {\n+\t\tset r [join [lrange [split $r :] 2 end] :]\n+\t\tregsub {^ } $r {} r\n+\t}\n+\tif {$r eq {unspecified}} {\n+\t\treturn $default\n+\t}\n+\treturn $r\n+}\n+\n+proc get_path_encoding {path} {\n+\tglobal gui_encoding\n+\tset tcl_enc [tcl_encoding $gui_encoding]\n+\tif {$tcl_enc eq {}} {\n+\t\tset tcl_enc [encoding system]\n+\t}\n+\tif {$path ne {}} {\n+\t\tset enc2 [tcl_encoding [gitattr $path encoding $tcl_enc]]\n+\t\tif {$enc2 ne {}} {\n+\t\t\tset tcl_enc $enc2\n+\t\t}\n+\t}\n+\treturn $tcl_enc\n+}\n+\n+proc get_cached_encoding {path} {\n+\tglobal path_encoding_cache\n+\tif {[info exists path_encoding_cache($path)]} {\n+\t\treturn $path_encoding_cache($path)\n+\t} else {\n+\t\tset enc [get_path_encoding $path]\n+\t\tset path_encoding_cache($path) $enc\n+\t\treturn $enc\n+\t}\n+}\n+\n # First check that Tcl/Tk is recent enough\n if {[catch {package require Tk 8.4} err]} {\n     show_error {} . [mc \"Sorry, gitk cannot run with this version of Tcl/Tk.\\n\\\n@@ -9817,6 +9856,11 @@ if {$tclencoding == {}} {\n     puts stderr \"Warning: encoding $gitencoding is not supported by Tcl/Tk\"\n }\n \n+set gui_encoding [encoding system]\n+catch {\n+\tset gui_encoding [exec git config --get gui.encoding]\n+}\n+\n set mainfont {Helvetica 9}\n set textfont {Courier 9}\n set uifont {Helvetica 9 bold}\n-- \n1.6.0.20.g6148bc\n"},{"id":"90974","messageId":"1221685659-476-8-git-send-email-angavrilov@gmail.com","threadId":"15568","inReplyTo":"1221685659-476-7-git-send-email-angavrilov@gmail.com","subject":"[PATCH (GIT-GUI,GITK) 7/8] gitk: Implement file contents encoding support.","fromName":"Alexander Gavrilov","fromEmail":"angavrilov@gmail.com","sentAt":"2008-09-17T21:07:38Z","receivedAt":"2008-09-17T21:07:38Z","isPatch":true,"sender":{"key":"angavrilov@gmail.com","avatar":"https://avatars.githubusercontent.com/u/42666?v=4"},"body":"Use new functions to support using explicit encoding\nconfiguration for file contents.\n\nSigned-off-by: Alexander Gavrilov <angavrilov@gmail.com>\n---\n gitk |   19 ++++++++++++++++---\n 1 files changed, 16 insertions(+), 3 deletions(-)\n\ndiff --git a/gitk b/gitk\nindex b210f79..98923e7 100755\n--- a/gitk\n+++ b/gitk\n@@ -6295,7 +6295,7 @@ proc showfile {f} {\n \t    return\n \t}\n     }\n-    fconfigure $bf -blocking 0\n+    fconfigure $bf -blocking 0 -encoding [get_cached_encoding $f]\n     filerun $bf [list getblobline $bf $diffids]\n     $ctext config -state normal\n     clear_ctext $commentend\n@@ -6333,6 +6333,7 @@ proc mergediff {id} {\n     global diffids\n     global parents\n     global diffcontext\n+    global diffencoding\n     global limitdiffs vfilelimit curview\n \n     set diffmergeid $id\n@@ -6346,9 +6347,10 @@ proc mergediff {id} {\n \terror_popup \"[mc \"Error getting merge diffs:\"] $err\"\n \treturn\n     }\n-    fconfigure $mdf -blocking 0\n+    fconfigure $mdf -blocking 0 -encoding binary\n     set mdifffd($id) $mdf\n     set np [llength $parents($curview,$id)]\n+    set diffencoding [get_cached_encoding {}]\n     settabs $np\n     filerun $mdf [list getmergediffline $mdf $id $np]\n }\n@@ -6356,6 +6358,7 @@ proc mergediff {id} {\n proc getmergediffline {mdf id np} {\n     global diffmergeid ctext cflist mergemax\n     global difffilestart mdifffd\n+    global diffencoding\n \n     $ctext conf -state normal\n     set nr 0\n@@ -6371,14 +6374,17 @@ proc getmergediffline {mdf id np} {\n \t    set here [$ctext index \"end - 1c\"]\n \t    lappend difffilestart $here\n \t    add_flist [list $fname]\n+\t    set diffencoding [get_cached_encoding $fname]\n \t    set l [expr {(78 - [string length $fname]) / 2}]\n \t    set pad [string range \"----------------------------------------\" 1 $l]\n \t    $ctext insert end \"$pad $fname $pad\\n\" filesep\n \t} elseif {[regexp {^@@} $line]} {\n+\t    set line [encoding convertfrom $diffencoding $line]\n \t    $ctext insert end \"$line\\n\" hunksep\n \t} elseif {[regexp {^[0-9a-f]{40}$} $line] || [regexp {^index} $line]} {\n \t    # do nothing\n \t} else {\n+\t    set line [encoding convertfrom $diffencoding $line]\n \t    # parse the prefix - one ' ', '-' or '+' for each parent\n \t    set spaces {}\n \t    set minuses {}\n@@ -6586,6 +6592,7 @@ proc getblobdiffs {ids} {\n     global diffcontext\n     global ignorespace\n     global limitdiffs vfilelimit curview\n+    global diffencoding\n \n     set cmd [diffcmd $ids \"-p -C --no-commit-id -U$diffcontext\"]\n     if {$ignorespace} {\n@@ -6599,7 +6606,8 @@ proc getblobdiffs {ids} {\n \treturn\n     }\n     set diffinhdr 0\n-    fconfigure $bdf -blocking 0\n+    set diffencoding [get_cached_encoding {}]\n+    fconfigure $bdf -blocking 0 -encoding binary\n     set blobdifffd($ids) $bdf\n     filerun $bdf [list getblobdiffline $bdf $diffids]\n }\n@@ -6633,6 +6641,7 @@ proc getblobdiffline {bdf ids} {\n     global diffids blobdifffd ctext curdiffstart\n     global diffnexthead diffnextnote difffilestart\n     global diffinhdr treediffs\n+    global diffencoding\n \n     set nr 0\n     $ctext conf -state normal\n@@ -6670,10 +6679,12 @@ proc getblobdiffline {bdf ids} {\n \t    } else {\n \t\tset fname [string range $line 2 [expr {$i - 1}]]\n \t    }\n+\t    set diffencoding [get_cached_encoding $fname]\n \t    makediffhdr $fname $ids\n \n \t} elseif {[regexp {^@@ -([0-9]+)(,[0-9]+)? \\+([0-9]+)(,[0-9]+)? @@(.*)} \\\n \t\t       $line match f1l f1c f2l f2c rest]} {\n+\t    set line [encoding convertfrom $diffencoding $line]\n \t    $ctext insert end \"$line\\n\" hunksep\n \t    set diffinhdr 0\n \n@@ -6693,6 +6704,7 @@ proc getblobdiffline {bdf ids} {\n \t\tif {[string index $fname 0] eq \"\\\"\"} {\n \t\t    set fname [lindex $fname 0]\n \t\t}\n+\t\tset diffencoding [get_cached_encoding $fname]\n \t\tmakediffhdr $fname $ids\n \t    } elseif {[string compare -length 3 $line \"---\"] == 0} {\n \t\t# do nothing\n@@ -6704,6 +6716,7 @@ proc getblobdiffline {bdf ids} {\n \t    $ctext insert end \"$line\\n\" filesep\n \n \t} else {\n+\t    set line [encoding convertfrom $diffencoding $line]\n \t    set x [string range $line 0 0]\n \t    if {$x == \"-\" || $x == \"+\"} {\n \t\tset tag [expr {$x == \"+\"}]\n-- \n1.6.0.20.g6148bc\n"},{"id":"90969","messageId":"1221685659-476-9-git-send-email-angavrilov@gmail.com","threadId":"15568","inReplyTo":"1221685659-476-8-git-send-email-angavrilov@gmail.com","subject":"[PATCH (GIT-GUI,GITK) 8/8] gitk: Support filenames in the locale encoding.","fromName":"Alexander Gavrilov","fromEmail":"angavrilov@gmail.com","sentAt":"2008-09-17T21:07:39Z","receivedAt":"2008-09-17T21:07:39Z","isPatch":true,"sender":{"key":"angavrilov@gmail.com","avatar":"https://avatars.githubusercontent.com/u/42666?v=4"},"body":"Ensure that gitk works properly with non-ASCII names\nin the system encoding. Apparently git does not support\nusing file names encoded differently from the current\nlocale.\n\nSigned-off-by: Alexander Gavrilov <angavrilov@gmail.com>\n---\n gitk |   16 +++++++++++-----\n 1 files changed, 11 insertions(+), 5 deletions(-)\n\ndiff --git a/gitk b/gitk\nindex 98923e7..254faa1 100755\n--- a/gitk\n+++ b/gitk\n@@ -6228,7 +6228,7 @@ proc gettree {id} {\n \t    set treepending $id\n \t    set treefilelist($id) {}\n \t    set treeidlist($id) {}\n-\t    fconfigure $gtf -blocking 0\n+\t    fconfigure $gtf -blocking 0 -encoding binary\n \t    filerun $gtf [list gettreeline $gtf $id]\n \t}\n     } else {\n@@ -6250,11 +6250,12 @@ proc gettreeline {gtf id} {\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 \t    lappend treeidlist($id) $sha1\n \t}\n+\tif {[string index $fname 0] eq \"\\\"\"} {\n+\t    set fname [lindex $fname 0]\n+\t}\n+\tset fname [encoding convertfrom $fname]\n \tlappend treefilelist($id) $fname\n     }\n     if {![eof $gtf]} {\n@@ -6370,6 +6371,7 @@ proc getmergediffline {mdf id np} {\n \t}\n \tif {[regexp {^diff --cc (.*)} $line match fname]} {\n \t    # start of a new file\n+\t    set fname [encoding convertfrom $fname]\n \t    $ctext insert end \"\\n\"\n \t    set here [$ctext index \"end - 1c\"]\n \t    lappend difffilestart $here\n@@ -6519,7 +6521,7 @@ proc gettreediffs {ids} {\n \n     set treepending $ids\n     set treediff {}\n-    fconfigure $gdtf -blocking 0\n+    fconfigure $gdtf -blocking 0 -encoding binary\n     filerun $gdtf [list gettreediffline $gdtf $ids]\n }\n \n@@ -6535,6 +6537,7 @@ proc gettreediffline {gdtf ids} {\n \t    if {[string index $file 0] eq \"\\\"\"} {\n \t\tset file [lindex $file 0]\n \t    }\n+\t    set file [encoding convertfrom $file]\n \t    lappend treediff $file\n \t}\n     }\n@@ -6679,6 +6682,7 @@ proc getblobdiffline {bdf ids} {\n \t    } else {\n \t\tset fname [string range $line 2 [expr {$i - 1}]]\n \t    }\n+\t    set fname [encoding convertfrom $fname]\n \t    set diffencoding [get_cached_encoding $fname]\n \t    makediffhdr $fname $ids\n \n@@ -6694,6 +6698,7 @@ proc getblobdiffline {bdf ids} {\n \t\tif {[string index $fname 0] eq \"\\\"\"} {\n \t\t    set fname [lindex $fname 0]\n \t\t}\n+\t\tset fname [encoding convertfrom $fname]\n \t\tset i [lsearch -exact $treediffs($ids) $fname]\n \t\tif {$i >= 0} {\n \t\t    setinlist difffilestart $i $curdiffstart\n@@ -6704,6 +6709,7 @@ proc getblobdiffline {bdf ids} {\n \t\tif {[string index $fname 0] eq \"\\\"\"} {\n \t\t    set fname [lindex $fname 0]\n \t\t}\n+\t\tset fname [encoding convertfrom $fname]\n \t\tset diffencoding [get_cached_encoding $fname]\n \t\tmakediffhdr $fname $ids\n \t    } elseif {[string compare -length 3 $line \"---\"] == 0} {\n-- \n1.6.0.20.g6148bc\n"},{"id":"90977","messageId":"18641.31356.147503.708394@cargo.ozlabs.ibm.com","threadId":"15568","inReplyTo":"1221685659-476-1-git-send-email-angavrilov@gmail.com","subject":"Re: [PATCH (GIT-GUI,GITK) 0/8] Encoding support in GUI","fromName":"Paul Mackerras","fromEmail":"paulus@samba.org","sentAt":"2008-09-17T21:45:32Z","receivedAt":"2008-09-17T21:45:32Z","isPatch":true,"sender":{"key":"paulus@samba.org","avatar":"https://avatars.githubusercontent.com/u/1606439?v=4"},"body":"Alexander Gavrilov writes:\n\n> Currently GUI tools don't provide any support for\n> viewing files that contain non-ASCII characters.\n\nWell, that's just not true, at least as far as gitk is concerned.\n\nIf you feel there are deficiencies in how gitk handles encodings (and\nI'm quite willing to believe there are, since ASCII is sufficient for\nmy needs), then please give us a detailed explanation of what you\nwould like it to do or specifically what is wrong with what it does at\nthe moment.  I'd like to see several paragraphs, not just the one or\ntwo sentences you have put in the descriptions for patches 6-8.\n\nThanks,\nPaul.\n"},{"id":"91021","messageId":"bb6f213e0809180412o4559ef95jfba29aa540afa06f@mail.gmail.com","threadId":"15568","inReplyTo":"18641.31356.147503.708394@cargo.ozlabs.ibm.com","subject":"Re: [PATCH (GIT-GUI,GITK) 0/8] Encoding support in GUI","fromName":"Alexander Gavrilov","fromEmail":"angavrilov@gmail.com","sentAt":"2008-09-18T11:12:23Z","receivedAt":"2008-09-18T11:12:23Z","isPatch":true,"sender":{"key":"angavrilov@gmail.com","avatar":"https://avatars.githubusercontent.com/u/42666?v=4"},"body":"On Thu, Sep 18, 2008 at 1:45 AM, Paul Mackerras <paulus@samba.org> wrote:\n> Alexander Gavrilov writes:\n>> Currently GUI tools don't provide any support for\n>> viewing files that contain non-ASCII characters.\n>\n> Well, that's just not true, at least as far as gitk is concerned.\n\nSomehow being able to show files in the system encoding is not good\nenough for a tool that is supposed to be used for cross-platform\nprojects. It is only marginally better than always using ISO-8859-1,\nas git-gui, in effect, did.\n\n> If you feel there are deficiencies in how gitk handles encodings (and\n> I'm quite willing to believe there are, since ASCII is sufficient for\n> my needs), then please give us a detailed explanation of what you\n> would like it to do or specifically what is wrong with what it does at\n> the moment.  I'd like to see several paragraphs, not just the one or\n> two sentences you have put in the descriptions for patches 6-8.\n\nI did not combine this set of patches into a single group without a\nreason. This is a policy decision that spans the boundary of\nindividual tools, although it is initially implemented and documented\non the git-gui side. The gitk commits simply bring back changes to\ncode originally copied from gitk, tie in new logic that supports\nper-file encoding, and fix some obvious breakage (of course, I can\nwrite longer descriptions for them). By the way, patch 4 will apply to\ngitk, if you replace 'lib/encoding.tcl' with 'gitk', and specify -C2.\n\nP.S. All changes are build on top of these two commits:\nhttp://repo.or.cz/w/git-gui.git?a=log;h=refs/heads/pu\n\nAlexander\n"},{"id":"91027","messageId":"20080918150238.GC21650@dpotapov.dyndns.org","threadId":"15568","inReplyTo":"1221685659-476-2-git-send-email-angavrilov@gmail.com","subject":"Re: [PATCH (GIT-GUI,GITK) 1/8] git-gui: Cleanup handling of the default encoding.","fromName":"Dmitry Potapov","fromEmail":"dpotapov@gmail.com","sentAt":"2008-09-18T15:02:39Z","receivedAt":"2008-09-18T15:02:39Z","isPatch":true,"sender":{"key":"dpotapov@gmail.com","avatar":"https://avatars.githubusercontent.com/u/6568595?v=4"},"body":"On Thu, Sep 18, 2008 at 01:07:32AM +0400, Alexander Gavrilov wrote:\n> - Make diffs and blame default to the system (locale)\n>   encoding instead of hard-coding UTF-8.\n> - Add a gui.encoding option to allow overriding it.\n> - gitattributes still have the final word.\n\nThe subject line of this patch is a bit misleading. I would not expect\nfrom \"clean up\" to change the existing behavior and existing default.\n\n> The rationale for this is Windows support:\n> \n> 1) Windows people are accustomed to using legacy encodings\n>    for text files. For many of them defaulting to utf-8\n>    will be counter-intuitive.\n> 2) Windows doesn't support utf-8 locales, and switching\n>    the system encoding is a real pain. Thus the option.\n\nI don't care much what is the default for Windows, but I wonder whether\nthis rationale is good enough to change the default for other platforms.\nIf you have systems configured with utf-8 and others (usually old ones)\nwith legacy encoding, you will store files in utf-8 in your repo, thus\nhaving utf-8 as the default makes sense for non-Windows platforms.\n\nBTW, when you said the system encoding above, what exactly encoding do\nyou mean? AFAIK, Windows has two legacy encodings OEM-CP and ANSI-CP.\nIf I write a console program and compile it using MS-VC then it should\nuse OEM-CP.  However, if you write a GUI program or a console program\nthat is compiled using gcc from Cygwin, you have to use ANSI-CP. For\ninstance, if you use the Russian locale on Windows, ASNI-CP is 1251 and\nOEM-CP is 866. So, my question is what exactly encoding do you call as\n\"system\" above?\n\nDmitry\n"},{"id":"91029","messageId":"bb6f213e0809180814w74da6e36pfcf5a0622164ad44@mail.gmail.com","threadId":"15568","inReplyTo":"20080918150238.GC21650@dpotapov.dyndns.org","subject":"Re: [PATCH (GIT-GUI,GITK) 1/8] git-gui: Cleanup handling of the default encoding.","fromName":"Alexander Gavrilov","fromEmail":"angavrilov@gmail.com","sentAt":"2008-09-18T15:14:32Z","receivedAt":"2008-09-18T15:14:32Z","isPatch":true,"sender":{"key":"angavrilov@gmail.com","avatar":"https://avatars.githubusercontent.com/u/42666?v=4"},"body":"On Thu, Sep 18, 2008 at 7:02 PM, Dmitry Potapov <dpotapov@gmail.com> wrote:\n> The subject line of this patch is a bit misleading. I would not expect\n> from \"clean up\" to change the existing behavior and existing default.\n\nComments can be easily changed.\n\n>> The rationale for this is Windows support:\n>>\n>> 1) Windows people are accustomed to using legacy encodings\n>>    for text files. For many of them defaulting to utf-8\n>>    will be counter-intuitive.\n>> 2) Windows doesn't support utf-8 locales, and switching\n>>    the system encoding is a real pain. Thus the option.\n>\n> I don't care much what is the default for Windows, but I wonder whether\n> this rationale is good enough to change the default for other platforms.\n> If you have systems configured with utf-8 and others (usually old ones)\n> with legacy encoding, you will store files in utf-8 in your repo, thus\n> having utf-8 as the default makes sense for non-Windows platforms.\n\nIn fact, I think that the only reasonable default is the locale\nencoding. If they want something different, they can do \"git config\n--global gui.encoding utf-8\", that's what the option is there for.\n\n> BTW, when you said the system encoding above, what exactly encoding do\n> you mean? AFAIK, Windows has two legacy encodings OEM-CP and ANSI-CP.\n> If I write a console program and compile it using MS-VC then it should\n> use OEM-CP.  However, if you write a GUI program or a console program\n> that is compiled using gcc from Cygwin, you have to use ANSI-CP. For\n> instance, if you use the Russian locale on Windows, ASNI-CP is 1251 and\n> OEM-CP is 866. So, my question is what exactly encoding do you call as\n> \"system\" above?\n\nWhatever Tcl thinks the system encoding is. In this case it is cp1251.\nCP866 is for DOS.\n\nAlexander\n"},{"id":"91043","messageId":"48D281E6.1070204@viscovery.net","threadId":"15568","inReplyTo":"20080918150238.GC21650@dpotapov.dyndns.org","subject":"Re: [PATCH (GIT-GUI,GITK) 1/8] git-gui: Cleanup handling of the default encoding.","fromName":"Johannes Sixt","fromEmail":"j.sixt@viscovery.net","sentAt":"2008-09-18T16:29:26Z","receivedAt":"2008-09-18T16:29:26Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Dmitry Potapov schrieb:\n> On Thu, Sep 18, 2008 at 01:07:32AM +0400, Alexander Gavrilov wrote:\n>> The rationale for this is Windows support:\n>>\n>> 1) Windows people are accustomed to using legacy encodings\n>>    for text files. For many of them defaulting to utf-8\n>>    will be counter-intuitive.\n>> 2) Windows doesn't support utf-8 locales, and switching\n>>    the system encoding is a real pain. Thus the option.\n> \n> I don't care much what is the default for Windows, but I wonder whether\n> this rationale is good enough to change the default for other platforms.\n\n\"The default\" should not be hardcoded in the tool.\n\nBy setting the encoding to \"system\", \"the default\" is taken from whatever\nthe system's current locale is. If you are on modern Linux, your locale is\nmost likely set to UTF8, and everything is fine; you won't observe a\nchange in behavior.\n\nBut if you are on a system whose locale was not set to UTF8, then you very\nlikely did *not* produce UTF8 data, and the display in git-gui was screwed\nbecause it assumed UTF8. With this change it uses the system's encoding,\nand it is an improvement.\n\n> If you have systems configured with utf-8 and others (usually old ones)\n> with legacy encoding, you will store files in utf-8 in your repo, thus\n> having utf-8 as the default makes sense for non-Windows platforms.\n\nHow can you know? For example, I've to work with systems that use \"legacy\nencodings\", and I can't use UTF8 in my data. Hence, the default of UTF8\nwas not exactly useful. With this patch series there's now a mechanism\nthat allows me to state the encoding per file, and all platforms should be\nable to show the data in the correct way.\n\n-- Hannes\n"},{"id":"91047","messageId":"20080918165032.GD21650@dpotapov.dyndns.org","threadId":"15568","inReplyTo":"48D281E6.1070204@viscovery.net","subject":"Re: [PATCH (GIT-GUI,GITK) 1/8] git-gui: Cleanup handling of the default encoding.","fromName":"Dmitry Potapov","fromEmail":"dpotapov@gmail.com","sentAt":"2008-09-18T16:50:32Z","receivedAt":"2008-09-18T16:50:32Z","isPatch":true,"sender":{"key":"dpotapov@gmail.com","avatar":"https://avatars.githubusercontent.com/u/6568595?v=4"},"body":"On Thu, Sep 18, 2008 at 06:29:26PM +0200, Johannes Sixt wrote:\n> \n> By setting the encoding to \"system\", \"the default\" is taken from whatever\n> the system's current locale is. If you are on modern Linux, your locale is\n> most likely set to UTF8, and everything is fine; you won't observe a\n> change in behavior.\n\nThat's right.\n\n> But if you are on a system whose locale was not set to UTF8, then you very\n> likely did *not* produce UTF8 data, and the display in git-gui was screwed\n> because it assumed UTF8. With this change it uses the system's encoding,\n> and it is an improvement.\n\nIt is not about how data are stored locale but what is in repository.\nEven if you still have some Linux box with legacy encoding on it, you\nstill want to see what in repository, which is mostly likely to be in\nUTF-8. Even if you do not have UTF-8 locale, all decent editors are\ncapable to read and store files in UTF-8 (even if it is not your locale),\nand it is really make sense to store files in UTF-8, which makes sense\nbecause you are going then on a modern Linux, you want to have all data\nin the repository to be in a single encoding, and UTF-8 is the best\nchoice for that.\n\n> \n> > If you have systems configured with utf-8 and others (usually old ones)\n> > with legacy encoding, you will store files in utf-8 in your repo, thus\n> > having utf-8 as the default makes sense for non-Windows platforms.\n> \n> How can you know? For example, I've to work with systems that use \"legacy\n> encodings\", and I can't use UTF8 in my data. Hence, the default of UTF8\n> was not exactly useful. With this patch series there's now a mechanism\n> that allows me to state the encoding per file, and all platforms should be\n> able to show the data in the correct way.\n\nThis patch is certainly a big improvement, as it allows to choose what\nencoding you want to see, but I was not sure that changing the default\nfrom UTF-8 to the system locale is really a good idea for anything but\nWindows specific projects. Anyway, I have converted all computers that\nI use regularly to UTF-8, so I don't really care...\n\nDmitry\n"},{"id":"91049","messageId":"bb6f213e0809181000l52c55e8ctdfa49a59002e60cf@mail.gmail.com","threadId":"15568","inReplyTo":"20080918165032.GD21650@dpotapov.dyndns.org","subject":"Re: [PATCH (GIT-GUI,GITK) 1/8] git-gui: Cleanup handling of the default encoding.","fromName":"Alexander Gavrilov","fromEmail":"angavrilov@gmail.com","sentAt":"2008-09-18T17:00:07Z","receivedAt":"2008-09-18T17:00:07Z","isPatch":true,"sender":{"key":"angavrilov@gmail.com","avatar":"https://avatars.githubusercontent.com/u/42666?v=4"},"body":"On Thu, Sep 18, 2008 at 8:50 PM, Dmitry Potapov <dpotapov@gmail.com> wrote:\n> It is not about how data are stored locale but what is in repository.\n> Even if you still have some Linux box with legacy encoding on it, you\n> still want to see what in repository, which is mostly likely to be in\n> UTF-8. Even if you do not have UTF-8 locale, all decent editors are\n> capable to read and store files in UTF-8 (even if it is not your locale),\n> and it is really make sense to store files in UTF-8, which makes sense\n> because you are going then on a modern Linux, you want to have all data\n> in the repository to be in a single encoding, and UTF-8 is the best\n> choice for that.\n\nA new user would expect to see his files properly, and they are likely\nto be in the locale encoding. And if you know about utf-8, you can\nopen the Options dialog, and select it explicitly from a menu. And if\nyou commit a .gitattributes file with encoding specifications to the\nrepository, it will be used automatically wherever you check it out.\n\n> This patch is certainly a big improvement, as it allows to choose what\n> encoding you want to see, but I was not sure that changing the default\n> from UTF-8 to the system locale is really a good idea for anything but\n> Windows specific projects. Anyway, I have converted all computers that\n> I use regularly to UTF-8, so I don't really care...\n\nYou are here missing the fact, that the actual current default for\ngit-gui is not utf-8, but 'binary', essentially equivalent to\nISO-8859-1. UTF-8 was suggested by a patch that has been around in the\n'pu' branch since January, and which I took as a base for my series.\nGitk on the other hand uses the locale encoding.\n\nAlexander\n"},{"id":"91054","messageId":"20080918171936.GE21650@dpotapov.dyndns.org","threadId":"15568","inReplyTo":"bb6f213e0809181000l52c55e8ctdfa49a59002e60cf@mail.gmail.com","subject":"Re: [PATCH (GIT-GUI,GITK) 1/8] git-gui: Cleanup handling of the default encoding.","fromName":"Dmitry Potapov","fromEmail":"dpotapov@gmail.com","sentAt":"2008-09-18T17:19:36Z","receivedAt":"2008-09-18T17:19:36Z","isPatch":true,"sender":{"key":"dpotapov@gmail.com","avatar":"https://avatars.githubusercontent.com/u/6568595?v=4"},"body":"On Thu, Sep 18, 2008 at 09:00:07PM +0400, Alexander Gavrilov wrote:\n> \n> You are here missing the fact, that the actual current default for\n> git-gui is not utf-8, but 'binary', essentially equivalent to\n> ISO-8859-1.\n\nIn this case, I was just confused by the comment to the patch, which was\nsaying \"Make diffs and blame default to the system (locale) encoding\ninstead of hard-coding UTF-8.\"\n\n> UTF-8 was suggested by a patch that has been around in the\n> 'pu' branch since January, and which I took as a base for my series.\n> Gitk on the other hand uses the locale encoding.\n\nI see... Then your patch makes perfect sense regardless of Windows\nsupport, which was presented as the rationale for the patch.\n\nThanks,\nDmitry\n"},{"id":"91108","messageId":"48D396A8.4050607@viscovery.net","threadId":"15568","inReplyTo":"1221685659-476-7-git-send-email-angavrilov@gmail.com","subject":"Re: [PATCH (GIT-GUI,GITK) 6/8] gitk: Port new encoding logic from git-gui.","fromName":"Johannes Sixt","fromEmail":"j.sixt@viscovery.net","sentAt":"2008-09-19T12:10:16Z","receivedAt":"2008-09-19T12:10:16Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Alexander Gavrilov schrieb:\n> Add functions that implement the same logic for file\n> contents encoding as git-gui uses:\n> \n> - Defaults to the system encoding.\n> - Overridden by setting the gui.encoding option.\n> - Further overridden on per-file basis by gitattributes.\n> \n> Also extends the range of supported encoding names.\n\nIf I run\n\n  $ LANG=C gitk 146ed90\n\nwith this series on the git-gui repository, then I hoped to see the text\nin the patches in the right encoding. But I understand that I expected too\nmuch - the patch text is just a stream of bytes that comes from different\nfiles, and the best you can do is to apply the system encoding.\n\nBut if the view is switched to the tree view, and file contents are\ninspected, then this patch should help. But it doesn't. If you look at\npo/ja.po, it is appearent that the file was not read as UTF-8, which is\ndictated by .gitattributes.\n\n-- Hannes\n"},{"id":"91110","messageId":"bb6f213e0809190538m5bbfeb38o5510d06fa6757dd1@mail.gmail.com","threadId":"15568","inReplyTo":"48D396A8.4050607@viscovery.net","subject":"Re: [PATCH (GIT-GUI,GITK) 6/8] gitk: Port new encoding logic from git-gui.","fromName":"Alexander Gavrilov","fromEmail":"angavrilov@gmail.com","sentAt":"2008-09-19T12:38:53Z","receivedAt":"2008-09-19T12:38:53Z","isPatch":true,"sender":{"key":"angavrilov@gmail.com","avatar":"https://avatars.githubusercontent.com/u/42666?v=4"},"body":"On Fri, Sep 19, 2008 at 4:10 PM, Johannes Sixt <j.sixt@viscovery.net> wrote:\n> If I run\n>\n>  $ LANG=C gitk 146ed90\n>\n> with this series on the git-gui repository, then I hoped to see the text\n> in the patches in the right encoding. But I understand that I expected too\n> much - the patch text is just a stream of bytes that comes from different\n> files, and the best you can do is to apply the system encoding.\n>\n> But if the view is switched to the tree view, and file contents are\n> inspected, then this patch should help. But it doesn't. If you look at\n> po/ja.po, it is appearent that the file was not read as UTF-8, which is\n> dictated by .gitattributes.\n\nOn my system everything works. You must have made a mistake somewhere. Namely:\n\n1) Did you apply ALL patches to gitk? The first one is absolutely\nuseless without the other two.\n2) Did you install it? I.e. do you actually run the patched version?\n3) Do you have .gitattributes checked out?\n\nAlso, it should work in the patch mode as well: it reads the patch as\nbinary, and decodes each line separately, based on the encoding\ndetermined for the current file.\n\nAlexander\n"},{"id":"91112","messageId":"48D3A376.30905@viscovery.net","threadId":"15568","inReplyTo":"bb6f213e0809190538m5bbfeb38o5510d06fa6757dd1@mail.gmail.com","subject":"Re: [PATCH (GIT-GUI,GITK) 6/8] gitk: Port new encoding logic from git-gui.","fromName":"Johannes Sixt","fromEmail":"j.sixt@viscovery.net","sentAt":"2008-09-19T13:04:54Z","receivedAt":"2008-09-19T13:04:54Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Alexander Gavrilov schrieb:\n> On Fri, Sep 19, 2008 at 4:10 PM, Johannes Sixt <j.sixt@viscovery.net> wrote:\n>> If I run\n>>\n>>  $ LANG=C gitk 146ed90\n>>\n>> with this series on the git-gui repository, then I hoped to see the text\n>> in the patches in the right encoding. But I understand that I expected too\n>> much - the patch text is just a stream of bytes that comes from different\n>> files, and the best you can do is to apply the system encoding.\n>>\n>> But if the view is switched to the tree view, and file contents are\n>> inspected, then this patch should help. But it doesn't. If you look at\n>> po/ja.po, it is appearent that the file was not read as UTF-8, which is\n>> dictated by .gitattributes.\n> \n> On my system everything works. You must have made a mistake somewhere.\n\nIndeed. I was running above command form a git.git clone. Now, looking at\nanything that is in 146ed90 produces paths like\n\n   po/de.po\n   po/ja.po\n\nYet, .gitattributes says this:\n\n   /po/*.po    encoding=UTF-8\n\nwhich does not match any of the *.po files because the *.po are one level\ndeeper inside git-gui/po/. The change below made a difference.\nEverything's fine now!\n\ndiff --git a/git-gui/.gitattributes b/git-gui/.gitattributes\nindex f96112d..8ad5766 100644\n--- a/git-gui/.gitattributes\n+++ b/git-gui/.gitattributes\n@@ -1,3 +1,3 @@\n *           encoding=US-ASCII\n git-gui.sh  encoding=UTF-8\n-/po/*.po    encoding=UTF-8\n+*.po        encoding=UTF-8\n\n> Also, it should work in the patch mode as well: it reads the patch as\n> binary, and decodes each line separately, based on the encoding\n> determined for the current file.\n\nThis is great. But we'll have to see how this works on a multi-file diff\non Windows. (I sense slowness.)\n\nThanks,\n-- Hannes\n"},{"id":"91251","messageId":"200809212252.35769.angavrilov@gmail.com","threadId":"15568","inReplyTo":"48D3A376.30905@viscovery.net","subject":"Re: [PATCH (GIT-GUI,GITK) 6/8] gitk: Port new encoding logic from git-gui.","fromName":"Alexander Gavrilov","fromEmail":"angavrilov@gmail.com","sentAt":"2008-09-21T18:52:35Z","receivedAt":"2008-09-21T18:52:35Z","isPatch":true,"sender":{"key":"angavrilov@gmail.com","avatar":"https://avatars.githubusercontent.com/u/42666?v=4"},"body":"On Friday 19 September 2008 17:04:54 Johannes Sixt wrote:\n> Alexander Gavrilov schrieb:\n> > Also, it should work in the patch mode as well: it reads the patch as\n> > binary, and decodes each line separately, based on the encoding\n> > determined for the current file.\n> \n> This is great. But we'll have to see how this works on a multi-file diff\n> on Windows. (I sense slowness.)\n> \n\nYes, yesterday I noticed that when the patch is very big, like when the\nindex has got out of sync, and gitk claims local changes in all of the git-gui\nrepository (>1000 files), first view is slow even on Linux.\n\nI made a patch to optimize attribute lookup. I'm afraid that further optimization\nis impossible without interface changes in git-check-attr, or reimplementing\nthe attribute parser in Tcl.\n\n--- >8 ---\nFrom: Alexander Gavrilov <angavrilov@gmail.com>\nSubject: [PATCH] gitk: Implement batch lookup and caching of encoding attrs.\n\nWhen the diff contains thousands of files, calling git-check-attr\nonce per file is very slow. With this patch gitk does attribute\nlookup in batches of 30 files while reading the diff file list,\nwhich leads to a very noticeable speedup.\n\nSigned-off-by: Alexander Gavrilov <angavrilov@gmail.com>\n---\n gitk |   34 +++++++++++++++++++++++++++++++++-\n 1 files changed, 33 insertions(+), 1 deletions(-)\n\ndiff --git a/gitk b/gitk\nindex 1355aa2..6fc1e90 100755\n--- a/gitk\n+++ b/gitk\n@@ -6530,6 +6530,7 @@ proc gettreediffline {gdtf ids} {\n     global cmitmode vfilelimit curview limitdiffs\n \n     set nr 0\n+    set sublist {}\n     while {[incr nr] <= 1000 && [gets $gdtf line] >= 0} {\n \tset i [string first \"\\t\" $line]\n \tif {$i >= 0} {\n@@ -6539,8 +6540,10 @@ proc gettreediffline {gdtf ids} {\n \t    }\n \t    set file [encoding convertfrom $file]\n \t    lappend treediff $file\n+\t    lappend sublist $file\n \t}\n     }\n+    cache_gitattr encoding $sublist\n     if {![eof $gdtf]} {\n \treturn [expr {$nr >= 1000? 2: 1}]\n     }\n@@ -9839,18 +9842,47 @@ proc tcl_encoding {enc} {\n }\n \n proc gitattr {path attr default} {\n-\tif {[catch {set r [exec git check-attr $attr -- $path]}]} {\n+\tglobal path_attr_cache\n+\tif {[info exists path_attr_cache($attr,$path)]} {\n+\t\tset r $path_attr_cache($attr,$path)\n+\t} elseif {[catch {set r [exec git check-attr $attr -- $path]}]} {\n \t\tset r unspecified\n \t} else {\n \t\tset r [join [lrange [split $r :] 2 end] :]\n \t\tregsub {^ } $r {} r\n \t}\n+\tset path_attr_cache($attr,$path) $r\n \tif {$r eq {unspecified}} {\n \t\treturn $default\n \t}\n \treturn $r\n }\n \n+proc cache_gitattr {attr pathlist} {\n+\tglobal path_attr_cache\n+\tset newlist {}\n+\tforeach path $pathlist {\n+\t\tif {[info exists path_attr_cache($attr,$path)]} continue\n+\t\tlappend newlist $path\n+\t}\n+\twhile {$newlist ne {}} {\n+\t\tset head [lrange $newlist 0 29]\n+\t\tset newlist [lrange $newlist 30 end]\n+\t\tif {![catch {set rlist [eval exec git check-attr $attr -- $head]}]} {\n+\t\t\tforeach row [split $rlist \"\\n\"] {\n+\t\t\t\tset cols [split $row :]\n+\t\t\t\tset path [lindex $cols 0]\n+\t\t\t\tset value [join [lrange $cols 2 end] :]\n+\t\t\t\tif {[string index $path 0] eq \"\\\"\"} {\n+\t\t\t\t\tset path [encoding convertfrom [lindex $path 0]]\n+\t\t\t\t}\n+\t\t\t\tset path_attr_cache($attr,$path) $value\n+\t\t\t}\n+\t\t}\n+\t\tupdate\n+\t}\n+}\n+\n proc get_path_encoding {path} {\n \tglobal gui_encoding\n \tset tcl_enc [tcl_encoding $gui_encoding]\n-- \n1.6.0.20.g6148bc\n"},{"id":"91274","messageId":"18646.53492.20994.908025@cargo.ozlabs.ibm.com","threadId":"15568","inReplyTo":"1221685659-476-1-git-send-email-angavrilov@gmail.com","subject":"Re: [PATCH (GIT-GUI,GITK) 0/8] Encoding support in GUI","fromName":"Paul Mackerras","fromEmail":"paulus@samba.org","sentAt":"2008-09-21T22:55:48Z","receivedAt":"2008-09-21T22:55:48Z","isPatch":true,"sender":{"key":"paulus@samba.org","avatar":"https://avatars.githubusercontent.com/u/1606439?v=4"},"body":"Alexander Gavrilov writes:\n\n> File encoding can be specified in the following ways:\n> \n> 1) It defaults to the current locale encoding.\n> 2) It can be overridden by setting the gui.encoding option.\n\nI'm happy with providing a way to say what the default encoding of\nfiles in the repository is, but I wonder why it is seen as a property\nof the GUI.  Is it just that there is an existing \"gui\" section that\nis convenient to use, or does git-gui already use gui.encoding (before\nthis patch series), or is there some other reason?\n\n> 3) It can be further set on per-file basis by specifying\n>    the 'encoding' attribute in gitattributes.\n\nI haven't used .gitattributes before, but I would expect that the\n.gitattributes files would be stored in the repository along with\neverything else.  If that's the case, then for gitk at least there is\nthe question of which version of a given .gitattributes file one\nshould use when viewing the tree for a commit which isn't the\ncurrently checked-out commit - do you use the version from that tree,\nor the version in the working directory?  We seem to be using the\nlatter at present, and caching the results.  Is there a philosophical\nreason to do that, other than speed?  (Also it seems that we won't\nnotice if the user changes .gitattributes after we've looked at it, or\nif they create one after we've looked for one and not found it.)\n\n> Since git apparently cannot work with filenames in non-locale\n> encodings anyway, I did not try to do anything about it apart\n> from fixing some obvious bugs.\n\nFor Linux, filenames are sequences of non-null bytes, so using\nbinary encoding to read them in Tcl sounds about right.\n\n> There are also some bugs in handling of commit encodings in gitk,\n> but they are out of the scope of this series.\n\nI'm interested to hear what they are.\n\nPaul.\n"},{"id":"91281","messageId":"48D74877.9050607@viscovery.net","threadId":"15568","inReplyTo":"200809212252.35769.angavrilov@gmail.com","subject":"Re: [PATCH (GIT-GUI,GITK) 6/8] gitk: Port new encoding logic from git-gui.","fromName":"Johannes Sixt","fromEmail":"j.sixt@viscovery.net","sentAt":"2008-09-22T07:25:43Z","receivedAt":"2008-09-22T07:25:43Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Alexander Gavrilov schrieb:\n> Subject: [PATCH] gitk: Implement batch lookup and caching of encoding attrs.\n> \n> When the diff contains thousands of files, calling git-check-attr\n> once per file is very slow. With this patch gitk does attribute\n> lookup in batches of 30 files while reading the diff file list,\n> which leads to a very noticeable speedup.\n\nThis one does not work for me: The correct is not picked up anymore,\nneither in Patch mode nor Tree mode. (It works as expected without this\npatch.)\n\n> +proc cache_gitattr {attr pathlist} {\n> +\tglobal path_attr_cache\n> +\tset newlist {}\n> +\tforeach path $pathlist {\n> +\t\tif {[info exists path_attr_cache($attr,$path)]} continue\n> +\t\tlappend newlist $path\n> +\t}\n> +\twhile {$newlist ne {}} {\n> +\t\tset head [lrange $newlist 0 29]\n> +\t\tset newlist [lrange $newlist 30 end]\n> +\t\tif {![catch {set rlist [eval exec git check-attr $attr -- $head]}]} {\n> +\t\t\tforeach row [split $rlist \"\\n\"] {\n> +\t\t\t\tset cols [split $row :]\n\nThis colon made me nervous (because of the drive-colon combination on\nWindows), but as long as you feed relative paths into 'git check-attr',\nthis should not matter (in my case).\n\n> +\t\t\t\tset path [lindex $cols 0]\n> +\t\t\t\tset value [join [lrange $cols 2 end] :]\n> +\t\t\t\tif {[string index $path 0] eq \"\\\"\"} {\n> +\t\t\t\t\tset path [encoding convertfrom [lindex $path 0]]\n> +\t\t\t\t}\n> +\t\t\t\tset path_attr_cache($attr,$path) $value\n> +\t\t\t}\n> +\t\t}\n> +\t\tupdate\n> +\t}\n> +}\n"},{"id":"91285","messageId":"48D74D69.4010802@viscovery.net","threadId":"15568","inReplyTo":"48D74877.9050607@viscovery.net","subject":"Re: [PATCH (GIT-GUI,GITK) 6/8] gitk: Port new encoding logic from git-gui.","fromName":"Johannes Sixt","fromEmail":"j.sixt@viscovery.net","sentAt":"2008-09-22T07:46:49Z","receivedAt":"2008-09-22T07:46:49Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Johannes Sixt schrieb:\n> Alexander Gavrilov schrieb:\n>> Subject: [PATCH] gitk: Implement batch lookup and caching of encoding attrs.\n>>\n>> When the diff contains thousands of files, calling git-check-attr\n>> once per file is very slow. With this patch gitk does attribute\n>> lookup in batches of 30 files while reading the diff file list,\n>> which leads to a very noticeable speedup.\n> \n> This one does not work for me: The correct is not picked up anymore,\n\nThe correct _encoding_ is not picked up anymore...\n\n> neither in Patch mode nor Tree mode. (It works as expected without this\n> patch.)\n> \n>> +proc cache_gitattr {attr pathlist} {\n>> +\tglobal path_attr_cache\n>> +\tset newlist {}\n>> +\tforeach path $pathlist {\n>> +\t\tif {[info exists path_attr_cache($attr,$path)]} continue\n>> +\t\tlappend newlist $path\n>> +\t}\n>> +\twhile {$newlist ne {}} {\n>> +\t\tset head [lrange $newlist 0 29]\n>> +\t\tset newlist [lrange $newlist 30 end]\n>> +\t\tif {![catch {set rlist [eval exec git check-attr $attr -- $head]}]} {\n>> +\t\t\tforeach row [split $rlist \"\\n\"] {\n>> +\t\t\t\tset cols [split $row :]\n> \n> This colon made me nervous (because of the drive-colon combination on\n> Windows), but as long as you feed relative paths into 'git check-attr',\n> this should not matter (in my case).\n\nThis comment does not imply that I debugged this code. I just noticed the\ncolon while reading the patch.\n\n>> +\t\t\t\tset path [lindex $cols 0]\n>> +\t\t\t\tset value [join [lrange $cols 2 end] :]\n>> +\t\t\t\tif {[string index $path 0] eq \"\\\"\"} {\n>> +\t\t\t\t\tset path [encoding convertfrom [lindex $path 0]]\n>> +\t\t\t\t}\n>> +\t\t\t\tset path_attr_cache($attr,$path) $value\n>> +\t\t\t}\n>> +\t\t}\n>> +\t\tupdate\n>> +\t}\n>> +}\n"},{"id":"91286","messageId":"200809221201.35507.angavrilov@gmail.com","threadId":"15568","inReplyTo":"48D74877.9050607@viscovery.net","subject":"Re: [PATCH (GIT-GUI,GITK) 6/8] gitk: Port new encoding logic from git-gui.","fromName":"Alexander Gavrilov","fromEmail":"angavrilov@gmail.com","sentAt":"2008-09-22T08:01:35Z","receivedAt":"2008-09-22T08:01:35Z","isPatch":true,"sender":{"key":"angavrilov@gmail.com","avatar":"https://avatars.githubusercontent.com/u/42666?v=4"},"body":"On Monday 22 September 2008 11:25:43 Johannes Sixt wrote:\n> Alexander Gavrilov schrieb:\n> > Subject: [PATCH] gitk: Implement batch lookup and caching of encoding attrs.\n> > \n> > When the diff contains thousands of files, calling git-check-attr\n> > once per file is very slow. With this patch gitk does attribute\n> > lookup in batches of 30 files while reading the diff file list,\n> > which leads to a very noticeable speedup.\n> \n> This one does not work for me: The correct is not picked up anymore,\n> neither in Patch mode nor Tree mode. (It works as expected without this\n> patch.)\n> \n\nOOPS, I forgot to copy the line that removes leading whitespace:\n\n@@ -9876,6 +9876,7 @@ proc cache_gitattr {attr pathlist} {\n                                if {[string index $path 0] eq \"\\\"\"} {\n                                        set path [encoding convertfrom [lindex $path 0]]\n                                }\n+                               regsub {^ } $value {} value\n                                set path_attr_cache($attr,$path) $value\n                        }\n                }\n\n> > +\t\t\t\tset cols [split $row :]\n> > +\t\t\t\tset path [lindex $cols 0]\n> \n> This colon made me nervous (because of the drive-colon combination on\n> Windows), but as long as you feed relative paths into 'git check-attr',\n> this should not matter (in my case).\n\nI'm afraid there is nothing to be done about it without changing git-check-attr.\nFor example, it could quote ':' in the path in octal -- current interface allows it.\nBut since the path is relative, it is not a big deal.\n\n\n--- >8 ---\nFrom: Alexander Gavrilov <angavrilov@gmail.com>\nSubject: [PATCH v2] gitk: Implement batch lookup and caching of encoding attrs.\n\nWhen the diff contains thousands of files, calling git-check-attr\nonce per file is very slow. With this patch gitk does attribute\nlookup in batches of 30 files while reading the diff file list,\nwhich leads to a very noticeable speedup.\n\nSigned-off-by: Alexander Gavrilov <angavrilov@gmail.com>\n---\n gitk |   35 ++++++++++++++++++++++++++++++++++-\n 1 files changed, 34 insertions(+), 1 deletions(-)\n\ndiff --git a/gitk b/gitk\nindex 1355aa2..cf557c3 100755\n--- a/gitk\n+++ b/gitk\n@@ -6530,6 +6530,7 @@ proc gettreediffline {gdtf ids} {\n     global cmitmode vfilelimit curview limitdiffs\n \n     set nr 0\n+    set sublist {}\n     while {[incr nr] <= 1000 && [gets $gdtf line] >= 0} {\n \tset i [string first \"\\t\" $line]\n \tif {$i >= 0} {\n@@ -6539,8 +6540,10 @@ proc gettreediffline {gdtf ids} {\n \t    }\n \t    set file [encoding convertfrom $file]\n \t    lappend treediff $file\n+\t    lappend sublist $file\n \t}\n     }\n+    cache_gitattr encoding $sublist\n     if {![eof $gdtf]} {\n \treturn [expr {$nr >= 1000? 2: 1}]\n     }\n@@ -9839,18 +9842,48 @@ proc tcl_encoding {enc} {\n }\n \n proc gitattr {path attr default} {\n-\tif {[catch {set r [exec git check-attr $attr -- $path]}]} {\n+\tglobal path_attr_cache\n+\tif {[info exists path_attr_cache($attr,$path)]} {\n+\t\tset r $path_attr_cache($attr,$path)\n+\t} elseif {[catch {set r [exec git check-attr $attr -- $path]}]} {\n \t\tset r unspecified\n \t} else {\n \t\tset r [join [lrange [split $r :] 2 end] :]\n \t\tregsub {^ } $r {} r\n \t}\n+\tset path_attr_cache($attr,$path) $r\n \tif {$r eq {unspecified}} {\n \t\treturn $default\n \t}\n \treturn $r\n }\n \n+proc cache_gitattr {attr pathlist} {\n+\tglobal path_attr_cache\n+\tset newlist {}\n+\tforeach path $pathlist {\n+\t\tif {[info exists path_attr_cache($attr,$path)]} continue\n+\t\tlappend newlist $path\n+\t}\n+\twhile {$newlist ne {}} {\n+\t\tset head [lrange $newlist 0 29]\n+\t\tset newlist [lrange $newlist 30 end]\n+\t\tif {![catch {set rlist [eval exec git check-attr $attr -- $head]}]} {\n+\t\t\tforeach row [split $rlist \"\\n\"] {\n+\t\t\t\tset cols [split $row :]\n+\t\t\t\tset path [lindex $cols 0]\n+\t\t\t\tset value [join [lrange $cols 2 end] :]\n+\t\t\t\tif {[string index $path 0] eq \"\\\"\"} {\n+\t\t\t\t\tset path [encoding convertfrom [lindex $path 0]]\n+\t\t\t\t}\n+\t\t\t\tregsub {^ } $value {} value\n+\t\t\t\tset path_attr_cache($attr,$path) $value\n+\t\t\t}\n+\t\t}\n+\t\tupdate\n+\t}\n+}\n+\n proc get_path_encoding {path} {\n \tglobal gui_encoding\n \tset tcl_enc [tcl_encoding $gui_encoding]\n-- \n1.6.0.20.g6148bc\n"},{"id":"91287","messageId":"48D7554C.4020601@viscovery.net","threadId":"15568","inReplyTo":"200809221201.35507.angavrilov@gmail.com","subject":"Re: [PATCH (GIT-GUI,GITK) 6/8] gitk: Port new encoding logic from git-gui.","fromName":"Johannes Sixt","fromEmail":"j.sixt@viscovery.net","sentAt":"2008-09-22T08:20:28Z","receivedAt":"2008-09-22T08:20:28Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Alexander Gavrilov schrieb:\n> On Monday 22 September 2008 11:25:43 Johannes Sixt wrote:\n>> Alexander Gavrilov schrieb:\n>>> Subject: [PATCH] gitk: Implement batch lookup and caching of encoding attrs.\n>>>\n>>> When the diff contains thousands of files, calling git-check-attr\n>>> once per file is very slow. With this patch gitk does attribute\n>>> lookup in batches of 30 files while reading the diff file list,\n>>> which leads to a very noticeable speedup.\n>> This one does not work for me: The correct is not picked up anymore,\n>> neither in Patch mode nor Tree mode. (It works as expected without this\n>> patch.)\n>>\n> \n> OOPS, I forgot to copy the line that removes leading whitespace:\n\nThanks, with this it works now. The delay for a 1000 file patch is\nbearable (on Windows, but y'know, Windows types are masochists :-).\n\nFeel free to add:\n\nTested-by: Johannes Sixt <johannes.sixt@telecom.at>\n\nto the patches in the series when you resend it - and I hope you do resend\nit after addressing Paul's concerns.\n\n-- Hannes\n"},{"id":"91292","messageId":"20080922090151.GJ21650@dpotapov.dyndns.org","threadId":"15568","inReplyTo":"200809212252.35769.angavrilov@gmail.com","subject":"Re: [PATCH (GIT-GUI,GITK) 6/8] gitk: Port new encoding logic from git-gui.","fromName":"Dmitry Potapov","fromEmail":"dpotapov@gmail.com","sentAt":"2008-09-22T09:01:51Z","receivedAt":"2008-09-22T09:01:51Z","isPatch":true,"sender":{"key":"dpotapov@gmail.com","avatar":"https://avatars.githubusercontent.com/u/6568595?v=4"},"body":"On Sun, Sep 21, 2008 at 10:52:35PM +0400, Alexander Gavrilov wrote:\n> \n> I made a patch to optimize attribute lookup. I'm afraid that further optimization\n> is impossible without interface changes in git-check-attr, or reimplementing\n> the attribute parser in Tcl.\n\nI wonder would not make sense to add --stdin-paths option to git\ncheck-attr in the same way as we have for git hash-object?\n\nDmitry\n"},{"id":"91293","messageId":"200809221302.52424.angavrilov@gmail.com","threadId":"15568","inReplyTo":"48D7554C.4020601@viscovery.net","subject":"Re: [PATCH (GIT-GUI,GITK) 6/8] gitk: Port new encoding logic from git-gui.","fromName":"Alexander Gavrilov","fromEmail":"angavrilov@gmail.com","sentAt":"2008-09-22T09:02:52Z","receivedAt":"2008-09-22T09:02:52Z","isPatch":true,"sender":{"key":"angavrilov@gmail.com","avatar":"https://avatars.githubusercontent.com/u/42666?v=4"},"body":"On Monday 22 September 2008 12:20:28 Johannes Sixt wrote:\n> Alexander Gavrilov schrieb:\n> > On Monday 22 September 2008 11:25:43 Johannes Sixt wrote:\n> >> Alexander Gavrilov schrieb:\n> >>> Subject: [PATCH] gitk: Implement batch lookup and caching of encoding attrs.\n> >>>\n> >>> When the diff contains thousands of files, calling git-check-attr\n> >>> once per file is very slow. With this patch gitk does attribute\n> >>> lookup in batches of 30 files while reading the diff file list,\n> >>> which leads to a very noticeable speedup.\n> >> This one does not work for me: The correct is not picked up anymore,\n> >> neither in Patch mode nor Tree mode. (It works as expected without this\n> >> patch.)\n> >>\n> > \n> > OOPS, I forgot to copy the line that removes leading whitespace:\n> \n> Thanks, with this it works now. The delay for a 1000 file patch is\n> bearable (on Windows, but y'know, Windows types are masochists :-).\n\nYou can also try applying this patch (originally made for git-gui). It may save\nadditional 0.3 sec, especially for obscure legacy encodings.\n\nP.S. I do believe there is a place for a library shared between gitk & git-gui.\nThis code duplication is ugly and annoying; moreover, they have different\nindentation conventions, which get messed up...\n\n--- >8 --- \nFrom: Alexander Gavrilov <angavrilov@gmail.com>\nSubject: [PATCH] git-gui: Optimize encoding name resolution using a lookup table.\n\nEncoding menu construction does almost a hundred of encoding\nresolutions, which with the old implementation led to a\nsmall but noticeable delay.\n\nSigned-off-by: Alexander Gavrilov <angavrilov@gmail.com>\n---\n gitk |   84 ++++++++++++++++++++++++++++++++++++++++++-----------------------\n 1 files changed, 54 insertions(+), 30 deletions(-)\n\ndiff --git a/gitk b/gitk\nindex 254faa1..1355aa2 100755\n--- a/gitk\n+++ b/gitk\n@@ -9779,39 +9779,63 @@ set encoding_aliases {\n     { Big5 csBig5 }\n }\n \n-proc tcl_encoding {enc} {\n-    global encoding_aliases\n-    set names [encoding names]\n-    set lcnames [string tolower $names]\n-    set enc [string tolower $enc]\n-    set i [lsearch -exact $lcnames $enc]\n-    if {$i < 0} {\n-\t# look for \"isonnn\" instead of \"iso-nnn\" or \"iso_nnn\"\n-\tif {[regsub {^(iso|cp|ibm|jis)[-_]} $enc {\\1} encx]} {\n-\t    set i [lsearch -exact $lcnames $encx]\n+proc build_encoding_table {} {\n+\tglobal encoding_aliases encoding_lookup_table\n+\n+\t# Prepare the lookup list; cannot use lsort -nocase because\n+\t# of compatibility issues with older Tcl (e.g. in msysgit)\n+\tset names [list]\n+\tforeach item [encoding names] {\n+\t\tlappend names [list [string tolower $item] $item]\n+\t}\n+\tset names [lsort -ascii -index 0 $names]\n+\t# neither can we use lsearch -index\n+\tset lnames [list]\n+\tforeach item $names {\n+\t\tlappend lnames [lindex $item 0]\n+\t}\n+\n+\tforeach grp $encoding_aliases {\n+\t\tset target {}\n+\t\tforeach item $grp {\n+\t\t\tset i [lsearch -sorted -ascii $lnames \\\n+\t\t\t\t\t[string tolower $item]]\n+\t\t\tif {$i >= 0} {\n+\t\t\t\tset target [lindex $names $i 1]\n+\t\t\t\tbreak\n+\t\t\t}\n+\t\t}\n+\t\tif {$target eq {}} continue\n+\t\tforeach item $grp {\n+\t\t\tset encoding_lookup_table([string tolower $item]) $target\n+\t\t}\n \t}\n-    }\n-    if {$i < 0} {\n-\tforeach l $encoding_aliases {\n-\t    set ll [string tolower $l]\n-\t    if {[lsearch -exact $ll $enc] < 0} continue\n-\t    # look through the aliases for one that tcl knows about\n-\t    foreach e $ll {\n-\t\tset i [lsearch -exact $lcnames $e]\n-\t\tif {$i < 0} {\n-\t\t    if {[regsub {^(iso|cp|ibm|jis)[-_]} $e {\\1} ex]} {\n-\t\t\tset i [lsearch -exact $lcnames $ex]\n-\t\t    }\n+\n+\tforeach item $names {\n+\t\tset encoding_lookup_table([lindex $item 0]) [lindex $item 1]\n+\t}\n+}\n+\n+proc tcl_encoding {enc} {\n+\tglobal encoding_lookup_table\n+\tif {$enc eq {}} {\n+\t\treturn {}\n+\t}\n+\tif {![info exists encoding_lookup_table]} {\n+\t\tbuild_encoding_table\n+\t}\n+\tset enc [string tolower $enc]\n+\tif {![info exists encoding_lookup_table($enc)]} {\n+\t\t# look for \"isonnn\" instead of \"iso-nnn\" or \"iso_nnn\"\n+\t\tif {[regsub {^(iso|cp|ibm|jis)[-_]} $enc {\\1} encx]} {\n+\t\t\tset enc $encx\n \t\t}\n-\t\tif {$i >= 0} break\n-\t    }\n-\t    break\n \t}\n-    }\n-    if {$i >= 0} {\n-\treturn [lindex $names $i]\n-    }\n-    return {}\n+\tif {[info exists encoding_lookup_table($enc)]} {\n+\t\treturn $encoding_lookup_table($enc)\n+\t} else {\n+\t\treturn {}\n+\t}\n }\n \n proc gitattr {path attr default} {\n-- \n1.6.0.20.g6148bc\n"},{"id":"91297","messageId":"48D762EC.2030009@viscovery.net","threadId":"15568","inReplyTo":"200809221302.52424.angavrilov@gmail.com","subject":"Re: [PATCH (GIT-GUI,GITK) 6/8] gitk: Port new encoding logic from git-gui.","fromName":"Johannes Sixt","fromEmail":"j.sixt@viscovery.net","sentAt":"2008-09-22T09:18:36Z","receivedAt":"2008-09-22T09:18:36Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Alexander Gavrilov schrieb:\n> You can also try applying this patch (originally made for git-gui). It may save\n> additional 0.3 sec, especially for obscure legacy encodings.\n\nIs this about startup time? Personally, I don't care about 0.3 sec startup\ntime. I close my primary gitk and git-gui Windows only once a week. ;-)\n\n-- Hannes\n"},{"id":"91299","messageId":"bb6f213e0809220312m6cb8022csa3843cfaccc5b69b@mail.gmail.com","threadId":"15568","inReplyTo":"18646.53492.20994.908025@cargo.ozlabs.ibm.com","subject":"Re: [PATCH (GIT-GUI,GITK) 0/8] Encoding support in GUI","fromName":"Alexander Gavrilov","fromEmail":"angavrilov@gmail.com","sentAt":"2008-09-22T10:12:33Z","receivedAt":"2008-09-22T10:12:33Z","isPatch":true,"sender":{"key":"angavrilov@gmail.com","avatar":"https://avatars.githubusercontent.com/u/42666?v=4"},"body":"On Mon, Sep 22, 2008 at 2:55 AM, Paul Mackerras <paulus@samba.org> wrote:\n> I'm happy with providing a way to say what the default encoding of\n> files in the repository is, but I wonder why it is seen as a property\n> of the GUI.  Is it just that there is an existing \"gui\" section that\n> is convenient to use, or does git-gui already use gui.encoding (before\n> this patch series), or is there some other reason?\n\nNo particular reason, it can be easily renamed to i18n.encoding, or\nsomething else. I only recall seeing the name 'gui.encoding' in a\ndiscussion on this topic several months ago.\n\n> I haven't used .gitattributes before, but I would expect that the\n> .gitattributes files would be stored in the repository along with\n> everything else.  If that's the case, then for gitk at least there is\n> the question of which version of a given .gitattributes file one\n> should use when viewing the tree for a commit which isn't the\n> currently checked-out commit - do you use the version from that tree,\n> or the version in the working directory?  We seem to be using the\n> latter at present, and caching the results.  Is there a philosophical\n> reason to do that, other than speed?  (Also it seems that we won't\n> notice if the user changes .gitattributes after we've looked at it, or\n> if they create one after we've looked for one and not found it.)\n\nCore git does not provide any interface for reading attributes from\nolder commits, so they are loaded from the working copy. And caching\nis necessary for performance when lookup involves calling an external\napplication at least once per 30 files. This may change if\ngit-check-attr is modified to support --stdin-paths.\n\n>> There are also some bugs in handling of commit encodings in gitk,\n>> but they are out of the scope of this series.\n>\n> I'm interested to hear what they are.\n\nWhen I tested it, I noticed that:\n\n1. It works correctly only if all commits use the encoding specified\nin i18n.commitencoding\n2. Even when they do, sometimes commits are loaded through cat-file,\nand in this case they are processed using the locale encoding.\n\nAlexander\n"},{"id":"91300","messageId":"bb6f213e0809220318k7e505281n53a3948540869894@mail.gmail.com","threadId":"15568","inReplyTo":"48D762EC.2030009@viscovery.net","subject":"Re: [PATCH (GIT-GUI,GITK) 6/8] gitk: Port new encoding logic from git-gui.","fromName":"Alexander Gavrilov","fromEmail":"angavrilov@gmail.com","sentAt":"2008-09-22T10:18:10Z","receivedAt":"2008-09-22T10:18:10Z","isPatch":true,"sender":{"key":"angavrilov@gmail.com","avatar":"https://avatars.githubusercontent.com/u/42666?v=4"},"body":"On Mon, Sep 22, 2008 at 1:18 PM, Johannes Sixt <j.sixt@viscovery.net> wrote:\n> Alexander Gavrilov schrieb:\n>> You can also try applying this patch (originally made for git-gui). It may save\n>> additional 0.3 sec, especially for obscure legacy encodings.\n>\n> Is this about startup time? Personally, I don't care about 0.3 sec startup\n> time. I close my primary gitk and git-gui Windows only once a week. ;-)\n\nAs encoding lookups are currently cached, all this discussion is about\nthe first viewing.\n\nThis patch addresses the time necessary to convert an arbitrary\nencoding name to a name that is known to Tcl, or determine that it is\nnot supported. Without the patch it is done using a linear search\nthrough a large table of aliases. In git-gui it caused a noticeable\ndelay before the Encoding submenu, which lists all available\nencodings, was displayed.\n\nAlexander\n"},{"id":"92045","messageId":"48E36086.7050504@viscovery.net","threadId":"15568","inReplyTo":"18646.53492.20994.908025@cargo.ozlabs.ibm.com","subject":"Re: [PATCH (GIT-GUI,GITK) 0/8] Encoding support in GUI","fromName":"Johannes Sixt","fromEmail":"j.sixt@viscovery.net","sentAt":"2008-10-01T11:35:34Z","receivedAt":"2008-10-01T11:35:34Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Paul Mackerras schrieb:\n> Alexander Gavrilov writes:\n>> 3) It can be further set on per-file basis by specifying\n>>    the 'encoding' attribute in gitattributes.\n> \n> I haven't used .gitattributes before, but I would expect that the\n> .gitattributes files would be stored in the repository along with\n> everything else.  If that's the case, then for gitk at least there is\n> the question of which version of a given .gitattributes file one\n> should use when viewing the tree for a commit which isn't the\n> currently checked-out commit - do you use the version from that tree,\n> or the version in the working directory?  We seem to be using the\n> latter at present, and caching the results.  Is there a philosophical\n> reason to do that, other than speed?\n\nI understand your concerns that an encoding may be picked from the \"wrong\"\n.gitattributes file. But in practice it doesn't matter much, and picking\nthe attribute from a past commit's tree would even be counter-productive:\n\nI'm about to add a .gitattributes file that specifies the encoding for\nsome of my files *today* because I was not clever enough to anticipate the\nusefulness of an \"encoding\" attribute a year ago when those files were\nadded to the repository. When I browse history, I *do* want that *today's*\nencoding is picked.\n\n> (Also it seems that we won't\n> notice if the user changes .gitattributes after we've looked at it, or\n> if they create one after we've looked for one and not found it.)\n\nThis is not a show stopper, IMHO. The user will notice soon enough, and\ncan restart gitk. Nobody sane will change the encoding attributes every hour.\n\nThat said, a menu command to flush the attribute cache would be useful\nevery now and then.\n\n-- Hannes\n"},{"id":"92317","messageId":"1223173855-6173-1-git-send-email-dpotapov@gmail.com","threadId":"15568","inReplyTo":"bb6f213e0809220312m6cb8022csa3843cfaccc5b69b@mail.gmail.com","subject":"[PATCH 1/2] check-attr: add an internal check_attr() function","fromName":"Dmitry Potapov","fromEmail":"dpotapov@gmail.com","sentAt":"2008-10-05T02:30:54Z","receivedAt":"2008-10-05T02:30:54Z","isPatch":true,"sender":{"key":"dpotapov@gmail.com","avatar":"https://avatars.githubusercontent.com/u/6568595?v=4"},"body":"This step is preparation to introducing --stdin-paths option\n\nSigned-off-by: Dmitry Potapov <dpotapov@gmail.com>\n---\nOn Mon, Sep 22, 2008 at 02:12:33PM +0400, Alexander Gavrilov wrote:\n> \n> Core git does not provide any interface for reading attributes from\n> older commits, so they are loaded from the working copy. And caching\n> is necessary for performance when lookup involves calling an external\n> application at least once per 30 files. This may change if\n> git-check-attr is modified to support --stdin-paths.\n\n builtin-check-attr.c |   41 +++++++++++++++++++++++------------------\n 1 files changed, 23 insertions(+), 18 deletions(-)\n\ndiff --git a/builtin-check-attr.c b/builtin-check-attr.c\nindex cb783fc..5a2e329 100644\n--- a/builtin-check-attr.c\n+++ b/builtin-check-attr.c\n@@ -6,6 +6,27 @@\n static const char check_attr_usage[] =\n \"git check-attr attr... [--] pathname...\";\n \n+static void check_attr(int cnt, struct git_attr_check *check,\n+\tconst char** name, const char *file)\n+{\n+\tint j;\n+\tif (git_checkattr(file, cnt, check))\n+\t\tdie(\"git_checkattr died\");\n+\tfor (j = 0; j < cnt; j++) {\n+\t\tconst char *value = check[j].value;\n+\n+\t\tif (ATTR_TRUE(value))\n+\t\t\tvalue = \"set\";\n+\t\telse if (ATTR_FALSE(value))\n+\t\t\tvalue = \"unset\";\n+\t\telse if (ATTR_UNSET(value))\n+\t\t\tvalue = \"unspecified\";\n+\n+\t\tquote_c_style(file, NULL, stdout, 0);\n+\t\tprintf(\": %s: %s\\n\", name[j], value);\n+\t}\n+}\n+\n int cmd_check_attr(int argc, const char **argv, const char *prefix)\n {\n \tstruct git_attr_check *check;\n@@ -42,23 +63,7 @@ int cmd_check_attr(int argc, const char **argv, const char *prefix)\n \t\tcheck[i].attr = a;\n \t}\n \n-\tfor (i = doubledash; i < argc; i++) {\n-\t\tint j;\n-\t\tif (git_checkattr(argv[i], cnt, check))\n-\t\t\tdie(\"git_checkattr died\");\n-\t\tfor (j = 0; j < cnt; j++) {\n-\t\t\tconst char *value = check[j].value;\n-\n-\t\t\tif (ATTR_TRUE(value))\n-\t\t\t\tvalue = \"set\";\n-\t\t\telse if (ATTR_FALSE(value))\n-\t\t\t\tvalue = \"unset\";\n-\t\t\telse if (ATTR_UNSET(value))\n-\t\t\t\tvalue = \"unspecified\";\n-\n-\t\t\tquote_c_style(argv[i], NULL, stdout, 0);\n-\t\t\tprintf(\": %s: %s\\n\", argv[j+1], value);\n-\t\t}\n-\t}\n+\tfor (i = doubledash; i < argc; i++)\n+\t\tcheck_attr(cnt, check, argv+1, argv[i]);\n \treturn 0;\n }\n-- \n1.6.0.2.447.g3befd\n"},{"id":"92318","messageId":"1223173855-6173-2-git-send-email-dpotapov@gmail.com","threadId":"15568","inReplyTo":"1223173855-6173-1-git-send-email-dpotapov@gmail.com","subject":"[PATCH 2/2] check-attr: Add --stdin-paths option","fromName":"Dmitry Potapov","fromEmail":"dpotapov@gmail.com","sentAt":"2008-10-05T02:30:55Z","receivedAt":"2008-10-05T02:30:55Z","isPatch":true,"sender":{"key":"dpotapov@gmail.com","avatar":"https://avatars.githubusercontent.com/u/6568595?v=4"},"body":"This allows multiple paths to be specified on stdin.\n\nSigned-off-by: Dmitry Potapov <dpotapov@gmail.com>\n---\n Documentation/git-check-attr.txt |    4 ++\n builtin-check-attr.c             |   66 ++++++++++++++++++++++++++++++++------\n t/t0003-attributes.sh            |   17 ++++++++++\n 3 files changed, 77 insertions(+), 10 deletions(-)\n\ndiff --git a/Documentation/git-check-attr.txt b/Documentation/git-check-attr.txt\nindex 2b821f2..0839a57 100644\n--- a/Documentation/git-check-attr.txt\n+++ b/Documentation/git-check-attr.txt\n@@ -9,6 +9,7 @@ git-check-attr - Display gitattributes information.\n SYNOPSIS\n --------\n 'git check-attr' attr... [--] pathname...\n+'git check-attr' --stdin-paths attr... < <list-of-paths\n \n DESCRIPTION\n -----------\n@@ -17,6 +18,9 @@ For every pathname, this command will list if each attr is 'unspecified',\n \n OPTIONS\n -------\n+--stdin-paths::\n+\tRead file names from stdin instead of from the command-line.\n+\n \\--::\n \tInterpret all preceding arguments as attributes, and all following\n \targuments as path names. If not supplied, only the first argument will\ndiff --git a/builtin-check-attr.c b/builtin-check-attr.c\nindex 5a2e329..821eb5e 100644\n--- a/builtin-check-attr.c\n+++ b/builtin-check-attr.c\n@@ -2,9 +2,19 @@\n #include \"cache.h\"\n #include \"attr.h\"\n #include \"quote.h\"\n+#include \"parse-options.h\"\n \n-static const char check_attr_usage[] =\n-\"git check-attr attr... [--] pathname...\";\n+static int stdin_paths;\n+static const char * const check_attr_usage[] = {\n+\"git check-attr attr... [--] pathname...\",\n+\"git check-attr --stdin-paths attr... < <list-of-paths>\",\n+NULL\n+};\n+\n+static const struct option check_attr_options[] = {\n+\tOPT_BOOLEAN(0 , \"stdin-paths\", &stdin_paths, \"read file names from stdin\"),\n+\tOPT_END()\n+};\n \n static void check_attr(int cnt, struct git_attr_check *check,\n \tconst char** name, const char *file)\n@@ -27,17 +37,43 @@ static void check_attr(int cnt, struct git_attr_check *check,\n \t}\n }\n \n+static void check_attr_stdin_paths(int cnt, struct git_attr_check *check,\n+\tconst char** name)\n+{\n+\tstruct strbuf buf, nbuf;\n+\n+\tstrbuf_init(&buf, 0);\n+\tstrbuf_init(&nbuf, 0);\n+\twhile (strbuf_getline(&buf, stdin, '\\n') != EOF) {\n+\t\tif (buf.buf[0] == '\"') {\n+\t\t\tstrbuf_reset(&nbuf);\n+\t\t\tif (unquote_c_style(&nbuf, buf.buf, NULL))\n+\t\t\t\tdie(\"line is badly quoted\");\n+\t\t\tstrbuf_swap(&buf, &nbuf);\n+\t\t}\n+\t\tcheck_attr(cnt, check, name, buf.buf);\n+\t}\n+\tstrbuf_release(&buf);\n+\tstrbuf_release(&nbuf);\n+}\n+\n int cmd_check_attr(int argc, const char **argv, const char *prefix)\n {\n \tstruct git_attr_check *check;\n \tint cnt, i, doubledash;\n+\tconst char *errstr = NULL;\n+\n+\targc = parse_options(argc, argv, check_attr_options, check_attr_usage,\n+\t\tPARSE_OPT_KEEP_DASHDASH);\n+\tif (!argc)\n+\t\tusage_with_options(check_attr_usage, check_attr_options);\n \n \tif (read_cache() < 0) {\n \t\tdie(\"invalid cache\");\n \t}\n \n \tdoubledash = -1;\n-\tfor (i = 1; doubledash < 0 && i < argc; i++) {\n+\tfor (i = 0; doubledash < 0 && i < argc; i++) {\n \t\tif (!strcmp(argv[i], \"--\"))\n \t\t\tdoubledash = i;\n \t}\n@@ -45,25 +81,35 @@ int cmd_check_attr(int argc, const char **argv, const char *prefix)\n \t/* If there is no double dash, we handle only one attribute */\n \tif (doubledash < 0) {\n \t\tcnt = 1;\n-\t\tdoubledash = 1;\n+\t\tdoubledash = 0;\n \t} else\n-\t\tcnt = doubledash - 1;\n+\t\tcnt = doubledash;\n \tdoubledash++;\n \n-\tif (cnt <= 0 || argc < doubledash)\n-\t\tusage(check_attr_usage);\n+\tif (cnt <= 0)\n+\t\terrstr = \"No attribute specified\";\n+\telse if (stdin_paths && doubledash < argc)\n+\t\terrstr = \"Can't specify files with --stdin-paths\";\n+\tif (errstr) {\n+\t\terror (errstr);\n+\t\tusage_with_options(check_attr_usage, check_attr_options);\n+\t}\n+\n \tcheck = xcalloc(cnt, sizeof(*check));\n \tfor (i = 0; i < cnt; i++) {\n \t\tconst char *name;\n \t\tstruct git_attr *a;\n-\t\tname = argv[i + 1];\n+\t\tname = argv[i];\n \t\ta = git_attr(name, strlen(name));\n \t\tif (!a)\n \t\t\treturn error(\"%s: not a valid attribute name\", name);\n \t\tcheck[i].attr = a;\n \t}\n \n-\tfor (i = doubledash; i < argc; i++)\n-\t\tcheck_attr(cnt, check, argv+1, argv[i]);\n+\tif (stdin_paths)\n+\t\tcheck_attr_stdin_paths(cnt, check, argv);\n+\telse\n+\t\tfor (i = doubledash; i < argc; i++)\n+\t\t\tcheck_attr(cnt, check, argv, argv[i]);\n \treturn 0;\n }\ndiff --git a/t/t0003-attributes.sh b/t/t0003-attributes.sh\nindex 3d8e06a..f6901b4 100755\n--- a/t/t0003-attributes.sh\n+++ b/t/t0003-attributes.sh\n@@ -47,6 +47,23 @@ test_expect_success 'attribute test' '\n \n '\n \n+test_expect_success 'attribute test: read paths from stdin' '\n+\n+\tcat <<EOF > expect\n+f: test: f\n+a/f: test: f\n+a/c/f: test: f\n+a/g: test: a/g\n+a/b/g: test: a/b/g\n+b/g: test: unspecified\n+a/b/h: test: a/b/h\n+a/b/d/g: test: a/b/d/*\n+EOF\n+\n+\tsed -e \"s/:.*//\" < expect | git check-attr --stdin-paths test > actual &&\n+\ttest_cmp expect actual\n+'\n+\n test_expect_success 'root subdir attribute test' '\n \n \tattr_check a/i a/i &&\n-- \n1.6.0.2.447.g3befd\n"},{"id":"92392","messageId":"48E9B997.1010006@viscovery.net","threadId":"15568","inReplyTo":"1223173855-6173-2-git-send-email-dpotapov@gmail.com","subject":"Re: [PATCH 2/2] check-attr: Add --stdin-paths option","fromName":"Johannes Sixt","fromEmail":"j.sixt@viscovery.net","sentAt":"2008-10-06T07:09:11Z","receivedAt":"2008-10-06T07:09:11Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Dmitry Potapov schrieb:\n> +static void check_attr_stdin_paths(int cnt, struct git_attr_check *check,\n> +\tconst char** name)\n> +{\n> +\tstruct strbuf buf, nbuf;\n> +\n> +\tstrbuf_init(&buf, 0);\n> +\tstrbuf_init(&nbuf, 0);\n> +\twhile (strbuf_getline(&buf, stdin, '\\n') != EOF) {\n> +\t\tif (buf.buf[0] == '\"') {\n> +\t\t\tstrbuf_reset(&nbuf);\n> +\t\t\tif (unquote_c_style(&nbuf, buf.buf, NULL))\n> +\t\t\t\tdie(\"line is badly quoted\");\n> +\t\t\tstrbuf_swap(&buf, &nbuf);\n> +\t\t}\n> +\t\tcheck_attr(cnt, check, name, buf.buf);\n> +\t}\n> +\tstrbuf_release(&buf);\n> +\tstrbuf_release(&nbuf);\n> +}\n> +\n\nWe know that you will want to use this feature in gitk to reduce the\nnumber of fork()s. But you've a problem: gitk will first write a path to\ngit-check-addr's stdin, and then wait for the result on its stdout. But\nthis is a classic pitfall: You are not guaranteed that something will be\nreturned from stdout right away due to buffering. The least that is needed\nis fflush(stdout) in this loop (after each iteration!) so that gitk sees\nsome result and does not hang forever.\n\n-- Hannes\n"},{"id":"92465","messageId":"20081007001418.GQ21650@dpotapov.dyndns.org","threadId":"15568","inReplyTo":"48E9B997.1010006@viscovery.net","subject":"[PATCH 1/2 v2] check-attr: add an internal check_attr() function","fromName":"Dmitry Potapov","fromEmail":"dpotapov@gmail.com","sentAt":"2008-10-07T00:14:18Z","receivedAt":"2008-10-07T00:14:18Z","isPatch":true,"sender":{"key":"dpotapov@gmail.com","avatar":"https://avatars.githubusercontent.com/u/6568595?v=4"},"body":"This step is preparation to introducing --stdin-paths option.\n\nI have also added maybe_flush_or_die() at the end of main() to ensure that\nwe exit with the zero code only when we flushed the output successfully.\n\nSigned-off-by: Dmitry Potapov <dpotapov@gmail.com>\n---\nmaybe_flush_or_die() is added in this version of patch.\n\n builtin-check-attr.c |   42 ++++++++++++++++++++++++------------------\n 1 files changed, 24 insertions(+), 18 deletions(-)\n\ndiff --git a/builtin-check-attr.c b/builtin-check-attr.c\nindex cb783fc..786256e 100644\n--- a/builtin-check-attr.c\n+++ b/builtin-check-attr.c\n@@ -6,6 +6,27 @@\n static const char check_attr_usage[] =\n \"git check-attr attr... [--] pathname...\";\n \n+static void check_attr(int cnt, struct git_attr_check *check,\n+\tconst char** name, const char *file)\n+{\n+\tint j;\n+\tif (git_checkattr(file, cnt, check))\n+\t\tdie(\"git_checkattr died\");\n+\tfor (j = 0; j < cnt; j++) {\n+\t\tconst char *value = check[j].value;\n+\n+\t\tif (ATTR_TRUE(value))\n+\t\t\tvalue = \"set\";\n+\t\telse if (ATTR_FALSE(value))\n+\t\t\tvalue = \"unset\";\n+\t\telse if (ATTR_UNSET(value))\n+\t\t\tvalue = \"unspecified\";\n+\n+\t\tquote_c_style(file, NULL, stdout, 0);\n+\t\tprintf(\": %s: %s\\n\", name[j], value);\n+\t}\n+}\n+\n int cmd_check_attr(int argc, const char **argv, const char *prefix)\n {\n \tstruct git_attr_check *check;\n@@ -42,23 +63,8 @@ int cmd_check_attr(int argc, const char **argv, const char *prefix)\n \t\tcheck[i].attr = a;\n \t}\n \n-\tfor (i = doubledash; i < argc; i++) {\n-\t\tint j;\n-\t\tif (git_checkattr(argv[i], cnt, check))\n-\t\t\tdie(\"git_checkattr died\");\n-\t\tfor (j = 0; j < cnt; j++) {\n-\t\t\tconst char *value = check[j].value;\n-\n-\t\t\tif (ATTR_TRUE(value))\n-\t\t\t\tvalue = \"set\";\n-\t\t\telse if (ATTR_FALSE(value))\n-\t\t\t\tvalue = \"unset\";\n-\t\t\telse if (ATTR_UNSET(value))\n-\t\t\t\tvalue = \"unspecified\";\n-\n-\t\t\tquote_c_style(argv[i], NULL, stdout, 0);\n-\t\t\tprintf(\": %s: %s\\n\", argv[j+1], value);\n-\t\t}\n-\t}\n+\tfor (i = doubledash; i < argc; i++)\n+\t\tcheck_attr(cnt, check, argv+1, argv[i]);\n+\tmaybe_flush_or_die(stdout, \"attribute to stdout\");\n \treturn 0;\n }\n-- \n1.6.0.2.447.g3befd\n"},{"id":"92466","messageId":"20081007001652.GR21650@dpotapov.dyndns.org","threadId":"15568","inReplyTo":"48E9B997.1010006@viscovery.net","subject":"[PATCH 2/2 v2] check-attr: Add --stdin-paths option","fromName":"Dmitry Potapov","fromEmail":"dpotapov@gmail.com","sentAt":"2008-10-07T00:16:52Z","receivedAt":"2008-10-07T00:16:52Z","isPatch":true,"sender":{"key":"dpotapov@gmail.com","avatar":"https://avatars.githubusercontent.com/u/6568595?v=4"},"body":"This allows multiple paths to be specified on stdin.\n\nSigned-off-by: Dmitry Potapov <dpotapov@gmail.com>\n---\nOn Mon, Oct 06, 2008 at 09:09:11AM +0200, Johannes Sixt wrote:\n> \n> The least that is needed is fflush(stdout) in this loop (after each\n> iteration!)\n\nThanks. Somehow, I forgot about it though it is quite obvious.\nI have added maybe_flush_or_die().\n\n Documentation/git-check-attr.txt |    4 ++\n builtin-check-attr.c             |   70 ++++++++++++++++++++++++++++++++------\n t/t0003-attributes.sh            |   17 +++++++++\n 3 files changed, 80 insertions(+), 11 deletions(-)\n\ndiff --git a/Documentation/git-check-attr.txt b/Documentation/git-check-attr.txt\nindex 2b821f2..0839a57 100644\n--- a/Documentation/git-check-attr.txt\n+++ b/Documentation/git-check-attr.txt\n@@ -9,6 +9,7 @@ git-check-attr - Display gitattributes information.\n SYNOPSIS\n --------\n 'git check-attr' attr... [--] pathname...\n+'git check-attr' --stdin-paths attr... < <list-of-paths\n \n DESCRIPTION\n -----------\n@@ -17,6 +18,9 @@ For every pathname, this command will list if each attr is 'unspecified',\n \n OPTIONS\n -------\n+--stdin-paths::\n+\tRead file names from stdin instead of from the command-line.\n+\n \\--::\n \tInterpret all preceding arguments as attributes, and all following\n \targuments as path names. If not supplied, only the first argument will\ndiff --git a/builtin-check-attr.c b/builtin-check-attr.c\nindex 786256e..fa1e4d5 100644\n--- a/builtin-check-attr.c\n+++ b/builtin-check-attr.c\n@@ -2,9 +2,19 @@\n #include \"cache.h\"\n #include \"attr.h\"\n #include \"quote.h\"\n+#include \"parse-options.h\"\n \n-static const char check_attr_usage[] =\n-\"git check-attr attr... [--] pathname...\";\n+static int stdin_paths;\n+static const char * const check_attr_usage[] = {\n+\"git check-attr attr... [--] pathname...\",\n+\"git check-attr --stdin-paths attr... < <list-of-paths>\",\n+NULL\n+};\n+\n+static const struct option check_attr_options[] = {\n+\tOPT_BOOLEAN(0 , \"stdin-paths\", &stdin_paths, \"read file names from stdin\"),\n+\tOPT_END()\n+};\n \n static void check_attr(int cnt, struct git_attr_check *check,\n \tconst char** name, const char *file)\n@@ -27,17 +37,44 @@ static void check_attr(int cnt, struct git_attr_check *check,\n \t}\n }\n \n+static void check_attr_stdin_paths(int cnt, struct git_attr_check *check,\n+\tconst char** name)\n+{\n+\tstruct strbuf buf, nbuf;\n+\n+\tstrbuf_init(&buf, 0);\n+\tstrbuf_init(&nbuf, 0);\n+\twhile (strbuf_getline(&buf, stdin, '\\n') != EOF) {\n+\t\tif (buf.buf[0] == '\"') {\n+\t\t\tstrbuf_reset(&nbuf);\n+\t\t\tif (unquote_c_style(&nbuf, buf.buf, NULL))\n+\t\t\t\tdie(\"line is badly quoted\");\n+\t\t\tstrbuf_swap(&buf, &nbuf);\n+\t\t}\n+\t\tcheck_attr(cnt, check, name, buf.buf);\n+\t\tmaybe_flush_or_die(stdout, \"attribute to stdout\");\n+\t}\n+\tstrbuf_release(&buf);\n+\tstrbuf_release(&nbuf);\n+}\n+\n int cmd_check_attr(int argc, const char **argv, const char *prefix)\n {\n \tstruct git_attr_check *check;\n \tint cnt, i, doubledash;\n+\tconst char *errstr = NULL;\n+\n+\targc = parse_options(argc, argv, check_attr_options, check_attr_usage,\n+\t\tPARSE_OPT_KEEP_DASHDASH);\n+\tif (!argc)\n+\t\tusage_with_options(check_attr_usage, check_attr_options);\n \n \tif (read_cache() < 0) {\n \t\tdie(\"invalid cache\");\n \t}\n \n \tdoubledash = -1;\n-\tfor (i = 1; doubledash < 0 && i < argc; i++) {\n+\tfor (i = 0; doubledash < 0 && i < argc; i++) {\n \t\tif (!strcmp(argv[i], \"--\"))\n \t\t\tdoubledash = i;\n \t}\n@@ -45,26 +82,37 @@ int cmd_check_attr(int argc, const char **argv, const char *prefix)\n \t/* If there is no double dash, we handle only one attribute */\n \tif (doubledash < 0) {\n \t\tcnt = 1;\n-\t\tdoubledash = 1;\n+\t\tdoubledash = 0;\n \t} else\n-\t\tcnt = doubledash - 1;\n+\t\tcnt = doubledash;\n \tdoubledash++;\n \n-\tif (cnt <= 0 || argc < doubledash)\n-\t\tusage(check_attr_usage);\n+\tif (cnt <= 0)\n+\t\terrstr = \"No attribute specified\";\n+\telse if (stdin_paths && doubledash < argc)\n+\t\terrstr = \"Can't specify files with --stdin-paths\";\n+\tif (errstr) {\n+\t\terror (errstr);\n+\t\tusage_with_options(check_attr_usage, check_attr_options);\n+\t}\n+\n \tcheck = xcalloc(cnt, sizeof(*check));\n \tfor (i = 0; i < cnt; i++) {\n \t\tconst char *name;\n \t\tstruct git_attr *a;\n-\t\tname = argv[i + 1];\n+\t\tname = argv[i];\n \t\ta = git_attr(name, strlen(name));\n \t\tif (!a)\n \t\t\treturn error(\"%s: not a valid attribute name\", name);\n \t\tcheck[i].attr = a;\n \t}\n \n-\tfor (i = doubledash; i < argc; i++)\n-\t\tcheck_attr(cnt, check, argv+1, argv[i]);\n-\tmaybe_flush_or_die(stdout, \"attribute to stdout\");\n+\tif (stdin_paths)\n+\t\tcheck_attr_stdin_paths(cnt, check, argv);\n+\telse {\n+\t\tfor (i = doubledash; i < argc; i++)\n+\t\t\tcheck_attr(cnt, check, argv, argv[i]);\n+\t\tmaybe_flush_or_die(stdout, \"attribute to stdout\");\n+\t}\n \treturn 0;\n }\ndiff --git a/t/t0003-attributes.sh b/t/t0003-attributes.sh\nindex 3d8e06a..f6901b4 100755\n--- a/t/t0003-attributes.sh\n+++ b/t/t0003-attributes.sh\n@@ -47,6 +47,23 @@ test_expect_success 'attribute test' '\n \n '\n \n+test_expect_success 'attribute test: read paths from stdin' '\n+\n+\tcat <<EOF > expect\n+f: test: f\n+a/f: test: f\n+a/c/f: test: f\n+a/g: test: a/g\n+a/b/g: test: a/b/g\n+b/g: test: unspecified\n+a/b/h: test: a/b/h\n+a/b/d/g: test: a/b/d/*\n+EOF\n+\n+\tsed -e \"s/:.*//\" < expect | git check-attr --stdin-paths test > actual &&\n+\ttest_cmp expect actual\n+'\n+\n test_expect_success 'root subdir attribute test' '\n \n \tattr_check a/i a/i &&\n-- \n1.6.0.2.447.g3befd\n"},{"id":"92622","messageId":"20081008152443.GA4795@spearce.org","threadId":"15568","inReplyTo":"20081007001652.GR21650@dpotapov.dyndns.org","subject":"Re: [PATCH 2/2 v2] check-attr: Add --stdin-paths option","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2008-10-08T15:24:43Z","receivedAt":"2008-10-08T15:24:43Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Dmitry Potapov <dpotapov@gmail.com> wrote:\n> This allows multiple paths to be specified on stdin.\n\n> diff --git a/Documentation/git-check-attr.txt b/Documentation/git-check-attr.txt\n> index 2b821f2..0839a57 100644\n> --- a/Documentation/git-check-attr.txt\n> +++ b/Documentation/git-check-attr.txt\n> @@ -9,6 +9,7 @@ git-check-attr - Display gitattributes information.\n>  SYNOPSIS\n>  --------\n>  'git check-attr' attr... [--] pathname...\n> +'git check-attr' --stdin-paths attr... < <list-of-paths\n\nI wonder if the option should just be \"--stdin\".  And since its being\nused mostly by automated tools (gitk/git-gui) I wonder if a -z should\nalso be supported for input termination with NUL instead of LF.\n\n> diff --git a/t/t0003-attributes.sh b/t/t0003-attributes.sh\n> index 3d8e06a..f6901b4 100755\n> --- a/t/t0003-attributes.sh\n> +++ b/t/t0003-attributes.sh\n> @@ -47,6 +47,23 @@ test_expect_success 'attribute test' '\n>  \n>  '\n>  \n> +test_expect_success 'attribute test: read paths from stdin' '\n\nA test case for the quoting might also be good.\n\n> +\n> +\tcat <<EOF > expect\n> +f: test: f\n> +a/f: test: f\n> +a/c/f: test: f\n> +a/g: test: a/g\n> +a/b/g: test: a/b/g\n> +b/g: test: unspecified\n> +a/b/h: test: a/b/h\n> +a/b/d/g: test: a/b/d/*\n> +EOF\n> +\n> +\tsed -e \"s/:.*//\" < expect | git check-attr --stdin-paths test > actual &&\n> +\ttest_cmp expect actual\n\n-- \nShawn.\n"},{"id":"92742","messageId":"18671.12913.653592.847535@cargo.ozlabs.ibm.com","threadId":"15568","inReplyTo":"48E36086.7050504@viscovery.net","subject":"Re: [PATCH (GIT-GUI,GITK) 0/8] Encoding support in GUI","fromName":"Paul Mackerras","fromEmail":"paulus@samba.org","sentAt":"2008-10-10T10:46:09Z","receivedAt":"2008-10-10T10:46:09Z","isPatch":true,"sender":{"key":"paulus@samba.org","avatar":"https://avatars.githubusercontent.com/u/1606439?v=4"},"body":"Johannes Sixt writes:\n\n> I'm about to add a .gitattributes file that specifies the encoding for\n> some of my files *today* because I was not clever enough to anticipate the\n> usefulness of an \"encoding\" attribute a year ago when those files were\n> added to the repository. When I browse history, I *do* want that *today's*\n> encoding is picked.\n\nFair enough.\n\n> > (Also it seems that we won't\n> > notice if the user changes .gitattributes after we've looked at it, or\n> > if they create one after we've looked for one and not found it.)\n> \n> This is not a show stopper, IMHO. The user will notice soon enough, and\n> can restart gitk. Nobody sane will change the encoding attributes every hour.\n\nThe scenario I'm thinking of is this: a user clicks on a file to\ndisplay it, sees that it isn't displayed using the encoding he wants,\nsays \"duh\" and creates a .gitattributes file.  User clicks on the file\nagain, sees that it *still* isn't displayed using the right encoding,\nand says something worse than \"duh\". :)\n\nIf it was just one .gitattributes file, then it wouldn't be hard to\nstat it each time we go to display some file, and throw away our cache\nif it has changed.  But it looks like we would have to do N+1 stats\nfor a file N levels deep in the tree (since it looks like we also need\nto stat $GIT_DIR/info/attributes).  Still, it may be worth it.  At\nleast on Linux, stat is pretty fast.\n\nPaul.\n"},{"id":"92775","messageId":"18671.55733.970601.454074@cargo.ozlabs.ibm.com","threadId":"15568","inReplyTo":"20081007001652.GR21650@dpotapov.dyndns.org","subject":"Re: [PATCH 2/2 v2] check-attr: Add --stdin-paths option","fromName":"Paul Mackerras","fromEmail":"paulus@samba.org","sentAt":"2008-10-10T22:39:49Z","receivedAt":"2008-10-10T22:39:49Z","isPatch":true,"sender":{"key":"paulus@samba.org","avatar":"https://avatars.githubusercontent.com/u/1606439?v=4"},"body":"Dmitry Potapov writes:\n\n> This allows multiple paths to be specified on stdin.\n> \n> Signed-off-by: Dmitry Potapov <dpotapov@gmail.com>\n> ---\n> On Mon, Oct 06, 2008 at 09:09:11AM +0200, Johannes Sixt wrote:\n> > \n> > The least that is needed is fflush(stdout) in this loop (after each\n> > iteration!)\n> \n> Thanks. Somehow, I forgot about it though it is quite obvious.\n> I have added maybe_flush_or_die().\n\nActually, what was done with git diff-tree --stdin was to have it do\nfflush(stdout) when it sees a blank line in the input.  That gives the\ncalling program a way to get the output up to that point without\nhaving to do a flush for every line of output.\n\nPaul.\n"},{"id":"92843","messageId":"20081012141952.GD21650@dpotapov.dyndns.org","threadId":"15568","inReplyTo":"20081008152443.GA4795@spearce.org","subject":"Re: [PATCH 2/2 v2] check-attr: Add --stdin-paths option","fromName":"Dmitry Potapov","fromEmail":"dpotapov@gmail.com","sentAt":"2008-10-12T14:19:52Z","receivedAt":"2008-10-12T14:19:52Z","isPatch":true,"sender":{"key":"dpotapov@gmail.com","avatar":"https://avatars.githubusercontent.com/u/6568595?v=4"},"body":"On Wed, Oct 08, 2008 at 08:24:43AM -0700, Shawn O. Pearce wrote:\n> Dmitry Potapov <dpotapov@gmail.com> wrote:\n> > This allows multiple paths to be specified on stdin.\n> \n> > diff --git a/Documentation/git-check-attr.txt b/Documentation/git-check-attr.txt\n> > index 2b821f2..0839a57 100644\n> > --- a/Documentation/git-check-attr.txt\n> > +++ b/Documentation/git-check-attr.txt\n> > @@ -9,6 +9,7 @@ git-check-attr - Display gitattributes information.\n> >  SYNOPSIS\n> >  --------\n> >  'git check-attr' attr... [--] pathname...\n> > +'git check-attr' --stdin-paths attr... < <list-of-paths\n> \n> I wonder if the option should just be \"--stdin\".\n\nI used \"--stdin-paths\" because git hash-object uses it, while \"--stdin\"\nmeans to read the object from standard input. OTOH, we are never going\nto read the object from standard input in check-attr and some other git\ncommands use \"--stdin\" to mean: read the list of paths from the standard\ninput. So, I fully agree here.\n\n> And since its being\n> used mostly by automated tools (gitk/git-gui) I wonder if a -z should\n> also be supported for input termination with NUL instead of LF.\n\nI have added it, but after I did, I start to wonder whether it is the\nright thing to do to unquote NUL terminated input line?\n\nNUL terminated makes sense when you feed raw-bytes, and if the first\nbyte happen to be a quote character, I suppose it should be treated\njust as any other byte, not as a sign that the string is quited. But\nthen I looked at git checkout-index, and it unquotes string even if it\nis NUL terminated. I don't think it is the right thing to do, but just\nto be consistent, I have decided to leave as-is, i.e. to unquote a NUL\nterminated string.\n\n> > +test_expect_success 'attribute test: read paths from stdin' '\n> \n> A test case for the quoting might also be good.\n\nAs far as I can tell, there is no test case for special characters in\nfilenames when these filenames are given as arguments. And there are a\nfew problems with them. First, it is using colon as a separator in\noutput, which breaks parsing of a filename containing colons.  Second,\nI still have not figured out how to specify filenames with special\ncharacters in gitattributes. The documentation does not say anything\nand was lazy to study the code. Does gitattributes understand quote\nstrings in filenames?\n\n\nAnyway, here is interdiff to my previous patch, which addresses two\nfirst points as I described above. (I can resend the full patch if\nnecessary).\n\n-- >8 --\nFrom: Dmitry Potapov <dpotapov@gmail.com>\nDate: Sun, 12 Oct 2008 18:08:43 +0400\nSubject: [PATCH] check-attr: Add --stdin option\n\n---\n Documentation/git-check-attr.txt |    8 ++++++--\n builtin-check-attr.c             |   13 +++++++++----\n t/t0003-attributes.sh            |    2 +-\n 3 files changed, 16 insertions(+), 7 deletions(-)\n\ndiff --git a/Documentation/git-check-attr.txt b/Documentation/git-check-attr.txt\nindex 0839a57..14e4374 100644\n--- a/Documentation/git-check-attr.txt\n+++ b/Documentation/git-check-attr.txt\n@@ -9,7 +9,7 @@ git-check-attr - Display gitattributes information.\n SYNOPSIS\n --------\n 'git check-attr' attr... [--] pathname...\n-'git check-attr' --stdin-paths attr... < <list-of-paths\n+'git check-attr' --stdin [-z] attr... < <list-of-paths\n \n DESCRIPTION\n -----------\n@@ -18,9 +18,13 @@ For every pathname, this command will list if each attr is 'unspecified',\n \n OPTIONS\n -------\n---stdin-paths::\n+--stdin::\n \tRead file names from stdin instead of from the command-line.\n \n+-z::\n+\tOnly meaningful with `--stdin`; paths are separated with\n+\tNUL character instead of LF.\n+\n \\--::\n \tInterpret all preceding arguments as attributes, and all following\n \targuments as path names. If not supplied, only the first argument will\ndiff --git a/builtin-check-attr.c b/builtin-check-attr.c\nindex fa1e4d5..02a8292 100644\n--- a/builtin-check-attr.c\n+++ b/builtin-check-attr.c\n@@ -7,12 +7,16 @@\n static int stdin_paths;\n static const char * const check_attr_usage[] = {\n \"git check-attr attr... [--] pathname...\",\n-\"git check-attr --stdin-paths attr... < <list-of-paths>\",\n+\"git check-attr --stdin attr... < <list-of-paths>\",\n NULL\n };\n \n+static int null_term_line;\n+\n static const struct option check_attr_options[] = {\n-\tOPT_BOOLEAN(0 , \"stdin-paths\", &stdin_paths, \"read file names from stdin\"),\n+\tOPT_BOOLEAN(0 , \"stdin\", &stdin_paths, \"read file names from stdin\"),\n+\tOPT_BOOLEAN('z', NULL, &null_term_line,\n+\t\t\"input paths are terminated by a null character\"),\n \tOPT_END()\n };\n \n@@ -41,10 +45,11 @@ static void check_attr_stdin_paths(int cnt, struct git_attr_check *check,\n \tconst char** name)\n {\n \tstruct strbuf buf, nbuf;\n+\tint line_termination = null_term_line ? 0 : '\\n';\n \n \tstrbuf_init(&buf, 0);\n \tstrbuf_init(&nbuf, 0);\n-\twhile (strbuf_getline(&buf, stdin, '\\n') != EOF) {\n+\twhile (strbuf_getline(&buf, stdin, line_termination) != EOF) {\n \t\tif (buf.buf[0] == '\"') {\n \t\t\tstrbuf_reset(&nbuf);\n \t\t\tif (unquote_c_style(&nbuf, buf.buf, NULL))\n@@ -90,7 +95,7 @@ int cmd_check_attr(int argc, const char **argv, const char *prefix)\n \tif (cnt <= 0)\n \t\terrstr = \"No attribute specified\";\n \telse if (stdin_paths && doubledash < argc)\n-\t\terrstr = \"Can't specify files with --stdin-paths\";\n+\t\terrstr = \"Can't specify files with --stdin\";\n \tif (errstr) {\n \t\terror (errstr);\n \t\tusage_with_options(check_attr_usage, check_attr_options);\ndiff --git a/t/t0003-attributes.sh b/t/t0003-attributes.sh\nindex f6901b4..1c77192 100755\n--- a/t/t0003-attributes.sh\n+++ b/t/t0003-attributes.sh\n@@ -60,7 +60,7 @@ a/b/h: test: a/b/h\n a/b/d/g: test: a/b/d/*\n EOF\n \n-\tsed -e \"s/:.*//\" < expect | git check-attr --stdin-paths test > actual &&\n+\tsed -e \"s/:.*//\" < expect | git check-attr --stdin test > actual &&\n \ttest_cmp expect actual\n '\n \n-- \n1.6.0.2.521.g49aa8.dirty\n\n-- >8 --\n"},{"id":"92844","messageId":"20081012143019.GE21650@dpotapov.dyndns.org","threadId":"15568","inReplyTo":"18671.55733.970601.454074@cargo.ozlabs.ibm.com","subject":"Re: [PATCH 2/2 v2] check-attr: Add --stdin-paths option","fromName":"Dmitry Potapov","fromEmail":"dpotapov@gmail.com","sentAt":"2008-10-12T14:30:19Z","receivedAt":"2008-10-12T14:30:19Z","isPatch":true,"sender":{"key":"dpotapov@gmail.com","avatar":"https://avatars.githubusercontent.com/u/6568595?v=4"},"body":"On Sat, Oct 11, 2008 at 09:39:49AM +1100, Paul Mackerras wrote:\n> \n> Actually, what was done with git diff-tree --stdin was to have it do\n> fflush(stdout) when it sees a blank line in the input.  That gives the\n> calling program a way to get the output up to that point without\n> having to do a flush for every line of output.\n\nIt is an interesting idea, but I have not seen any other git command\ndoing so, and my measurement in git repo on Linux have not offered\nany noticeable speed-up. So, I am not sure if it is worth it.\n\nDmitry\n"},{"id":"92845","messageId":"gct3lk$s16$1@ger.gmane.org","threadId":"15568","inReplyTo":"20081012141952.GD21650@dpotapov.dyndns.org","subject":"Re: [PATCH 2/2 v2] check-attr: Add --stdin-paths option","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2008-10-12T15:04:21Z","receivedAt":"2008-10-12T15:04:21Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Dmitry Potapov wrote:\n\n>> And since its being\n>> used mostly by automated tools (gitk/git-gui) I wonder if a -z should\n>> also be supported for input termination with NUL instead of LF.\n> \n> I have added it, but after I did, I start to wonder whether it is the\n> right thing to do to unquote NUL terminated input line?\n\nI think that -z should be not quoted (like git-diff-tree or git-ls-tree\n_output_); if it is, then IMHO it is a bug.\n\n-- \nJakub Narebski\nWarsaw, Poland\nShadeHawk on #git\n"},{"id":"92854","messageId":"20081012163504.GF21650@dpotapov.dyndns.org","threadId":"15568","inReplyTo":"gct3lk$s16$1@ger.gmane.org","subject":"Re: [PATCH 2/2 v2] check-attr: Add --stdin-paths option","fromName":"Dmitry Potapov","fromEmail":"dpotapov@gmail.com","sentAt":"2008-10-12T16:35:05Z","receivedAt":"2008-10-12T16:35:05Z","isPatch":true,"sender":{"key":"dpotapov@gmail.com","avatar":"https://avatars.githubusercontent.com/u/6568595?v=4"},"body":"On Sun, Oct 12, 2008 at 05:04:21PM +0200, Jakub Narebski wrote:\n> Dmitry Potapov wrote:\n> \n> >> And since its being\n> >> used mostly by automated tools (gitk/git-gui) I wonder if a -z should\n> >> also be supported for input termination with NUL instead of LF.\n> > \n> > I have added it, but after I did, I start to wonder whether it is the\n> > right thing to do to unquote NUL terminated input line?\n> \n> I think that -z should be not quoted (like git-diff-tree or git-ls-tree\n> _output_); if it is, then IMHO it is a bug.\n\nI am sorry. I was obviously wrong about 'git checkout-index', as it does\nnot try to unquote if '-z' is specified. So, my previous patch was wrong.\nThe corrected patch is below.\n\nIt still uses the same output format whether '-z' is specified or not.\nMaybe I should change that too to use '\\0' as the separator if '-z' is\nspecified?\n\nDmitry\nPS Please, add me to 'To:' or 'Cc:' when you reply to my email.\n\n\n-- >8 --\nFrom: Dmitry Potapov <dpotapov@gmail.com>\nDate: Sun, 12 Oct 2008 18:08:43 +0400\nSubject: [PATCH] check-attr: Add --stdin option\n\n---\nThis patch is meant to be squash on top of dp/checkattr in pu.\n\n Documentation/git-check-attr.txt |    8 ++++++--\n builtin-check-attr.c             |   15 ++++++++++-----\n t/t0003-attributes.sh            |    2 +-\n 3 files changed, 17 insertions(+), 8 deletions(-)\n\ndiff --git a/Documentation/git-check-attr.txt b/Documentation/git-check-attr.txt\nindex 0839a57..14e4374 100644\n--- a/Documentation/git-check-attr.txt\n+++ b/Documentation/git-check-attr.txt\n@@ -9,7 +9,7 @@ git-check-attr - Display gitattributes information.\n SYNOPSIS\n --------\n 'git check-attr' attr... [--] pathname...\n-'git check-attr' --stdin-paths attr... < <list-of-paths\n+'git check-attr' --stdin [-z] attr... < <list-of-paths\n \n DESCRIPTION\n -----------\n@@ -18,9 +18,13 @@ For every pathname, this command will list if each attr is 'unspecified',\n \n OPTIONS\n -------\n---stdin-paths::\n+--stdin::\n \tRead file names from stdin instead of from the command-line.\n \n+-z::\n+\tOnly meaningful with `--stdin`; paths are separated with\n+\tNUL character instead of LF.\n+\n \\--::\n \tInterpret all preceding arguments as attributes, and all following\n \targuments as path names. If not supplied, only the first argument will\ndiff --git a/builtin-check-attr.c b/builtin-check-attr.c\nindex fa1e4d5..4921341 100644\n--- a/builtin-check-attr.c\n+++ b/builtin-check-attr.c\n@@ -7,12 +7,16 @@\n static int stdin_paths;\n static const char * const check_attr_usage[] = {\n \"git check-attr attr... [--] pathname...\",\n-\"git check-attr --stdin-paths attr... < <list-of-paths>\",\n+\"git check-attr --stdin attr... < <list-of-paths>\",\n NULL\n };\n \n+static int null_term_line;\n+\n static const struct option check_attr_options[] = {\n-\tOPT_BOOLEAN(0 , \"stdin-paths\", &stdin_paths, \"read file names from stdin\"),\n+\tOPT_BOOLEAN(0 , \"stdin\", &stdin_paths, \"read file names from stdin\"),\n+\tOPT_BOOLEAN('z', NULL, &null_term_line,\n+\t\t\"input paths are terminated by a null character\"),\n \tOPT_END()\n };\n \n@@ -41,11 +45,12 @@ static void check_attr_stdin_paths(int cnt, struct git_attr_check *check,\n \tconst char** name)\n {\n \tstruct strbuf buf, nbuf;\n+\tint line_termination = null_term_line ? 0 : '\\n';\n \n \tstrbuf_init(&buf, 0);\n \tstrbuf_init(&nbuf, 0);\n-\twhile (strbuf_getline(&buf, stdin, '\\n') != EOF) {\n-\t\tif (buf.buf[0] == '\"') {\n+\twhile (strbuf_getline(&buf, stdin, line_termination) != EOF) {\n+\t\tif (line_termination && buf.buf[0] == '\"') {\n \t\t\tstrbuf_reset(&nbuf);\n \t\t\tif (unquote_c_style(&nbuf, buf.buf, NULL))\n \t\t\t\tdie(\"line is badly quoted\");\n@@ -90,7 +95,7 @@ int cmd_check_attr(int argc, const char **argv, const char *prefix)\n \tif (cnt <= 0)\n \t\terrstr = \"No attribute specified\";\n \telse if (stdin_paths && doubledash < argc)\n-\t\terrstr = \"Can't specify files with --stdin-paths\";\n+\t\terrstr = \"Can't specify files with --stdin\";\n \tif (errstr) {\n \t\terror (errstr);\n \t\tusage_with_options(check_attr_usage, check_attr_options);\ndiff --git a/t/t0003-attributes.sh b/t/t0003-attributes.sh\nindex f6901b4..1c77192 100755\n--- a/t/t0003-attributes.sh\n+++ b/t/t0003-attributes.sh\n@@ -60,7 +60,7 @@ a/b/h: test: a/b/h\n a/b/d/g: test: a/b/d/*\n EOF\n \n-\tsed -e \"s/:.*//\" < expect | git check-attr --stdin-paths test > actual &&\n+\tsed -e \"s/:.*//\" < expect | git check-attr --stdin test > actual &&\n \ttest_cmp expect actual\n '\n \n-- \n1.6.0.2.521.g739d3\n\n-- >8 --\n"}]}