git-gui: Use gitattribute "encoding" for file content display
Most folks using git-gui on internationalized files have complained that it doesn't recognize UTF-8 correctly. In the past we have just ignored the problem and showed the file contents as binary/US-ASCII, which is wrong no matter how you look at it. This really should be a per-file attribute, managed by .gitattributes, so we now pull the "encoding" attribute data for the given path from the .gitattributes (if available) and use that, falling back to UTF-8 if the attributes are unavailable, git-check-attr is broken, or an encoding for this path not specified. We apply the encoding anytime we show file content, which currently is limited to only the diff viewer and the blame viewer. Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
This commit is contained in:
parent
2cd1fd1f6d
commit
1ffca60f0b
3
.gitattributes
vendored
Normal file
3
.gitattributes
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
* encoding=US-ASCII
|
||||||
|
git-gui.sh encoding=UTF-8
|
||||||
|
/po/*.po encoding=UTF-8
|
13
git-gui.sh
13
git-gui.sh
@ -521,6 +521,19 @@ proc kill_file_process {fd} {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
proc gitattr {path attr default} {
|
||||||
|
if {[catch {set r [git check-attr $attr -- $path]}]} {
|
||||||
|
set r unspecified
|
||||||
|
} else {
|
||||||
|
set r [join [lrange [split $r :] 2 end] :]
|
||||||
|
regsub {^ } $r {} r
|
||||||
|
}
|
||||||
|
if {$r eq {unspecified}} {
|
||||||
|
return $default
|
||||||
|
}
|
||||||
|
return $r
|
||||||
|
}
|
||||||
|
|
||||||
proc sq {value} {
|
proc sq {value} {
|
||||||
regsub -all ' $value "'\\''" value
|
regsub -all ' $value "'\\''" value
|
||||||
return "'$value'"
|
return "'$value'"
|
||||||
|
@ -399,7 +399,10 @@ method _load {jump} {
|
|||||||
} else {
|
} else {
|
||||||
set fd [git_read cat-file blob "$commit:$path"]
|
set fd [git_read cat-file blob "$commit:$path"]
|
||||||
}
|
}
|
||||||
fconfigure $fd -blocking 0 -translation lf -encoding binary
|
fconfigure $fd \
|
||||||
|
-blocking 0 \
|
||||||
|
-translation lf \
|
||||||
|
-encoding [tcl_encoding [gitattr $path encoding UTF-8]]
|
||||||
fileevent $fd readable [cb _read_file $fd $jump]
|
fileevent $fd readable [cb _read_file $fd $jump]
|
||||||
set current_fd $fd
|
set current_fd $fd
|
||||||
}
|
}
|
||||||
|
@ -164,8 +164,11 @@ proc show_other_diff {path w m scroll_pos} {
|
|||||||
set sz [string length $content]
|
set sz [string length $content]
|
||||||
}
|
}
|
||||||
file {
|
file {
|
||||||
|
set enc [gitattr $path encoding UTF-8]
|
||||||
set fd [open $path r]
|
set fd [open $path r]
|
||||||
fconfigure $fd -eofchar {}
|
fconfigure $fd \
|
||||||
|
-eofchar {} \
|
||||||
|
-encoding [tcl_encoding $enc]
|
||||||
set content [read $fd $max_sz]
|
set content [read $fd $max_sz]
|
||||||
close $fd
|
close $fd
|
||||||
set sz [file size $path]
|
set sz [file size $path]
|
||||||
@ -279,8 +282,8 @@ proc start_show_diff {scroll_pos {add_opts {}}} {
|
|||||||
set ::current_diff_inheader 1
|
set ::current_diff_inheader 1
|
||||||
fconfigure $fd \
|
fconfigure $fd \
|
||||||
-blocking 0 \
|
-blocking 0 \
|
||||||
-encoding binary \
|
-encoding [tcl_encoding [gitattr $path encoding UTF-8]] \
|
||||||
-translation binary
|
-translation lf
|
||||||
fileevent $fd readable [list read_diff $fd $scroll_pos]
|
fileevent $fd readable [list read_diff $fd $scroll_pos]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user