diff options
Diffstat (limited to 'git-gui/lib')
-rw-r--r-- | git-gui/lib/blame.tcl | 28 | ||||
-rw-r--r-- | git-gui/lib/branch_rename.tcl | 2 | ||||
-rw-r--r-- | git-gui/lib/browser.tcl | 2 | ||||
-rw-r--r-- | git-gui/lib/choose_repository.tcl | 25 | ||||
-rw-r--r-- | git-gui/lib/commit.tcl | 9 | ||||
-rw-r--r-- | git-gui/lib/diff.tcl | 150 | ||||
-rw-r--r-- | git-gui/lib/index.tcl | 10 | ||||
-rw-r--r-- | git-gui/lib/merge.tcl | 2 | ||||
-rw-r--r-- | git-gui/lib/mergetool.tcl | 101 | ||||
-rw-r--r-- | git-gui/lib/option.tcl | 1 | ||||
-rw-r--r-- | git-gui/lib/remote.tcl | 91 | ||||
-rw-r--r-- | git-gui/lib/remote_branch_delete.tcl | 9 | ||||
-rw-r--r-- | git-gui/lib/shortcut.tcl | 4 | ||||
-rw-r--r-- | git-gui/lib/status_bar.tcl | 1 | ||||
-rw-r--r-- | git-gui/lib/transport.tcl | 34 | ||||
-rw-r--r-- | git-gui/lib/win32.tcl | 4 |
16 files changed, 342 insertions, 131 deletions
diff --git a/git-gui/lib/blame.tcl b/git-gui/lib/blame.tcl index 786b50b8c2..61e358f960 100644 --- a/git-gui/lib/blame.tcl +++ b/git-gui/lib/blame.tcl @@ -449,11 +449,35 @@ method _load {jump} { $status show [mc "Reading %s..." "$commit:[escape_path $path]"] $w_path conf -text [escape_path $path] + + set do_textconv 0 + if {![is_config_false gui.textconv] && [git-version >= 1.7.2]} { + set filter [gitattr $path diff set] + set textconv [get_config [join [list diff $filter textconv] .]] + if {$filter ne {set} && $textconv ne {}} { + set do_textconv 1 + } + } if {$commit eq {}} { - set fd [open $path r] + if {$do_textconv ne 0} { + # Run textconv with sh -c "..." to allow it to + # contain command + arguments. On windows, just + # call the filter command. + if {![file executable [shellpath]]} { + set fd [open |[linsert $textconv end $path] r] + } else { + set fd [open |[list [shellpath] -c "$textconv \"\$0\"" $path] r] + } + } else { + set fd [open $path r] + } fconfigure $fd -eofchar {} } else { - set fd [git_read cat-file blob "$commit:$path"] + if {$do_textconv ne 0} { + set fd [git_read cat-file --textconv "$commit:$path"] + } else { + set fd [git_read cat-file blob "$commit:$path"] + } } fconfigure $fd \ -blocking 0 \ diff --git a/git-gui/lib/branch_rename.tcl b/git-gui/lib/branch_rename.tcl index 63988773ba..6e510ec2e3 100644 --- a/git-gui/lib/branch_rename.tcl +++ b/git-gui/lib/branch_rename.tcl @@ -53,7 +53,7 @@ constructor dialog {} { return 1 } - grid $w.rename.oldname_l $w.rename.oldname_m -sticky w -padx {0 5} + grid $w.rename.oldname_l $w.rename.oldname_m -sticky we -padx {0 5} grid $w.rename.newname_l $w.rename.newname_t -sticky we -padx {0 5} grid columnconfigure $w.rename 1 -weight 1 pack $w.rename -anchor nw -fill x -pady 5 -padx 5 diff --git a/git-gui/lib/browser.tcl b/git-gui/lib/browser.tcl index c2415729e0..a8c6223511 100644 --- a/git-gui/lib/browser.tcl +++ b/git-gui/lib/browser.tcl @@ -121,7 +121,7 @@ method _parent {} { if {$browser_stack eq {}} { regsub {:.*$} $browser_path {:} browser_path } else { - regsub {/[^/]+$} $browser_path {} browser_path + regsub {/[^/]+/$} $browser_path {/} browser_path } set browser_status [mc "Loading %s..." $browser_path] _ls $this [lindex $parent 0] [lindex $parent 1] diff --git a/git-gui/lib/choose_repository.tcl b/git-gui/lib/choose_repository.tcl index 64f06748b6..657f7d5dc1 100644 --- a/git-gui/lib/choose_repository.tcl +++ b/git-gui/lib/choose_repository.tcl @@ -100,12 +100,17 @@ constructor pick {} { $opts insert end [mc "Clone Existing Repository"] link_clone $opts insert end "\n" if {$m_repo ne {}} { + if {[tk windowingsystem] eq "win32"} { + set key L + } else { + set key C + } $m_repo add command \ -command [cb _next clone] \ - -accelerator $M1T-C \ + -accelerator $M1T-$key \ -label [mc "Clone..."] - bind $top <$M1B-c> [cb _next clone] - bind $top <$M1B-C> [cb _next clone] + bind $top <$M1B-[string tolower $key]> [cb _next clone] + bind $top <$M1B-[string toupper $key]> [cb _next clone] } $opts tag conf link_open -foreground blue -underline 1 @@ -209,14 +214,6 @@ constructor pick {} { } } -proc _home {} { - if {[catch {set h $::env(HOME)}] - || ![file isdirectory $h]} { - set h . - } - return $h -} - method _center {} { set nx [winfo reqwidth $top] set ny [winfo reqheight $top] @@ -415,7 +412,7 @@ method _new_local_path {} { if {$local_path ne {}} { set p [file dirname $local_path] } else { - set p [_home] + set p [pwd] } set p [tk_chooseDirectory \ @@ -536,7 +533,7 @@ method _open_origin {} { if {$origin_url ne {} && [file isdirectory $origin_url]} { set p $origin_url } else { - set p [_home] + set p [pwd] } set p [tk_chooseDirectory \ @@ -1037,7 +1034,7 @@ method _open_local_path {} { if {$local_path ne {}} { set p $local_path } else { - set p [_home] + set p [pwd] } set p [tk_chooseDirectory \ diff --git a/git-gui/lib/commit.tcl b/git-gui/lib/commit.tcl index 7f459cd564..5ce46877bf 100644 --- a/git-gui/lib/commit.tcl +++ b/git-gui/lib/commit.tcl @@ -161,11 +161,12 @@ The rescan will be automatically started now. # set files_ready 0 foreach path [array names file_states] { - switch -glob -- [lindex $file_states($path) 0] { + set s $file_states($path) + switch -glob -- [lindex $s 0] { _? {continue} A? - D? - - T_ - + T? - M? {set files_ready 1} _U - U? { @@ -452,7 +453,11 @@ A rescan will be automatically started now. } AM - AD - + AT - + TM - + TD - MM - + MT - MD { set file_states($path) [list \ _[string index $m 1] \ diff --git a/git-gui/lib/diff.tcl b/git-gui/lib/diff.tcl index ec8c11eeb7..cf8a95ec34 100644 --- a/git-gui/lib/diff.tcl +++ b/git-gui/lib/diff.tcl @@ -55,7 +55,7 @@ proc handle_empty_diff {} { set path $current_diff_path set s $file_states($path) - if {[lindex $s 0] ne {_M}} return + if {[lindex $s 0] ne {_M} || [has_textconv $path]} return # Prevent infinite rescan loops incr diff_empty_count @@ -122,22 +122,22 @@ proc show_unmerged_diff {cont_info} { if {$merge_stages(2) eq {}} { set is_conflict_diff 1 lappend current_diff_queue \ - [list [mc "LOCAL: deleted\nREMOTE:\n"] d======= \ + [list [mc "LOCAL: deleted\nREMOTE:\n"] d= \ [list ":1:$current_diff_path" ":3:$current_diff_path"]] } elseif {$merge_stages(3) eq {}} { set is_conflict_diff 1 lappend current_diff_queue \ - [list [mc "REMOTE: deleted\nLOCAL:\n"] d======= \ + [list [mc "REMOTE: deleted\nLOCAL:\n"] d= \ [list ":1:$current_diff_path" ":2:$current_diff_path"]] } elseif {[lindex $merge_stages(1) 0] eq {120000} || [lindex $merge_stages(2) 0] eq {120000} || [lindex $merge_stages(3) 0] eq {120000}} { set is_conflict_diff 1 lappend current_diff_queue \ - [list [mc "LOCAL:\n"] d======= \ + [list [mc "LOCAL:\n"] d= \ [list ":1:$current_diff_path" ":2:$current_diff_path"]] lappend current_diff_queue \ - [list [mc "REMOTE:\n"] d======= \ + [list [mc "REMOTE:\n"] d= \ [list ":1:$current_diff_path" ":3:$current_diff_path"]] } else { start_show_diff $cont_info @@ -208,32 +208,32 @@ proc show_other_diff {path w m cont_info} { $ui_diff insert end [append \ "* " \ [mc "Git Repository (subproject)"] \ - "\n"] d_@ + "\n"] d_info } elseif {![catch {set type [exec file $path]}]} { set n [string length $path] if {[string equal -length $n $path $type]} { set type [string range $type $n end] regsub {^:?\s*} $type {} type } - $ui_diff insert end "* $type\n" d_@ + $ui_diff insert end "* $type\n" d_info } if {[string first "\0" $content] != -1} { $ui_diff insert end \ [mc "* Binary file (not showing content)."] \ - d_@ + d_info } else { if {$sz > $max_sz} { $ui_diff insert end [mc \ "* Untracked file is %d bytes. * Showing only first %d bytes. -" $sz $max_sz] d_@ +" $sz $max_sz] d_info } $ui_diff insert end $content if {$sz > $max_sz} { $ui_diff insert end [mc " * Untracked file clipped here by %s. * To see the entire file, use an external editor. -" [appname]] d_@ +" [appname]] d_info } } $ui_diff conf -state disabled @@ -253,6 +253,19 @@ proc show_other_diff {path w m cont_info} { } } +proc get_conflict_marker_size {path} { + set size 7 + catch { + set fd_rc [eval [list git_read check-attr "conflict-marker-size" -- $path]] + set ret [gets $fd_rc line] + close $fd_rc + if {$ret > 0} { + regexp {.*: conflict-marker-size: (\d+)$} $line line size + } + } + return $size +} + proc start_show_diff {cont_info {add_opts {}}} { global file_states file_lists global is_3way_diff is_submodule_diff diff_active repo_config @@ -268,6 +281,7 @@ proc start_show_diff {cont_info {add_opts {}}} { set is_submodule_diff 0 set diff_active 1 set current_diff_header {} + set conflict_size [get_conflict_marker_size $path] set cmd [list] if {$w eq $ui_index} { @@ -280,6 +294,9 @@ proc start_show_diff {cont_info {add_opts {}}} { lappend cmd diff-files } } + if {![is_config_false gui.textconv] && [git-version >= 1.6.1]} { + lappend cmd --textconv + } if {[string match {160000 *} [lindex $s 2]] || [string match {160000 *} [lindex $s 3]]} { @@ -291,7 +308,7 @@ proc start_show_diff {cont_info {add_opts {}}} { } lappend cmd -p - lappend cmd --no-color + lappend cmd --color if {$repo_config(gui.diffcontext) >= 1} { lappend cmd "-U$repo_config(gui.diffcontext)" } @@ -326,10 +343,35 @@ proc start_show_diff {cont_info {add_opts {}}} { -blocking 0 \ -encoding [get_path_encoding $path] \ -translation lf - fileevent $fd readable [list read_diff $fd $cont_info] + fileevent $fd readable [list read_diff $fd $conflict_size $cont_info] } -proc read_diff {fd cont_info} { +proc parse_color_line {line} { + set start 0 + set result "" + set markup [list] + set regexp {\033\[((?:\d+;)*\d+)?m} + set need_reset 0 + while {[regexp -indices -start $start $regexp $line match code]} { + foreach {begin end} $match break + append result [string range $line $start [expr {$begin - 1}]] + set pos [string length $result] + set col [eval [linsert $code 0 string range $line]] + set start [incr end] + if {$col eq "0" || $col eq ""} { + if {!$need_reset} continue + set need_reset 0 + } else { + set need_reset 1 + } + lappend markup $pos $col + } + append result [string range $line $start end] + if {[llength $markup] < 4} {set markup {}} + return [list $result $markup] +} + +proc read_diff {fd conflict_size cont_info} { global ui_diff diff_active is_submodule_diff global is_3way_diff is_conflict_diff current_diff_header global current_diff_queue @@ -337,37 +379,53 @@ proc read_diff {fd cont_info} { $ui_diff conf -state normal while {[gets $fd line] >= 0} { - # -- Cleanup uninteresting diff header lines. + foreach {line markup} [parse_color_line $line] break + set line [string map {\033 ^} $line] + + set tags {} + + # -- Check for start of diff header. + if { [string match {diff --git *} $line] + || [string match {diff --cc *} $line] + || [string match {diff --combined *} $line]} { + set ::current_diff_inheader 1 + } + + # -- Check for end of diff header (any hunk line will do this). + # + if {[regexp {^@@+ } $line]} {set ::current_diff_inheader 0} + + # -- Automatically detect if this is a 3 way diff. # + if {[string match {@@@ *} $line]} {set is_3way_diff 1} + if {$::current_diff_inheader} { + + # -- These two lines stop a diff header and shouldn't be in there + if { [string match {Binary files * and * differ} $line] + || [regexp {^\* Unmerged path } $line]} { + set ::current_diff_inheader 0 + } else { + append current_diff_header $line "\n" + } + + # -- 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" + || [string match {+++ *} $line] + || [string match {index *} $line]} { 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. - # - if {[string match {@@@ *} $line]} {set is_3way_diff 1} + # -- Name it symlink, not 120000 + # Note, that the original line is in $current_diff_header + regsub {^(deleted|new) file mode 120000} $line {\1 symlink} line - if {[string match {mode *} $line] - || [string match {new file *} $line] - || [regexp {^(old|new) mode *} $line] - || [string match {deleted file *} $line] - || [string match {deleted symlink} $line] - || [string match {Binary files * and * differ} $line] - || $line eq {\ No newline at end of file} - || [regexp {^\* Unmerged path } $line]} { - set tags {} + } elseif { $line eq {\ No newline at end of file}} { + # -- Handle some special lines } elseif {$is_3way_diff} { set op [string range $line 0 1] switch -- $op { @@ -379,7 +437,9 @@ proc read_diff {fd cont_info} { {- } {set tags d_-s} {--} {set tags d_--} {++} { - if {[regexp {^\+\+([<>]{7} |={7})} $line _g op]} { + set regexp [string map [list %conflict_size $conflict_size]\ + {^\+\+([<>=]){%conflict_size}(?: |$)}] + if {[regexp $regexp $line _g op]} { set is_conflict_diff 1 set line [string replace $line 0 1 { }] set tags d$op @@ -395,10 +455,10 @@ proc read_diff {fd cont_info} { } elseif {$is_submodule_diff} { if {$line == ""} continue if {[regexp {^Submodule } $line]} { - set tags d_@ + set tags d_info } elseif {[regexp {^\* } $line]} { set line [string replace $line 0 1 {Submodule }] - set tags d_@ + set tags d_info } else { set op [string range $line 0 2] switch -- $op { @@ -418,7 +478,9 @@ proc read_diff {fd cont_info} { {@} {set tags d_@} {-} {set tags d_-} {+} { - if {[regexp {^\+([<>]{7} |={7})} $line _g op]} { + set regexp [string map [list %conflict_size $conflict_size]\ + {^\+([<>=]){%conflict_size}(?: |$)}] + if {[regexp $regexp $line _g op]} { set is_conflict_diff 1 set tags d$op } else { @@ -431,11 +493,23 @@ proc read_diff {fd cont_info} { } } } + set mark [$ui_diff index "end - 1 line linestart"] $ui_diff insert end $line $tags if {[string index $line end] eq "\r"} { $ui_diff tag add d_cr {end - 2c} } $ui_diff insert end "\n" $tags + + foreach {posbegin colbegin posend colend} $markup { + set prefix clr + foreach style [split $colbegin ";"] { + if {$style eq "7"} {append prefix i; continue} + if {$style < 30 || $style > 47} {continue} + set a "$mark linestart + $posbegin chars" + set b "$mark linestart + $posend chars" + catch {$ui_diff tag add $prefix$style $a $b} + } + } } $ui_diff conf -state disabled diff --git a/git-gui/lib/index.tcl b/git-gui/lib/index.tcl index e9db0c4989..5d7bbf23ed 100644 --- a/git-gui/lib/index.tcl +++ b/git-gui/lib/index.tcl @@ -103,8 +103,11 @@ proc write_update_indexinfo {fd pathList totalCnt batch after} { set s $file_states($path) switch -glob -- [lindex $s 0] { A? {set new _O} - M? {set new _M} + MT - + TM - T_ {set new _T} + M? {set new _M} + TD - D_ {set new _D} D? {set new _?} ?? {continue} @@ -167,7 +170,10 @@ proc write_update_index {fd pathList totalCnt batch after} { AD {set new __} ?D {set new D_} _O - + AT - AM {set new A_} + TM - + MT - _T {set new T_} _U - U? { @@ -261,7 +267,7 @@ proc unstage_helper {txt paths} { switch -glob -- [lindex $file_states($path) 0] { A? - M? - - T_ - + T? - D? { lappend pathList $path if {$path eq $current_diff_path} { diff --git a/git-gui/lib/merge.tcl b/git-gui/lib/merge.tcl index 5cded2341c..460d32fa22 100644 --- a/git-gui/lib/merge.tcl +++ b/git-gui/lib/merge.tcl @@ -83,6 +83,7 @@ method _visualize {} { method _start {} { global HEAD current_branch remote_url + global _last_merged_branch set name [_rev $this] if {$name eq {}} { @@ -109,6 +110,7 @@ method _start {} { regsub ^refs/heads/ $branch {} branch puts $fh "$cmit\t\tbranch '$branch' of $remote" close $fh + set _last_merged_branch $branch set cmd [list git] lappend cmd merge diff --git a/git-gui/lib/mergetool.tcl b/git-gui/lib/mergetool.tcl index 3fe90e6970..3c8e73bceb 100644 --- a/git-gui/lib/mergetool.tcl +++ b/git-gui/lib/mergetool.tcl @@ -175,43 +175,56 @@ proc merge_resolve_tool2 {} { # Build the command line switch -- $tool { - kdiff3 { + araxis { 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"] + 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" --auto --L1 "$MERGED (Local)" \ - --L2 "$MERGED (Remote)" -o "$MERGED" "$LOCAL" "$REMOTE"] + set cmdline [list "$merge_tool_path" -wait -2 \ + -title1:"'$MERGED (Local)'" -title2:"'$MERGED (Remote)'" \ + "$LOCAL" "$REMOTE" "$MERGED"] } } - tkdiff { + bc3 { if {$base_stage ne {}} { - set cmdline [list "$merge_tool_path" -a "$BASE" -o "$MERGED" "$LOCAL" "$REMOTE"] + set cmdline [list "$merge_tool_path" "$LOCAL" "$REMOTE" "$BASE" -mergeoutput="$MERGED"] } else { - set cmdline [list "$merge_tool_path" -o "$MERGED" "$LOCAL" "$REMOTE"] + set cmdline [list "$merge_tool_path" "$LOCAL" "$REMOTE" -mergeoutput="$MERGED"] } } - meld { - set cmdline [list "$merge_tool_path" "$LOCAL" "$MERGED" "$REMOTE"] + 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"] + } } gvimdiff { set cmdline [list "$merge_tool_path" -f "$LOCAL" "$MERGED" "$REMOTE"] } - xxdiff { + kdiff3 { 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"] + 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" -X --show-merged-pane \ - -R {Accel.SaveAsMerged: "Ctrl-S"} \ - -R {Accel.Search: "Ctrl+F"} \ - -R {Accel.SearchForward: "Ctrl-G"} \ - --merged-file "$MERGED" "$LOCAL" "$REMOTE"] + set cmdline [list "$merge_tool_path" --auto --L1 "$MERGED (Local)" \ + --L2 "$MERGED (Remote)" -o "$MERGED" "$LOCAL" "$REMOTE"] } } + meld { + set cmdline [list "$merge_tool_path" "$LOCAL" "$MERGED" "$REMOTE"] + } opendiff { if {$base_stage ne {}} { set cmdline [list "$merge_tool_path" "$LOCAL" "$REMOTE" -ancestor "$BASE" -merge "$MERGED"] @@ -219,22 +232,20 @@ proc merge_resolve_tool2 {} { 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"] - } + p4merge { + set cmdline [list "$merge_tool_path" "$BASE" "$REMOTE" "$LOCAL" "$MERGED"] } - emerge { + tkdiff { if {$base_stage ne {}} { - set cmdline [list "$merge_tool_path" -f emerge-files-with-ancestor-command \ - "$LOCAL" "$REMOTE" "$BASE" "$basename"] + set cmdline [list "$merge_tool_path" -a "$BASE" -o "$MERGED" "$LOCAL" "$REMOTE"] } else { - set cmdline [list "$merge_tool_path" -f emerge-files-command \ - "$LOCAL" "$REMOTE" "$basename"] + set cmdline [list "$merge_tool_path" -o "$MERGED" "$LOCAL" "$REMOTE"] } } + vimdiff { + error_popup [mc "Not a GUI merge tool: '%s'" $tool] + return + } winmerge { if {$base_stage ne {}} { # This tool does not support 3-way merges. @@ -245,25 +256,21 @@ proc merge_resolve_tool2 {} { -dl "Theirs File" -dr "Mine File" "$REMOTE" "$LOCAL" "$MERGED"] } } - araxis { + xxdiff { 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"] + 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" -wait -2 \ - -title1:"'$MERGED (Local)'" -title2:"'$MERGED (Remote)'" \ - "$LOCAL" "$REMOTE" "$MERGED"] + 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"] } } - 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 diff --git a/git-gui/lib/option.tcl b/git-gui/lib/option.tcl index d4c5e45c8a..3807c8d283 100644 --- a/git-gui/lib/option.tcl +++ b/git-gui/lib/option.tcl @@ -148,6 +148,7 @@ proc do_options {} { {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.textconv {mc "Use Textconv For Diffs and Blames"}} {b gui.fastcopyblame {mc "Blame Copy Only On Changed Files"}} {i-20..200 gui.copyblamethreshold {mc "Minimum Letters To Blame Copy On"}} {i-0..300 gui.blamehistoryctx {mc "Blame History Context Radius (days)"}} diff --git a/git-gui/lib/remote.tcl b/git-gui/lib/remote.tcl index b92b429cf7..5e4e7f4c83 100644 --- a/git-gui/lib/remote.tcl +++ b/git-gui/lib/remote.tcl @@ -157,22 +157,7 @@ proc add_fetch_entry {r} { } if {$enable} { - if {![winfo exists $fetch_m]} { - menu $remove_m - $remote_m insert 0 cascade \ - -label [mc "Remove Remote"] \ - -menu $remove_m - - menu $prune_m - $remote_m insert 0 cascade \ - -label [mc "Prune from"] \ - -menu $prune_m - - menu $fetch_m - $remote_m insert 0 cascade \ - -label [mc "Fetch from"] \ - -menu $fetch_m - } + make_sure_remote_submenues_exist $remote_m $fetch_m add command \ -label $r \ @@ -222,6 +207,70 @@ proc add_push_entry {r} { } } +proc make_sure_remote_submenues_exist {remote_m} { + set fetch_m $remote_m.fetch + set prune_m $remote_m.prune + set remove_m $remote_m.remove + + if {![winfo exists $fetch_m]} { + menu $remove_m + $remote_m insert 0 cascade \ + -label [mc "Remove Remote"] \ + -menu $remove_m + + menu $prune_m + $remote_m insert 0 cascade \ + -label [mc "Prune from"] \ + -menu $prune_m + + menu $fetch_m + $remote_m insert 0 cascade \ + -label [mc "Fetch from"] \ + -menu $fetch_m + } +} + +proc update_all_remotes_menu_entry {} { + global all_remotes + + if {[git-version < 1.6.6]} { return } + + set have_remote 0 + foreach r $all_remotes { + incr have_remote + } + + set remote_m .mbar.remote + set fetch_m $remote_m.fetch + set prune_m $remote_m.prune + if {$have_remote > 1} { + make_sure_remote_submenues_exist $remote_m + if {[$fetch_m entrycget end -label] ne "All"} { + + $fetch_m insert end separator + $fetch_m insert end command \ + -label "All" \ + -command fetch_from_all + + $prune_m insert end separator + $prune_m insert end command \ + -label "All" \ + -command prune_from_all + } + } else { + if {[winfo exists $fetch_m]} { + if {[$fetch_m entrycget end -label] eq "All"} { + + delete_from_menu $fetch_m end + delete_from_menu $fetch_m end + + delete_from_menu $prune_m end + delete_from_menu $prune_m end + } + } + } +} + proc populate_remotes_menu {} { global all_remotes @@ -229,6 +278,8 @@ proc populate_remotes_menu {} { add_fetch_entry $r add_push_entry $r } + + update_all_remotes_menu_entry } proc add_single_remote {name location} { @@ -244,6 +295,8 @@ proc add_single_remote {name location} { add_fetch_entry $name add_push_entry $name + + update_all_remotes_menu_entry } proc delete_from_menu {menu name} { @@ -264,8 +317,8 @@ proc remove_remote {name} { unset repo_config(remote.$name.push) } - set i [lsearch -exact all_remotes $name] - lreplace all_remotes $i $i + set i [lsearch -exact $all_remotes $name] + set all_remotes [lreplace $all_remotes $i $i] set remote_m .mbar.remote delete_from_menu $remote_m.fetch $name @@ -273,4 +326,6 @@ proc remove_remote {name} { delete_from_menu $remote_m.remove $name # Not all remotes are in the push menu catch { delete_from_menu $remote_m.push $name } + + update_all_remotes_menu_entry } diff --git a/git-gui/lib/remote_branch_delete.tcl b/git-gui/lib/remote_branch_delete.tcl index f872a3d89d..fcc06d03a1 100644 --- a/git-gui/lib/remote_branch_delete.tcl +++ b/git-gui/lib/remote_branch_delete.tcl @@ -251,7 +251,7 @@ method _write_url {args} { set urltype url } method _write_check_head {args} { set checktype head } method _write_head_list {args} { - global current_branch + global current_branch _last_merged_branch $head_m delete 0 end foreach abr $head_list { @@ -267,6 +267,13 @@ method _write_head_list {args} { set check_head $current_branch } } + set lmb [lsearch -exact -sorted $head_list $_last_merged_branch] + if {$lmb >= 0} { + $w.heads.l conf -state normal + $w.heads.l select set $lmb + $w.heads.l yview $lmb + $w.heads.l conf -state disabled + } } method _write_urltype {args} { diff --git a/git-gui/lib/shortcut.tcl b/git-gui/lib/shortcut.tcl index 79c1888e11..78878ef89d 100644 --- a/git-gui/lib/shortcut.tcl +++ b/git-gui/lib/shortcut.tcl @@ -16,7 +16,7 @@ proc do_windows_shortcut {} { [info nameofexecutable] \ [file normalize $::argv0] \ ] \ - [file normalize [$_gitworktree]] + [file normalize $_gitworktree] } err]} { error_popup [strcat [mc "Cannot write shortcut:"] "\n\n$err"] } @@ -57,7 +57,7 @@ proc do_cygwin_shortcut {} { $sh -c \ "CHERE_INVOKING=1 source /etc/profile;[sq $me] &" \ ] \ - [file normalize [$_gitworktree]] + [file normalize $_gitworktree] } err]} { error_popup [strcat [mc "Cannot write shortcut:"] "\n\n$err"] } diff --git a/git-gui/lib/status_bar.tcl b/git-gui/lib/status_bar.tcl index 5fe3aad382..95cb44991f 100644 --- a/git-gui/lib/status_bar.tcl +++ b/git-gui/lib/status_bar.tcl @@ -39,6 +39,7 @@ method _oneline_pack {} { } constructor two_line {path} { + global NS set w $path set w_l $w.l set w_c $w.c diff --git a/git-gui/lib/transport.tcl b/git-gui/lib/transport.tcl index 60e3a642c5..7fad9b7d91 100644 --- a/git-gui/lib/transport.tcl +++ b/git-gui/lib/transport.tcl @@ -20,6 +20,35 @@ proc prune_from {remote} { console::exec $w [list git remote prune $remote] } +proc fetch_from_all {} { + set w [console::new \ + [mc "fetch all remotes"] \ + [mc "Fetching new changes from all remotes"]] + + set cmd [list git fetch --all] + if {[is_config_true gui.pruneduringfetch]} { + lappend cmd --prune + } + + console::exec $w $cmd +} + +proc prune_from_all {} { + global all_remotes + + set w [console::new \ + [mc "remote prune all remotes"] \ + [mc "Pruning tracking branches deleted from all remotes"]] + + set cmd [list git remote prune] + + foreach r $all_remotes { + lappend cmd $r + } + + console::exec $w $cmd +} + proc push_to {remote} { set w [console::new \ [mc "push %s" $remote] \ @@ -123,6 +152,7 @@ proc do_push_anywhere {} { $w.source.l insert end $h if {$h eq $current_branch} { $w.source.l select set end + $w.source.l yview end } } pack $w.source.l -side left -fill both -expand 1 @@ -135,7 +165,9 @@ proc do_push_anywhere {} { -value remote \ -variable push_urltype if {$use_ttk} { - ttk::combobox $w.dest.remote_m -textvariable push_remote \ + ttk::combobox $w.dest.remote_m -state readonly \ + -exportselection false \ + -textvariable push_remote \ -values $all_remotes } else { eval tk_optionMenu $w.dest.remote_m push_remote $all_remotes diff --git a/git-gui/lib/win32.tcl b/git-gui/lib/win32.tcl index d7f93d045d..db91ab84a5 100644 --- a/git-gui/lib/win32.tcl +++ b/git-gui/lib/win32.tcl @@ -18,9 +18,9 @@ proc win32_create_lnk {lnk_path lnk_exec lnk_dir} { eval [list exec wscript.exe \ /E:jscript \ /nologo \ - [file join $oguilib win32_shortcut.js] \ + [file nativename [file join $oguilib win32_shortcut.js]] \ $lnk_path \ - [file join $oguilib git-gui.ico] \ + [file nativename [file join $oguilib git-gui.ico]] \ $lnk_dir \ $lnk_exec] $lnk_args } |