Merge git://git.bogomips.org/git-svn
authorJunio C Hamano <gitster@pobox.com>
Sun, 7 Sep 2008 02:39:13 +0000 (19:39 -0700)
committerJunio C Hamano <gitster@pobox.com>
Sun, 7 Sep 2008 02:39:13 +0000 (19:39 -0700)
* git://git.bogomips.org/git-svn:
git-svn: set auto_props when renaming files
t9124: clean up chdir usage
git-svn: fix 'info' tests for unknown items
git-svn: match SVN 1.5 behaviour of info' on unknown item
git svn info: always quote URLs in 'info' output
git svn info: make info relative to the current directory
git svn info: tests: fix ptouch argument order in setup
git svn info: tests: use test_cmp instead of git-diff
git svn info: tests: do not use set -e
git svn info: tests: let 'init' test run with SVN 1.5
git svn: catch lack of upstream info for dcommit earlier
git-svn: check error code of send_txstream
git-svn: Send deltas during commits
git-svn: Introduce SVN::Git::Editor::_chg_file_get_blob
git-svn: extract base blob in generate_diff

16 files changed:
Documentation/RelNotes-1.6.0.2.txt
Documentation/git-annotate.txt
builtin-blame.c
git-gui/git-gui.sh
git-gui/lib/blame.tcl
git-gui/lib/browser.tcl
git-gui/lib/commit.tcl
git-gui/lib/diff.tcl
git-gui/lib/index.tcl
git-gui/lib/mergetool.tcl [new file with mode: 0644]
git-gui/lib/option.tcl
git-gui/po/fr.po
git-gui/po/po2msg.sh
git-stash.sh
gitk-git/gitk
t/t9400-git-cvsserver-server.sh
index 686e60713bc6c508b214414ed88068d338c36bb0..6c5446bc074afd912f80f4e9dd8205ddc3527fff 100644 (file)
@@ -18,19 +18,32 @@ Fixes since v1.6.0.1
   with GIT_WORK_TREE environment settings.
 
 
-
 * "git apply --unidiff-zero" incorrectly applied a -U0 patch that inserts
   a new line before the second line.
 
+* "git blame -c" did not exactly work like "git annotate" when range
+  boundaries are involved.
+
 * "git clone $there $here/" with extra trailing slashes after explicit
   local directory name $here did not work as expected.
 
 * "git diff --dirstat -M" did not add changes in subdirectories up
   correctly for renamed paths.
 
+* "git diff --cumulative" did not imply "--dirstat".
+
 * "git for-each-ref refs/heads/" did not work as expected.
 
-* "git log --grep=pattern -i" did not ignore case.
+* "git gui" allowed users to feed patch without any context to be applied.
+
+* "git gui" botched parsing "diff" output when a line that begins with two
+  dashes and a space gets removed or a line that begins with two pluses
+  and a space gets added.
+
+* "git gui" translation updates and i18n fixes.
+
+* "git log -i --grep=pattern" did not ignore case; neither "git log -E
+  --grep=pattern" triggered extended regexp.
 
 * "git log --pretty="%ad" --date=short" did not use short format when
   showing the timestamp.
@@ -38,6 +51,9 @@ Fixes since v1.6.0.1
 * Build procedure for "git shell" that used stub versions of some
   functions and globals was not understood by linkers on some platforms.
 
+* "git stash" was fooled by a stat-dirty but otherwise unmodified paths
+  and refused to work until the user refreshed the index.
+
 * "git verify-pack -v" did not work correctly when given more than one
   packfile.
 
@@ -45,6 +61,7 @@ Also contains many documentation updates.
 
 --
 exec >/var/tmp/1
-O=v1.6.0.1-49-g6a42cfe
+O=v1.6.0.1-61-g1eff26c
 echo O=$(git describe maint)
 git shortlog --no-merges $O..maint
+
index 8b6b56a54409dd586047a1a6cdf1138e8bb0e77b..0aba022ba6838442721a0584f3eaa293a3a90f74 100644 (file)
@@ -14,6 +14,11 @@ DESCRIPTION
 Annotates each line in the given file with information from the commit
 which introduced the line. Optionally annotate from a given revision.
 
+The only difference between this command and linkgit:git-blame[1] is that
+they use slightly different output formats, and this command exists only
+for backward compatibility to support existing scripts, and provide more
+familiar command name for people coming from other SCM systems.
+
 OPTIONS
 -------
 include::blame-options.txt[]
index adc3dc7270afd0dff8763d8c480c8ab98ee25b0d..6b7b9f4466989ca02d3a5e53caac9ff5c7e8a922 100644 (file)
@@ -38,7 +38,6 @@ static int show_root;
 static int reverse;
 static int blank_boundary;
 static int incremental;
-static int cmd_is_annotate;
 static int xdl_opts = XDF_NEED_MINIMAL;
 static struct string_list mailmap;
 
@@ -1682,7 +1681,7 @@ static void emit_other(struct scoreboard *sb, struct blame_entry *ent, int opt)
                if (suspect->commit->object.flags & UNINTERESTING) {
                        if (blank_boundary)
                                memset(hex, ' ', length);
-                       else if (!cmd_is_annotate) {
+                       else if (!(opt & OUTPUT_ANNOTATE_COMPAT)) {
                                length--;
                                putchar('^');
                        }
@@ -2313,8 +2312,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
        };
 
        struct parse_opt_ctx_t ctx;
-
-       cmd_is_annotate = !strcmp(argv[0], "annotate");
+       int cmd_is_annotate = !strcmp(argv[0], "annotate");
 
        git_config(git_blame_config, NULL);
        init_revisions(&revs, NULL);
@@ -2342,6 +2340,9 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
 parse_done:
        argc = parse_options_end(&ctx);
 
+       if (cmd_is_annotate)
+               output_option |= OUTPUT_ANNOTATE_COMPAT;
+
        if (DIFF_OPT_TST(&revs.diffopt, FIND_COPIES_HARDER))
                opt |= (PICKAXE_BLAME_COPY | PICKAXE_BLAME_MOVE |
                        PICKAXE_BLAME_COPY_HARDER);
index ad65aaad5a696ec355d9b965b13704f57145678f..10d8a4422f151eda78a24ff533eb20c3d775d099 100755 (executable)
@@ -657,6 +657,8 @@ proc apply_config {} {
 }
 
 set default_config(branch.autosetupmerge) true
+set default_config(merge.tool) {}
+set default_config(merge.keepbackup) true
 set default_config(merge.diffstat) true
 set default_config(merge.summary) false
 set default_config(merge.verbosity) 2
@@ -668,6 +670,7 @@ set default_config(gui.pruneduringfetch) false
 set default_config(gui.trustmtime) false
 set default_config(gui.fastcopyblame) false
 set default_config(gui.copyblamethreshold) 40
+set default_config(gui.blamehistoryctx) 7
 set default_config(gui.diffcontext) 5
 set default_config(gui.commitmsgwidth) 75
 set default_config(gui.newbranchtemplate) {}
@@ -1323,6 +1326,8 @@ proc rescan_done {fd buf after} {
        unlock_index
        display_all_files
        if {$current_diff_path ne {}} reshow_diff
+       if {$current_diff_path eq {}} select_first_diff
+
        uplevel #0 $after
 }
 
@@ -1619,6 +1624,15 @@ static unsigned char file_merge_bits[] = {
    0xfa, 0x17, 0x02, 0x10, 0xfe, 0x1f};
 } -maskdata $filemask
 
+image create bitmap file_statechange -background white -foreground green -data {
+#define file_merge_width 14
+#define file_merge_height 15
+static unsigned char file_statechange_bits[] = {
+   0xfe, 0x01, 0x02, 0x03, 0x02, 0x05, 0x02, 0x09, 0x02, 0x1f, 0x62, 0x10,
+   0x62, 0x10, 0xba, 0x11, 0xba, 0x11, 0x62, 0x10, 0x62, 0x10, 0x02, 0x10,
+   0x02, 0x10, 0x02, 0x10, 0xfe, 0x1f};
+} -maskdata $filemask
+
 set ui_index .vpane.files.index.list
 set ui_workdir .vpane.files.workdir.list
 
@@ -1627,12 +1641,14 @@ set all_icons(A$ui_index)   file_fulltick
 set all_icons(M$ui_index)   file_fulltick
 set all_icons(D$ui_index)   file_removed
 set all_icons(U$ui_index)   file_merge
+set all_icons(T$ui_index)   file_statechange
 
 set all_icons(_$ui_workdir) file_plain
 set all_icons(M$ui_workdir) file_mod
 set all_icons(D$ui_workdir) file_question
 set all_icons(U$ui_workdir) file_merge
 set all_icons(O$ui_workdir) file_plain
+set all_icons(T$ui_workdir) file_statechange
 
 set max_status_desc 0
 foreach i {
@@ -1643,6 +1659,9 @@ foreach i {
                {MM {mc "Portions staged for commit"}}
                {MD {mc "Staged for commit, missing"}}
 
+               {_T {mc "File type changed, not staged"}}
+               {T_ {mc "File type changed, staged"}}
+
                {_O {mc "Untracked, not staged"}}
                {A_ {mc "Staged for commit"}}
                {AM {mc "Portions staged for commit"}}
@@ -1652,10 +1671,12 @@ foreach i {
                {D_ {mc "Staged for removal"}}
                {DO {mc "Staged for removal, still present"}}
 
+               {_U {mc "Requires merge resolution"}}
                {U_ {mc "Requires merge resolution"}}
                {UU {mc "Requires merge resolution"}}
                {UM {mc "Requires merge resolution"}}
                {UD {mc "Requires merge resolution"}}
+               {UT {mc "Requires merge resolution"}}
        } {
        set text [eval [lindex $i 1]]
        if {$max_status_desc < [string length $text]} {
@@ -1796,13 +1817,120 @@ proc do_rescan {} {
        rescan ui_ready
 }
 
+proc ui_do_rescan {} {
+       rescan {force_first_diff; ui_ready}
+}
+
 proc do_commit {} {
        commit_tree
 }
 
 proc next_diff {} {
        global next_diff_p next_diff_w next_diff_i
-       show_diff $next_diff_p $next_diff_w $next_diff_i
+       show_diff $next_diff_p $next_diff_w {}
+}
+
+proc find_anchor_pos {lst name} {
+       set lid [lsearch -sorted -exact $lst $name]
+
+       if {$lid == -1} {
+               set lid 0
+               foreach lname $lst {
+                       if {$lname >= $name} break
+                       incr lid
+               }
+       }
+
+       return $lid
+}
+
+proc find_file_from {flist idx delta path mmask} {
+       global file_states
+
+       set len [llength $flist]
+       while {$idx >= 0 && $idx < $len} {
+               set name [lindex $flist $idx]
+
+               if {$name ne $path && [info exists file_states($name)]} {
+                       set state [lindex $file_states($name) 0]
+
+                       if {$mmask eq {} || [regexp $mmask $state]} {
+                               return $idx
+                       }
+               }
+
+               incr idx $delta
+       }
+
+       return {}
+}
+
+proc find_next_diff {w path {lno {}} {mmask {}}} {
+       global next_diff_p next_diff_w next_diff_i
+       global file_lists ui_index ui_workdir
+
+       set flist $file_lists($w)
+       if {$lno eq {}} {
+               set lno [find_anchor_pos $flist $path]
+       } else {
+               incr lno -1
+       }
+
+       if {$mmask ne {} && ![regexp {(^\^)|(\$$)} $mmask]} {
+               if {$w eq $ui_index} {
+                       set mmask "^$mmask"
+               } else {
+                       set mmask "$mmask\$"
+               }
+       }
+
+       set idx [find_file_from $flist $lno 1 $path $mmask]
+       if {$idx eq {}} {
+               incr lno -1
+               set idx [find_file_from $flist $lno -1 $path $mmask]
+       }
+
+       if {$idx ne {}} {
+               set next_diff_w $w
+               set next_diff_p [lindex $flist $idx]
+               set next_diff_i [expr {$idx+1}]
+               return 1
+       } else {
+               return 0
+       }
+}
+
+proc next_diff_after_action {w path {lno {}} {mmask {}}} {
+       global current_diff_path
+
+       if {$path ne $current_diff_path} {
+               return {}
+       } elseif {[find_next_diff $w $path $lno $mmask]} {
+               return {next_diff;}
+       } else {
+               return {reshow_diff;}
+       }
+}
+
+proc select_first_diff {} {
+       global ui_workdir
+
+       if {[find_next_diff $ui_workdir {} 1 {^_?U}] ||
+           [find_next_diff $ui_workdir {} 1 {[^O]$}]} {
+               next_diff
+       }
+}
+
+proc force_first_diff {} {
+       global current_diff_path
+
+       if {[info exists file_states($current_diff_path)]} {
+               set state [lindex $file_states($current_diff_path) 0]
+
+               if {[string index $state 1] ne {O}} return
+       }
+
+       select_first_diff
 }
 
 proc toggle_or_diff {w x y} {
@@ -1823,34 +1951,27 @@ 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
 
-       if {$col == 0 && $y > 1} {
-               set i [expr {$lno-1}]
-               set ll [expr {[llength $file_lists($w)]-1}]
-
-               if {$i == $ll && $i == 0} {
-                       set after {reshow_diff;}
-               } else {
-                       global next_diff_p next_diff_w next_diff_i
-
-                       set next_diff_w $w
-
-                       if {$i < $ll} {
-                               set i [expr {$i + 1}]
-                               set next_diff_i $i
-                       } else {
-                               set next_diff_i $i
-                               set i [expr {$i - 1}]
-                       }
+       # Do not stage files with conflicts
+       if {[info exists file_states($path)]} {
+               set state [lindex $file_states($path) 0]
+       } else {
+               set state {__}
+       }
 
-                       set next_diff_p [lindex $file_lists($w) $i]
+       if {[string first {U} $state] >= 0} {
+               set col 1
+       }
 
-                       if {$next_diff_p ne {} && $current_diff_path ne {}} {
-                               set after {next_diff;}
-                       } else {
-                               set after {}
-                       }
+       # Restage the file, or simply show the diff
+       if {$col == 0 && $y > 1} {
+               if {[string index $state 1] eq {O}} {
+                       set mmask {}
+               } else {
+                       set mmask {[^O]}
                }
 
+               set after [next_diff_after_action $w $path $lno $mmask]
+
                if {$w eq $ui_index} {
                        update_indexinfo \
                                "Unstaging [short_path $path] from commit" \
@@ -1932,7 +2053,7 @@ proc show_more_context {} {
 
 proc show_less_context {} {
        global repo_config
-       if {$repo_config(gui.diffcontext) >= 1} {
+       if {$repo_config(gui.diffcontext) > 1} {
                incr repo_config(gui.diffcontext) -1
                reshow_diff
        }
@@ -2113,7 +2234,7 @@ if {[is_enabled multicommit] || [is_enabled singlecommit]} {
        .mbar.commit add separator
 
        .mbar.commit add command -label [mc Rescan] \
-               -command do_rescan \
+               -command ui_do_rescan \
                -accelerator F5
        lappend disable_on_lock \
                [list .mbar.commit entryconf [.mbar.commit index last] -state]
@@ -2281,10 +2402,15 @@ proc usage {} {
 switch -- $subcommand {
 browser -
 blame {
-       set subcommand_args {rev? path}
+       if {$subcommand eq "blame"} {
+               set subcommand_args {[--line=<num>] rev? path}
+       } else {
+               set subcommand_args {rev? path}
+       }
        if {$argv eq {}} usage
        set head {}
        set path {}
+       set jump_spec {}
        set is_path 0
        foreach a $argv {
                if {$is_path || [file exists $_prefix$a]} {
@@ -2298,6 +2424,9 @@ blame {
                                set path {}
                        }
                        set is_path 1
+               } elseif {[regexp {^--line=(\d+)$} $a a lnum]} {
+                       if {$jump_spec ne {} || $head ne {}} usage
+                       set jump_spec [list $lnum]
                } elseif {$head eq {}} {
                        if {$head ne {}} usage
                        set head $a
@@ -2329,6 +2458,7 @@ blame {
 
        switch -- $subcommand {
        browser {
+               if {$jump_spec ne {}} usage
                if {$head eq {}} {
                        if {$path ne {} && [file isdirectory $path]} {
                                set head $current_branch
@@ -2344,7 +2474,7 @@ blame {
                        puts stderr [mc "fatal: cannot stat path %s: No such file or directory" $path]
                        exit 1
                }
-               blame::new $head $path
+               blame::new $head $path $jump_spec
        }
        }
        return
@@ -2460,7 +2590,7 @@ pack .vpane.lower.commarea.buttons.l -side top -fill x
 pack .vpane.lower.commarea.buttons -side left -fill y
 
 button .vpane.lower.commarea.buttons.rescan -text [mc Rescan] \
-       -command do_rescan
+       -command ui_do_rescan
 pack .vpane.lower.commarea.buttons.rescan -side top -fill x
 lappend disable_on_lock \
        {.vpane.lower.commarea.buttons.rescan conf -state}
@@ -2689,6 +2819,51 @@ $ui_diff tag raise sel
 
 # -- Diff Body Context Menu
 #
+
+proc create_common_diff_popup {ctxm} {
+       $ctxm add command \
+               -label [mc "Show Less Context"] \
+               -command show_less_context
+       lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
+       $ctxm add command \
+               -label [mc "Show More Context"] \
+               -command show_more_context
+       lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
+       $ctxm add separator
+       $ctxm add command \
+               -label [mc Refresh] \
+               -command reshow_diff
+       lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
+       $ctxm add command \
+               -label [mc Copy] \
+               -command {tk_textCopy $ui_diff}
+       lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
+       $ctxm add command \
+               -label [mc "Select All"] \
+               -command {focus $ui_diff;$ui_diff tag add sel 0.0 end}
+       lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
+       $ctxm add command \
+               -label [mc "Copy All"] \
+               -command {
+                       $ui_diff tag add sel 0.0 end
+                       tk_textCopy $ui_diff
+                       $ui_diff tag remove sel 0.0 end
+               }
+       lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
+       $ctxm add separator
+       $ctxm add command \
+               -label [mc "Decrease Font Size"] \
+               -command {incr_font_size font_diff -1}
+       lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
+       $ctxm add command \
+               -label [mc "Increase Font Size"] \
+               -command {incr_font_size font_diff 1}
+       lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
+       $ctxm add separator
+       $ctxm add command -label [mc "Options..."] \
+               -command do_options
+}
+
 set ctxm .vpane.lower.diff.body.ctxm
 menu $ctxm -tearoff 0
 $ctxm add command \
@@ -2702,71 +2877,65 @@ $ctxm add command \
 set ui_diff_applyline [$ctxm index last]
 lappend diff_actions [list $ctxm entryconf $ui_diff_applyline -state]
 $ctxm add separator
-$ctxm add command \
-       -label [mc "Show Less Context"] \
-       -command show_less_context
-lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
-$ctxm add command \
-       -label [mc "Show More Context"] \
-       -command show_more_context
-lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
-$ctxm add separator
-$ctxm add command \
-       -label [mc Refresh] \
-       -command reshow_diff
-lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
-$ctxm add command \
-       -label [mc Copy] \
-       -command {tk_textCopy $ui_diff}
-lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
-$ctxm add command \
-       -label [mc "Select All"] \
-       -command {focus $ui_diff;$ui_diff tag add sel 0.0 end}
-lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
-$ctxm add command \
-       -label [mc "Copy All"] \
-       -command {
-               $ui_diff tag add sel 0.0 end
-               tk_textCopy $ui_diff
-               $ui_diff tag remove sel 0.0 end
-       }
-lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
-$ctxm add separator
-$ctxm add command \
-       -label [mc "Decrease Font Size"] \
-       -command {incr_font_size font_diff -1}
-lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
-$ctxm add command \
-       -label [mc "Increase Font Size"] \
-       -command {incr_font_size font_diff 1}
-lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
-$ctxm add separator
-$ctxm add command -label [mc "Options..."] \
-       -command do_options
-proc popup_diff_menu {ctxm x y X Y} {
+create_common_diff_popup $ctxm
+
+set ctxmmg .vpane.lower.diff.body.ctxmmg
+menu $ctxmmg -tearoff 0
+$ctxmmg add command \
+       -label [mc "Run Merge Tool"] \
+       -command {merge_resolve_tool}
+lappend diff_actions [list $ctxmmg entryconf [$ctxmmg index last] -state]
+$ctxmmg add separator
+$ctxmmg add command \
+       -label [mc "Use Remote Version"] \
+       -command {merge_resolve_one 3}
+lappend diff_actions [list $ctxmmg entryconf [$ctxmmg index last] -state]
+$ctxmmg add command \
+       -label [mc "Use Local Version"] \
+       -command {merge_resolve_one 2}
+lappend diff_actions [list $ctxmmg entryconf [$ctxmmg index last] -state]
+$ctxmmg add command \
+       -label [mc "Revert To Base"] \
+       -command {merge_resolve_one 1}
+lappend diff_actions [list $ctxmmg entryconf [$ctxmmg index last] -state]
+$ctxmmg add separator
+create_common_diff_popup $ctxmmg
+
+proc popup_diff_menu {ctxm ctxmmg x y X Y} {
        global current_diff_path file_states
        set ::cursorX $x
        set ::cursorY $y
-       if {$::ui_index eq $::current_diff_side} {
-               set l [mc "Unstage Hunk From Commit"]
-               set t [mc "Unstage Line From Commit"]
+       if {[info exists file_states($current_diff_path)]} {
+               set state [lindex $file_states($current_diff_path) 0]
        } else {
-               set l [mc "Stage Hunk For Commit"]
-               set t [mc "Stage Line For Commit"]
-       }
-       if {$::is_3way_diff
-               || $current_diff_path eq {}
-               || ![info exists file_states($current_diff_path)]
-               || {_O} eq [lindex $file_states($current_diff_path) 0]} {
-               set s disabled
+               set state {__}
+       }
+       if {[string first {U} $state] >= 0} {
+               tk_popup $ctxmmg $X $Y
        } else {
-               set s normal
+               if {$::ui_index eq $::current_diff_side} {
+                       set l [mc "Unstage Hunk From Commit"]
+                       set t [mc "Unstage Line From Commit"]
+               } else {
+                       set l [mc "Stage Hunk For Commit"]
+                       set t [mc "Stage Line For Commit"]
+               }
+               if {$::is_3way_diff
+                       || $current_diff_path eq {}
+                       || {__} eq $state
+                       || {_O} eq $state
+                       || {_T} eq $state
+                       || {T_} eq $state} {
+                       set s disabled
+               } else {
+                       set s normal
+               }
+               $ctxm entryconf $::ui_diff_applyhunk -state $s -label $l
+               $ctxm entryconf $::ui_diff_applyline -state $s -label $t
+               tk_popup $ctxm $X $Y
        }
-       $ctxm entryconf $::ui_diff_applyhunk -state $s -label $l
-       $ctxm entryconf $::ui_diff_applyline -state $s -label $t
-       tk_popup $ctxm $X $Y
 }
-bind_button3 $ui_diff [list popup_diff_menu $ctxm %x %y %X %Y]
+bind_button3 $ui_diff [list popup_diff_menu $ctxm $ctxmmg %x %y %X %Y]
 
 # -- Status Bar
 #
@@ -2842,9 +3011,9 @@ if {[is_enabled transport]} {
        bind . <$M1B-Key-P> do_push_anywhere
 }
 
-bind .   <Key-F5>     do_rescan
-bind .   <$M1B-Key-r> do_rescan
-bind .   <$M1B-Key-R> do_rescan
+bind .   <Key-F5>     ui_do_rescan
+bind .   <$M1B-Key-r> ui_do_rescan
+bind .   <$M1B-Key-R> ui_do_rescan
 bind .   <$M1B-Key-s> do_signoff
 bind .   <$M1B-Key-S> do_signoff
 bind .   <$M1B-Key-t> do_add_selection
index b6e42cbc8fe0a49c301335f78cc2941bd9d59870..827c85d67f0b0f18d22b1399624e6819cf93f23f 100644 (file)
@@ -58,7 +58,7 @@ field tooltip_t         {} ; # Text widget in $tooltip_wm
 field tooltip_timer     {} ; # Current timer event for our tooltip
 field tooltip_commit    {} ; # Commit(s) in tooltip
 
-constructor new {i_commit i_path} {
+constructor new {i_commit i_path i_jump} {
        global cursor_ptr
        variable active_color
        variable group_colors
@@ -259,6 +259,12 @@ constructor new {i_commit i_path} {
        $w.ctxm add command \
                -label [mc "Do Full Copy Detection"] \
                -command [cb _fullcopyblame]
+       $w.ctxm add command \
+               -label [mc "Show History Context"] \
+               -command [cb _gitkcommit]
+       $w.ctxm add command \
+               -label [mc "Blame Parent Commit"] \
+               -command [cb _blameparent]
 
        foreach i $w_columns {
                for {set g 0} {$g < [llength $group_colors]} {incr g} {
@@ -332,7 +338,7 @@ constructor new {i_commit i_path} {
        wm protocol $top WM_DELETE_WINDOW "destroy $top"
        bind $top <Destroy> [cb _kill]
 
-       _load $this {}
+       _load $this $i_jump
 }
 
 method _kill {} {
@@ -787,19 +793,27 @@ method _load_commit {cur_w cur_d pos} {
        set lno [lindex [split [$cur_w index $pos] .] 0]
        set dat [lindex $line_data $lno]
        if {$dat ne {}} {
-               lappend history [list \
-                       $commit $path \
-                       $highlight_column \
-                       $highlight_line \
-                       [lindex [$w_file xview] 0] \
-                       [lindex [$w_file yview] 0] \
-                       ]
-               set commit [lindex $dat 0]
-               set path   [lindex $dat 1]
-               _load $this [list [lindex $dat 2]]
+               _load_new_commit $this  \
+                       [lindex $dat 0] \
+                       [lindex $dat 1] \
+                       [list [lindex $dat 2]]
        }
 }
 
+method _load_new_commit {new_commit new_path jump} {
+       lappend history [list \
+               $commit $path \
+               $highlight_column \
+               $highlight_line \
+               [lindex [$w_file xview] 0] \
+               [lindex [$w_file yview] 0] \
+               ]
+
+       set commit $new_commit
+       set path   $new_path
+       _load $this $jump
+}
+
 method _showcommit {cur_w lno} {
        global repo_config
        variable active_color
@@ -905,10 +919,14 @@ method _showcommit {cur_w lno} {
        }
 }
 
-method _copycommit {} {
+method _get_click_amov_info {} {
        set pos @$::cursorX,$::cursorY
        set lno [lindex [split [$::cursorW index $pos] .] 0]
-       set dat [lindex $amov_data $lno]
+       return [lindex $amov_data $lno]
+}
+
+method _copycommit {} {
+       set dat [_get_click_amov_info $this]
        if {$dat ne {}} {
                clipboard clear
                clipboard append \
@@ -918,6 +936,124 @@ method _copycommit {} {
        }
 }
 
+method _format_offset_date {base offset} {
+       set exval [expr {$base + $offset*24*60*60}]
+       return [clock format $exval -format {%Y-%m-%d}]
+}
+
+method _gitkcommit {} {
+       set dat [_get_click_amov_info $this]
+       if {$dat ne {}} {
+               set cmit [lindex $dat 0]
+               set radius [get_config gui.blamehistoryctx]
+               set cmdline [list --select-commit=$cmit]
+
+                if {$radius > 0} {
+                       set author_time {}
+                       set committer_time {}
+
+                       catch {set author_time $header($cmit,author-time)}
+                       catch {set committer_time $header($cmit,committer-time)}
+
+                       if {$committer_time eq {}} {
+                               set committer_time $author_time
+                       }
+
+                       set after_time [_format_offset_date $this $committer_time [expr {-$radius}]]
+                       set before_time [_format_offset_date $this $committer_time $radius]
+
+                       lappend cmdline --after=$after_time --before=$before_time
+               }
+
+               lappend cmdline $cmit
+
+               set base_rev "HEAD"
+               if {$commit ne {}} {
+                       set base_rev $commit
+               }
+
+               if {$base_rev ne $cmit} {
+                       lappend cmdline $base_rev
+               }
+
+               do_gitk $cmdline
+       }
+}
+
+method _blameparent {} {
+       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^"]}]} {
+                       error_popup [strcat [mc "Cannot find parent commit:"] "\n\n$err"]
+                       return;
+               }
+
+               _kill $this
+
+               # 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]} {
+                       $status stop [mc "Unable to display parent"]
+                       error_popup [strcat [mc "Error loading diff:"] "\n\n$err"]
+                       return
+               }
+
+               set r_orig_line [lindex $dat 2]
+
+               fconfigure $fd \
+                       -blocking 0 \
+                       -encoding binary \
+                       -translation binary
+               fileevent $fd readable [cb _read_diff_load_commit \
+                       $fd $cparent $new_path $r_orig_line]
+               set current_fd $fd
+       }
+}
+
+method _read_diff_load_commit {fd cparent new_path tline} {
+       if {$fd ne $current_fd} {
+               catch {close $fd}
+               return
+       }
+
+       while {[gets $fd line] >= 0} {
+               if {[regexp {^@@ -(\d+)(,(\d+))? \+(\d+)(,(\d+))? @@} $line line \
+                       old_line osz old_size new_line nsz new_size]} {
+
+                       if {$osz eq {}} { set old_size 1 }
+                       if {$nsz eq {}} { set new_size 1 }
+
+                       if {$new_line <= $tline} {
+                               if {[expr {$new_line + $new_size}] > $tline} {
+                                       # Target line within the hunk
+                                       set line_shift [expr {
+                                               ($new_size-$old_size)*($tline-$new_line)/$new_size
+                                               }]
+                               } else {
+                                       set line_shift [expr {$new_size-$old_size}]
+                               }
+
+                               set r_orig_line [expr {$r_orig_line - $line_shift}]
+                       }
+               }
+       }
+
+       if {[eof $fd]} {
+               close $fd;
+               set current_fd {}
+
+               _load_new_commit $this  \
+                       $cparent        \
+                       $new_path       \
+                       [list $r_orig_line]
+       }
+} ifdeleted { catch {close $fd} }
+
 method _show_tooltip {cur_w pos} {
        if {$tooltip_wm ne {}} {
                _open_tooltip $this $cur_w
index ab470d12648c1dd3560b411e70ea210cc4381e3e..0410cc68df186d6e8e0080058be94126243fd4d3 100644 (file)
@@ -151,7 +151,7 @@ method _enter {} {
                                append p [lindex $n 1]
                        }
                        append p $name
-                       blame::new $browser_commit $p
+                       blame::new $browser_commit $p {}
                }
                }
        }
index 40a710355751836e78b65101592b753266f507ca..2977315624fc5deeecff275d8dc8b3f2e3210a70 100644 (file)
@@ -149,7 +149,9 @@ The rescan will be automatically started now.
                _? {continue}
                A? -
                D? -
+               T_ -
                M? {set files_ready 1}
+               _U -
                U? {
                        error_popup [mc "Unmerged files cannot be committed.
 
@@ -428,6 +430,7 @@ A rescan will be automatically started now.
                __ -
                A_ -
                M_ -
+               T_ -
                D_ {
                        unset file_states($path)
                        catch {unset selected_paths($path)}
index 52b79e4a1f476c2ee9b65087f66a352a25ed0903..a30c80a935b58ce0c783dfffde196a85eadca9a2 100644 (file)
@@ -24,10 +24,16 @@ proc reshow_diff {} {
        set p $current_diff_path
        if {$p eq {}} {
                # No diff is being shown.
-       } elseif {$current_diff_side eq {}
-               || [catch {set s $file_states($p)}]
-               || [lsearch -sorted -exact $file_lists($current_diff_side) $p] == -1} {
+       } elseif {$current_diff_side eq {}} {
                clear_diff
+       } elseif {[catch {set s $file_states($p)}]
+               || [lsearch -sorted -exact $file_lists($current_diff_side) $p] == -1} {
+
+               if {[find_next_diff $current_diff_side $p {} {[^O]}]} {
+                       next_diff
+               } else {
+                       clear_diff
+               }
        } else {
                set save_pos [lindex [$ui_diff yview] 0]
                show_diff $p $current_diff_side {} $save_pos
@@ -59,6 +65,7 @@ proc show_diff {path w {lno {}} {scroll_pos {}}} {
        global is_3way_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
 
        if {$diff_active || ![lock_index read]} return
 
@@ -71,17 +78,74 @@ proc show_diff {path w {lno {}} {scroll_pos {}}} {
        }
        if {$lno >= 1} {
                $w tag add in_diff $lno.0 [expr {$lno + 1}].0
+               $w see $lno.0
        }
 
        set s $file_states($path)
        set m [lindex $s 0]
-       set is_3way_diff 0
-       set diff_active 1
        set current_diff_path $path
        set current_diff_side $w
-       set current_diff_header {}
+       set current_diff_queue {}
        ui_status [mc "Loading diff of %s..." [escape_path $path]]
 
+       if {[string first {U} $m] >= 0} {
+               merge_load_stages $path [list show_unmerged_diff $scroll_pos]
+       } elseif {$m eq {_O}} {
+               show_other_diff $path $w $m $scroll_pos
+       } else {
+               start_show_diff $scroll_pos
+       }
+}
+
+proc show_unmerged_diff {scroll_pos} {
+       global current_diff_path current_diff_side
+       global merge_stages ui_diff
+       global current_diff_queue
+
+       if {$merge_stages(2) eq {}} {
+               lappend current_diff_queue \
+                       [list "LOCAL: deleted\nREMOTE:\n" d======= \
+                           [list ":1:$current_diff_path" ":3:$current_diff_path"]]
+       } elseif {$merge_stages(3) eq {}} {
+               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}} {
+               lappend current_diff_queue \
+                       [list "LOCAL:\n" d======= \
+                           [list ":1:$current_diff_path" ":2:$current_diff_path"]]
+               lappend current_diff_queue \
+                       [list "REMOTE:\n" d======= \
+                           [list ":1:$current_diff_path" ":3:$current_diff_path"]]
+       } else {
+               start_show_diff $scroll_pos
+               return
+       }
+
+       advance_diff_queue $scroll_pos
+}
+
+proc advance_diff_queue {scroll_pos} {
+       global current_diff_queue ui_diff
+
+       set item [lindex $current_diff_queue 0]
+       set current_diff_queue [lrange $current_diff_queue 1 end]
+
+       $ui_diff conf -state normal
+       $ui_diff insert end [lindex $item 0] [lindex $item 1]
+       $ui_diff conf -state disabled
+
+       start_show_diff $scroll_pos [lindex $item 2]
+}
+
+proc show_other_diff {path w m scroll_pos} {
+       global file_states file_lists
+       global is_3way_diff diff_active repo_config
+       global ui_diff ui_index ui_workdir
+       global current_diff_path current_diff_side current_diff_header
+
        # - Git won't give us the diff, there's nothing to compare to!
        #
        if {$m eq {_O}} {
@@ -160,13 +224,29 @@ proc show_diff {path w {lno {}} {scroll_pos {}}} {
                ui_ready
                return
        }
+}
+
+proc start_show_diff {scroll_pos {add_opts {}}} {
+       global file_states file_lists
+       global is_3way_diff diff_active repo_config
+       global ui_diff ui_index ui_workdir
+       global current_diff_path current_diff_side current_diff_header
+
+       set path $current_diff_path
+       set w $current_diff_side
+
+       set s $file_states($path)
+       set m [lindex $s 0]
+       set is_3way_diff 0
+       set diff_active 1
+       set current_diff_header {}
 
        set cmd [list]
        if {$w eq $ui_index} {
                lappend cmd diff-index
                lappend cmd --cached
        } elseif {$w eq $ui_workdir} {
-               if {[string index $m 0] eq {U}} {
+               if {[string first {U} $m] >= 0} {
                        lappend cmd diff
                } else {
                        lappend cmd diff-files
@@ -175,14 +255,18 @@ proc show_diff {path w {lno {}} {scroll_pos {}}} {
 
        lappend cmd -p
        lappend cmd --no-color
-       if {$repo_config(gui.diffcontext) >= 0} {
+       if {$repo_config(gui.diffcontext) >= 1} {
                lappend cmd "-U$repo_config(gui.diffcontext)"
        }
        if {$w eq $ui_index} {
                lappend cmd [PARENT]
        }
-       lappend cmd --
-       lappend cmd $path
+       if {$add_opts ne {}} {
+               eval lappend cmd $add_opts
+       } else {
+               lappend cmd --
+               lappend cmd $path
+       }
 
        if {[catch {set fd [eval git_read --nice $cmd]} err]} {
                set diff_active 0
@@ -192,6 +276,7 @@ proc show_diff {path w {lno {}} {scroll_pos {}}} {
                return
        }
 
+       set ::current_diff_inheader 1
        fconfigure $fd \
                -blocking 0 \
                -encoding binary \
@@ -202,23 +287,27 @@ proc show_diff {path w {lno {}} {scroll_pos {}}} {
 proc read_diff {fd scroll_pos} {
        global ui_diff diff_active
        global is_3way_diff current_diff_header
+       global current_diff_queue
 
        $ui_diff conf -state normal
        while {[gets $fd line] >= 0} {
                # -- Cleanup uninteresting diff header lines.
                #
-               if {   [string match {diff --git *}      $line]
-                       || [string match {diff --cc *}       $line]
-                       || [string match {diff --combined *} $line]
-                       || [string match {--- *}             $line]
-                       || [string match {+++ *}             $line]} {
-                       append current_diff_header $line "\n"
-                       continue
+               if {$::current_diff_inheader} {
+                       if {   [string match {diff --git *}      $line]
+                           || [string match {diff --cc *}       $line]
+                           || [string match {diff --combined *} $line]
+                           || [string match {--- *}             $line]
+                           || [string match {+++ *}             $line]} {
+                               append current_diff_header $line "\n"
+                               continue
+                       }
                }
                if {[string match {index *} $line]} continue
                if {$line eq {deleted file mode 120000}} {
                        set line "deleted symlink"
                }
+               set ::current_diff_inheader 0
 
                # -- Automatically detect if this is a 3 way diff.
                #
@@ -286,6 +375,12 @@ proc read_diff {fd scroll_pos} {
 
        if {[eof $fd]} {
                close $fd
+
+               if {$current_diff_queue ne {}} {
+                       advance_diff_queue $scroll_pos
+                       return
+               }
+
                set diff_active 0
                unlock_index
                if {$scroll_pos ne {}} {
@@ -366,10 +461,9 @@ proc apply_hunk {x y} {
        }
        unlock_index
        display_file $current_diff_path $mi
+       # This should trigger shift to the next changed file
        if {$o eq {_}} {
-               clear_diff
-       } else {
-               set current_diff_path $current_diff_path
+               reshow_diff
        }
 }
 
index 3c1fce7475d362d1880d915ff4bdf168fda28593..b045219a1cca6bf46218bf211c0c88b8d699e144 100644 (file)
@@ -99,6 +99,7 @@ proc write_update_indexinfo {fd pathList totalCnt batch after} {
                switch -glob -- [lindex $s 0] {
                A? {set new _O}
                M? {set new _M}
+               T_ {set new _T}
                D_ {set new _D}
                D? {set new _?}
                ?? {continue}
@@ -162,6 +163,8 @@ proc write_update_index {fd pathList totalCnt batch after} {
                ?D {set new D_}
                _O -
                AM {set new A_}
+               _T {set new T_}
+               _U -
                U? {
                        if {[file exists $path]} {
                                set new M_
@@ -231,6 +234,7 @@ proc write_checkout_index {fd pathList totalCnt batch after} {
                switch -glob -- [lindex $file_states($path) 0] {
                U? {continue}
                ?M -
+               ?T -
                ?D {
                        puts -nonewline $fd "[encoding convertto $path]\0"
                        display_file $path ?_
@@ -252,6 +256,7 @@ proc unstage_helper {txt paths} {
                switch -glob -- [lindex $file_states($path) 0] {
                A? -
                M? -
+               T_ -
                D? {
                        lappend pathList $path
                        if {$path eq $current_diff_path} {
@@ -296,6 +301,7 @@ proc add_helper {txt paths} {
                _O -
                ?M -
                ?D -
+               ?T -
                U? {
                        lappend pathList $path
                        if {$path eq $current_diff_path} {
@@ -336,6 +342,7 @@ proc do_add_all {} {
                switch -glob -- [lindex $file_states($path) 0] {
                U? {continue}
                ?M -
+               ?T -
                ?D {lappend paths $path}
                }
        }
@@ -353,6 +360,7 @@ proc revert_helper {txt paths} {
                switch -glob -- [lindex $file_states($path) 0] {
                U? {continue}
                ?M -
+               ?T -
                ?D {
                        lappend pathList $path
                        if {$path eq $current_diff_path} {
@@ -409,11 +417,11 @@ proc do_revert_selection {} {
 
        if {[array size selected_paths] > 0} {
                revert_helper \
-                       {Reverting selected files} \
+                       [mc "Reverting selected files"] \
                        [array names selected_paths]
        } elseif {$current_diff_path ne {}} {
                revert_helper \
-                       "Reverting [short_path $current_diff_path]" \
+                       [mc "Reverting %s" [short_path $current_diff_path]] \
                        [list $current_diff_path]
        }
 }
diff --git a/git-gui/lib/mergetool.tcl b/git-gui/lib/mergetool.tcl
new file mode 100644 (file)
index 0000000..79c58bc
--- /dev/null
@@ -0,0 +1,373 @@
+# git-gui merge conflict resolution
+# parts based on git-mergetool (c) 2006 Theodore Y. Ts'o
+
+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"] }
+       }
+
+       set op_question [mc "Force resolution to %s?
+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]]
+
+       if {[ask_popup $op_question] eq {yes}} {
+               merge_load_stages $current_diff_path [list merge_force_stage $stage]
+       }
+}
+
+proc merge_add_resolution {path} {
+       global current_diff_path ui_workdir
+
+       set after [next_diff_after_action $ui_workdir $path {} {^_?U}]
+
+       update_index \
+               [mc "Adding resolution for %s" [short_path $path]] \
+               [list $path] \
+               [concat $after [list ui_ready]]
+}
+
+proc merge_force_stage {stage} {
+       global current_diff_path merge_stages
+
+       if {$merge_stages($stage) ne {}} {
+               git checkout-index -f --stage=$stage -- $current_diff_path
+       } else {
+               file delete -- $current_diff_path
+       }
+
+       merge_add_resolution $current_diff_path
+}
+
+proc merge_load_stages {path cont} {
+       global merge_stages_fd merge_stages merge_stages_buf
+
+       if {[info exists merge_stages_fd]} {
+               catch { kill_file_process $merge_stages_fd }
+               catch { close $merge_stages_fd }
+       }
+
+       set merge_stages(0) {}
+       set merge_stages(1) {}
+       set merge_stages(2) {}
+       set merge_stages(3) {}
+       set merge_stages_buf {}
+
+       set merge_stages_fd [eval git_read ls-files -u -z -- $path]
+
+       fconfigure $merge_stages_fd -blocking 0 -translation binary -encoding binary
+       fileevent $merge_stages_fd readable [list read_merge_stages $merge_stages_fd $cont]
+}
+
+proc read_merge_stages {fd cont} {
+       global merge_stages_buf merge_stages_fd merge_stages
+
+       append merge_stages_buf [read $fd]
+       set pck [split $merge_stages_buf "\0"]
+       set merge_stages_buf [lindex $pck end]
+
+       if {[eof $fd] && $merge_stages_buf ne {}} {
+               lappend pck {}
+               set merge_stages_buf {}
+       }
+
+       foreach p [lrange $pck 0 end-1] {
+               set fcols [split $p "\t"]
+               set cols  [split [lindex $fcols 0] " "]
+               set stage [lindex $cols 2]
+               
+               set merge_stages($stage) [lrange $cols 0 1]
+       }
+
+       if {[eof $fd]} {
+               close $fd
+               unset merge_stages_fd
+               eval $cont
+       }
+}
+
+proc merge_resolve_tool {} {
+       global current_diff_path
+
+       merge_load_stages $current_diff_path [list merge_resolve_tool2]
+}
+
+proc merge_resolve_tool2 {} {
+       global current_diff_path merge_stages
+
+       # Validate the stages
+       if {$merge_stages(2) eq {} ||
+           [lindex $merge_stages(2) 0] eq {120000} ||
+           [lindex $merge_stages(2) 0] eq {160000} ||
+           $merge_stages(3) eq {} ||
+           [lindex $merge_stages(3) 0] eq {120000} ||
+           [lindex $merge_stages(3) 0] eq {160000}
+       } {
+               error_popup [mc "Cannot resolve deletion or link conflicts using a tool"]
+               return
+       }
+
+       if {![file exists $current_diff_path]} {
+               error_popup [mc "Conflict file does not exist"]
+               return
+       }
+
+       # Determine the tool to use
+       set tool [get_config merge.tool]
+       if {$tool eq {}} { set tool meld }
+
+       set merge_tool_path [get_config "mergetool.$tool.path"]
+       if {$merge_tool_path eq {}} {
+               switch -- $tool {
+               emerge { set merge_tool_path "emacs" }
+               araxis { set merge_tool_path "compare" }
+               default { set merge_tool_path $tool }
+               }
+       }
+
+       # Make file names
+       set filebase [file rootname $current_diff_path]
+       set fileext  [file extension $current_diff_path]
+       set basename [lindex [file split $current_diff_path] end]
+
+       set MERGED   $current_diff_path
+       set BASE     "./$MERGED.BASE$fileext"
+       set LOCAL    "./$MERGED.LOCAL$fileext"
+       set REMOTE   "./$MERGED.REMOTE$fileext"
+       set BACKUP   "./$MERGED.BACKUP$fileext"
+
+       set base_stage $merge_stages(1)
+
+       # Build the command line
+       switch -- $tool {
+       kdiff3 {
+               if {$base_stage ne {}} {
+                       set cmdline [list "$merge_tool_path" --auto --L1 "$MERGED (Base)" \
+                               --L2 "$MERGED (Local)" --L3 "$MERGED (Remote)" -o "$MERGED" "$BASE" "$LOCAL" "$REMOTE"]
+               } else {
+                       set cmdline [list "$merge_tool_path" --auto --L1 "$MERGED (Local)" \
+                               --L2 "$MERGED (Remote)" -o "$MERGED" "$LOCAL" "$REMOTE"]
+               }
+       }
+       tkdiff {
+               if {$base_stage ne {}} {
+                       set cmdline [list "$merge_tool_path" -a "$BASE" -o "$MERGED" "$LOCAL" "$REMOTE"]
+               } else {
+                       set cmdline [list "$merge_tool_path" -o "$MERGED" "$LOCAL" "$REMOTE"]
+               }
+       }
+       meld {
+               set cmdline [list "$merge_tool_path" "$LOCAL" "$MERGED" "$REMOTE"]
+       }
+       gvimdiff {
+               set cmdline [list "$merge_tool_path" -f "$LOCAL" "$MERGED" "$REMOTE"]
+       }
+       xxdiff {
+               if {$base_stage ne {}} {
+                       set cmdline [list "$merge_tool_path" -X --show-merged-pane \
+                                           -R {Accel.SaveAsMerged: "Ctrl-S"} \
+                                           -R {Accel.Search: "Ctrl+F"} \
+                                           -R {Accel.SearchForward: "Ctrl-G"} \
+                                           --merged-file "$MERGED" "$LOCAL" "$BASE" "$REMOTE"]
+               } else {
+                       set cmdline [list "$merge_tool_path" -X --show-merged-pane \
+                                           -R {Accel.SaveAsMerged: "Ctrl-S"} \
+                                           -R {Accel.Search: "Ctrl+F"} \
+                                           -R {Accel.SearchForward: "Ctrl-G"} \
+                                           --merged-file "$MERGED" "$LOCAL" "$REMOTE"]
+               }
+       }
+       opendiff {
+               if {$base_stage ne {}} {
+                       set cmdline [list "$merge_tool_path" "$LOCAL" "$REMOTE" -ancestor "$BASE" -merge "$MERGED"]
+               } else {
+                       set cmdline [list "$merge_tool_path" "$LOCAL" "$REMOTE" -merge "$MERGED"]
+               }
+       }
+       ecmerge {
+               if {$base_stage ne {}} {
+                       set cmdline [list "$merge_tool_path" "$BASE" "$LOCAL" "$REMOTE" --default --mode=merge3 --to="$MERGED"]
+               } else {
+                       set cmdline [list "$merge_tool_path" "$LOCAL" "$REMOTE" --default --mode=merge2 --to="$MERGED"]
+               }
+       }
+       emerge {
+               if {$base_stage ne {}} {
+                       set cmdline [list "$merge_tool_path" -f emerge-files-with-ancestor-command \
+                                       "$LOCAL" "$REMOTE" "$BASE" "$basename"]
+               } else {
+                       set cmdline [list "$merge_tool_path" -f emerge-files-command \
+                                       "$LOCAL" "$REMOTE" "$basename"]
+               }
+       }
+       winmerge {
+               if {$base_stage ne {}} {
+                       # This tool does not support 3-way merges.
+                       # Use the 'conflict file' resolution feature instead.
+                       set cmdline [list "$merge_tool_path" -e -ub "$MERGED"]
+               } else {
+                       set cmdline [list "$merge_tool_path" -e -ub -wl \
+                               -dl "Theirs File" -dr "Mine File" "$REMOTE" "$LOCAL" "$MERGED"]
+               }
+       }
+       araxis {
+               if {$base_stage ne {}} {
+                       set cmdline [list "$merge_tool_path" -wait -merge -3 -a1 \
+                               -title1:"'$MERGED (Base)'" -title2:"'$MERGED (Local)'" \
+                               -title3:"'$MERGED (Remote)'" \
+                               "$BASE" "$LOCAL" "$REMOTE" "$MERGED"]
+               } else {
+                       set cmdline [list "$merge_tool_path" -wait -2 \
+                                -title1:"'$MERGED (Local)'" -title2:"'$MERGED (Remote)'" \
+                                "$LOCAL" "$REMOTE" "$MERGED"]
+               }
+       }
+       p4merge {
+               set cmdline [list "$merge_tool_path" "$BASE" "$REMOTE" "$LOCAL" "$MERGED"]
+       }
+       vimdiff {
+               error_popup [mc "Not a GUI merge tool: '%s'" $tool]
+               return
+       }
+       default {
+               error_popup [mc "Unsupported merge tool '%s'" $tool]
+               return
+       }
+       }
+
+       merge_tool_start $cmdline $MERGED $BACKUP [list $BASE $LOCAL $REMOTE]
+}
+
+proc delete_temp_files {files} {
+       foreach fname $files {
+               file delete $fname
+       }
+}
+
+proc merge_tool_get_stages {target stages} {
+       global merge_stages
+
+       set i 1
+       foreach fname $stages {
+               if {$merge_stages($i) eq {}} {
+                       file delete $fname
+                       catch { close [open $fname w] }
+               } else {
+                       # A hack to support autocrlf properly
+                       git checkout-index -f --stage=$i -- $target
+                       file rename -force -- $target $fname
+               }
+               incr i
+       }
+}
+
+proc merge_tool_start {cmdline target backup stages} {
+       global merge_stages mtool_target mtool_tmpfiles mtool_fd mtool_mtime
+
+       if {[info exists mtool_fd]} {
+               if {[ask_popup [mc "Merge tool is already running, terminate it?"]] eq {yes}} {
+                       catch { kill_file_process $mtool_fd }
+                       catch { close $mtool_fd }
+                       unset mtool_fd
+
+                       set old_backup [lindex $mtool_tmpfiles end]
+                       file rename -force -- $old_backup $mtool_target
+                       delete_temp_files $mtool_tmpfiles
+               } else {
+                       return
+               }
+       }
+
+       # Save the original file
+       file rename -force -- $target $backup
+
+       # Get the blobs; it destroys $target
+       if {[catch {merge_tool_get_stages $target $stages} err]} {
+               file rename -force -- $backup $target
+               delete_temp_files $stages
+               error_popup [mc "Error retrieving versions:\n%s" $err]
+               return
+       }
+
+       # Restore the conflict file
+       file copy -force -- $backup $target
+
+       # Initialize global state
+       set mtool_target $target
+       set mtool_mtime [file mtime $target]
+       set mtool_tmpfiles $stages
+
+       lappend mtool_tmpfiles $backup
+
+       # Force redirection to avoid interpreting output on stderr
+       # as an error, and launch the tool
+       lappend cmdline {2>@1}
+
+       if {[catch { set mtool_fd [_open_stdout_stderr $cmdline] } err]} {
+               delete_temp_files $mtool_tmpfiles
+               error_popup [mc "Could not start the merge tool:\n\n%s" $err]
+               return
+       }
+
+       ui_status [mc "Running merge tool..."]
+
+       fconfigure $mtool_fd -blocking 0 -translation binary -encoding binary
+       fileevent $mtool_fd readable [list read_mtool_output $mtool_fd]
+}
+
+proc read_mtool_output {fd} {
+       global mtool_fd mtool_tmpfiles
+
+       read $fd
+       if {[eof $fd]} {
+               unset mtool_fd
+
+               fconfigure $fd -blocking 1
+               merge_tool_finish $fd
+       }
+}
+
+proc merge_tool_finish {fd} {
+       global mtool_tmpfiles mtool_target mtool_mtime
+
+       set backup [lindex $mtool_tmpfiles end]
+       set failed 0
+
+       # Check the return code
+       if {[catch {close $fd} err]} {
+               set failed 1
+               if {$err ne {child process exited abnormally}} {
+                       error_popup [strcat [mc "Merge tool failed."] "\n\n$err"]
+               }
+       }
+
+       # Check the modification time of the target file
+       if {!$failed && [file mtime $mtool_target] eq $mtool_mtime} {
+               if {[ask_popup [mc "File %s unchanged, still accept as resolved?" \
+                               [short_path $mtool_target]]] ne {yes}} {
+                       set failed 1
+               }
+       }
+
+       # Finish
+       if {$failed} {
+               file rename -force -- $backup $mtool_target
+               delete_temp_files $mtool_tmpfiles
+               ui_status [mc "Merge tool failed."]
+       } else {
+               if {[is_config_true merge.keepbackup]} {
+                       file rename -force -- $backup "$mtool_target.orig"
+               }
+
+               delete_temp_files $mtool_tmpfiles
+
+               merge_add_resolution $mtool_target
+       }
+}
index ffb3f00ff0a992254804cc047b5a63ce82aa5bd9..9b865f6a754aeb0933e1696ae1c9ffaee899e936 100644 (file)
@@ -119,13 +119,15 @@ proc do_options {} {
                {b merge.summary {mc "Summarize Merge Commits"}}
                {i-1..5 merge.verbosity {mc "Merge Verbosity"}}
                {b merge.diffstat {mc "Show Diffstat After Merge"}}
+               {t merge.tool {mc "Use Merge Tool"}}
 
                {b gui.trustmtime  {mc "Trust File Modification Timestamps"}}
                {b gui.pruneduringfetch {mc "Prune Tracking Branches During Fetch"}}
                {b gui.matchtrackingbranch {mc "Match Tracking Branches"}}
                {b gui.fastcopyblame {mc "Blame Copy Only On Changed Files"}}
                {i-20..200 gui.copyblamethreshold {mc "Minimum Letters To Blame Copy On"}}
-               {i-0..99 gui.diffcontext {mc "Number of Diff Context Lines"}}
+               {i-0..300 gui.blamehistoryctx {mc "Blame History Context Radius (days)"}}
+               {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"}}
                } {
index 89b6d51ea011d5b0fc8a343ffdda078d659571cb..26b866f5510788fd0dac1df1d7f59114713ce53a 100644 (file)
@@ -1,50 +1,51 @@
-# translation of fr.po to French
+# translation of fr.po to Français
 # Translation of git-gui to French.
 # Copyright (C) 2008 Shawn Pearce, et al.
 # This file is distributed under the same license as the git package.
 #
 # Christian Couder <chriscool@tuxfamily.org>, 2008.
+# Alexandre Bourget <alexandre.bourget@savoirfairelinux.com>, 2008.
 msgid ""
 msgstr ""
 "Project-Id-Version: fr\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-03-14 07:18+0100\n"
-"PO-Revision-Date: 2008-04-04 22:05+0200\n"
-"Last-Translator: Christian Couder <chriscool@tuxfamily.org>\n"
-"Language-Team: French\n"
+"POT-Creation-Date: 2008-08-02 14:45-0700\n"
+"PO-Revision-Date: 2008-08-11 17:12-0400\n"
+"Last-Translator: Alexandre Bourget <alexandre.bourget@savoirfairelinux.com>\n"
+"Language-Team: Français <fr@li.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "X-Generator: KBabel 1.11.4\n"
 "Plural-Forms:  nplurals=2; plural=(n > 1);\n"
 
-#: git-gui.sh:41 git-gui.sh:634 git-gui.sh:648 git-gui.sh:661 git-gui.sh:744
-#: git-gui.sh:763
+#: git-gui.sh:41 git-gui.sh:688 git-gui.sh:702 git-gui.sh:715 git-gui.sh:798
+#: git-gui.sh:817
 msgid "git-gui: fatal error"
 msgstr "git-gui: erreur fatale"
 
-#: git-gui.sh:593
+#: git-gui.sh:644
 #, tcl-format
 msgid "Invalid font specified in %s:"
-msgstr "Invalide fonte spécifiée dans %s :"
+msgstr "Police invalide spécifiée dans %s :"
 
-#: git-gui.sh:620
+#: git-gui.sh:674
 msgid "Main Font"
-msgstr "Fonte principale"
+msgstr "Police principale"
 
-#: git-gui.sh:621
+#: git-gui.sh:675
 msgid "Diff/Console Font"
-msgstr "Fonte diff/console"
+msgstr "Police diff/console"
 
-#: git-gui.sh:635
+#: git-gui.sh:689
 msgid "Cannot find git in PATH."
 msgstr "Impossible de trouver git dans PATH."
 
-#: git-gui.sh:662
+#: git-gui.sh:716
 msgid "Cannot parse Git version string:"
 msgstr "Impossible de parser la version de Git :"
 
-#: git-gui.sh:680
+#: git-gui.sh:734
 #, tcl-format
 msgid ""
 "Git version cannot be determined.\n"
@@ -63,378 +64,381 @@ msgstr ""
 "\n"
 "Peut'on considérer que '%s' est en version 1.5.0 ?\n"
 
-#: git-gui.sh:918
+#: git-gui.sh:972
 msgid "Git directory not found:"
-msgstr "Impossible de trouver le répertoire de Git :"
+msgstr "Impossible de trouver le répertoire git :"
 
-#: git-gui.sh:925
+#: git-gui.sh:979
 msgid "Cannot move to top of working directory:"
 msgstr "Impossible d'aller à la racine du répertoire de travail :"
 
-#: git-gui.sh:932
+#: git-gui.sh:986
 msgid "Cannot use funny .git directory:"
-msgstr "Impossible d'utiliser un drôle de répertoire git :"
+msgstr "Impossible d'utiliser le répertoire .git:"
 
-#: git-gui.sh:937
+#: git-gui.sh:991
 msgid "No working directory"
-msgstr "Pas de répertoire de travail"
+msgstr "Aucun répertoire de travail"
 
-#: git-gui.sh:1084 lib/checkout_op.tcl:283
+#: git-gui.sh:1138 lib/checkout_op.tcl:305
 msgid "Refreshing file status..."
 msgstr "Rafraichissement du status des fichiers..."
 
-#: git-gui.sh:1149
+#: git-gui.sh:1194
 msgid "Scanning for modified files ..."
 msgstr "Recherche de fichiers modifiés..."
 
-#: git-gui.sh:1324 lib/browser.tcl:246
+#: git-gui.sh:1369 lib/browser.tcl:246
 msgid "Ready."
 msgstr "Prêt."
 
-#: git-gui.sh:1590
+#: git-gui.sh:1635
 msgid "Unmodified"
 msgstr "Non modifié"
 
-#: git-gui.sh:1592
+#: git-gui.sh:1637
 msgid "Modified, not staged"
-msgstr "Modifié, non pré-commité"
+msgstr "Modifié, pas indexé"
 
-#: git-gui.sh:1593 git-gui.sh:1598
+#: git-gui.sh:1638 git-gui.sh:1643
 msgid "Staged for commit"
-msgstr "Pré-commité"
+msgstr "Indexé"
 
-#: git-gui.sh:1594 git-gui.sh:1599
+#: git-gui.sh:1639 git-gui.sh:1644
 msgid "Portions staged for commit"
-msgstr "En partie pré-commité"
+msgstr "Portions indexées"
 
-#: git-gui.sh:1595 git-gui.sh:1600
+#: git-gui.sh:1640 git-gui.sh:1645
 msgid "Staged for commit, missing"
-msgstr "Pré-commité, manquant"
+msgstr "Indexés, manquant"
 
-#: git-gui.sh:1597
+#: git-gui.sh:1642
 msgid "Untracked, not staged"
-msgstr "Non suivi, non pré-commité"
+msgstr "Non versionné, non indexé"
 
-#: git-gui.sh:1602
+#: git-gui.sh:1647
 msgid "Missing"
 msgstr "Manquant"
 
-#: git-gui.sh:1603
+#: git-gui.sh:1648
 msgid "Staged for removal"
-msgstr "Pré-commité pour suppression"
+msgstr "Indexé pour suppression"
 
-#: git-gui.sh:1604
+#: git-gui.sh:1649
 msgid "Staged for removal, still present"
-msgstr "Pré-commité pour suppression, toujours présent"
+msgstr "Indexé pour suppression, toujours présent"
 
-#: git-gui.sh:1606 git-gui.sh:1607 git-gui.sh:1608 git-gui.sh:1609
+#: git-gui.sh:1651 git-gui.sh:1652 git-gui.sh:1653 git-gui.sh:1654
 msgid "Requires merge resolution"
 msgstr "Nécessite la résolution d'une fusion"
 
-#: git-gui.sh:1644
+#: git-gui.sh:1689
 msgid "Starting gitk... please wait..."
-msgstr "Lancement de gitk... merci de patienter..."
+msgstr "Lancement de gitk... un instant..."
 
-#: git-gui.sh:1653
-#, tcl-format
-msgid ""
-"Unable to start gitk:\n"
-"\n"
-"%s does not exist"
-msgstr ""
-"Impossible de lancer gitk :\n"
-"\n"
-"%s inexistant"
+#: git-gui.sh:1698
+msgid "Couldn't find gitk in PATH"
+msgstr "Impossible de trouver gitk dans PATH."
 
-#: git-gui.sh:1860 lib/choose_repository.tcl:36
+#: git-gui.sh:1948 lib/choose_repository.tcl:36
 msgid "Repository"
-msgstr "Référentiel"
+msgstr "Dépôt"
 
-#: git-gui.sh:1861
+#: git-gui.sh:1949
 msgid "Edit"
-msgstr "Editer"
+msgstr "Edition"
 
-#: git-gui.sh:1863 lib/choose_rev.tcl:561
+#: git-gui.sh:1951 lib/choose_rev.tcl:561
 msgid "Branch"
 msgstr "Branche"
 
-#: git-gui.sh:1866 lib/choose_rev.tcl:548
+#: git-gui.sh:1954 lib/choose_rev.tcl:548
 msgid "Commit@@noun"
 msgstr "Commit"
 
-#: git-gui.sh:1869 lib/merge.tcl:120 lib/merge.tcl:149 lib/merge.tcl:167
+#: git-gui.sh:1957 lib/merge.tcl:120 lib/merge.tcl:149 lib/merge.tcl:167
 msgid "Merge"
 msgstr "Fusionner"
 
-#: git-gui.sh:1870 lib/choose_rev.tcl:557
+#: git-gui.sh:1958 lib/choose_rev.tcl:557
 msgid "Remote"
-msgstr "Référentiel distant"
+msgstr "Dépôt distant"
 
-#: git-gui.sh:1879
+#: git-gui.sh:1967
 msgid "Browse Current Branch's Files"
-msgstr "Visionner fichiers dans branche courante"
+msgstr "Naviguer dans la branche courante"
 
-#: git-gui.sh:1883
+#: git-gui.sh:1971
 msgid "Browse Branch Files..."
-msgstr "Visionner fichiers de branche"
+msgstr "Naviguer dans la branche..."
 
-#: git-gui.sh:1888
+#: git-gui.sh:1976
 msgid "Visualize Current Branch's History"
 msgstr "Visualiser historique branche courante"
 
-#: git-gui.sh:1892
+#: git-gui.sh:1980
 msgid "Visualize All Branch History"
-msgstr "Visualiser historique toutes branches"
+msgstr "Voir l'historique de toutes les branches"
 
-#: git-gui.sh:1899
+#: git-gui.sh:1987
 #, tcl-format
 msgid "Browse %s's Files"
-msgstr "Visionner fichiers de %s"
+msgstr "Naviguer l'arborescence de %s"
 
-#: git-gui.sh:1901
+#: git-gui.sh:1989
 #, tcl-format
 msgid "Visualize %s's History"
-msgstr "Visualiser historique de %s"
+msgstr "Voir l'historique de la branche: %s"
 
-#: git-gui.sh:1906 lib/database.tcl:27 lib/database.tcl:67
+#: git-gui.sh:1994 lib/database.tcl:27 lib/database.tcl:67
 msgid "Database Statistics"
-msgstr "Statistiques base de donnée"
+msgstr "Statistiques du dépôt"
 
-#: git-gui.sh:1909 lib/database.tcl:34
+#: git-gui.sh:1997 lib/database.tcl:34
 msgid "Compress Database"
-msgstr "Comprimer base de donnée"
+msgstr "Comprimer le dépôt"
 
-#: git-gui.sh:1912
+#: git-gui.sh:2000
 msgid "Verify Database"
-msgstr "Vérifier base de donnée"
+msgstr "Vérifier le dépôt"
 
-#: git-gui.sh:1919 git-gui.sh:1923 git-gui.sh:1927 lib/shortcut.tcl:7
+#: git-gui.sh:2007 git-gui.sh:2011 git-gui.sh:2015 lib/shortcut.tcl:7
 #: lib/shortcut.tcl:39 lib/shortcut.tcl:71
 msgid "Create Desktop Icon"
 msgstr "Créer icône sur bureau"
 
-#: git-gui.sh:1932 lib/choose_repository.tcl:177 lib/choose_repository.tcl:185
+#: git-gui.sh:2023 lib/choose_repository.tcl:177 lib/choose_repository.tcl:185
 msgid "Quit"
 msgstr "Quitter"
 
-#: git-gui.sh:1939
+#: git-gui.sh:2031
 msgid "Undo"
 msgstr "Défaire"
 
-#: git-gui.sh:1942
+#: git-gui.sh:2034
 msgid "Redo"
 msgstr "Refaire"
 
-#: git-gui.sh:1946 git-gui.sh:2443
+#: git-gui.sh:2038 git-gui.sh:2545
 msgid "Cut"
 msgstr "Couper"
 
-#: git-gui.sh:1949 git-gui.sh:2446 git-gui.sh:2520 git-gui.sh:2614
+#: git-gui.sh:2041 git-gui.sh:2548 git-gui.sh:2622 git-gui.sh:2715
 #: lib/console.tcl:69
 msgid "Copy"
 msgstr "Copier"
 
-#: git-gui.sh:1952 git-gui.sh:2449
+#: git-gui.sh:2044 git-gui.sh:2551
 msgid "Paste"
 msgstr "Coller"
 
-#: git-gui.sh:1955 git-gui.sh:2452 lib/branch_delete.tcl:26
+#: git-gui.sh:2047 git-gui.sh:2554 lib/branch_delete.tcl:26
 #: lib/remote_branch_delete.tcl:38
 msgid "Delete"
 msgstr "Supprimer"
 
-#: git-gui.sh:1959 git-gui.sh:2456 git-gui.sh:2618 lib/console.tcl:71
+#: git-gui.sh:2051 git-gui.sh:2558 git-gui.sh:2719 lib/console.tcl:71
 msgid "Select All"
 msgstr "Tout sélectionner"
 
-#: git-gui.sh:1968
+#: git-gui.sh:2060
 msgid "Create..."
 msgstr "Créer..."
 
-#: git-gui.sh:1974
+#: git-gui.sh:2066
 msgid "Checkout..."
-msgstr "Emprunter... "
+msgstr "Charger (checkout)..."
 
-#: git-gui.sh:1980
+#: git-gui.sh:2072
 msgid "Rename..."
 msgstr "Renommer..."
 
-#: git-gui.sh:1985 git-gui.sh:2085
+#: git-gui.sh:2077 git-gui.sh:2187
 msgid "Delete..."
 msgstr "Supprimer..."
 
-#: git-gui.sh:1990
+#: git-gui.sh:2082
 msgid "Reset..."
 msgstr "Réinitialiser..."
 
-#: git-gui.sh:2002 git-gui.sh:2389
+#: git-gui.sh:2094 git-gui.sh:2491
 msgid "New Commit"
 msgstr "Nouveau commit"
 
-#: git-gui.sh:2010 git-gui.sh:2396
+#: git-gui.sh:2102 git-gui.sh:2498
 msgid "Amend Last Commit"
 msgstr "Corriger dernier commit"
 
-#: git-gui.sh:2019 git-gui.sh:2356 lib/remote_branch_delete.tcl:99
+#: git-gui.sh:2111 git-gui.sh:2458 lib/remote_branch_delete.tcl:99
 msgid "Rescan"
-msgstr "Resynchroniser"
+msgstr "Recharger modifs."
 
-#: git-gui.sh:2025
+#: git-gui.sh:2117
 msgid "Stage To Commit"
-msgstr "Commiter un pré-commit"
+msgstr "Indexer"
 
-#: git-gui.sh:2031
+#: git-gui.sh:2123
 msgid "Stage Changed Files To Commit"
-msgstr "Commiter fichiers modifiés dans pré-commit"
+msgstr "Indexer toutes modifications"
 
-#: git-gui.sh:2037
+#: git-gui.sh:2129
 msgid "Unstage From Commit"
-msgstr "Commit vers pré-commit"
+msgstr "Désindexer"
 
-#: git-gui.sh:2042 lib/index.tcl:395
+#: git-gui.sh:2134 lib/index.tcl:395
 msgid "Revert Changes"
-msgstr "Inverser modification"
+msgstr "Annuler les modifications (revert)"
 
-#: git-gui.sh:2049 git-gui.sh:2368 git-gui.sh:2467
+#: git-gui.sh:2141 git-gui.sh:2702
+msgid "Show Less Context"
+msgstr "Montrer moins de contexte"
+
+#: git-gui.sh:2145 git-gui.sh:2706
+msgid "Show More Context"
+msgstr "Montrer plus de contexte"
+
+#: git-gui.sh:2151 git-gui.sh:2470 git-gui.sh:2569
 msgid "Sign Off"
-msgstr "Se désinscrire"
+msgstr "Signer"
 
-#: git-gui.sh:2053 git-gui.sh:2372
+#: git-gui.sh:2155 git-gui.sh:2474
 msgid "Commit@@verb"
 msgstr "Commiter"
 
-#: git-gui.sh:2064
+#: git-gui.sh:2166
 msgid "Local Merge..."
 msgstr "Fusion locale..."
 
-#: git-gui.sh:2069
+#: git-gui.sh:2171
 msgid "Abort Merge..."
 msgstr "Abandonner fusion..."
 
-#: git-gui.sh:2081
+#: git-gui.sh:2183
 msgid "Push..."
 msgstr "Pousser..."
 
-#: git-gui.sh:2092 lib/choose_repository.tcl:41
-msgid "Apple"
-msgstr "Pomme"
-
-#: git-gui.sh:2095 git-gui.sh:2117 lib/about.tcl:14
+#: git-gui.sh:2197 git-gui.sh:2219 lib/about.tcl:14
 #: lib/choose_repository.tcl:44 lib/choose_repository.tcl:50
 #, tcl-format
 msgid "About %s"
-msgstr "A propos de %s"
+msgstr "À propos de %s"
 
-#: git-gui.sh:2099
+#: git-gui.sh:2201
 msgid "Preferences..."
 msgstr "Préférences..."
 
-#: git-gui.sh:2107 git-gui.sh:2639
+#: git-gui.sh:2209 git-gui.sh:2740
 msgid "Options..."
 msgstr "Options..."
 
-#: git-gui.sh:2113 lib/choose_repository.tcl:47
+#: git-gui.sh:2215 lib/choose_repository.tcl:47
 msgid "Help"
 msgstr "Aide"
 
-#: git-gui.sh:2154
+#: git-gui.sh:2256
 msgid "Online Documentation"
 msgstr "Documentation en ligne"
 
-#: git-gui.sh:2238
+#: git-gui.sh:2340
 #, tcl-format
 msgid "fatal: cannot stat path %s: No such file or directory"
-msgstr "erreur fatale : pas d'infos sur le chemin %s : Fichier ou répertoire inexistant"
+msgstr ""
+"erreur fatale : pas d'infos sur le chemin %s : Fichier ou répertoire "
+"inexistant"
 
-#: git-gui.sh:2271
+#: git-gui.sh:2373
 msgid "Current Branch:"
 msgstr "Branche courante :"
 
-#: git-gui.sh:2292
+#: git-gui.sh:2394
 msgid "Staged Changes (Will Commit)"
-msgstr "Modifications pré-commitées"
+msgstr "Modifs. indexées (pour commit)"
 
-#: git-gui.sh:2312
+#: git-gui.sh:2414
 msgid "Unstaged Changes"
-msgstr "Modifications non pré-commitées"
+msgstr "Modifs. non indexées"
 
-#: git-gui.sh:2362
+#: git-gui.sh:2464
 msgid "Stage Changed"
-msgstr "Pré-commit modifié"
+msgstr "Indexer modifs."
 
-#: git-gui.sh:2378 lib/transport.tcl:93 lib/transport.tcl:182
+#: git-gui.sh:2480 lib/transport.tcl:93 lib/transport.tcl:182
 msgid "Push"
 msgstr "Pousser"
 
-#: git-gui.sh:2408
+#: git-gui.sh:2510
 msgid "Initial Commit Message:"
 msgstr "Message de commit initial :"
 
-#: git-gui.sh:2409
+#: git-gui.sh:2511
 msgid "Amended Commit Message:"
 msgstr "Message de commit corrigé :"
 
-#: git-gui.sh:2410
+#: git-gui.sh:2512
 msgid "Amended Initial Commit Message:"
 msgstr "Message de commit initial corrigé :"
 
-#: git-gui.sh:2411
+#: git-gui.sh:2513
 msgid "Amended Merge Commit Message:"
 msgstr "Message de commit de fusion corrigé :"
 
-#: git-gui.sh:2412
+#: git-gui.sh:2514
 msgid "Merge Commit Message:"
 msgstr "Message de commit de fusion :"
 
-#: git-gui.sh:2413
+#: git-gui.sh:2515
 msgid "Commit Message:"
 msgstr "Message de commit :"
 
-#: git-gui.sh:2459 git-gui.sh:2622 lib/console.tcl:73
+#: git-gui.sh:2561 git-gui.sh:2723 lib/console.tcl:73
 msgid "Copy All"
 msgstr "Copier tout"
 
-#: git-gui.sh:2483 lib/blame.tcl:107
+#: git-gui.sh:2585 lib/blame.tcl:100
 msgid "File:"
 msgstr "Fichier :"
 
-#: git-gui.sh:2589
+#: git-gui.sh:2691
 msgid "Apply/Reverse Hunk"
 msgstr "Appliquer/Inverser section"
 
-#: git-gui.sh:2595
-msgid "Show Less Context"
-msgstr "Montrer moins de contexte"
-
-#: git-gui.sh:2602
-msgid "Show More Context"
-msgstr "Montrer plus de contexte"
+#: git-gui.sh:2696
+msgid "Apply/Reverse Line"
+msgstr "Appliquer/Inverser la ligne"
 
-#: git-gui.sh:2610
+#: git-gui.sh:2711
 msgid "Refresh"
 msgstr "Rafraichir"
 
-#: git-gui.sh:2631
+#: git-gui.sh:2732
 msgid "Decrease Font Size"
-msgstr "Réduire fonte"
+msgstr "Diminuer la police"
 
-#: git-gui.sh:2635
+#: git-gui.sh:2736
 msgid "Increase Font Size"
-msgstr "Agrandir fonte"
+msgstr "Agrandir la police"
 
-#: git-gui.sh:2646
+#: git-gui.sh:2747
 msgid "Unstage Hunk From Commit"
-msgstr "Enlever section pré-commitée"
+msgstr "Désindexer la section"
+
+#: git-gui.sh:2748
+msgid "Unstage Line From Commit"
+msgstr "Désindexer la ligne"
 
-#: git-gui.sh:2648
+#: git-gui.sh:2750
 msgid "Stage Hunk For Commit"
-msgstr "Pré-commiter section"
+msgstr "Indexer la section"
 
-#: git-gui.sh:2667
+#: git-gui.sh:2751
+msgid "Stage Line For Commit"
+msgstr "Indexer la ligne"
+
+#: git-gui.sh:2771
 msgid "Initializing..."
 msgstr "Initialisation..."
 
-#: git-gui.sh:2762
+#: git-gui.sh:2876
 #, tcl-format
 msgid ""
 "Possible environment issues exist.\n"
@@ -451,7 +455,7 @@ msgstr ""
 "sous-processus de Git lancés par %s\n"
 "\n"
 
-#: git-gui.sh:2792
+#: git-gui.sh:2906
 msgid ""
 "\n"
 "This is due to a known issue with the\n"
@@ -461,7 +465,7 @@ msgstr ""
 "Ceci est du à un problème connu avec\n"
 "le binaire Tcl distribué par Cygwin."
 
-#: git-gui.sh:2797
+#: git-gui.sh:2911
 #, tcl-format
 msgid ""
 "\n"
@@ -482,78 +486,94 @@ msgstr ""
 msgid "git-gui - a graphical user interface for Git."
 msgstr "git-gui - une interface graphique utilisateur pour Git"
 
-#: lib/blame.tcl:77
+#: lib/blame.tcl:70
 msgid "File Viewer"
 msgstr "Visionneur de fichier"
 
-#: lib/blame.tcl:81
+#: lib/blame.tcl:74
 msgid "Commit:"
 msgstr "Commit :"
 
-#: lib/blame.tcl:264
+#: lib/blame.tcl:257
 msgid "Copy Commit"
 msgstr "Copier commit"
 
-#: lib/blame.tcl:384
+#: lib/blame.tcl:260
+msgid "Do Full Copy Detection"
+msgstr "Lancer la détection approfondie des copies"
+
+#: lib/blame.tcl:388
 #, tcl-format
 msgid "Reading %s..."
 msgstr "Lecture de %s..."
 
-#: lib/blame.tcl:488
+#: lib/blame.tcl:492
 msgid "Loading copy/move tracking annotations..."
 msgstr "Chargement des annotations de suivi des copies/déplacements..."
 
-#: lib/blame.tcl:508
+#: lib/blame.tcl:512
 msgid "lines annotated"
 msgstr "lignes annotées"
 
-#: lib/blame.tcl:689
+#: lib/blame.tcl:704
 msgid "Loading original location annotations..."
 msgstr "Chargement des annotations d'emplacement original"
 
-#: lib/blame.tcl:692
+#: lib/blame.tcl:707
 msgid "Annotation complete."
 msgstr "Annotation terminée."
 
-#: lib/blame.tcl:746
+#: lib/blame.tcl:737
+msgid "Busy"
+msgstr "Occupé"
+
+#: lib/blame.tcl:738
+msgid "Annotation process is already running."
+msgstr "Annotation en cours d'exécution."
+
+#: lib/blame.tcl:777
+msgid "Running thorough copy detection..."
+msgstr "Recherche de copie approfondie en cours..."
+
+#: lib/blame.tcl:827
 msgid "Loading annotation..."
 msgstr "Chargement des annotations..."
 
-#: lib/blame.tcl:802
+#: lib/blame.tcl:883
 msgid "Author:"
 msgstr "Auteur :"
 
-#: lib/blame.tcl:806
+#: lib/blame.tcl:887
 msgid "Committer:"
 msgstr "Commiteur :"
 
-#: lib/blame.tcl:811
+#: lib/blame.tcl:892
 msgid "Original File:"
 msgstr "Fichier original :"
 
-#: lib/blame.tcl:925
+#: lib/blame.tcl:1006
 msgid "Originally By:"
 msgstr "A l'origine par :"
 
-#: lib/blame.tcl:931
+#: lib/blame.tcl:1012
 msgid "In File:"
 msgstr "Dans le fichier :"
 
-#: lib/blame.tcl:936
+#: lib/blame.tcl:1017
 msgid "Copied Or Moved Here By:"
 msgstr "Copié ou déplacé ici par :"
 
 #: lib/branch_checkout.tcl:14 lib/branch_checkout.tcl:19
 msgid "Checkout Branch"
-msgstr "Emprunter branche"
+msgstr "Charger la branche (checkout)"
 
 #: lib/branch_checkout.tcl:23
 msgid "Checkout"
-msgstr "Emprunter"
+msgstr "Charger (checkout)"
 
 #: lib/branch_checkout.tcl:27 lib/branch_create.tcl:35
 #: lib/branch_delete.tcl:32 lib/branch_rename.tcl:30 lib/browser.tcl:282
-#: lib/checkout_op.tcl:522 lib/choose_font.tcl:43 lib/merge.tcl:171
+#: lib/checkout_op.tcl:544 lib/choose_font.tcl:43 lib/merge.tcl:171
 #: lib/option.tcl:103 lib/remote_branch_delete.tcl:42 lib/transport.tcl:97
 msgid "Cancel"
 msgstr "Annuler"
@@ -562,17 +582,17 @@ msgstr "Annuler"
 msgid "Revision"
 msgstr "Révision"
 
-#: lib/branch_checkout.tcl:36 lib/branch_create.tcl:69 lib/option.tcl:242
+#: lib/branch_checkout.tcl:36 lib/branch_create.tcl:69 lib/option.tcl:244
 msgid "Options"
 msgstr "Options"
 
 #: lib/branch_checkout.tcl:39 lib/branch_create.tcl:92
 msgid "Fetch Tracking Branch"
-msgstr "Branche suivant récupération"
+msgstr "Récupérer la branche de suivi"
 
 #: lib/branch_checkout.tcl:44
 msgid "Detach From Local Branch"
-msgstr "Détacher de branche locale"
+msgstr "Détacher de la branche locale"
 
 #: lib/branch_create.tcl:22
 msgid "Create Branch"
@@ -600,7 +620,7 @@ msgstr "Trouver nom de branche de suivi"
 
 #: lib/branch_create.tcl:66
 msgid "Starting Revision"
-msgstr "Début de révision"
+msgstr "Révision initiale"
 
 #: lib/branch_create.tcl:72
 msgid "Update Existing Branch:"
@@ -612,28 +632,28 @@ msgstr "Non"
 
 #: lib/branch_create.tcl:80
 msgid "Fast Forward Only"
-msgstr "Avance rapide seulement"
+msgstr "Mise-à-jour rectiligne seulement (fast-forward)"
 
-#: lib/branch_create.tcl:85 lib/checkout_op.tcl:514
+#: lib/branch_create.tcl:85 lib/checkout_op.tcl:536
 msgid "Reset"
 msgstr "Réinitialiser"
 
 #: lib/branch_create.tcl:97
 msgid "Checkout After Creation"
-msgstr "Emprunt après création"
+msgstr "Charger (checkout) après création"
 
 #: lib/branch_create.tcl:131
 msgid "Please select a tracking branch."
-msgstr "Merci de choisir une branche de suivi"
+msgstr "Choisissez une branche de suivi"
 
 #: lib/branch_create.tcl:140
 #, tcl-format
 msgid "Tracking branch %s is not a branch in the remote repository."
-msgstr "La branche de suivi %s n'est pas une branche dans le référentiel distant."
+msgstr "La branche de suivi %s n'est pas une branche dans le dépôt distant."
 
 #: lib/branch_create.tcl:153 lib/branch_rename.tcl:86
 msgid "Please supply a branch name."
-msgstr "Merci de fournir un nom de branche."
+msgstr "Fournissez un nom de branche."
 
 #: lib/branch_create.tcl:164 lib/branch_rename.tcl:106
 #, tcl-format
@@ -654,7 +674,7 @@ msgstr "Branches locales"
 
 #: lib/branch_delete.tcl:52
 msgid "Delete Only If Merged Into"
-msgstr "Supprimer ssi fusion dedans"
+msgstr "Supprimer seulement si fusionnée dans:"
 
 #: lib/branch_delete.tcl:54
 msgid "Always (Do not perform merge test.)"
@@ -704,7 +724,7 @@ msgstr "Nouveau nom :"
 msgid "Please select a branch to rename."
 msgstr "Merci de sélectionner une branche à renommer."
 
-#: lib/branch_rename.tcl:96 lib/checkout_op.tcl:179
+#: lib/branch_rename.tcl:96 lib/checkout_op.tcl:201
 #, tcl-format
 msgid "Branch '%s' already exists."
 msgstr "La branche '%s' existe déjà."
@@ -712,7 +732,7 @@ msgstr "La branche '%s' existe déjà."
 #: lib/branch_rename.tcl:117
 #, tcl-format
 msgid "Failed to rename '%s'."
-msgstr "Le renommage de '%s' a échoué."
+msgstr "Échec pour renommer '%s'."
 
 #: lib/browser.tcl:17
 msgid "Starting..."
@@ -733,34 +753,39 @@ msgstr "[Jusqu'au parent]"
 
 #: lib/browser.tcl:267 lib/browser.tcl:273
 msgid "Browse Branch Files"
-msgstr "Visionner fichiers de branches"
+msgstr "Naviguer dans les fichiers de le branche"
 
 #: lib/browser.tcl:278 lib/choose_repository.tcl:387
-#: lib/choose_repository.tcl:474 lib/choose_repository.tcl:484
-#: lib/choose_repository.tcl:987
+#: lib/choose_repository.tcl:472 lib/choose_repository.tcl:482
+#: lib/choose_repository.tcl:985
 msgid "Browse"
-msgstr "Visionner"
+msgstr "Naviguer"
 
-#: lib/checkout_op.tcl:79
+#: lib/checkout_op.tcl:84
 #, tcl-format
 msgid "Fetching %s from %s"
 msgstr "Récupération de %s à partir de %s"
 
-#: lib/checkout_op.tcl:127
+#: lib/checkout_op.tcl:132
 #, tcl-format
 msgid "fatal: Cannot resolve %s"
 msgstr "erreur fatale : Impossible de résoudre %s"
 
-#: lib/checkout_op.tcl:140 lib/console.tcl:81 lib/database.tcl:31
+#: lib/checkout_op.tcl:145 lib/console.tcl:81 lib/database.tcl:31
 msgid "Close"
 msgstr "Fermer"
 
-#: lib/checkout_op.tcl:169
+#: lib/checkout_op.tcl:174
 #, tcl-format
 msgid "Branch '%s' does not exist."
 msgstr "La branche '%s' n'existe pas."
 
-#: lib/checkout_op.tcl:206
+#: lib/checkout_op.tcl:193
+#, tcl-format
+msgid "Failed to configure simplified git-pull for '%s'."
+msgstr "Échec de la configuration simplifiée de git-pull pour '%s'."
+
+#: lib/checkout_op.tcl:228
 #, tcl-format
 msgid ""
 "Branch '%s' already exists.\n"
@@ -770,24 +795,24 @@ msgid ""
 msgstr ""
 "La branche '%s' existe déjà.\n"
 "\n"
-"Impossible d'avancer rapidement à %s.\n"
+"Impossible de faire une avance rapide (fast forward) vers %s.\n"
 "Une fusion est nécessaire."
 
-#: lib/checkout_op.tcl:220
+#: lib/checkout_op.tcl:242
 #, tcl-format
 msgid "Merge strategy '%s' not supported."
 msgstr "La stratégie de fusion '%s' n'est pas supportée."
 
-#: lib/checkout_op.tcl:239
+#: lib/checkout_op.tcl:261
 #, tcl-format
 msgid "Failed to update '%s'."
 msgstr "La mise à jour de '%s' a échouée."
 
-#: lib/checkout_op.tcl:251
+#: lib/checkout_op.tcl:273
 msgid "Staging area (index) is already locked."
-msgstr "L'espace de pré-commit ('index' ou 'staging') est déjà vérouillé."
+msgstr "L'index (staging area) est déjà vérouillé"
 
-#: lib/checkout_op.tcl:266
+#: lib/checkout_op.tcl:288
 msgid ""
 "Last scanned state does not match repository state.\n"
 "\n"
@@ -796,36 +821,39 @@ msgid ""
 "\n"
 "The rescan will be automatically started now.\n"
 msgstr ""
-"L'état lors de la dernière synchronisation ne correspond plus à l'état du référentiel.\n"
+"L'état lors de la dernière synchronisation ne correspond plus à l'état du "
+"dépôt\n"
 "\n"
-"Un autre programme Git a modifié ce référentiel depuis la dernière synchronisation. Une resynchronisation doit être effectuée avant de pouvoir modifier la branche courante.\n"
+"Un autre programme Git a modifié ce dépôt depuis la dernière "
+"synchronisation. Une resynchronisation doit être effectuée avant de pouvoir "
+"modifier la branche courante.\n"
 "\n"
 "Cela va être fait tout de suite automatiquement.\n"
 
-#: lib/checkout_op.tcl:322
+#: lib/checkout_op.tcl:344
 #, tcl-format
 msgid "Updating working directory to '%s'..."
 msgstr "Mise à jour du répertoire courant avec '%s'..."
 
-#: lib/checkout_op.tcl:323
+#: lib/checkout_op.tcl:345
 msgid "files checked out"
-msgstr "fichiers empruntés"
+msgstr "fichiers chargés"
 
-#: lib/checkout_op.tcl:353
+#: lib/checkout_op.tcl:375
 #, tcl-format
 msgid "Aborted checkout of '%s' (file level merging is required)."
-msgstr "Emprunt de '%s' abandonné. (Il est nécessaire de fusionner des fichiers.)"
+msgstr "Chargement de '%s' abandonné (il est nécessaire de fusionner des fichiers)."
 
-#: lib/checkout_op.tcl:354
+#: lib/checkout_op.tcl:376
 msgid "File level merge required."
 msgstr "Il est nécessaire de fusionner des fichiers."
 
-#: lib/checkout_op.tcl:358
+#: lib/checkout_op.tcl:380
 #, tcl-format
 msgid "Staying on branch '%s'."
 msgstr "Le répertoire de travail reste sur la branche '%s'."
 
-#: lib/checkout_op.tcl:429
+#: lib/checkout_op.tcl:451
 msgid ""
 "You are no longer on a local branch.\n"
 "\n"
@@ -837,30 +865,30 @@ msgstr ""
 "Si vous vouliez être sur une branche, créez en une maintenant en partant de "
 "'Cet emprunt détaché'."
 
-#: lib/checkout_op.tcl:446 lib/checkout_op.tcl:450
+#: lib/checkout_op.tcl:468 lib/checkout_op.tcl:472
 #, tcl-format
 msgid "Checked out '%s'."
-msgstr "'%s' emprunté."
+msgstr "'%s' chargé."
 
-#: lib/checkout_op.tcl:478
+#: lib/checkout_op.tcl:500
 #, tcl-format
 msgid "Resetting '%s' to '%s' will lose the following commits:"
 msgstr "Réinitialiser '%s' à '%s' va faire perdre les commits suivants :"
 
-#: lib/checkout_op.tcl:500
+#: lib/checkout_op.tcl:522
 msgid "Recovering lost commits may not be easy."
 msgstr "Récupérer les commits perdus ne sera peut être pas facile."
 
-#: lib/checkout_op.tcl:505
+#: lib/checkout_op.tcl:527
 #, tcl-format
 msgid "Reset '%s'?"
 msgstr "Réinitialiser '%s' ?"
 
-#: lib/checkout_op.tcl:510 lib/merge.tcl:163
+#: lib/checkout_op.tcl:532 lib/merge.tcl:163
 msgid "Visualize"
 msgstr "Visualiser"
 
-#: lib/checkout_op.tcl:578
+#: lib/checkout_op.tcl:600
 #, tcl-format
 msgid ""
 "Failed to set current branch.\n"
@@ -884,15 +912,15 @@ msgstr "Sélectionner"
 
 #: lib/choose_font.tcl:53
 msgid "Font Family"
-msgstr "Famille de fonte"
+msgstr "Familles de polices"
 
 #: lib/choose_font.tcl:74
 msgid "Font Size"
-msgstr "Taille de fonte"
+msgstr "Taille de police"
 
 #: lib/choose_font.tcl:91
 msgid "Font Example"
-msgstr "Exemple de fonte"
+msgstr "Exemple de police"
 
 #: lib/choose_font.tcl:103
 msgid ""
@@ -900,7 +928,7 @@ msgid ""
 "If you like this text, it can be your font."
 msgstr ""
 "C'est un texte d'exemple.\n"
-"Si vous aimez ce texte, vous pouvez choisir cette fonte."
+"Si vous aimez ce texte, vous pouvez choisir cette police"
 
 #: lib/choose_repository.tcl:28
 msgid "Git Gui"
@@ -908,23 +936,23 @@ msgstr "Git Gui"
 
 #: lib/choose_repository.tcl:81 lib/choose_repository.tcl:376
 msgid "Create New Repository"
-msgstr "Créer nouveau référentiel"
+msgstr "Créer nouveau dépôt"
 
 #: lib/choose_repository.tcl:87
 msgid "New..."
 msgstr "Nouveau..."
 
-#: lib/choose_repository.tcl:94 lib/choose_repository.tcl:460
+#: lib/choose_repository.tcl:94 lib/choose_repository.tcl:458
 msgid "Clone Existing Repository"
-msgstr "Cloner référentiel existant"
+msgstr "Cloner dépôt existant"
 
 #: lib/choose_repository.tcl:100
 msgid "Clone..."
 msgstr "Cloner..."
 
-#: lib/choose_repository.tcl:107 lib/choose_repository.tcl:976
+#: lib/choose_repository.tcl:107 lib/choose_repository.tcl:974
 msgid "Open Existing Repository"
-msgstr "Ouvrir référentiel existant"
+msgstr "Ouvrir dépôt existant"
 
 #: lib/choose_repository.tcl:113
 msgid "Open..."
@@ -932,202 +960,202 @@ msgstr "Ouvrir..."
 
 #: lib/choose_repository.tcl:126
 msgid "Recent Repositories"
-msgstr "Référentiels récents"
+msgstr "Dépôt récemment utilisés"
 
 #: lib/choose_repository.tcl:132
 msgid "Open Recent Repository:"
-msgstr "Ouvrir référentiel récent :"
+msgstr "Ouvrir dépôt récent :"
 
 #: lib/choose_repository.tcl:296 lib/choose_repository.tcl:303
 #: lib/choose_repository.tcl:310
 #, tcl-format
 msgid "Failed to create repository %s:"
-msgstr "La création du référentiel %s a échouée :"
+msgstr "La création du dépôt %s a échouée :"
 
-#: lib/choose_repository.tcl:381 lib/choose_repository.tcl:478
+#: lib/choose_repository.tcl:381 lib/choose_repository.tcl:476
 msgid "Directory:"
 msgstr "Répertoire :"
 
-#: lib/choose_repository.tcl:412 lib/choose_repository.tcl:537
-#: lib/choose_repository.tcl:1011
+#: lib/choose_repository.tcl:410 lib/choose_repository.tcl:535
+#: lib/choose_repository.tcl:1007
 msgid "Git Repository"
-msgstr "Référentiel Git"
+msgstr "Dépôt Git"
 
-#: lib/choose_repository.tcl:437
+#: lib/choose_repository.tcl:435
 #, tcl-format
 msgid "Directory %s already exists."
 msgstr "Le répertoire %s existe déjà."
 
-#: lib/choose_repository.tcl:441
+#: lib/choose_repository.tcl:439
 #, tcl-format
 msgid "File %s already exists."
 msgstr "Le fichier %s existe déjà."
 
-#: lib/choose_repository.tcl:455
+#: lib/choose_repository.tcl:453
 msgid "Clone"
 msgstr "Cloner"
 
-#: lib/choose_repository.tcl:468
+#: lib/choose_repository.tcl:466
 msgid "URL:"
 msgstr "URL :"
 
-#: lib/choose_repository.tcl:489
+#: lib/choose_repository.tcl:487
 msgid "Clone Type:"
 msgstr "Type de clonage :"
 
-#: lib/choose_repository.tcl:495
+#: lib/choose_repository.tcl:493
 msgid "Standard (Fast, Semi-Redundant, Hardlinks)"
 msgstr "Standard (rapide, semi-redondant, liens durs)"
 
-#: lib/choose_repository.tcl:501
+#: lib/choose_repository.tcl:499
 msgid "Full Copy (Slower, Redundant Backup)"
 msgstr "Copy complète (plus lent, sauvegarde redondante)"
 
-#: lib/choose_repository.tcl:507
+#: lib/choose_repository.tcl:505
 msgid "Shared (Fastest, Not Recommended, No Backup)"
 msgstr "Partagé (le plus rapide, non recommandé, pas de sauvegarde)"
 
-#: lib/choose_repository.tcl:543 lib/choose_repository.tcl:590
-#: lib/choose_repository.tcl:736 lib/choose_repository.tcl:806
-#: lib/choose_repository.tcl:1017 lib/choose_repository.tcl:1025
+#: lib/choose_repository.tcl:541 lib/choose_repository.tcl:588
+#: lib/choose_repository.tcl:734 lib/choose_repository.tcl:804
+#: lib/choose_repository.tcl:1013 lib/choose_repository.tcl:1021
 #, tcl-format
 msgid "Not a Git repository: %s"
-msgstr "'%s' n'est pas un référentiel Git."
+msgstr "'%s' n'est pas un dépôt Git."
 
-#: lib/choose_repository.tcl:579
+#: lib/choose_repository.tcl:577
 msgid "Standard only available for local repository."
-msgstr "Standard n'est disponible que pour un référentiel local."
+msgstr "Standard n'est disponible que pour un dépôt local."
 
-#: lib/choose_repository.tcl:583
+#: lib/choose_repository.tcl:581
 msgid "Shared only available for local repository."
-msgstr "Partagé n'est disponible que pour un référentiel local."
+msgstr "Partagé n'est disponible que pour un dépôt local."
 
-#: lib/choose_repository.tcl:604
+#: lib/choose_repository.tcl:602
 #, tcl-format
 msgid "Location %s already exists."
 msgstr "L'emplacement %s existe déjà."
 
-#: lib/choose_repository.tcl:615
+#: lib/choose_repository.tcl:613
 msgid "Failed to configure origin"
 msgstr "La configuration de l'origine a échouée."
 
-#: lib/choose_repository.tcl:627
+#: lib/choose_repository.tcl:625
 msgid "Counting objects"
-msgstr "Comptage des objets"
+msgstr "Décompte des objets"
 
-#: lib/choose_repository.tcl:628
+#: lib/choose_repository.tcl:626
 msgid "buckets"
 msgstr "paniers"
 
-#: lib/choose_repository.tcl:652
+#: lib/choose_repository.tcl:650
 #, tcl-format
 msgid "Unable to copy objects/info/alternates: %s"
 msgstr "Impossible de copier 'objects/info/alternates' : %s"
 
-#: lib/choose_repository.tcl:688
+#: lib/choose_repository.tcl:686
 #, tcl-format
 msgid "Nothing to clone from %s."
 msgstr "Il n'y a rien à cloner depuis %s."
 
-#: lib/choose_repository.tcl:690 lib/choose_repository.tcl:904
-#: lib/choose_repository.tcl:916
+#: lib/choose_repository.tcl:688 lib/choose_repository.tcl:902
+#: lib/choose_repository.tcl:914
 msgid "The 'master' branch has not been initialized."
-msgstr "Cette branche 'master' n'a pas été initialisée."
+msgstr "La branche 'master' n'a pas été initialisée."
 
-#: lib/choose_repository.tcl:703
+#: lib/choose_repository.tcl:701
 msgid "Hardlinks are unavailable.  Falling back to copying."
-msgstr "Les liens durs ne sont pas disponibles. On se résoud à copier."
+msgstr "Les liens durs ne sont pas supportés. Une copie sera effectuée à la place."
 
-#: lib/choose_repository.tcl:715
+#: lib/choose_repository.tcl:713
 #, tcl-format
 msgid "Cloning from %s"
 msgstr "Clonage depuis %s"
 
-#: lib/choose_repository.tcl:746
+#: lib/choose_repository.tcl:744
 msgid "Copying objects"
 msgstr "Copie des objets"
 
-#: lib/choose_repository.tcl:747
+#: lib/choose_repository.tcl:745
 msgid "KiB"
 msgstr "KiB"
 
-#: lib/choose_repository.tcl:771
+#: lib/choose_repository.tcl:769
 #, tcl-format
 msgid "Unable to copy object: %s"
 msgstr "Impossible de copier l'objet : %s"
 
-#: lib/choose_repository.tcl:781
+#: lib/choose_repository.tcl:779
 msgid "Linking objects"
 msgstr "Liaison des objets"
 
-#: lib/choose_repository.tcl:782
+#: lib/choose_repository.tcl:780
 msgid "objects"
 msgstr "objets"
 
-#: lib/choose_repository.tcl:790
+#: lib/choose_repository.tcl:788
 #, tcl-format
 msgid "Unable to hardlink object: %s"
 msgstr "Impossible créer un lien dur pour l'objet : %s"
 
-#: lib/choose_repository.tcl:845
+#: lib/choose_repository.tcl:843
 msgid "Cannot fetch branches and objects.  See console output for details."
 msgstr ""
 "Impossible de récupérer les branches et objets. Voir la sortie console pour "
 "plus de détails."
 
-#: lib/choose_repository.tcl:856
+#: lib/choose_repository.tcl:854
 msgid "Cannot fetch tags.  See console output for details."
 msgstr ""
-"Impossible de récupérer les marques. Voir la sortie console pour plus de "
-"détails."
+"Impossible de récupérer les marques (tags). Voir la sortie console pour plus "
+"de détails."
 
-#: lib/choose_repository.tcl:880
+#: lib/choose_repository.tcl:878
 msgid "Cannot determine HEAD.  See console output for details."
 msgstr "Impossible de déterminer HEAD. Voir la sortie console pour plus de détails."
 
-#: lib/choose_repository.tcl:889
+#: lib/choose_repository.tcl:887
 #, tcl-format
 msgid "Unable to cleanup %s"
 msgstr "Impossible de nettoyer %s"
 
-#: lib/choose_repository.tcl:895
+#: lib/choose_repository.tcl:893
 msgid "Clone failed."
 msgstr "Le clonage a échoué."
 
-#: lib/choose_repository.tcl:902
+#: lib/choose_repository.tcl:900
 msgid "No default branch obtained."
 msgstr "Aucune branche par défaut n'a été obtenue."
 
-#: lib/choose_repository.tcl:913
+#: lib/choose_repository.tcl:911
 #, tcl-format
 msgid "Cannot resolve %s as a commit."
 msgstr "Impossible de résoudre %s comme commit."
 
-#: lib/choose_repository.tcl:925
+#: lib/choose_repository.tcl:923
 msgid "Creating working directory"
 msgstr "Création du répertoire de travail"
 
-#: lib/choose_repository.tcl:926 lib/index.tcl:65 lib/index.tcl:127
+#: lib/choose_repository.tcl:924 lib/index.tcl:65 lib/index.tcl:127
 #: lib/index.tcl:193
 msgid "files"
 msgstr "fichiers"
 
-#: lib/choose_repository.tcl:955
+#: lib/choose_repository.tcl:953
 msgid "Initial file checkout failed."
-msgstr "L'emprunt initial de fichier a échoué."
+msgstr "Chargement initial du fichier échoué."
 
-#: lib/choose_repository.tcl:971
+#: lib/choose_repository.tcl:969
 msgid "Open"
 msgstr "Ouvrir"
 
-#: lib/choose_repository.tcl:981
+#: lib/choose_repository.tcl:979
 msgid "Repository:"
-msgstr "Référentiel :"
+msgstr "Dépôt :"
 
-#: lib/choose_repository.tcl:1031
+#: lib/choose_repository.tcl:1027
 #, tcl-format
 msgid "Failed to open repository %s:"
-msgstr "Impossible d'ouvrir le référentiel %s :"
+msgstr "Impossible d'ouvrir le dépôt %s :"
 
 #: lib/choose_rev.tcl:53
 msgid "This Detached Checkout"
@@ -1143,11 +1171,11 @@ msgstr "Branche locale"
 
 #: lib/choose_rev.tcl:79
 msgid "Tracking Branch"
-msgstr "Suivi de branche"
+msgstr "Branche de suivi"
 
 #: lib/choose_rev.tcl:84 lib/choose_rev.tcl:538
 msgid "Tag"
-msgstr "Marque"
+msgstr "Marque (tag)"
 
 #: lib/choose_rev.tcl:317
 #, tcl-format
@@ -1164,7 +1192,7 @@ msgstr "L'expression de révision est vide."
 
 #: lib/choose_rev.tcl:531
 msgid "Updated"
-msgstr "Misa à jour"
+msgstr "Mise-à-jour:"
 
 #: lib/choose_rev.tcl:559
 msgid "URL"
@@ -1218,9 +1246,9 @@ msgid ""
 "The rescan will be automatically started now.\n"
 msgstr ""
 "L'état lors de la dernière synchronisation ne correspond plus à l'état du "
-"référentiel.\n"
+"dépôt.\n"
 "\n"
-"Un autre programme Git a modifié ce référentiel depuis la dernière "
+"Un autre programme Git a modifié ce dépôt depuis la dernière "
 "synchronisation. Une resynshronisation doit être effectuée avant de pouvoir "
 "créer un nouveau commit.\n"
 "\n"
@@ -1258,7 +1286,7 @@ msgid ""
 msgstr ""
 "Pas de modification à commiter.\n"
 "\n"
-"Vous devez pré-commiter au moins 1 fichier avant de pouvoir commiter.\n"
+"Vous devez indexer au moins 1 fichier avant de pouvoir commiter.\n"
 
 #: lib/commit.tcl:183
 msgid ""
@@ -1285,19 +1313,19 @@ msgstr "attention : Tcl ne supporte pas l'encodage '%s'."
 
 #: lib/commit.tcl:221
 msgid "Calling pre-commit hook..."
-msgstr "Appel du programme externe d'avant commit..."
+msgstr "Lancement de l'action d'avant-commit..."
 
 #: lib/commit.tcl:236
 msgid "Commit declined by pre-commit hook."
-msgstr "Commit refusé par le programme externe d'avant commit."
+msgstr "Commit refusé par l'action d'avant-commit."
 
 #: lib/commit.tcl:259
 msgid "Calling commit-msg hook..."
-msgstr "Appel du programme externe de message de commit..."
+msgstr "Lancement de l'action \"message de commit\"..."
 
 #: lib/commit.tcl:274
 msgid "Commit declined by commit-msg hook."
-msgstr "Commit refusé par le programme externe de message de commit."
+msgstr "Commit refusé par l'action \"message de commit\"."
 
 #: lib/commit.tcl:287
 msgid "Committing changes..."
@@ -1406,7 +1434,7 @@ msgid ""
 "\n"
 "Compress the database now?"
 msgstr ""
-"Ce référentiel comprend actuellement environ %i objets ayant leur fichier "
+"Ce dépôt comprend actuellement environ %i objets ayant leur fichier "
 "particulier.\n"
 "\n"
 "Pour conserver une performance optimale, il est fortement recommandé de "
@@ -1420,7 +1448,7 @@ msgstr ""
 msgid "Invalid date from Git: %s"
 msgstr "Date invalide de Git : %s"
 
-#: lib/diff.tcl:42
+#: lib/diff.tcl:44
 #, tcl-format
 msgid ""
 "No differences detected.\n"
@@ -1443,39 +1471,47 @@ msgstr ""
 "Une resynchronisation va être lancée automatiquement pour trouver d'autres "
 "fichiers qui pourraient se trouver dans le même état."
 
-#: lib/diff.tcl:81
+#: lib/diff.tcl:83
 #, tcl-format
 msgid "Loading diff of %s..."
 msgstr "Chargement des différences de %s..."
 
-#: lib/diff.tcl:114 lib/diff.tcl:184
+#: lib/diff.tcl:116 lib/diff.tcl:190
 #, tcl-format
 msgid "Unable to display %s"
 msgstr "Impossible d'afficher %s"
 
-#: lib/diff.tcl:115
+#: lib/diff.tcl:117
 msgid "Error loading file:"
 msgstr "Erreur lors du chargement du fichier :"
 
-#: lib/diff.tcl:122
+#: lib/diff.tcl:124
 msgid "Git Repository (subproject)"
-msgstr "Référentiel Git (sous projet)"
+msgstr "Dépôt Git (sous projet)"
 
-#: lib/diff.tcl:134
+#: lib/diff.tcl:136
 msgid "* Binary file (not showing content)."
 msgstr "* Fichier binaire (pas d'apperçu du contenu)."
 
-#: lib/diff.tcl:185
+#: lib/diff.tcl:191
 msgid "Error loading diff:"
 msgstr "Erreur lors du chargement des différences :"
 
-#: lib/diff.tcl:303
+#: lib/diff.tcl:313
 msgid "Failed to unstage selected hunk."
-msgstr "La suppression dans le pré-commit de la section sélectionnée a échouée."
+msgstr "Échec lors de la désindexation de la section sélectionnée."
 
-#: lib/diff.tcl:310
+#: lib/diff.tcl:320
 msgid "Failed to stage selected hunk."
-msgstr "Le pré-commit de la section sélectionnée a échoué."
+msgstr "Échec lors de l'indexation de la section."
+
+#: lib/diff.tcl:386
+msgid "Failed to unstage selected line."
+msgstr "Échec lors de la désindexation de la ligne sélectionnée."
+
+#: lib/diff.tcl:394
+msgid "Failed to stage selected line."
+msgstr "Échec lors de l'indexation de la ligne."
 
 #: lib/error.tcl:20 lib/error.tcl:114
 msgid "error"
@@ -1491,17 +1527,19 @@ msgstr "Vous devez corriger les erreurs suivantes avant de pouvoir commiter."
 
 #: lib/index.tcl:6
 msgid "Unable to unlock the index."
-msgstr "Impossible de dévérouiller le pré-commit."
+msgstr "Impossible de dévérouiller l'index."
 
 #: lib/index.tcl:15
 msgid "Index Error"
-msgstr "Erreur de pré-commit"
+msgstr "Erreur de l'index"
 
 #: lib/index.tcl:21
 msgid ""
 "Updating the Git index failed.  A rescan will be automatically started to "
 "resynchronize git-gui."
-msgstr "Le pré-commit a échoué. Une resynchronisation va être lancée automatiquement."
+msgstr ""
+"Échec de la mise à jour de l'index. Une resynchronisation va être lancée "
+"automatiquement."
 
 #: lib/index.tcl:27
 msgid "Continue"
@@ -1509,12 +1547,12 @@ msgstr "Continuer"
 
 #: lib/index.tcl:31
 msgid "Unlock Index"
-msgstr "Dévérouiller le pré-commit"
+msgstr "Déverouiller l'index"
 
 #: lib/index.tcl:282
 #, tcl-format
 msgid "Unstaging %s from commit"
-msgstr "Supprimer %s du commit"
+msgstr "Désindexation de: %s"
 
 #: lib/index.tcl:313
 msgid "Ready to commit."
@@ -1523,23 +1561,23 @@ msgstr "Prêt à être commité."
 #: lib/index.tcl:326
 #, tcl-format
 msgid "Adding %s"
-msgstr "Ajouter %s"
+msgstr "Ajout de %s"
 
 #: lib/index.tcl:381
 #, tcl-format
 msgid "Revert changes in file %s?"
-msgstr "Inverser les modifications dans le fichier %s ? "
+msgstr "Annuler les modifications dans le fichier %s ? "
 
 #: lib/index.tcl:383
 #, tcl-format
 msgid "Revert changes in these %i files?"
-msgstr "Inverser les modifications dans ces %i fichiers ?"
+msgstr "Annuler les modifications dans ces %i fichiers ?"
 
 #: lib/index.tcl:391
 msgid "Any unstaged changes will be permanently lost by the revert."
 msgstr ""
-"Toutes les modifications non pré-commitées seront définitivement perdues "
-"lors de l'inversion."
+"Toutes les modifications non-indexées seront définitivement perdues par "
+"l'annulation."
 
 #: lib/index.tcl:394
 msgid "Do Nothing"
@@ -1551,7 +1589,7 @@ msgid ""
 "\n"
 "You must finish amending this commit before starting any type of merge.\n"
 msgstr ""
-"Impossible de fucionner pendant une correction.\n"
+"Impossible de fusionner pendant une correction.\n"
 "\n"
 "Vous devez finir de corriger ce commit avant de lancer une quelconque "
 "fusion.\n"
@@ -1566,9 +1604,9 @@ msgid ""
 "The rescan will be automatically started now.\n"
 msgstr ""
 "L'état lors de la dernière synchronisation ne correspond plus à l'état du "
-"référentiel.\n"
+"dépôt.\n"
 "\n"
-"Un autre programme Git a modifié ce référentiel depuis la dernière "
+"Un autre programme Git a modifié ce dépôt depuis la dernière "
 "synchronisation. Une resynchronisation doit être effectuée avant de pouvoir "
 "fusionner de nouveau.\n"
 "\n"
@@ -1588,8 +1626,8 @@ msgstr ""
 "\n"
 "Le fichier %s a des conflicts de fusion.\n"
 "\n"
-"Vous devez les résoudre, puis pré-commiter le fichier, et enfin commiter "
-"pour terminer la fusion courante. Seulementà ce moment là, il sera possible "
+"Vous devez les résoudre, puis indexer le fichier, et enfin commiter pour "
+"terminer la fusion courante. Seulement à ce moment là sera-t-il possible "
 "d'effectuer une nouvelle fusion.\n"
 
 #: lib/merge.tcl:54
@@ -1685,11 +1723,11 @@ msgstr "Abandon"
 msgid "files reset"
 msgstr "fichiers réinitialisés"
 
-#: lib/merge.tcl:265
+#: lib/merge.tcl:266
 msgid "Abort failed."
 msgstr "L'abandon a échoué."
 
-#: lib/merge.tcl:267
+#: lib/merge.tcl:268
 msgid "Abort completed.  Ready."
 msgstr "Abandon teminé. Prêt."
 
@@ -1704,11 +1742,11 @@ msgstr "Sauvegarder"
 #: lib/option.tcl:109
 #, tcl-format
 msgid "%s Repository"
-msgstr "Référentiel de %s"
+msgstr "Dépôt: %s"
 
 #: lib/option.tcl:110
 msgid "Global (All Repositories)"
-msgstr "Globales (tous les référentiels)"
+msgstr "Globales (tous les dépôts)"
 
 #: lib/option.tcl:116
 msgid "User Name"
@@ -1736,56 +1774,76 @@ msgstr "Faire confiance aux dates de modification de fichiers "
 
 #: lib/option.tcl:124
 msgid "Prune Tracking Branches During Fetch"
-msgstr "Nettoyer les branches de suivi pendant la récupération"
+msgstr "Purger les branches de suivi pendant la récupération"
 
 #: lib/option.tcl:125
 msgid "Match Tracking Branches"
 msgstr "Faire correspondre les branches de suivi"
 
 #: lib/option.tcl:126
+msgid "Blame Copy Only On Changed Files"
+msgstr "Annoter les copies seulement sur fichiers modifiés"
+
+#: lib/option.tcl:127
+msgid "Minimum Letters To Blame Copy On"
+msgstr "Minimum de caratères pour annoter une copie"
+
+#: lib/option.tcl:128
 msgid "Number of Diff Context Lines"
 msgstr "Nombre de lignes de contexte dans les diffs"
 
-#: lib/option.tcl:127
+#: lib/option.tcl:129
 msgid "Commit Message Text Width"
 msgstr "Largeur du texte de message de commit"
 
-#: lib/option.tcl:128
+#: lib/option.tcl:130
 msgid "New Branch Name Template"
 msgstr "Nouveau modèle de nom de branche"
 
-#: lib/option.tcl:192
+#: lib/option.tcl:194
 msgid "Spelling Dictionary:"
 msgstr "Dictionnaire d'orthographe :"
 
-#: lib/option.tcl:216
+#: lib/option.tcl:218
 msgid "Change Font"
-msgstr "Modifier les fontes"
+msgstr "Modifier les polices"
 
-#: lib/option.tcl:220
+#: lib/option.tcl:222
 #, tcl-format
 msgid "Choose %s"
 msgstr "Choisir %s"
 
-#: lib/option.tcl:226
+#: lib/option.tcl:228
 msgid "pt."
 msgstr "pt."
 
-#: lib/option.tcl:240
+#: lib/option.tcl:242
 msgid "Preferences"
 msgstr "Préférences"
 
-#: lib/option.tcl:275
+#: lib/option.tcl:277
 msgid "Failed to completely save options:"
 msgstr "La sauvegarde complète des options a échouée :"
 
+#: lib/remote.tcl:165
+msgid "Prune from"
+msgstr "Purger de"
+
+#: lib/remote.tcl:170
+msgid "Fetch from"
+msgstr "Récupérer de"
+
+#: lib/remote.tcl:213
+msgid "Push to"
+msgstr "Pousser vers"
+
 #: lib/remote_branch_delete.tcl:29 lib/remote_branch_delete.tcl:34
 msgid "Delete Remote Branch"
 msgstr "Supprimer branche distante"
 
 #: lib/remote_branch_delete.tcl:47
 msgid "From Repository"
-msgstr "Référentiel"
+msgstr "Dépôt source"
 
 #: lib/remote_branch_delete.tcl:50 lib/transport.tcl:123
 msgid "Remote:"
@@ -1856,25 +1914,13 @@ msgstr "Supprimer les branches de %s"
 
 #: lib/remote_branch_delete.tcl:286
 msgid "No repository selected."
-msgstr "Aucun référentiel n'est sélectionné."
+msgstr "Aucun dépôt n'est sélectionné."
 
 #: lib/remote_branch_delete.tcl:291
 #, tcl-format
 msgid "Scanning %s..."
 msgstr "Synchronisation de %s..."
 
-#: lib/remote.tcl:165
-msgid "Prune from"
-msgstr "Nettoyer de"
-
-#: lib/remote.tcl:170
-msgid "Fetch from"
-msgstr "Récupérer de"
-
-#: lib/remote.tcl:213
-msgid "Push to"
-msgstr "Pousser vers"
-
 #: lib/shortcut.tcl:20 lib/shortcut.tcl:61
 msgid "Cannot write shortcut:"
 msgstr "Impossible d'écrire le raccourcis :"
@@ -1908,15 +1954,15 @@ msgstr "La vérification d'orthographe a échouée silentieusement au démarrage
 msgid "Unrecognized spell checker"
 msgstr "Vérificateur d'orthographe non reconnu"
 
-#: lib/spellcheck.tcl:180
+#: lib/spellcheck.tcl:186
 msgid "No Suggestions"
 msgstr "Aucune suggestion"
 
-#: lib/spellcheck.tcl:381
+#: lib/spellcheck.tcl:387
 msgid "Unexpected EOF from spell checker"
-msgstr "Fin de fichier innatendue envoyée par le vérificateur d'orthographe"
+msgstr "EOF inattendue envoyée par le vérificateur d'orthographe"
 
-#: lib/spellcheck.tcl:385
+#: lib/spellcheck.tcl:391
 msgid "Spell Checker Failed"
 msgstr "Le vérificateur d'orthographe a échoué"
 
@@ -1938,7 +1984,7 @@ msgstr "Récupération des dernières modifications de %s"
 #: lib/transport.tcl:18
 #, tcl-format
 msgid "remote prune %s"
-msgstr "nettoyer à distance %s"
+msgstr "purger à distance %s"
 
 #: lib/transport.tcl:19
 #, tcl-format
@@ -1970,11 +2016,11 @@ msgstr "Branches source"
 
 #: lib/transport.tcl:120
 msgid "Destination Repository"
-msgstr "Référentiel de destination"
+msgstr "Dépôt de destination"
 
 #: lib/transport.tcl:158
 msgid "Transfer Options"
-msgstr "Transférer options"
+msgstr "Options de transfert"
 
 #: lib/transport.tcl:160
 msgid "Force overwrite existing branch (may discard changes)"
@@ -1988,5 +2034,5 @@ msgstr "Utiliser des petits paquets (pour les connexions lentes)"
 
 #: lib/transport.tcl:168
 msgid "Include tags"
-msgstr "Inclure les marques"
+msgstr "Inclure les marques (tags)"
 
index b7c4bf3fdffb3d04b8c01b25e99a706e499de0d1..1e9f992528153fa62c167db8f8e8c184e7df86bd 100644 (file)
@@ -11,8 +11,8 @@ proc u2a {s} {
        foreach i [split $s ""] {
                scan $i %c c
                if {$c<128} {
-                       # escape '[', '\' and ']'
-                       if {$c == 0x5b || $c == 0x5d} {
+                       # escape '[', '\', '$' and ']'
+                       if {$c == 0x5b || $c == 0x5d || $c == 0x24} {
                                append res "\\"
                        }
                        append res $i
index e15c12abc31c1e4d22bb3943d70a65ddf33abb53..d799c763788ecd64b2508668f04c329b2de0c391 100755 (executable)
@@ -39,6 +39,7 @@ clear_stash () {
 create_stash () {
        stash_msg="$1"
 
+       git update-index -q --refresh
        if no_changes
        then
                exit 0
@@ -101,6 +102,7 @@ save_stash () {
 
        stash_msg="$*"
 
+       git update-index -q --refresh
        if no_changes
        then
                echo 'No local changes to save'
@@ -150,6 +152,7 @@ show_stash () {
 }
 
 apply_stash () {
+       git update-index -q --refresh &&
        git diff-files --quiet --ignore-submodules ||
                die 'Cannot restore on top of a dirty state'
 
index 087c4ac733be4b788751d0bae5b7aad22ce0dd99..2eaa2ae7d6f692f6063ebbd211eaab30212c2eae 100644 (file)
@@ -418,10 +418,12 @@ proc stop_rev_list {view} {
 }
 
 proc reset_pending_select {selid} {
-    global pending_select mainheadid
+    global pending_select mainheadid selectheadid
 
     if {$selid ne {}} {
        set pending_select $selid
+    } elseif {$selectheadid ne {}} {
+       set pending_select $selectheadid
     } else {
        set pending_select $mainheadid
     }
@@ -1609,6 +1611,7 @@ proc getcommit {id} {
 proc readrefs {} {
     global tagids idtags headids idheads tagobjid
     global otherrefids idotherrefs mainhead mainheadid
+    global selecthead selectheadid
 
     foreach v {tagids idtags headids idheads otherrefids idotherrefs} {
        catch {unset $v}
@@ -1655,6 +1658,12 @@ proc readrefs {} {
            set mainhead [string range $thehead 11 end]
        }
     }
+    set selectheadid {}
+    if {$selecthead ne {}} {
+       catch {
+           set selectheadid [exec git rev-parse --verify $selecthead]
+       }
+    }
 }
 
 # skip over fake commits
@@ -2205,6 +2214,8 @@ proc makewindow {} {
        -command {flist_hl 1}
     $flist_menu add command -label [mc "External diff"] \
         -command {external_diff}
+    $flist_menu add command -label [mc "Blame parent commit"] \
+        -command {external_blame 1}
 }
 
 # Windows sends all mouse wheel events to the current focused window, not
@@ -3012,6 +3023,27 @@ proc external_diff {} {
     }
 }
 
+proc external_blame {parent_idx} {
+    global flist_menu_file
+    global nullid nullid2
+    global parentlist selectedline currentid
+
+    if {$parent_idx > 0} {
+       set base_commit [lindex $parentlist $selectedline [expr {$parent_idx-1}]]
+    } else {
+       set base_commit $currentid
+    }
+
+    if {$base_commit eq {} || $base_commit eq $nullid || $base_commit eq $nullid2} {
+       error_popup [mc "No such commit"]
+       return
+    }
+
+    if {[catch {exec git gui blame $base_commit $flist_menu_file &} err]} {
+       error_popup [mc "git gui blame: command failed: $err"]
+    }
+}
+
 # delete $dir when we see eof on $f (presumably because the child has exited)
 proc delete_at_eof {f dir} {
     while {[gets $f line] >= 0} {}
@@ -9865,6 +9897,9 @@ if {![file isdirectory $gitdir]} {
     exit 1
 }
 
+set selecthead {}
+set selectheadid {}
+
 set revtreeargs {}
 set cmdline_files {}
 set i 0
@@ -9876,6 +9911,9 @@ foreach arg $argv {
            set cmdline_files [lrange $argv [expr {$i + 1}] end]
            break
        }
+       "--select-commit=*" {
+           set selecthead [string range $arg 16 end]
+       }
        "--argscmd=*" {
            set revtreeargscmd [string range $arg 10 end]
        }
@@ -9886,6 +9924,10 @@ foreach arg $argv {
     incr i
 }
 
+if {$selecthead eq "HEAD"} {
+    set selecthead {}
+}
+
 if {$i >= [llength $argv] && $revtreeargs ne {}} {
     # no -- on command line, but some arguments (other than --argscmd)
     if {[catch {
index 4b91f8d4c45dad075d69028c9c70aa9cb1959e2b..c1850d29239f8846c42b4552493d2d4898fa221e 100755 (executable)
@@ -488,4 +488,17 @@ test_expect_success 'cvs co -c (shows module database)' '
     ! grep -v "^master[         ]\+master$" < out
 '
 
+#------------
+# CVS ANNOTATE
+#------------
+
+cd "$WORKDIR"
+test_expect_success 'cvs annotate' '
+    cd cvswork &&
+    GIT_CONFIG="$git_config" cvs annotate merge >../out &&
+    sed -e "s/ .*//" ../out >../actual &&
+    for i in 3 1 1 1 1 1 1 1 2 4; do echo 1.$i; done >../expect &&
+    test_cmp ../expect ../actual
+'
+
 test_done