Merge git://repo.or.cz/git-gui
authorShawn O. Pearce <spearce@spearce.org>
Thu, 25 Sep 2008 15:41:07 +0000 (08:41 -0700)
committerShawn O. Pearce <spearce@spearce.org>
Thu, 25 Sep 2008 15:41:07 +0000 (08:41 -0700)
* git://repo.or.cz/git-gui:
  git-gui: Reenable staging unmerged files by clicking the icon.
  git-gui: Support the encoding menu in gui blame.
  git-gui: Optimize encoding name resolution using a lookup table.
  git-gui: Allow forcing display encoding for diffs using a submenu.
  git-gui: Add a menu of available encodings.
  git-gui: Cleanup handling of the default encoding.
  git-gui: Assume `blame --incremental` output is in UTF-8
  git-gui: Use gitattribute "encoding" for file content display
  git-gui: Add support for calling out to the prepare-commit-msg hook
  git-gui: Hide commit related UI during citool --nocommit
  git-gui: Add more integration options to citool.
  git-gui: Updated German translation.
  git-gui: I18n fix sentence parts into full sentences for translation again.
  git-gui: Restore ability to Stage Working Copy for conflicts.
  git-gui: Fix Blame Parent & Context for working copy lines.

1  2 
git-gui/.gitattributes
git-gui/git-gui.sh
git-gui/lib/blame.tcl
git-gui/lib/commit.tcl
git-gui/lib/diff.tcl
git-gui/lib/encoding.tcl
git-gui/lib/mergetool.tcl
git-gui/lib/option.tcl
git-gui/po/de.po

diff --combined git-gui/.gitattributes
index 0000000,0000000..f96112d
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,3 @@@
++*           encoding=US-ASCII
++git-gui.sh  encoding=UTF-8
++/po/*.po    encoding=UTF-8
diff --combined git-gui/git-gui.sh
@@@ -521,6 -521,19 +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} {
        regsub -all ' $value "'\\''" value
        return "'$value'"
@@@ -665,6 -678,7 +678,7 @@@ set default_config(merge.verbosity) 
  set default_config(user.name) {}
  set default_config(user.email) {}
  
+ set default_config(gui.encoding) [encoding system]
  set default_config(gui.matchtrackingbranch) false
  set default_config(gui.pruneduringfetch) false
  set default_config(gui.trustmtime) false
@@@ -948,10 -962,32 +962,32 @@@ blame 
  }
  citool {
        enable_option singlecommit
+       enable_option retcode
  
        disable_option multicommit
        disable_option branch
        disable_option transport
+       while {[llength $argv] > 0} {
+               set a [lindex $argv 0]
+               switch -- $a {
+               --amend {
+                       enable_option initialamend
+               }
+               --nocommit {
+                       enable_option nocommit
+                       enable_option nocommitmsg
+               }
+               --commitmsg {
+                       disable_option nocommitmsg
+               }
+               default {
+                       break
+               }
+               }
+               set argv [lrange $argv 1 end]
+       }
  }
  }
  
@@@ -1023,8 -1059,12 +1059,12 @@@ set current_branch {
  set is_detached 0
  set current_diff_path {}
  set is_3way_diff 0
+ set is_conflict_diff 0
  set selected_commit_type new
  
+ set nullid "0000000000000000000000000000000000000000"
+ set nullid2 "0000000000000000000000000000000000000001"
  ######################################################################
  ##
  ## task management
@@@ -1105,6 -1145,20 +1145,20 @@@ proc PARENT {} 
        return $empty_tree
  }
  
+ proc force_amend {} {
+       global selected_commit_type
+       global HEAD PARENT MERGE_HEAD commit_type
+       repository_state newType newHEAD newMERGE_HEAD
+       set HEAD $newHEAD
+       set PARENT $newHEAD
+       set MERGE_HEAD $newMERGE_HEAD
+       set commit_type $newType
+       set selected_commit_type amend
+       do_select_commit_type
+ }
  proc rescan {after {honor_trustmtime 1}} {
        global HEAD PARENT MERGE_HEAD commit_type
        global ui_index ui_workdir ui_comm
                || [string trim [$ui_comm get 0.0 end]] eq {})} {
                if {[string match amend* $commit_type]} {
                } elseif {[load_message GITGUI_MSG]} {
+               } elseif {[run_prepare_commit_msg_hook]} {
                } elseif {[load_message MERGE_MSG]} {
                } elseif {[load_message SQUASH_MSG]} {
                }
@@@ -1230,6 -1285,70 +1285,70 @@@ proc load_message {file} 
        return 0
  }
  
+ proc run_prepare_commit_msg_hook {} {
+       global pch_error
+       # prepare-commit-msg requires PREPARE_COMMIT_MSG exist.  From git-gui
+       # it will be .git/MERGE_MSG (merge), .git/SQUASH_MSG (squash), or an
+       # empty file but existant file.
+       set fd_pcm [open [gitdir PREPARE_COMMIT_MSG] a]
+       if {[file isfile [gitdir MERGE_MSG]]} {
+               set pcm_source "merge"
+               set fd_mm [open [gitdir MERGE_MSG] r]
+               puts -nonewline $fd_pcm [read $fd_mm]
+               close $fd_mm
+       } elseif {[file isfile [gitdir SQUASH_MSG]]} {
+               set pcm_source "squash"
+               set fd_sm [open [gitdir SQUASH_MSG] r]
+               puts -nonewline $fd_pcm [read $fd_sm]
+               close $fd_sm
+       } else {
+               set pcm_source ""
+       }
+       close $fd_pcm
+       set fd_ph [githook_read prepare-commit-msg \
+                       [gitdir PREPARE_COMMIT_MSG] $pcm_source]
+       if {$fd_ph eq {}} {
+               catch {file delete [gitdir PREPARE_COMMIT_MSG]}
+               return 0;
+       }
+       ui_status [mc "Calling prepare-commit-msg hook..."]
+       set pch_error {}
+       fconfigure $fd_ph -blocking 0 -translation binary -eofchar {}
+       fileevent $fd_ph readable \
+               [list prepare_commit_msg_hook_wait $fd_ph]
+       return 1;
+ }
+ proc prepare_commit_msg_hook_wait {fd_ph} {
+       global pch_error
+       append pch_error [read $fd_ph]
+       fconfigure $fd_ph -blocking 1
+       if {[eof $fd_ph]} {
+               if {[catch {close $fd_ph}]} {
+                       ui_status [mc "Commit declined by prepare-commit-msg hook."]
+                       hook_failed_popup prepare-commit-msg $pch_error
+                       catch {file delete [gitdir PREPARE_COMMIT_MSG]}
+                       exit 1
+               } else {
+                       load_message PREPARE_COMMIT_MSG
+               }
+               set pch_error {}
+               catch {file delete [gitdir PREPARE_COMMIT_MSG]}
+               return
+         }
+       fconfigure $fd_ph -blocking 0
+       catch {file delete [gitdir PREPARE_COMMIT_MSG]}
+ }
  proc read_diff_index {fd after} {
        global buf_rdi
  
@@@ -1751,11 -1870,19 +1870,19 @@@ proc do_gitk {revs} 
  }
  
  set is_quitting 0
+ set ret_code    1
+ proc terminate_me {win} {
+       global ret_code
+       if {$win ne {.}} return
+       exit $ret_code
+ }
  
- proc do_quit {} {
+ proc do_quit {{rc {1}}} {
        global ui_comm is_quitting repo_config commit_type
        global GITGUI_BCK_exists GITGUI_BCK_i
        global ui_comm_spell
+       global ret_code
  
        if {$is_quitting} return
        set is_quitting 1
                }
        }
  
+       set ret_code $rc
        destroy .
  }
  
@@@ -1951,19 -2079,21 +2079,21 @@@ proc toggle_or_diff {w x y} 
        $ui_index tag remove in_sel 0.0 end
        $ui_workdir tag remove in_sel 0.0 end
  
-       # Do not stage files with conflicts
+       # Determine the state of the file
        if {[info exists file_states($path)]} {
                set state [lindex $file_states($path) 0]
        } else {
                set state {__}
        }
  
-       if {[string first {U} $state] >= 0} {
-               set col 1
-       }
        # Restage the file, or simply show the diff
        if {$col == 0 && $y > 1} {
+               # Conflicts need special handling
+               if {[string first {U} $state] >= 0} {
+                       merge_stage_workdir $path $w $lno
+                       return
+               }
                if {[string index $state 1] eq {O}} {
                        set mmask {}
                } else {
@@@ -2212,26 -2342,36 +2342,36 @@@ if {[is_enabled branch]} 
  
  # -- Commit Menu
  #
+ proc commit_btn_caption {} {
+       if {[is_enabled nocommit]} {
+               return [mc "Done"]
+       } else {
+               return [mc Commit@@verb]
+       }
+ }
  if {[is_enabled multicommit] || [is_enabled singlecommit]} {
        menu .mbar.commit
  
-       .mbar.commit add radiobutton \
-               -label [mc "New Commit"] \
-               -command do_select_commit_type \
-               -variable selected_commit_type \
-               -value new
-       lappend disable_on_lock \
-               [list .mbar.commit entryconf [.mbar.commit index last] -state]
+       if {![is_enabled nocommit]} {
+               .mbar.commit add radiobutton \
+                       -label [mc "New Commit"] \
+                       -command do_select_commit_type \
+                       -variable selected_commit_type \
+                       -value new
+               lappend disable_on_lock \
+                       [list .mbar.commit entryconf [.mbar.commit index last] -state]
  
-       .mbar.commit add radiobutton \
-               -label [mc "Amend Last Commit"] \
-               -command do_select_commit_type \
-               -variable selected_commit_type \
-               -value amend
-       lappend disable_on_lock \
-               [list .mbar.commit entryconf [.mbar.commit index last] -state]
+               .mbar.commit add radiobutton \
+                       -label [mc "Amend Last Commit"] \
+                       -command do_select_commit_type \
+                       -variable selected_commit_type \
+                       -value amend
+               lappend disable_on_lock \
+                       [list .mbar.commit entryconf [.mbar.commit index last] -state]
  
-       .mbar.commit add separator
+               .mbar.commit add separator
+       }
  
        .mbar.commit add command -label [mc Rescan] \
                -command ui_do_rescan \
  
        .mbar.commit add separator
  
-       .mbar.commit add command -label [mc "Sign Off"] \
-               -command do_signoff \
-               -accelerator $M1T-S
+       if {![is_enabled nocommit]} {
+               .mbar.commit add command -label [mc "Sign Off"] \
+                       -command do_signoff \
+                       -accelerator $M1T-S
+       }
  
-       .mbar.commit add command -label [mc Commit@@verb] \
+       .mbar.commit add command -label [commit_btn_caption] \
                -command do_commit \
                -accelerator $M1T-Return
        lappend disable_on_lock \
@@@ -2601,19 -2743,23 +2743,23 @@@ pack .vpane.lower.commarea.buttons.inca
  lappend disable_on_lock \
        {.vpane.lower.commarea.buttons.incall conf -state}
  
- button .vpane.lower.commarea.buttons.signoff -text [mc "Sign Off"] \
-       -command do_signoff
- pack .vpane.lower.commarea.buttons.signoff -side top -fill x
+ if {![is_enabled nocommit]} {
+       button .vpane.lower.commarea.buttons.signoff -text [mc "Sign Off"] \
+               -command do_signoff
+       pack .vpane.lower.commarea.buttons.signoff -side top -fill x
+ }
  
- button .vpane.lower.commarea.buttons.commit -text [mc Commit@@verb] \
+ button .vpane.lower.commarea.buttons.commit -text [commit_btn_caption] \
        -command do_commit
  pack .vpane.lower.commarea.buttons.commit -side top -fill x
  lappend disable_on_lock \
        {.vpane.lower.commarea.buttons.commit conf -state}
  
- button .vpane.lower.commarea.buttons.push -text [mc Push] \
-       -command do_push_anywhere
- pack .vpane.lower.commarea.buttons.push -side top -fill x
+ if {![is_enabled nocommit]} {
+       button .vpane.lower.commarea.buttons.push -text [mc Push] \
+               -command do_push_anywhere
+       pack .vpane.lower.commarea.buttons.push -side top -fill x
+ }
  
  # -- Commit Message Buffer
  #
@@@ -2621,20 -2767,24 +2767,24 @@@ frame .vpane.lower.commarea.buffe
  frame .vpane.lower.commarea.buffer.header
  set ui_comm .vpane.lower.commarea.buffer.t
  set ui_coml .vpane.lower.commarea.buffer.header.l
- radiobutton .vpane.lower.commarea.buffer.header.new \
-       -text [mc "New Commit"] \
-       -command do_select_commit_type \
-       -variable selected_commit_type \
-       -value new
- lappend disable_on_lock \
-       [list .vpane.lower.commarea.buffer.header.new conf -state]
- radiobutton .vpane.lower.commarea.buffer.header.amend \
-       -text [mc "Amend Last Commit"] \
-       -command do_select_commit_type \
-       -variable selected_commit_type \
-       -value amend
- lappend disable_on_lock \
-       [list .vpane.lower.commarea.buffer.header.amend conf -state]
+ if {![is_enabled nocommit]} {
+       radiobutton .vpane.lower.commarea.buffer.header.new \
+               -text [mc "New Commit"] \
+               -command do_select_commit_type \
+               -variable selected_commit_type \
+               -value new
+       lappend disable_on_lock \
+               [list .vpane.lower.commarea.buffer.header.new conf -state]
+       radiobutton .vpane.lower.commarea.buffer.header.amend \
+               -text [mc "Amend Last Commit"] \
+               -command do_select_commit_type \
+               -variable selected_commit_type \
+               -value amend
+       lappend disable_on_lock \
+               [list .vpane.lower.commarea.buffer.header.amend conf -state]
+ }
  label $ui_coml \
        -anchor w \
        -justify left
@@@ -2652,8 -2802,11 +2802,11 @@@ proc trace_commit_type {varname args} 
  }
  trace add variable commit_type write trace_commit_type
  pack $ui_coml -side left -fill x
- pack .vpane.lower.commarea.buffer.header.amend -side right
- pack .vpane.lower.commarea.buffer.header.new -side right
+ if {![is_enabled nocommit]} {
+       pack .vpane.lower.commarea.buffer.header.amend -side right
+       pack .vpane.lower.commarea.buffer.header.new -side right
+ }
  
  text $ui_comm -background white -foreground black \
        -borderwidth 1 \
@@@ -2860,6 -3013,14 +3013,14 @@@ proc create_common_diff_popup {ctxm} 
                -command {incr_font_size font_diff 1}
        lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
        $ctxm add separator
+       set emenu $ctxm.enc
+       menu $emenu
+       build_encoding_menu $emenu [list force_diff_encoding]
+       $ctxm add cascade \
+               -label [mc "Encoding"] \
+               -menu $emenu
+       lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
+       $ctxm add separator
        $ctxm add command -label [mc "Options..."] \
                -command do_options
  }
@@@ -3191,7 -3352,20 +3352,20 @@@ lock_index begin-rea
  if {![winfo ismapped .]} {
        wm deiconify .
  }
- after 1 do_rescan
+ after 1 {
+       if {[is_enabled initialamend]} {
+               force_amend
+       } else {
+               do_rescan
+       }
+       if {[is_enabled nocommitmsg]} {
+               $ui_comm configure -state disabled -background gray
+       }
+ }
  if {[is_enabled multicommit]} {
        after 1000 hint_gc
  }
+ if {[is_enabled retcode]} {
+       bind . <Destroy> {+terminate_me %W}
+ }
diff --combined git-gui/lib/blame.tcl
@@@ -256,9 -256,16 +256,16 @@@ constructor new {i_commit i_path i_jump
        $w.ctxm add command \
                -label [mc "Copy Commit"] \
                -command [cb _copycommit]
+       $w.ctxm add separator
+       menu $w.ctxm.enc
+       build_encoding_menu $w.ctxm.enc [cb _setencoding]
+       $w.ctxm add cascade \
+               -label [mc "Encoding"] \
+               -menu $w.ctxm.enc
        $w.ctxm add command \
                -label [mc "Do Full Copy Detection"] \
                -command [cb _fullcopyblame]
+       $w.ctxm add separator
        $w.ctxm add command \
                -label [mc "Show History Context"] \
                -command [cb _gitkcommit]
@@@ -399,7 -406,10 +406,10 @@@ method _load {jump} 
        } else {
                set fd [git_read cat-file blob "$commit:$path"]
        }
-       fconfigure $fd -blocking 0 -translation lf -encoding binary
+       fconfigure $fd \
+               -blocking 0 \
+               -translation lf \
+               -encoding [get_path_encoding $path]
        fileevent $fd readable [cb _read_file $fd $jump]
        set current_fd $fd
  }
@@@ -508,7 -518,7 +518,7 @@@ method _exec_blame {cur_w cur_d option
        }
        lappend options -- $path
        set fd [eval git_read --nice blame $options]
-       fconfigure $fd -blocking 0 -translation lf -encoding binary
+       fconfigure $fd -blocking 0 -translation lf -encoding utf-8
        fileevent $fd readable [cb _read_blame $fd $cur_w $cur_d]
        set current_fd $fd
        set blame_lines 0
@@@ -788,6 -798,16 +798,16 @@@ method _click {cur_w pos} 
        _showcommit $this $cur_w $lno
  }
  
+ method _setencoding {enc} {
+       force_path_encoding $path $enc
+       _load $this [list \
+               $highlight_column \
+               $highlight_line \
+               [lindex [$w_file xview] 0] \
+               [lindex [$w_file yview] 0] \
+               ]
+ }
  method _load_commit {cur_w cur_d pos} {
        upvar #0 $cur_d line_data
        set lno [lindex [split [$cur_w index $pos] .] 0]
@@@ -881,12 -901,6 +901,6 @@@ method _showcommit {cur_w lno} 
                                set enc [tcl_encoding $enc]
                                if {$enc ne {}} {
                                        set msg [encoding convertfrom $enc $msg]
-                                       set author_name [encoding convertfrom $enc $author_name]
-                                       set committer_name [encoding convertfrom $enc $committer_name]
-                                       set header($cmit,author) $author_name
-                                       set header($cmit,committer) $committer_name
-                                       set header($cmit,summary) \
-                                       [encoding convertfrom $enc $header($cmit,summary)]
                                }
                                set msg [string trim $msg]
                        }
@@@ -942,9 -956,20 +956,20 @@@ method _format_offset_date {base offset
  }
  
  method _gitkcommit {} {
+       global nullid
        set dat [_get_click_amov_info $this]
        if {$dat ne {}} {
                set cmit [lindex $dat 0]
+               # If the line belongs to the working copy, use HEAD instead
+               if {$cmit eq $nullid} {
+                       if {[catch {set cmit [git rev-parse --verify HEAD]} err]} {
+                               error_popup [strcat [mc "Cannot find HEAD commit:"] "\n\n$err"]
+                               return;
+                       }
+               }
                set radius [get_config gui.blamehistoryctx]
                set cmdline [list --select-commit=$cmit]
  
  }
  
  method _blameparent {} {
+       global nullid
        set dat [_get_click_amov_info $this]
        if {$dat ne {}} {
                set cmit [lindex $dat 0]
                set new_path [lindex $dat 1]
  
-               if {[catch {set cparent [git rev-parse --verify "$cmit^"]}]} {
+               # Allow using Blame Parent on lines modified in the working copy
+               if {$cmit eq $nullid} {
+                       set parent_ref "HEAD"
+               } else {
+                       set parent_ref "$cmit^"
+               }
+               if {[catch {set cparent [git rev-parse --verify $parent_ref]} err]} {
                        error_popup [strcat [mc "Cannot find parent commit:"] "\n\n$err"]
                        return;
                }
                # Generate a diff between the commit and its parent,
                # and use the hunks to update the line number.
                # Request zero context to simplify calculations.
-               if {[catch {set fd [eval git_read diff-tree \
-                               --unified=0 $cparent $cmit $new_path]} err]} {
+               if {$cmit eq $nullid} {
+                       set diffcmd [list diff-index --unified=0 $cparent -- $new_path]
+               } else {
+                       set diffcmd [list diff-tree --unified=0 $cparent $cmit -- $new_path]
+               }
+               if {[catch {set fd [eval git_read $diffcmd]} err]} {
                        $status stop [mc "Unable to display parent"]
                        error_popup [strcat [mc "Error loading diff:"] "\n\n$err"]
                        return
diff --combined git-gui/lib/commit.tcl
@@@ -168,7 -168,7 +168,7 @@@ File %s cannot be committed by this pro
                }
                }
        }
-       if {!$files_ready && ![string match *merge $curType]} {
+       if {!$files_ready && ![string match *merge $curType] && ![is_enabled nocommit]} {
                info_popup [mc "No changes to commit.
  
  You must stage at least 1 file before you can commit.
                return
        }
  
+       if {[is_enabled nocommitmsg]} { do_quit 0 }
        # -- A message is required.
        #
        set msg [string trim [$ui_comm get 1.0 end]]
@@@ -212,6 -214,8 +214,8 @@@ A good commit message has the followin
        puts $msg_wt $msg
        close $msg_wt
  
+       if {[is_enabled nocommit]} { do_quit 0 }
        # -- Run the pre-commit hook.
        #
        set fd_ph [githook_read pre-commit]
@@@ -410,7 -414,7 +414,7 @@@ A rescan will be automatically started 
                set ::GITGUI_BCK_exists 0
        }
  
-       if {[is_enabled singlecommit]} do_quit
+       if {[is_enabled singlecommit]} { do_quit 0 }
  
        # -- Update in memory status
        #
diff --combined git-gui/lib/diff.tcl
@@@ -40,6 -40,15 +40,15 @@@ proc reshow_diff {} 
        }
  }
  
+ proc force_diff_encoding {enc} {
+       global current_diff_path
+       
+       if {$current_diff_path ne {}} {
+               force_path_encoding $current_diff_path $enc
+               reshow_diff
+       }
+ }
  proc handle_empty_diff {} {
        global current_diff_path file_states file_lists
  
@@@ -60,9 -69,9 +69,9 @@@ A rescan will be automatically started 
        rescan ui_ready 0
  }
  
- proc show_diff {path w {lno {}} {scroll_pos {}}} {
+ proc show_diff {path w {lno {}} {scroll_pos {}} {callback {}}} {
        global file_states file_lists
-       global is_3way_diff diff_active repo_config
+       global is_3way_diff is_conflict_diff diff_active repo_config
        global ui_diff ui_index ui_workdir
        global current_diff_path current_diff_side current_diff_header
        global current_diff_queue
  
        set s $file_states($path)
        set m [lindex $s 0]
+       set is_conflict_diff 0
        set current_diff_path $path
        set current_diff_side $w
        set current_diff_queue {}
        ui_status [mc "Loading diff of %s..." [escape_path $path]]
  
+       set cont_info [list $scroll_pos $callback]
        if {[string first {U} $m] >= 0} {
-               merge_load_stages $path [list show_unmerged_diff $scroll_pos]
+               merge_load_stages $path [list show_unmerged_diff $cont_info]
        } elseif {$m eq {_O}} {
-               show_other_diff $path $w $m $scroll_pos
+               show_other_diff $path $w $m $cont_info
        } else {
-               start_show_diff $scroll_pos
+               start_show_diff $cont_info
        }
  }
  
- proc show_unmerged_diff {scroll_pos} {
+ proc show_unmerged_diff {cont_info} {
        global current_diff_path current_diff_side
-       global merge_stages ui_diff
+       global merge_stages ui_diff is_conflict_diff
        global current_diff_queue
  
        if {$merge_stages(2) eq {}} {
+               set is_conflict_diff 1
                lappend current_diff_queue \
                        [list "LOCAL: deleted\nREMOTE:\n" d======= \
                            [list ":1:$current_diff_path" ":3:$current_diff_path"]]
        } elseif {$merge_stages(3) eq {}} {
+               set is_conflict_diff 1
                lappend current_diff_queue \
                        [list "REMOTE: deleted\nLOCAL:\n" d======= \
                            [list ":1:$current_diff_path" ":2:$current_diff_path"]]
        } elseif {[lindex $merge_stages(1) 0] eq {120000}
                || [lindex $merge_stages(2) 0] eq {120000}
                || [lindex $merge_stages(3) 0] eq {120000}} {
+               set is_conflict_diff 1
                lappend current_diff_queue \
                        [list "LOCAL:\n" d======= \
                            [list ":1:$current_diff_path" ":2:$current_diff_path"]]
                        [list "REMOTE:\n" d======= \
                            [list ":1:$current_diff_path" ":3:$current_diff_path"]]
        } else {
-               start_show_diff $scroll_pos
+               start_show_diff $cont_info
                return
        }
  
-       advance_diff_queue $scroll_pos
+       advance_diff_queue $cont_info
  }
  
- proc advance_diff_queue {scroll_pos} {
+ proc advance_diff_queue {cont_info} {
        global current_diff_queue ui_diff
  
        set item [lindex $current_diff_queue 0]
        $ui_diff insert end [lindex $item 0] [lindex $item 1]
        $ui_diff conf -state disabled
  
-       start_show_diff $scroll_pos [lindex $item 2]
+       start_show_diff $cont_info [lindex $item 2]
  }
  
- proc show_other_diff {path w m scroll_pos} {
+ proc show_other_diff {path w m cont_info} {
        global file_states file_lists
        global is_3way_diff diff_active repo_config
        global ui_diff ui_index ui_workdir
                                }
                                file {
                                        set fd [open $path r]
-                                       fconfigure $fd -eofchar {}
+                                       fconfigure $fd \
+                                               -eofchar {} \
+                                               -encoding [get_path_encoding $path]
                                        set content [read $fd $max_sz]
                                        close $fd
                                        set sz [file size $path]
                $ui_diff conf -state disabled
                set diff_active 0
                unlock_index
+               set scroll_pos [lindex $cont_info 0]
                if {$scroll_pos ne {}} {
                        update
                        $ui_diff yview moveto $scroll_pos
                }
                ui_ready
+               set callback [lindex $cont_info 1]
+               if {$callback ne {}} {
+                       eval $callback
+               }
                return
        }
  }
  
- proc start_show_diff {scroll_pos {add_opts {}}} {
+ proc start_show_diff {cont_info {add_opts {}}} {
        global file_states file_lists
        global is_3way_diff diff_active repo_config
        global ui_diff ui_index ui_workdir
        set ::current_diff_inheader 1
        fconfigure $fd \
                -blocking 0 \
-               -encoding binary \
-               -translation binary
-       fileevent $fd readable [list read_diff $fd $scroll_pos]
+               -encoding [get_path_encoding $path] \
+               -translation lf
+       fileevent $fd readable [list read_diff $fd $cont_info]
  }
  
- proc read_diff {fd scroll_pos} {
+ proc read_diff {fd cont_info} {
        global ui_diff diff_active
-       global is_3way_diff current_diff_header
+       global is_3way_diff is_conflict_diff current_diff_header
        global current_diff_queue
  
        $ui_diff conf -state normal
                        {--} {set tags d_--}
                        {++} {
                                if {[regexp {^\+\+([<>]{7} |={7})} $line _g op]} {
+                                       set is_conflict_diff 1
                                        set line [string replace $line 0 1 {  }]
                                        set tags d$op
                                } else {
                        {-} {set tags d_-}
                        {+} {
                                if {[regexp {^\+([<>]{7} |={7})} $line _g op]} {
+                                       set is_conflict_diff 1
                                        set line [string replace $line 0 0 { }]
                                        set tags d$op
                                } else {
                close $fd
  
                if {$current_diff_queue ne {}} {
-                       advance_diff_queue $scroll_pos
+                       advance_diff_queue $cont_info
                        return
                }
  
                set diff_active 0
                unlock_index
+               set scroll_pos [lindex $cont_info 0]
                if {$scroll_pos ne {}} {
                        update
                        $ui_diff yview moveto $scroll_pos
                if {[$ui_diff index end] eq {2.0}} {
                        handle_empty_diff
                }
+               set callback [lindex $cont_info 1]
+               if {$callback ne {}} {
+                       eval $callback
+               }
        }
  }
  
@@@ -432,8 -461,9 +461,9 @@@ proc apply_hunk {x y} 
        }
  
        if {[catch {
+               set enc [get_path_encoding $current_diff_path]
                set p [eval git_write $apply_cmd]
-               fconfigure $p -translation binary -encoding binary
+               fconfigure $p -translation binary -encoding $enc
                puts -nonewline $p $current_diff_header
                puts -nonewline $p [$ui_diff get $s_lno $e_lno]
                close $p} err]} {
@@@ -601,8 -631,9 +631,9 @@@ proc apply_line {x y} 
        set patch "@@ -$hln,$n +$hln,[eval expr $n $sign 1] @@\n$patch"
  
        if {[catch {
+               set enc [get_path_encoding $current_diff_path]
                set p [eval git_write $apply_cmd]
-               fconfigure $p -translation binary -encoding binary
+               fconfigure $p -translation binary -encoding $enc
                puts -nonewline $p $current_diff_header
                puts -nonewline $p $patch
                close $p} err]} {
diff --combined git-gui/lib/encoding.tcl
@@@ -206,7 -206,7 +206,7 @@@ set encoding_aliases 
      { ISO-8859-16 iso-ir-226 ISO_8859-16:2001 ISO_8859-16 latin10 l10 }
      { GBK CP936 MS936 windows-936 }
      { JIS_Encoding csJISEncoding }
-     { Shift_JIS MS_Kanji csShiftJIS }
+     { Shift_JIS MS_Kanji csShiftJIS ShiftJIS Shift-JIS }
      { Extended_UNIX_Code_Packed_Format_for_Japanese csEUCPkdFmtJapanese
        EUC-JP }
      { Extended_UNIX_Code_Fixed_Width_for_Japanese csEUCFixWidJapanese }
      { Big5 csBig5 }
  }
  
+ set encoding_groups {
+     {"" ""
+       {"Unicode" UTF-8}
+       {"Western" ISO-8859-1}}
+     {we "West European"
+       {"Western" ISO-8859-15 CP-437 CP-850 MacRoman CP-1252 Windows-1252}
+       {"Celtic" ISO-8859-14}
+       {"Greek" ISO-8859-14 ISO-8859-7 CP-737 CP-869 MacGreek CP-1253 Windows-1253}
+       {"Icelandic" MacIceland MacIcelandic CP-861}
+       {"Nordic" ISO-8859-10 CP-865}
+       {"Portuguese" CP-860}
+       {"South European" ISO-8859-3}}
+     {ee "East European"
+       {"Baltic" CP-775 ISO-8859-4 ISO-8859-13 CP-1257 Windows-1257}
+       {"Central European" CP-852 ISO-8859-2 MacCE CP-1250 Windows-1250}
+       {"Croatian" MacCroatian}
+       {"Cyrillic" CP-855 ISO-8859-5 ISO-IR-111 KOI8-R MacCyrillic CP-1251 Windows-1251}
+       {"Russian" CP-866}
+       {"Ukrainian" KOI8-U MacUkraine MacUkrainian}
+       {"Romanian" ISO-8859-16 MacRomania MacRomanian}}
+     {ea "East Asian"
+       {"Generic" ISO-2022}
+       {"Chinese Simplified" GB2312 GB1988 GB12345 GB2312-RAW GBK EUC-CN GB18030 HZ ISO-2022-CN}
+       {"Chinese Traditional" Big5 Big5-HKSCS EUC-TW CP-950}
+       {"Japanese" EUC-JP ISO-2022-JP Shift-JIS JIS-0212 JIS-0208 JIS-0201 CP-932 MacJapan}
+       {"Korean" EUC-KR UHC JOHAB ISO-2022-KR CP-949 KSC5601}}
+     {sa "SE & SW Asian"
+       {"Armenian" ARMSCII-8}
+       {"Georgian" GEOSTD8}
+       {"Thai" TIS-620 ISO-8859-11 CP-874 Windows-874 MacThai}
+       {"Turkish" CP-857 CP857 ISO-8859-9 MacTurkish CP-1254 Windows-1254}
+       {"Vietnamese" TCVN VISCII VPS CP-1258 Windows-1258}
+       {"Hindi" MacDevanagari}
+       {"Gujarati" MacGujarati}
+       {"Gurmukhi" MacGurmukhi}}
+     {me "Middle Eastern"
+       {"Arabic" ISO-8859-6 Windows-1256 CP-1256 CP-864 MacArabic}
+       {"Farsi" MacFarsi}
+       {"Hebrew" ISO-8859-8-I Windows-1255 CP-1255 ISO-8859-8 CP-862 MacHebrew}}
+     {mi "Misc"
+       {"7-bit" ASCII}
+       {"16-bit" Unicode}
+       {"Legacy" CP-863 EBCDIC}
+       {"Symbol" Symbol Dingbats MacDingbats MacCentEuro}}
+ }
+ proc build_encoding_table {} {
+       global encoding_aliases encoding_lookup_table
+       # Prepare the lookup list; cannot use lsort -nocase because
+       # of compatibility issues with older Tcl (e.g. in msysgit)
+       set names [list]
+       foreach item [encoding names] {
+               lappend names [list [string tolower $item] $item]
+       }
+       set names [lsort -ascii -index 0 $names]
+       # neither can we use lsearch -index
+       set lnames [list]
+       foreach item $names {
+               lappend lnames [lindex $item 0]
+       }
+       foreach grp $encoding_aliases {
+               set target {}
+               foreach item $grp {
+                       set i [lsearch -sorted -ascii $lnames \
+                                       [string tolower $item]]
+                       if {$i >= 0} {
+                               set target [lindex $names $i 1]
+                               break
+                       }
+               }
+               if {$target eq {}} continue
+               foreach item $grp {
+                       set encoding_lookup_table([string tolower $item]) $target
+               }
+       }
+       foreach item $names {
+               set encoding_lookup_table([lindex $item 0]) [lindex $item 1]
+       }
+ }
  proc tcl_encoding {enc} {
-     global encoding_aliases
-     set names [encoding names]
-     set lcnames [string tolower $names]
-     set enc [string tolower $enc]
-     set i [lsearch -exact $lcnames $enc]
-     if {$i < 0} {
-       # look for "isonnn" instead of "iso-nnn" or "iso_nnn"
-       if {[regsub {^iso[-_]} $enc iso encx]} {
-           set i [lsearch -exact $lcnames $encx]
+       global encoding_lookup_table
+       if {$enc eq {}} {
+               return {}
+       }
+       if {![info exists encoding_lookup_table]} {
+               build_encoding_table
+       }
+       set enc [string tolower $enc]
+       if {![info exists encoding_lookup_table($enc)]} {
+               # look for "isonnn" instead of "iso-nnn" or "iso_nnn"
+               if {[regsub {^(iso|cp|ibm|jis)[-_]} $enc {\1} encx]} {
+                       set enc $encx
+               }
+       }
+       if {[info exists encoding_lookup_table($enc)]} {
+               return $encoding_lookup_table($enc)
+       } else {
+               return {}
+       }
+ }
+ proc force_path_encoding {path enc} {
+       global path_encoding_overrides last_encoding_override
+       set enc [tcl_encoding $enc]
+       if {$enc eq {}} {
+               catch { unset last_encoding_override }
+               catch { unset path_encoding_overrides($path) }
+       } else {
+               set last_encoding_override $enc
+               if {$path ne {}} {
+                       set path_encoding_overrides($path) $enc
+               }
+       }
+ }
+ proc get_path_encoding {path} {
+       global path_encoding_overrides last_encoding_override
+       if {[info exists last_encoding_override]} {
+               set tcl_enc $last_encoding_override
+       } else {
+               set tcl_enc [tcl_encoding [get_config gui.encoding]]
        }
-     }
-     if {$i < 0} {
-       foreach l $encoding_aliases {
-           set ll [string tolower $l]
-           if {[lsearch -exact $ll $enc] < 0} continue
-           # look through the aliases for one that tcl knows about
-           foreach e $ll {
-               set i [lsearch -exact $lcnames $e]
-               if {$i < 0} {
-                   if {[regsub {^iso[-_]} $e iso ex]} {
-                       set i [lsearch -exact $lcnames $ex]
-                   }
+       if {$tcl_enc eq {}} {
+               set tcl_enc [encoding system]
+       }
+       if {$path ne {}} {
+               if {[info exists path_encoding_overrides($path)]} {
+                       set enc2 $path_encoding_overrides($path)
+               } else {
+                       set enc2 [tcl_encoding [gitattr $path encoding $tcl_enc]]
+               }
+               if {$enc2 ne {}} {
+                       set tcl_enc $enc2
+               }
+       }
+       return $tcl_enc
+ }
+ proc build_encoding_submenu {parent grp cmd} {
+       global used_encodings
+       set mid [lindex $grp 0]
+       set gname [mc [lindex $grp 1]]
+       set smenu {}
+       foreach subset [lrange $grp 2 end] {
+               set name [mc [lindex $subset 0]]
+               foreach enc [lrange $subset 1 end] {
+                       set tcl_enc [tcl_encoding $enc]
+                       if {$tcl_enc eq {}} continue
+                       if {$smenu eq {}} {
+                               if {$mid eq {}} {
+                                       set smenu $parent
+                               } else {
+                                       set smenu "$parent.$mid"
+                                       menu $smenu
+                                       $parent add cascade \
+                                               -label $gname \
+                                               -menu $smenu
+                               }
+                       }
+                       if {$name ne {}} {
+                               set lbl "$name ($enc)"
+                       } else {
+                               set lbl $enc
+                       }
+                       $smenu add command \
+                               -label $lbl \
+                               -command [concat $cmd [list $tcl_enc]]
+                       lappend used_encodings $tcl_enc
+               }
+       }
+ }
+ proc popup_btn_menu {m b} {
+       tk_popup $m [winfo pointerx $b] [winfo pointery $b]
+ }
+ proc build_encoding_menu {emenu cmd {nodef 0}} {
+       $emenu configure -postcommand \
+               [list do_build_encoding_menu $emenu $cmd $nodef]
+ }
+ proc do_build_encoding_menu {emenu cmd {nodef 0}} {
+       global used_encodings encoding_groups
+       $emenu configure -postcommand {}
+       if {!$nodef} {
+               $emenu add command \
+                       -label [mc "Default"] \
+                       -command [concat $cmd [list {}]]
+       }
+       set sysenc [encoding system]
+       $emenu add command \
+               -label [mc "System (%s)" $sysenc] \
+               -command [concat $cmd [list $sysenc]]
+       # Main encoding tree
+       set used_encodings [list identity]
+       $emenu add separator
+       foreach grp $encoding_groups {
+               build_encoding_submenu $emenu $grp $cmd
+       }
+       # Add unclassified encodings
+       set unused_grp [list [mc Other]]
+       foreach enc [encoding names] {
+               if {[lsearch -exact $used_encodings $enc] < 0} {
+                       lappend unused_grp $enc
                }
-               if {$i >= 0} break
-           }
-           break
        }
-     }
-     if {$i >= 0} {
-       return [lindex $names $i]
-     }
-     return {}
+       build_encoding_submenu $emenu [list other [mc Other] $unused_grp] $cmd
  }
@@@ -5,24 -5,51 +5,51 @@@ proc merge_resolve_one {stage} 
        global current_diff_path
  
        switch -- $stage {
-               1 { set target [mc "the base version"] }
-               2 { set target [mc "this branch"] }
-               3 { set target [mc "the other branch"] }
+               1 { set targetquestion [mc "Force resolution to the base version?"] }
+               2 { set targetquestion [mc "Force resolution to this branch?"] }
+               3 { set targetquestion [mc "Force resolution to the other branch?"] }
        }
  
-       set op_question [mc "Force resolution to %s?
- Note that the diff shows only conflicting changes.
+       set op_question [strcat $targetquestion "\n" \
[mc "Note that the diff shows only conflicting changes.
  
  %s will be overwritten.
  
  This operation can be undone only by restarting the merge." \
-               $target [short_path $current_diff_path]]
+               [short_path $current_diff_path]]]
  
        if {[ask_popup $op_question] eq {yes}} {
                merge_load_stages $current_diff_path [list merge_force_stage $stage]
        }
  }
  
+ proc merge_stage_workdir {path w lno} {
+       global current_diff_path diff_active
+       if {$diff_active} return
+       if {$path ne $current_diff_path} {
+               show_diff $path $w $lno {} [list do_merge_stage_workdir $path]
+       } else {
+               do_merge_stage_workdir $path
+       }
+ }
+ proc do_merge_stage_workdir {path} {
+       global current_diff_path is_conflict_diff
+       if {$path ne $current_diff_path} return;
+       if {$is_conflict_diff} {
+               if {[ask_popup [mc "File %s seems to have unresolved conflicts, still stage?" \
+                               [short_path $path]]] ne {yes}} {
+                       return
+               }
+       }
+       merge_add_resolution $path
+ }
  proc merge_add_resolution {path} {
        global current_diff_path ui_workdir
  
diff --combined git-gui/lib/option.tcl
@@@ -1,6 -1,28 +1,28 @@@
  # git-gui options editor
  # Copyright (C) 2006, 2007 Shawn Pearce
  
+ proc config_check_encodings {} {
+       global repo_config_new global_config_new
+       set enc $global_config_new(gui.encoding)
+       if {$enc eq {}} {
+               set global_config_new(gui.encoding) [encoding system]
+       } elseif {[tcl_encoding $enc] eq {}} {
+               error_popup [mc "Invalid global encoding '%s'" $enc]
+               return 0
+       }
+       set enc $repo_config_new(gui.encoding)
+       if {$enc eq {}} {
+               set repo_config_new(gui.encoding) [encoding system]
+       } elseif {[tcl_encoding $enc] eq {}} {
+               error_popup [mc "Invalid repo encoding '%s'" $enc]
+               return 0
+       }
+       return 1
+ }
  proc save_config {} {
        global default_config font_descs
        global repo_config global_config
@@@ -130,6 -152,7 +152,7 @@@ proc do_options {} 
                {i-1..99 gui.diffcontext {mc "Number of Diff Context Lines"}}
                {i-0..99 gui.commitmsgwidth {mc "Commit Message Text Width"}}
                {t gui.newbranchtemplate {mc "New Branch Name Template"}}
+               {c gui.encoding {mc "Default File Contents Encoding"}}
                } {
                set type [lindex $option 0]
                set name [lindex $option 1]
                                pack $w.$f.$optid.v -side right -anchor e -padx 5
                                pack $w.$f.$optid -side top -anchor w -fill x
                        }
+                       c -
                        t {
                                frame $w.$f.$optid
                                label $w.$f.$optid.l -text "$text:"
                                pack $w.$f.$optid.v -side left -anchor w \
                                        -fill x -expand 1 \
                                        -padx 5
+                               if {$type eq {c}} {
+                                       menu $w.$f.$optid.m
+                                       build_encoding_menu $w.$f.$optid.m \
+                                               [list set ${f}_config_new($name)] 1
+                                       button $w.$f.$optid.b \
+                                               -text [mc "Change"] \
+                                               -command [list popup_btn_menu \
+                                                       $w.$f.$optid.m $w.$f.$optid.b]
+                                       pack $w.$f.$optid.b -side left -anchor w
+                               }
                                pack $w.$f.$optid -side top -anchor w -fill x
                        }
                        }
@@@ -275,6 -309,7 +309,7 @@@ proc do_restore_defaults {} 
  }
  
  proc do_save_config {w} {
+       if {![config_check_encodings]} return
        if {[catch {save_config} err]} {
                error_popup [strcat [mc "Failed to completely save options:"] "\n\n$err"]
        }
diff --combined git-gui/po/de.po
@@@ -7,8 -7,8 +7,8 @@@ msgid "
  msgstr ""
  "Project-Id-Version: git-gui\n"
  "Report-Msgid-Bugs-To: \n"
- "POT-Creation-Date: 2008-08-02 08:58+0200\n"
- "PO-Revision-Date: 2008-08-02 09:09+0200\n"
+ "POT-Creation-Date: 2008-09-13 10:20+0200\n"
+ "PO-Revision-Date: 2008-09-13 10:24+0200\n"
  "Last-Translator: Christian Stimming <stimming@tuhh.de>\n"
  "Language-Team: German\n"
  "MIME-Version: 1.0\n"
@@@ -110,7 -110,15 +110,15 @@@ msgstr "Teilweise bereitgestellt zum Ei
  msgid "Staged for commit, missing"
  msgstr "Bereitgestellt zum Eintragen, fehlend"
  
- #: git-gui.sh:1597
+ #: git-gui.sh:1658
+ msgid "File type changed, not staged"
+ msgstr "Dateityp geändert, nicht bereitgestellt"
+ #: git-gui.sh:1659
+ msgid "File type changed, staged"
+ msgstr "Dateityp geändert, bereitgestellt"
+ #: git-gui.sh:1661
  msgid "Untracked, not staged"
  msgstr "Nicht unter Versionskontrolle, nicht bereitgestellt"
  
@@@ -396,15 -404,7 +404,7 @@@ msgstr "Alle kopieren
  msgid "File:"
  msgstr "Datei:"
  
- #: git-gui.sh:2589
- msgid "Apply/Reverse Hunk"
- msgstr "Kontext anwenden/umkehren"
- #: git-gui.sh:2696
- msgid "Apply/Reverse Line"
- msgstr "Zeile anwenden/umkehren"
- #: git-gui.sh:2711
+ #: git-gui.sh:2834
  msgid "Refresh"
  msgstr "Aktualisieren"
  
@@@ -416,7 -416,35 +416,35 @@@ msgstr "Schriftgröße verkleinern
  msgid "Increase Font Size"
  msgstr "Schriftgröße vergrößern"
  
- #: git-gui.sh:2646
+ #: git-gui.sh:2870
+ msgid "Apply/Reverse Hunk"
+ msgstr "Kontext anwenden/umkehren"
+ #: git-gui.sh:2875
+ msgid "Apply/Reverse Line"
+ msgstr "Zeile anwenden/umkehren"
+ #: git-gui.sh:2885
+ msgid "Run Merge Tool"
+ msgstr "Zusammenführungswerkzeug"
+ #: git-gui.sh:2890
+ msgid "Use Remote Version"
+ msgstr "Entfernte Version benutzen"
+ #: git-gui.sh:2894
+ msgid "Use Local Version"
+ msgstr "Lokale Version benutzen"
+ #: git-gui.sh:2898
+ msgid "Revert To Base"
+ msgstr "Ursprüngliche Version benutzen"
+ #: git-gui.sh:2906
+ msgid "Stage Working Copy"
+ msgstr "Arbeitskopie bereitstellen"
+ #: git-gui.sh:2925
  msgid "Unstage Hunk From Commit"
  msgstr "Kontext aus Bereitstellung herausnehmen"
  
@@@ -498,7 -526,15 +526,15 @@@ msgstr "Version kopieren
  msgid "Do Full Copy Detection"
  msgstr "Volle Kopie-Erkennung"
  
- #: lib/blame.tcl:388
+ #: lib/blame.tcl:263
+ msgid "Show History Context"
+ msgstr "Historien-Kontext anzeigen"
+ #: lib/blame.tcl:266
+ msgid "Blame Parent Commit"
+ msgstr "Elternversion annotieren"
+ #: lib/blame.tcl:394
  #, tcl-format
  msgid "Reading %s..."
  msgstr "%s lesen..."
@@@ -547,7 -583,19 +583,19 @@@ msgstr "Eintragender:
  msgid "Original File:"
  msgstr "Ursprüngliche Datei:"
  
- #: lib/blame.tcl:925
+ #: lib/blame.tcl:990
+ msgid "Cannot find parent commit:"
+ msgstr "Elternversion kann nicht gefunden werden:"
+ #: lib/blame.tcl:1001
+ msgid "Unable to display parent"
+ msgstr "Elternversion kann nicht angezeigt werden"
+ #: lib/blame.tcl:1002 lib/diff.tcl:191
+ msgid "Error loading diff:"
+ msgstr "Fehler beim Laden des Vergleichs:"
+ #: lib/blame.tcl:1142
  msgid "Originally By:"
  msgstr "Ursprünglich von:"
  
@@@ -1494,11 -1542,7 +1542,7 @@@ msgstr "Git-Projektarchiv (Unterprojekt
  msgid "* Binary file (not showing content)."
  msgstr "* Binärdatei (Inhalt wird nicht angezeigt)"
  
- #: lib/diff.tcl:185
- msgid "Error loading diff:"
- msgstr "Fehler beim Laden des Vergleichs:"
- #: lib/diff.tcl:303
+ #: lib/diff.tcl:313
  msgid "Failed to unstage selected hunk."
  msgstr ""
  "Fehler beim Herausnehmen des gewählten Kontexts aus der Bereitstellung."
@@@ -1586,6 -1630,15 +1630,15 @@@ msgstr "
  msgid "Do Nothing"
  msgstr "Nichts tun"
  
+ #: lib/index.tcl:419
+ msgid "Reverting selected files"
+ msgstr "Änderungen in gewählten Dateien verwerfen"
+ #: lib/index.tcl:423
+ #, tcl-format
+ msgid "Reverting %s"
+ msgstr "Änderungen in %s verwerfen"
  #: lib/merge.tcl:13
  msgid ""
  "Cannot merge while amending.\n"
@@@ -1730,6 -1783,96 +1783,96 @@@ msgstr "Abbruch fehlgeschlagen.
  msgid "Abort completed.  Ready."
  msgstr "Abbruch durchgeführt. Bereit."
  
+ #: lib/mergetool.tcl:14
+ msgid "Force resolution to the base version?"
+ msgstr "Konflikt durch Basisversion ersetzen?"
+ #: lib/mergetool.tcl:15
+ msgid "Force resolution to this branch?"
+ msgstr "Konflikt durch diesen Zweig ersetzen?"
+ #: lib/mergetool.tcl:16
+ msgid "Force resolution to the other branch?"
+ msgstr "Konflikt durch anderen Zweig ersetzen?"
+ #: lib/mergetool.tcl:20
+ #, tcl-format
+ msgid ""
+ "Note that the diff shows only conflicting changes.\n"
+ "\n"
+ "%s will be overwritten.\n"
+ "\n"
+ "This operation can be undone only by restarting the merge."
+ msgstr ""
+ "Hinweis: Der Vergleich zeigt nur konfliktverursachende Änderungen an.\n"
+ "\n"
+ "»%s« wird überschrieben.\n"
+ "\n"
+ "Diese Operation kann nur rückgängig gemacht werden, wenn die\n"
+ "Zusammenführung erneut gestartet wird."
+ #: lib/mergetool.tcl:32
+ #, tcl-format
+ msgid "Adding resolution for %s"
+ msgstr "Auflösung hinzugefügt für %s"
+ #: lib/mergetool.tcl:119
+ msgid "Cannot resolve deletion or link conflicts using a tool"
+ msgstr ""
+ "Konflikte durch gelöschte Dateien oder symbolische Links können nicht durch "
+ "das Zusamenführungswerkzeug gelöst werden."
+ #: lib/mergetool.tcl:124
+ msgid "Conflict file does not exist"
+ msgstr "Konflikt-Datei existiert nicht"
+ #: lib/mergetool.tcl:236
+ #, tcl-format
+ msgid "Not a GUI merge tool: '%s'"
+ msgstr "Kein GUI Zusammenführungswerkzeug: »%s«"
+ #: lib/mergetool.tcl:240
+ #, tcl-format
+ msgid "Unsupported merge tool '%s'"
+ msgstr "Unbekanntes Zusammenführungswerkzeug: »%s«"
+ #: lib/mergetool.tcl:275
+ msgid "Merge tool is already running, terminate it?"
+ msgstr "Zusammenführungswerkzeug läuft bereits. Soll es abgebrochen werden?"
+ #: lib/mergetool.tcl:295
+ #, tcl-format
+ msgid ""
+ "Error retrieving versions:\n"
+ "%s"
+ msgstr ""
+ "Fehler beim Abrufen der Dateiversionen:\n"
+ "%s"
+ #: lib/mergetool.tcl:315
+ #, tcl-format
+ msgid ""
+ "Could not start the merge tool:\n"
+ "\n"
+ "%s"
+ msgstr ""
+ "Zusammenführungswerkzeug konnte nicht gestartet werden:\n"
+ "\n"
+ "%s"
+ #: lib/mergetool.tcl:319
+ msgid "Running merge tool..."
+ msgstr "Zusammenführungswerkzeug starten..."
+ #: lib/mergetool.tcl:347 lib/mergetool.tcl:363
+ msgid "Merge tool failed."
+ msgstr "Zusammenführungswerkzeug fehlgeschlagen."
+ #: lib/mergetool.tcl:353
+ #, tcl-format
+ msgid "File %s unchanged, still accept as resolved?"
+ msgstr "Datei »%s« unverändert. Trotzdem Konflikt als gelöst akzeptieren?"
  #: lib/option.tcl:95
  msgid "Restore Defaults"
  msgstr "Voreinstellungen wiederherstellen"
@@@ -1767,7 -1910,11 +1910,11 @@@ msgstr "Ausführlichkeit der ZusammenfÃ
  msgid "Show Diffstat After Merge"
  msgstr "Vergleichsstatistik nach Zusammenführen anzeigen"
  
- #: lib/option.tcl:123
+ #: lib/option.tcl:122
+ msgid "Use Merge Tool"
+ msgstr "Zusammenführungswerkzeug"
+ #: lib/option.tcl:124
  msgid "Trust File Modification Timestamps"
  msgstr "Auf Dateiänderungsdatum verlassen"
  
@@@ -1788,6 -1935,10 +1935,10 @@@ msgid "Minimum Letters To Blame Copy On
  msgstr "Mindestzahl Zeichen für Kopie-Annotieren"
  
  #: lib/option.tcl:128
+ msgid "Blame History Context Radius (days)"
+ msgstr "Anzahl Tage für Historien-Kontext"
+ #: lib/option.tcl:129
  msgid "Number of Diff Context Lines"
  msgstr "Anzahl der Kontextzeilen beim Vergleich"