Merge branch 'master' of git://repo.or.cz/git-gui
* 'master' of git://repo.or.cz/git-gui: (50 commits) git-gui: Minor refactoring of merge command line in merge support git-gui: Use more modern looking icons in the tree browser git-gui: Don't offer to stage hunks from untracked files git-gui: Make sure remotes are loaded when picking revisions git-gui: Use progress bar while resetting/aborting files git-gui: Honor core.excludesfile when listing extra files git-gui: Unify wording to say "to stage" instead of "to add" git-gui: Don't kill modified commit message buffer with merge templates git-gui: Remove usernames from absolute SSH urls during merging git-gui: Format tracking branch merges as though they were pulls git-gui: Cleanup bindings within merge dialog git-gui: Replace merge dialog with our revision picker widget git-gui: Show ref last update times in revision chooser tooltips git-gui: Display commit/tag/remote info in tooltip of revision picker git-gui: Save remote urls obtained from config/remotes setup git-gui: Avoid unnecessary symbolic-ref call during checkout git-gui: Refactor current branch menu items to make i18n easier git-gui: Refactor diff popup into a procedure to ease i18n work git-gui: Paper bag fix quitting crash after commit git-gui: Clarify meaning of add tracked menu option ...
This commit is contained in:
commit
b8de7f764e
@ -154,12 +154,10 @@ proc gitexec {args} {
|
||||
}
|
||||
|
||||
proc reponame {} {
|
||||
global _reponame
|
||||
return $_reponame
|
||||
return $::_reponame
|
||||
}
|
||||
|
||||
proc is_MacOSX {} {
|
||||
global tcl_platform tk_library
|
||||
if {[tk windowingsystem] eq {aqua}} {
|
||||
return 1
|
||||
}
|
||||
@ -167,17 +165,16 @@ proc is_MacOSX {} {
|
||||
}
|
||||
|
||||
proc is_Windows {} {
|
||||
global tcl_platform
|
||||
if {$tcl_platform(platform) eq {windows}} {
|
||||
if {$::tcl_platform(platform) eq {windows}} {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
proc is_Cygwin {} {
|
||||
global tcl_platform _iscygwin
|
||||
global _iscygwin
|
||||
if {$_iscygwin eq {}} {
|
||||
if {$tcl_platform(platform) eq {windows}} {
|
||||
if {$::tcl_platform(platform) eq {windows}} {
|
||||
if {[catch {set p [exec cygpath --windir]} err]} {
|
||||
set _iscygwin 0
|
||||
} else {
|
||||
@ -367,16 +364,25 @@ proc _which {what} {
|
||||
return {}
|
||||
}
|
||||
|
||||
proc _lappend_nice {cmd_var} {
|
||||
global _nice
|
||||
upvar $cmd_var cmd
|
||||
|
||||
if {![info exists _nice]} {
|
||||
set _nice [_which nice]
|
||||
}
|
||||
if {$_nice ne {}} {
|
||||
lappend cmd $_nice
|
||||
}
|
||||
}
|
||||
|
||||
proc git {args} {
|
||||
set opt [list exec]
|
||||
|
||||
while {1} {
|
||||
switch -- [lindex $args 0] {
|
||||
--nice {
|
||||
global _nice
|
||||
if {$_nice ne {}} {
|
||||
lappend opt $_nice
|
||||
}
|
||||
_lappend_nice opt
|
||||
}
|
||||
|
||||
default {
|
||||
@ -414,6 +420,7 @@ proc _open_stdout_stderr {cmd} {
|
||||
error $err
|
||||
}
|
||||
}
|
||||
fconfigure $fd -eofchar {}
|
||||
return $fd
|
||||
}
|
||||
|
||||
@ -423,10 +430,7 @@ proc git_read {args} {
|
||||
while {1} {
|
||||
switch -- [lindex $args 0] {
|
||||
--nice {
|
||||
global _nice
|
||||
if {$_nice ne {}} {
|
||||
lappend opt $_nice
|
||||
}
|
||||
_lappend_nice opt
|
||||
}
|
||||
|
||||
--stderr {
|
||||
@ -454,10 +458,7 @@ proc git_write {args} {
|
||||
while {1} {
|
||||
switch -- [lindex $args 0] {
|
||||
--nice {
|
||||
global _nice
|
||||
if {$_nice ne {}} {
|
||||
lappend opt $_nice
|
||||
}
|
||||
_lappend_nice opt
|
||||
}
|
||||
|
||||
default {
|
||||
@ -524,7 +525,6 @@ if {$_git eq {}} {
|
||||
error_popup "Cannot find git in PATH."
|
||||
exit 1
|
||||
}
|
||||
set _nice [_which nice]
|
||||
|
||||
######################################################################
|
||||
##
|
||||
@ -544,8 +544,34 @@ if {![regsub {^git version } $_git_version {} _git_version]} {
|
||||
error_popup "Cannot parse Git version string:\n\n$_git_version"
|
||||
exit 1
|
||||
}
|
||||
|
||||
set _real_git_version $_git_version
|
||||
regsub -- {-dirty$} $_git_version {} _git_version
|
||||
regsub {\.[0-9]+\.g[0-9a-f]+$} $_git_version {} _git_version
|
||||
regsub {\.rc[0-9]+$} $_git_version {} _git_version
|
||||
regsub {\.GIT$} $_git_version {} _git_version
|
||||
|
||||
if {![regexp {^[1-9]+(\.[0-9]+)+$} $_git_version]} {
|
||||
catch {wm withdraw .}
|
||||
if {[tk_messageBox \
|
||||
-icon warning \
|
||||
-type yesno \
|
||||
-default no \
|
||||
-title "[appname]: warning" \
|
||||
-message "Git version cannot be determined.
|
||||
|
||||
$_git claims it is version '$_real_git_version'.
|
||||
|
||||
[appname] requires at least Git 1.5.0 or later.
|
||||
|
||||
Assume '$_real_git_version' is version 1.5.0?
|
||||
"] eq {yes}} {
|
||||
set _git_version 1.5.0
|
||||
} else {
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
unset _real_git_version
|
||||
|
||||
proc git-version {args} {
|
||||
global _git_version
|
||||
@ -601,6 +627,46 @@ You are using [git-version]:
|
||||
exit 1
|
||||
}
|
||||
|
||||
######################################################################
|
||||
##
|
||||
## feature option selection
|
||||
|
||||
if {[regexp {^git-(.+)$} [appname] _junk subcommand]} {
|
||||
unset _junk
|
||||
} else {
|
||||
set subcommand gui
|
||||
}
|
||||
if {$subcommand eq {gui.sh}} {
|
||||
set subcommand gui
|
||||
}
|
||||
if {$subcommand eq {gui} && [llength $argv] > 0} {
|
||||
set subcommand [lindex $argv 0]
|
||||
set argv [lrange $argv 1 end]
|
||||
}
|
||||
|
||||
enable_option multicommit
|
||||
enable_option branch
|
||||
enable_option transport
|
||||
disable_option bare
|
||||
|
||||
switch -- $subcommand {
|
||||
browser -
|
||||
blame {
|
||||
enable_option bare
|
||||
|
||||
disable_option multicommit
|
||||
disable_option branch
|
||||
disable_option transport
|
||||
}
|
||||
citool {
|
||||
enable_option singlecommit
|
||||
|
||||
disable_option multicommit
|
||||
disable_option branch
|
||||
disable_option transport
|
||||
}
|
||||
}
|
||||
|
||||
######################################################################
|
||||
##
|
||||
## repository setup
|
||||
@ -625,19 +691,24 @@ if {![file isdirectory $_gitdir]} {
|
||||
error_popup "Git directory not found:\n\n$_gitdir"
|
||||
exit 1
|
||||
}
|
||||
if {[lindex [file split $_gitdir] end] ne {.git}} {
|
||||
if {![is_enabled bare]} {
|
||||
if {[lindex [file split $_gitdir] end] ne {.git}} {
|
||||
catch {wm withdraw .}
|
||||
error_popup "Cannot use funny .git directory:\n\n$_gitdir"
|
||||
exit 1
|
||||
}
|
||||
if {[catch {cd [file dirname $_gitdir]} err]} {
|
||||
}
|
||||
if {[catch {cd [file dirname $_gitdir]} err]} {
|
||||
catch {wm withdraw .}
|
||||
error_popup "No working directory [file dirname $_gitdir]:\n\n$err"
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
set _reponame [file split [file normalize $_gitdir]]
|
||||
if {[lindex $_reponame end] eq {.git}} {
|
||||
set _reponame [lindex $_reponame end-1]
|
||||
} else {
|
||||
set _reponame [lindex $_reponame end]
|
||||
}
|
||||
set _reponame [lindex [file split \
|
||||
[file normalize [file dirname $_gitdir]]] \
|
||||
end]
|
||||
|
||||
######################################################################
|
||||
##
|
||||
@ -758,8 +829,9 @@ proc rescan {after {honor_trustmtime 1}} {
|
||||
|
||||
array unset file_states
|
||||
|
||||
if {![$ui_comm edit modified]
|
||||
|| [string trim [$ui_comm get 0.0 end]] eq {}} {
|
||||
if {!$::GITGUI_BCK_exists &&
|
||||
(![$ui_comm edit modified]
|
||||
|| [string trim [$ui_comm get 0.0 end]] eq {})} {
|
||||
if {[string match amend* $commit_type]} {
|
||||
} elseif {[load_message GITGUI_MSG]} {
|
||||
} elseif {[load_message MERGE_MSG]} {
|
||||
@ -800,6 +872,10 @@ proc rescan_stage2 {fd after} {
|
||||
if {[file readable $info_exclude]} {
|
||||
lappend ls_others "--exclude-from=$info_exclude"
|
||||
}
|
||||
set user_exclude [get_config core.excludesfile]
|
||||
if {$user_exclude ne {} && [file readable $user_exclude]} {
|
||||
lappend ls_others "--exclude-from=$user_exclude"
|
||||
}
|
||||
|
||||
set buf_rdi {}
|
||||
set buf_rdf {}
|
||||
@ -827,6 +903,7 @@ proc load_message {file} {
|
||||
if {[catch {set fd [open $f r]}]} {
|
||||
return 0
|
||||
}
|
||||
fconfigure $fd -eofchar {}
|
||||
set content [string trim [read $fd]]
|
||||
close $fd
|
||||
regsub -all -line {[ \r\t]+$} $content {} content
|
||||
@ -1219,32 +1296,6 @@ static unsigned char file_merge_bits[] = {
|
||||
0xfa, 0x17, 0x02, 0x10, 0xfe, 0x1f};
|
||||
} -maskdata $filemask
|
||||
|
||||
set file_dir_data {
|
||||
#define file_width 18
|
||||
#define file_height 18
|
||||
static unsigned char file_bits[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x03, 0x00,
|
||||
0x0c, 0x03, 0x00, 0x04, 0xfe, 0x00, 0x06, 0x80, 0x00, 0xff, 0x9f, 0x00,
|
||||
0x03, 0x98, 0x00, 0x02, 0x90, 0x00, 0x06, 0xb0, 0x00, 0x04, 0xa0, 0x00,
|
||||
0x0c, 0xe0, 0x00, 0x08, 0xc0, 0x00, 0xf8, 0xff, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
}
|
||||
image create bitmap file_dir -background white -foreground blue \
|
||||
-data $file_dir_data -maskdata $file_dir_data
|
||||
unset file_dir_data
|
||||
|
||||
set file_uplevel_data {
|
||||
#define up_width 15
|
||||
#define up_height 15
|
||||
static unsigned char up_bits[] = {
|
||||
0x80, 0x00, 0xc0, 0x01, 0xe0, 0x03, 0xf0, 0x07, 0xf8, 0x0f, 0xfc, 0x1f,
|
||||
0xfe, 0x3f, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01,
|
||||
0xc0, 0x01, 0xc0, 0x01, 0x00, 0x00};
|
||||
}
|
||||
image create bitmap file_uplevel -background white -foreground red \
|
||||
-data $file_uplevel_data -maskdata $file_uplevel_data
|
||||
unset file_uplevel_data
|
||||
|
||||
set ui_index .vpane.files.index.list
|
||||
set ui_workdir .vpane.files.workdir.list
|
||||
|
||||
@ -1345,6 +1396,7 @@ set is_quitting 0
|
||||
|
||||
proc do_quit {} {
|
||||
global ui_comm is_quitting repo_config commit_type
|
||||
global GITGUI_BCK_exists GITGUI_BCK_i
|
||||
|
||||
if {$is_quitting} return
|
||||
set is_quitting 1
|
||||
@ -1353,6 +1405,10 @@ proc do_quit {} {
|
||||
# -- Stash our current commit buffer.
|
||||
#
|
||||
set save [gitdir GITGUI_MSG]
|
||||
if {$GITGUI_BCK_exists && ![$ui_comm edit modified]} {
|
||||
file rename -force [gitdir GITGUI_BCK] $save
|
||||
set GITGUI_BCK_exists 0
|
||||
} else {
|
||||
set msg [string trim [$ui_comm get 0.0 end]]
|
||||
regsub -all -line {[ \r\t]+$} $msg {} msg
|
||||
if {(![string match amend* $commit_type]
|
||||
@ -1366,6 +1422,14 @@ proc do_quit {} {
|
||||
} else {
|
||||
catch {file delete $save}
|
||||
}
|
||||
}
|
||||
|
||||
# -- Remove our editor backup, its not needed.
|
||||
#
|
||||
after cancel $GITGUI_BCK_i
|
||||
if {$GITGUI_BCK_exists} {
|
||||
catch {file delete [gitdir GITGUI_BCK]}
|
||||
}
|
||||
|
||||
# -- Stash our current window geometry into this repository.
|
||||
#
|
||||
@ -1566,43 +1630,6 @@ set font_descs {
|
||||
load_config 0
|
||||
apply_config
|
||||
|
||||
######################################################################
|
||||
##
|
||||
## feature option selection
|
||||
|
||||
if {[regexp {^git-(.+)$} [appname] _junk subcommand]} {
|
||||
unset _junk
|
||||
} else {
|
||||
set subcommand gui
|
||||
}
|
||||
if {$subcommand eq {gui.sh}} {
|
||||
set subcommand gui
|
||||
}
|
||||
if {$subcommand eq {gui} && [llength $argv] > 0} {
|
||||
set subcommand [lindex $argv 0]
|
||||
set argv [lrange $argv 1 end]
|
||||
}
|
||||
|
||||
enable_option multicommit
|
||||
enable_option branch
|
||||
enable_option transport
|
||||
|
||||
switch -- $subcommand {
|
||||
browser -
|
||||
blame {
|
||||
disable_option multicommit
|
||||
disable_option branch
|
||||
disable_option transport
|
||||
}
|
||||
citool {
|
||||
enable_option singlecommit
|
||||
|
||||
disable_option multicommit
|
||||
disable_option branch
|
||||
disable_option transport
|
||||
}
|
||||
}
|
||||
|
||||
######################################################################
|
||||
##
|
||||
## ui construction
|
||||
@ -1632,20 +1659,32 @@ if {[is_enabled transport]} {
|
||||
menu .mbar.repository
|
||||
|
||||
.mbar.repository add command \
|
||||
-label {Browse Current Branch} \
|
||||
-label {Browse Current Branch's Files} \
|
||||
-command {browser::new $current_branch}
|
||||
trace add variable current_branch write ".mbar.repository entryconf [.mbar.repository index last] -label \"Browse \$current_branch\" ;#"
|
||||
set ui_browse_current [.mbar.repository index last]
|
||||
.mbar.repository add command \
|
||||
-label {Browse Branch Files...} \
|
||||
-command browser_open::dialog
|
||||
.mbar.repository add separator
|
||||
|
||||
.mbar.repository add command \
|
||||
-label {Visualize Current Branch} \
|
||||
-label {Visualize Current Branch's History} \
|
||||
-command {do_gitk $current_branch}
|
||||
trace add variable current_branch write ".mbar.repository entryconf [.mbar.repository index last] -label \"Visualize \$current_branch\" ;#"
|
||||
set ui_visualize_current [.mbar.repository index last]
|
||||
.mbar.repository add command \
|
||||
-label {Visualize All Branches} \
|
||||
-label {Visualize All Branch History} \
|
||||
-command {do_gitk --all}
|
||||
.mbar.repository add separator
|
||||
|
||||
proc current_branch_write {args} {
|
||||
global current_branch
|
||||
.mbar.repository entryconf $::ui_browse_current \
|
||||
-label "Browse $current_branch's Files"
|
||||
.mbar.repository entryconf $::ui_visualize_current \
|
||||
-label "Visualize $current_branch's History"
|
||||
}
|
||||
trace add variable current_branch write current_branch_write
|
||||
|
||||
if {[is_enabled multicommit]} {
|
||||
.mbar.repository add command -label {Database Statistics} \
|
||||
-command do_stats
|
||||
@ -1766,12 +1805,12 @@ if {[is_enabled multicommit] || [is_enabled singlecommit]} {
|
||||
lappend disable_on_lock \
|
||||
[list .mbar.commit entryconf [.mbar.commit index last] -state]
|
||||
|
||||
.mbar.commit add command -label {Add To Commit} \
|
||||
.mbar.commit add command -label {Stage To Commit} \
|
||||
-command do_add_selection
|
||||
lappend disable_on_lock \
|
||||
[list .mbar.commit entryconf [.mbar.commit index last] -state]
|
||||
|
||||
.mbar.commit add command -label {Add Existing To Commit} \
|
||||
.mbar.commit add command -label {Stage Changed Files To Commit} \
|
||||
-command do_add_all \
|
||||
-accelerator $M1T-I
|
||||
lappend disable_on_lock \
|
||||
@ -1805,14 +1844,14 @@ if {[is_enabled multicommit] || [is_enabled singlecommit]} {
|
||||
if {[is_enabled branch]} {
|
||||
menu .mbar.merge
|
||||
.mbar.merge add command -label {Local Merge...} \
|
||||
-command merge::dialog
|
||||
-command merge::dialog \
|
||||
-accelerator $M1T-M
|
||||
lappend disable_on_lock \
|
||||
[list .mbar.merge entryconf [.mbar.merge index last] -state]
|
||||
.mbar.merge add command -label {Abort Merge...} \
|
||||
-command merge::reset_hard
|
||||
lappend disable_on_lock \
|
||||
[list .mbar.merge entryconf [.mbar.merge index last] -state]
|
||||
|
||||
}
|
||||
|
||||
# -- Transport Menu
|
||||
@ -1844,33 +1883,6 @@ if {[is_MacOSX]} {
|
||||
.mbar.edit add separator
|
||||
.mbar.edit add command -label {Options...} \
|
||||
-command do_options
|
||||
|
||||
# -- Tools Menu
|
||||
#
|
||||
if {[is_Cygwin] && [file exists /usr/local/miga/lib/gui-miga]} {
|
||||
proc do_miga {} {
|
||||
if {![lock_index update]} return
|
||||
set cmd [list sh --login -c "/usr/local/miga/lib/gui-miga \"[pwd]\""]
|
||||
set miga_fd [open "|$cmd" r]
|
||||
fconfigure $miga_fd -blocking 0
|
||||
fileevent $miga_fd readable [list miga_done $miga_fd]
|
||||
ui_status {Running miga...}
|
||||
}
|
||||
proc miga_done {fd} {
|
||||
read $fd 512
|
||||
if {[eof $fd]} {
|
||||
close $fd
|
||||
unlock_index
|
||||
rescan ui_ready
|
||||
}
|
||||
}
|
||||
.mbar add cascade -label Tools -menu .mbar.tools
|
||||
menu .mbar.tools
|
||||
.mbar.tools add command -label "Migrate" \
|
||||
-command do_miga
|
||||
lappend disable_on_lock \
|
||||
[list .mbar.tools entryconf [.mbar.tools index last] -state]
|
||||
}
|
||||
}
|
||||
|
||||
# -- Help Menu
|
||||
@ -1938,29 +1950,10 @@ proc usage {} {
|
||||
# -- Not a normal commit type invocation? Do that instead!
|
||||
#
|
||||
switch -- $subcommand {
|
||||
browser {
|
||||
set subcommand_args {rev?}
|
||||
switch [llength $argv] {
|
||||
0 { load_current_branch }
|
||||
1 {
|
||||
set current_branch [lindex $argv 0]
|
||||
if {[regexp {^[0-9a-f]{1,39}$} $current_branch]} {
|
||||
if {[catch {
|
||||
set current_branch \
|
||||
[git rev-parse --verify $current_branch]
|
||||
} err]} {
|
||||
puts stderr $err
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
}
|
||||
default usage
|
||||
}
|
||||
browser::new $current_branch
|
||||
return
|
||||
}
|
||||
browser -
|
||||
blame {
|
||||
set subcommand_args {rev? path?}
|
||||
set subcommand_args {rev? path}
|
||||
if {$argv eq {}} usage
|
||||
set head {}
|
||||
set path {}
|
||||
set is_path 0
|
||||
@ -1979,12 +1972,18 @@ blame {
|
||||
} elseif {$head eq {}} {
|
||||
if {$head ne {}} usage
|
||||
set head $a
|
||||
set is_path 1
|
||||
} else {
|
||||
usage
|
||||
}
|
||||
}
|
||||
unset is_path
|
||||
|
||||
if {$head ne {} && $path eq {}} {
|
||||
set path $_prefix$head
|
||||
set head {}
|
||||
}
|
||||
|
||||
if {$head eq {}} {
|
||||
load_current_branch
|
||||
} else {
|
||||
@ -1999,8 +1998,26 @@ blame {
|
||||
set current_branch $head
|
||||
}
|
||||
|
||||
if {$path eq {}} usage
|
||||
switch -- $subcommand {
|
||||
browser {
|
||||
if {$head eq {}} {
|
||||
if {$path ne {} && [file isdirectory $path]} {
|
||||
set head $current_branch
|
||||
} else {
|
||||
set head $path
|
||||
set path {}
|
||||
}
|
||||
}
|
||||
browser::new $head $path
|
||||
}
|
||||
blame {
|
||||
if {$head eq {} && ![file exists $path]} {
|
||||
puts stderr "fatal: cannot stat path $path: No such file or directory"
|
||||
exit 1
|
||||
}
|
||||
blame::new $head $path
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
citool -
|
||||
@ -2115,7 +2132,7 @@ pack .vpane.lower.commarea.buttons.rescan -side top -fill x
|
||||
lappend disable_on_lock \
|
||||
{.vpane.lower.commarea.buttons.rescan conf -state}
|
||||
|
||||
button .vpane.lower.commarea.buttons.incall -text {Add Existing} \
|
||||
button .vpane.lower.commarea.buttons.incall -text {Stage Changed} \
|
||||
-command do_add_all
|
||||
pack .vpane.lower.commarea.buttons.incall -side top -fill x
|
||||
lappend disable_on_lock \
|
||||
@ -2389,17 +2406,25 @@ lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
|
||||
$ctxm add separator
|
||||
$ctxm add command -label {Options...} \
|
||||
-command do_options
|
||||
bind_button3 $ui_diff "
|
||||
set cursorX %x
|
||||
set cursorY %y
|
||||
if {\$ui_index eq \$current_diff_side} {
|
||||
$ctxm entryconf $ui_diff_applyhunk -label {Unstage Hunk From Commit}
|
||||
proc popup_diff_menu {ctxm x y X Y} {
|
||||
set ::cursorX $x
|
||||
set ::cursorY $y
|
||||
if {$::ui_index eq $::current_diff_side} {
|
||||
$ctxm entryconf $::ui_diff_applyhunk \
|
||||
-state normal \
|
||||
-label {Unstage Hunk From Commit}
|
||||
} elseif {{_O} eq [lindex $::file_states($::current_diff_path) 0]} {
|
||||
$ctxm entryconf $::ui_diff_applyhunk \
|
||||
-state disabled \
|
||||
-label {Stage Hunk For Commit}
|
||||
} else {
|
||||
$ctxm entryconf $ui_diff_applyhunk -label {Stage Hunk For Commit}
|
||||
$ctxm entryconf $::ui_diff_applyhunk \
|
||||
-state normal \
|
||||
-label {Stage Hunk For Commit}
|
||||
}
|
||||
tk_popup $ctxm %X %Y
|
||||
"
|
||||
unset ui_diff_applyhunk
|
||||
tk_popup $ctxm $X $Y
|
||||
}
|
||||
bind_button3 $ui_diff [list popup_diff_menu $ctxm %x %y %X %Y]
|
||||
|
||||
# -- Status Bar
|
||||
#
|
||||
@ -2460,6 +2485,8 @@ if {[is_enabled branch]} {
|
||||
bind . <$M1B-Key-N> branch_create::dialog
|
||||
bind . <$M1B-Key-o> branch_checkout::dialog
|
||||
bind . <$M1B-Key-O> branch_checkout::dialog
|
||||
bind . <$M1B-Key-m> merge::dialog
|
||||
bind . <$M1B-Key-M> merge::dialog
|
||||
}
|
||||
if {[is_enabled transport]} {
|
||||
bind . <$M1B-Key-p> do_push_anywhere
|
||||
@ -2551,24 +2578,64 @@ if {[is_enabled transport]} {
|
||||
populate_push_menu
|
||||
}
|
||||
|
||||
# -- Only suggest a gc run if we are going to stay running.
|
||||
#
|
||||
if {[is_enabled multicommit]} {
|
||||
set object_limit 2000
|
||||
if {[is_Windows]} {set object_limit 200}
|
||||
regexp {^([0-9]+) objects,} [git count-objects] _junk objects_current
|
||||
if {$objects_current >= $object_limit} {
|
||||
if {[ask_popup \
|
||||
"This repository currently has $objects_current loose objects.
|
||||
if {[winfo exists $ui_comm]} {
|
||||
set GITGUI_BCK_exists [load_message GITGUI_BCK]
|
||||
|
||||
To maintain optimal performance it is strongly recommended that you compress the database when more than $object_limit loose objects exist.
|
||||
|
||||
Compress the database now?"] eq yes} {
|
||||
do_gc
|
||||
# -- If both our backup and message files exist use the
|
||||
# newer of the two files to initialize the buffer.
|
||||
#
|
||||
if {$GITGUI_BCK_exists} {
|
||||
set m [gitdir GITGUI_MSG]
|
||||
if {[file isfile $m]} {
|
||||
if {[file mtime [gitdir GITGUI_BCK]] > [file mtime $m]} {
|
||||
catch {file delete [gitdir GITGUI_MSG]}
|
||||
} else {
|
||||
$ui_comm delete 0.0 end
|
||||
$ui_comm edit reset
|
||||
$ui_comm edit modified false
|
||||
catch {file delete [gitdir GITGUI_BCK]}
|
||||
set GITGUI_BCK_exists 0
|
||||
}
|
||||
}
|
||||
unset object_limit _junk objects_current
|
||||
unset m
|
||||
}
|
||||
|
||||
proc backup_commit_buffer {} {
|
||||
global ui_comm GITGUI_BCK_exists
|
||||
|
||||
set m [$ui_comm edit modified]
|
||||
if {$m || $GITGUI_BCK_exists} {
|
||||
set msg [string trim [$ui_comm get 0.0 end]]
|
||||
regsub -all -line {[ \r\t]+$} $msg {} msg
|
||||
|
||||
if {$msg eq {}} {
|
||||
if {$GITGUI_BCK_exists} {
|
||||
catch {file delete [gitdir GITGUI_BCK]}
|
||||
set GITGUI_BCK_exists 0
|
||||
}
|
||||
} elseif {$m} {
|
||||
catch {
|
||||
set fd [open [gitdir GITGUI_BCK] w]
|
||||
puts -nonewline $fd $msg
|
||||
close $fd
|
||||
set GITGUI_BCK_exists 1
|
||||
}
|
||||
}
|
||||
|
||||
$ui_comm edit modified false
|
||||
}
|
||||
|
||||
set ::GITGUI_BCK_i [after 2000 backup_commit_buffer]
|
||||
}
|
||||
|
||||
backup_commit_buffer
|
||||
}
|
||||
|
||||
lock_index begin-read
|
||||
if {![winfo ismapped .]} {
|
||||
wm deiconify .
|
||||
}
|
||||
after 1 do_rescan
|
||||
if {[is_enabled multicommit]} {
|
||||
after 1000 hint_gc
|
||||
}
|
||||
|
@ -370,6 +370,7 @@ method _load {jump} {
|
||||
$w_path conf -text [escape_path $path]
|
||||
if {$commit eq {}} {
|
||||
set fd [open $path r]
|
||||
fconfigure $fd -eofchar {}
|
||||
} else {
|
||||
set fd [git_read cat-file blob "$commit:$path"]
|
||||
}
|
||||
@ -770,15 +771,20 @@ method _showcommit {cur_w lno} {
|
||||
set enc [string tolower [string range $line 9 end]]
|
||||
}
|
||||
}
|
||||
set msg [encoding convertfrom $enc [read $fd]]
|
||||
set msg [string trim $msg]
|
||||
set msg [read $fd]
|
||||
close $fd
|
||||
|
||||
set enc [tcl_encoding $enc]
|
||||
if {$enc ne {}} {
|
||||
set msg [encoding convertfrom $enc $msg]
|
||||
set author_name [encoding convertfrom $enc $author_name]
|
||||
set committer_name [encoding convertfrom $enc $committer_name]
|
||||
|
||||
set header($cmit,author) $author_name
|
||||
set header($cmit,committer) $committer_name
|
||||
set header($cmit,summary) \
|
||||
[encoding convertfrom $enc $header($cmit,summary)]
|
||||
}
|
||||
set msg [string trim $msg]
|
||||
}
|
||||
set header($cmit,message) $msg
|
||||
}
|
||||
@ -873,6 +879,11 @@ method _open_tooltip {cur_w} {
|
||||
set org [lindex $amov_data $lno]
|
||||
}
|
||||
|
||||
if {$dat eq {}} {
|
||||
_hide_tooltip $this
|
||||
return
|
||||
}
|
||||
|
||||
set cmit [lindex $dat 0]
|
||||
set tooltip_commit [list $cmit]
|
||||
|
||||
|
@ -3,6 +3,13 @@
|
||||
|
||||
class browser {
|
||||
|
||||
image create photo ::browser::img_parent -data {R0lGODlhEAAQAIUAAPwCBBxSHBxOHMTSzNzu3KzCtBRGHCSKFIzCjLzSxBQ2FAxGHDzCLCyeHBQ+FHSmfAwuFBxKLDSCNMzizISyjJzOnDSyLAw+FAQSDAQeDBxWJAwmDAQOBKzWrDymNAQaDAQODAwaDDyKTFSyXFTGTEy6TAQCBAQKDAwiFBQyHAwSFAwmHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAZ1QIBwSCwaj0hiQCBICpcDQsFgGAaIguhhi0gohIsrQEDYMhiNrRfgeAQC5fMCAolIDhD2hFI5WC4YRBkaBxsOE2l/RxsHHA4dHmkfRyAbIQ4iIyQlB5NFGCAACiakpSZEJyinTgAcKSesACorgU4mJ6uxR35BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=}
|
||||
image create photo ::browser::img_rblob -data {R0lGODlhEAAQAIUAAPwCBFxaXNze3Ly2rJSWjPz+/Ozq7GxqbJyanPT29HRydMzOzDQyNIyKjERCROTi3Pz69PTy7Pzy7PTu5Ozm3LyqlJyWlJSSjJSOhOzi1LyulPz27PTq3PTm1OzezLyqjIyKhJSKfOzaxPz29OzizLyidIyGdIyCdOTOpLymhOzavOTStMTCtMS+rMS6pMSynMSulLyedAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaQQIAQECgajcNkQMBkDgKEQFK4LFgLhkMBIVUKroWEYlEgMLxbBKLQUBwc52HgAQ4LBo049atWQyIPA3pEdFcQEhMUFYNVagQWFxgZGoxfYRsTHB0eH5UJCJAYICEinUoPIxIcHCQkIiIllQYEGCEhJicoKYwPmiQeKisrKLFKLCwtLi8wHyUlMYwM0tPUDH5BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=}
|
||||
image create photo ::browser::img_xblob -data {R0lGODlhEAAQAIYAAPwCBFRWVFxaXNza3OTi3Nze3Ly2tJyanPz+/Ozq7GxubNzSxMzOzMTGxHRybDQyNLy+vHRydHx6fKSipISChIyKjGxqbERCRCwuLLy6vGRiZExKTCQiJAwKDLSytLy2rJSSlHx+fDw6PKyqrBQWFPTu5Ozm3LyulLS2tCQmJAQCBPTq3Ozi1MSynCwqLAQGBOTazOzizOzezLyqjBweHNzSvOzaxKyurHRuZNzOtLymhDw+PIyCdOzWvOTOpLyidNzKtOTStLyifMTCtMS+rLyedAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAfZgACCAAEChYeGg4oCAwQFjgYBBwGKggEECJkICQoIkwADCwwNDY2mDA4Lng8QDhESsLARExQVDhYXGBkWExIaGw8cHR4SCQQfFQ8eFgUgIQEiwiMSBMYfGB4atwEXDyQd0wQlJicPKAHoFyIpJCoeDgMrLC0YKBsX6i4kL+4OMDEyZijr5oLGNxUqUCioEcPGDAwjPNyI6MEDChQjcOSwsUDHgw07RIgI4KCkAgs8cvTw8eOBogAxQtXIASTISiEuBwUYMoRIixYnZggpUgTDywdIkWJIitRPIAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7}
|
||||
image create photo ::browser::img_tree -data {R0lGODlhEAAQAIYAAPwCBAQCBExKTBwWHMzKzOzq7ERCRExGTCwqLARqnAQ+ZHR2dKyqrNTOzHx2fCQiJMTi9NTu9HzC3AxmnAQ+XPTm7Dy67DymzITC3IzG5AxypHRydKymrMzOzOzu7BweHByy9AyGtFyy1IzG3NTu/ARupFRSVByazBR6rAyGvFyuzJTK3MTm9BR+tAxWhHS61MTi7Pz+/IymvCxulBRelAx2rHS63Pz6/PTy9PTu9Nza3ISitBRupFSixNTS1CxqnDQyNMzGzOTi5MTCxMTGxGxubGxqbLy2vLSutGRiZLy6vLSytKyurDQuNFxaXKSipDw6PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAfDgACCAAECg4eIAAMEBQYHCImDBgkKCwwNBQIBBw4Bhw8QERITFJYEFQUFnoIPFhcYoRkaFBscHR4Ggh8gIRciEiMQJBkltCa6JyUoKSkXKhIrLCQYuQAPLS4TEyUhKb0qLzDVAjEFMjMuNBMoNcw21QY3ODkFOjs82RM1PfDzFRU3fOggcM7Fj2pAgggRokOHDx9DhhAZUqQaISBGhjwMEvEIkiIHEgUAkgSJkiNLmFSMJChAEydPGBSBwvJQgAc0/QQCACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=}
|
||||
image create photo ::browser::img_symlink -data {R0lGODlhEAAQAIQAAPwCBCwqLLSytLy+vERGRFRWVDQ2NKSmpAQCBKyurMTGxISChJyanHR2dIyKjGxubHRydGRmZIyOjFxeXHx6fAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAVbICACwWieY1CibCCsrBkMb0zchSEcNYskCtqBBzshFkOGQFk0IRqOxqPBODRHCMhCQKteRc9FI/KQWGOIyFYgkDC+gPR4snCcfRGKOIKIgSMQE31+f4OEYCZ+IQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7}
|
||||
image create photo ::browser::img_unknown -data {R0lGODlhEAAQAIUAAPwCBFxaXIyKjNTW1Nze3LS2tJyanER2RGS+VPz+/PTu5GxqbPz69BQ6BCxeLFSqRPT29HRydMzOzDQyNERmPKSypCRWHIyKhERCRDyGPKz2nESiLBxGHCyCHGxubPz6/PTy7Ozi1Ly2rKSipOzm3LyqlKSWhCRyFOzizLymhNTKtNzOvOzaxOTStPz27OzWvOTOpLSupLyedMS+rMS6pMSulLyqjLymfLyifAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAamQIAQECgajcOkYEBoDgoBQyAJOCCuiENCsWBIh9aGw9F4HCARiXciRDQoBUnlYRlcIgsMG5CxXAgMGhscBRAEBRd7AB0eBBoIgxUfICEiikSPgyMMIAokJZcBkBybJgomIaBJAZoMpyCmqkMBFCcVCrgKKAwpoSorKqchKCwtvasIFBIhLiYvLzDHsxQNMcMKLDAwMqEz3jQ1NTY3ONyrE+jp6hN+QQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7}
|
||||
|
||||
field w
|
||||
field browser_commit
|
||||
field browser_path
|
||||
@ -13,13 +20,13 @@ field browser_busy 1
|
||||
|
||||
field ls_buf {}; # Buffered record output from ls-tree
|
||||
|
||||
constructor new {commit} {
|
||||
constructor new {commit {path {}}} {
|
||||
global cursor_ptr M1B
|
||||
make_toplevel top w
|
||||
wm title $top "[appname] ([reponame]): File Browser"
|
||||
|
||||
set browser_commit $commit
|
||||
set browser_path $browser_commit:
|
||||
set browser_path $browser_commit:$path
|
||||
|
||||
label $w.path \
|
||||
-textvariable @browser_path \
|
||||
@ -73,7 +80,11 @@ constructor new {commit} {
|
||||
|
||||
bind $w_list <Visibility> [list focus $w_list]
|
||||
set w $w_list
|
||||
_ls $this $browser_commit
|
||||
if {$path ne {}} {
|
||||
_ls $this $browser_commit:$path $path
|
||||
} else {
|
||||
_ls $this $browser_commit $path
|
||||
}
|
||||
return $this
|
||||
}
|
||||
|
||||
@ -173,7 +184,7 @@ method _ls {tree_id {name {}}} {
|
||||
$w image create end \
|
||||
-align center -padx 5 -pady 1 \
|
||||
-name icon0 \
|
||||
-image file_uplevel
|
||||
-image ::browser::img_parent
|
||||
$w insert end {[Up To Parent]}
|
||||
lappend browser_files parent
|
||||
}
|
||||
@ -203,14 +214,21 @@ method _read {fd} {
|
||||
|
||||
switch -- $type {
|
||||
blob {
|
||||
set image file_mod
|
||||
scan [lindex $info 0] %o mode
|
||||
if {$mode == 0120000} {
|
||||
set image ::browser::img_symlink
|
||||
} elseif {($mode & 0100) != 0} {
|
||||
set image ::browser::img_xblob
|
||||
} else {
|
||||
set image ::browser::img_rblob
|
||||
}
|
||||
}
|
||||
tree {
|
||||
set image file_dir
|
||||
set image ::browser::img_tree
|
||||
append path /
|
||||
}
|
||||
default {
|
||||
set image file_question
|
||||
set image ::browser::img_unknown
|
||||
}
|
||||
}
|
||||
|
||||
@ -239,3 +257,56 @@ method _read {fd} {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class browser_open {
|
||||
|
||||
field w ; # widget path
|
||||
field w_rev ; # mega-widget to pick the initial revision
|
||||
|
||||
constructor dialog {} {
|
||||
make_toplevel top w
|
||||
wm title $top "[appname] ([reponame]): Browse Branch Files"
|
||||
if {$top ne {.}} {
|
||||
wm geometry $top "+[winfo rootx .]+[winfo rooty .]"
|
||||
}
|
||||
|
||||
label $w.header \
|
||||
-text {Browse Branch Files} \
|
||||
-font font_uibold
|
||||
pack $w.header -side top -fill x
|
||||
|
||||
frame $w.buttons
|
||||
button $w.buttons.browse -text Browse \
|
||||
-default active \
|
||||
-command [cb _open]
|
||||
pack $w.buttons.browse -side right
|
||||
button $w.buttons.cancel -text {Cancel} \
|
||||
-command [list destroy $w]
|
||||
pack $w.buttons.cancel -side right -padx 5
|
||||
pack $w.buttons -side bottom -fill x -pady 10 -padx 10
|
||||
|
||||
set w_rev [::choose_rev::new $w.rev {Revision}]
|
||||
$w_rev bind_listbox <Double-Button-1> [cb _open]
|
||||
pack $w.rev -anchor nw -fill both -expand 1 -pady 5 -padx 5
|
||||
|
||||
bind $w <Visibility> [cb _visible]
|
||||
bind $w <Key-Escape> [list destroy $w]
|
||||
bind $w <Key-Return> [cb _open]\;break
|
||||
tkwait window $w
|
||||
}
|
||||
|
||||
method _open {} {
|
||||
if {[catch {$w_rev commit_or_die} err]} {
|
||||
return
|
||||
}
|
||||
set name [$w_rev get]
|
||||
destroy $w
|
||||
browser::new $name
|
||||
}
|
||||
|
||||
method _visible {} {
|
||||
grab $w
|
||||
$w_rev focus_filter
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ field new_ref ; # ref we are updating/creating
|
||||
|
||||
field parent_w .; # window that started us
|
||||
field merge_type none; # type of merge to apply to existing branch
|
||||
field merge_base {}; # merge base if we have another ref involved
|
||||
field fetch_spec {}; # refetch tracking branch if used?
|
||||
field checkout 1; # actually checkout the branch?
|
||||
field create 0; # create the branch if it doesn't exist?
|
||||
@ -65,14 +66,19 @@ method run {} {
|
||||
set r_head [lindex $fetch_spec 2]
|
||||
regsub ^refs/heads/ $r_head {} r_name
|
||||
|
||||
set cmd [list git fetch $remote]
|
||||
if {$l_trck ne {}} {
|
||||
lappend cmd +$r_head:$l_trck
|
||||
} else {
|
||||
lappend cmd $r_head
|
||||
}
|
||||
|
||||
_toplevel $this {Refreshing Tracking Branch}
|
||||
set w_cons [::console::embed \
|
||||
$w.console \
|
||||
"Fetching $r_name from $remote"]
|
||||
pack $w.console -fill both -expand 1
|
||||
$w_cons exec \
|
||||
[list git fetch $remote +$r_head:$l_trck] \
|
||||
[cb _finish_fetch]
|
||||
$w_cons exec $cmd [cb _finish_fetch]
|
||||
|
||||
bind $w <$M1B-Key-w> break
|
||||
bind $w <$M1B-Key-W> break
|
||||
@ -113,6 +119,9 @@ method _noop {} {}
|
||||
method _finish_fetch {ok} {
|
||||
if {$ok} {
|
||||
set l_trck [lindex $fetch_spec 0]
|
||||
if {$l_trck eq {}} {
|
||||
set l_trck FETCH_HEAD
|
||||
}
|
||||
if {[catch {set new_hash [git rev-parse --verify "$l_trck^0"]} err]} {
|
||||
set ok 0
|
||||
$w_cons insert "fatal: Cannot resolve $l_trck"
|
||||
@ -180,29 +189,25 @@ method _update_ref {} {
|
||||
# No merge would be required, don't compute anything.
|
||||
#
|
||||
} else {
|
||||
set mrb {}
|
||||
catch {set mrb [git merge-base $new $cur]}
|
||||
switch -- $merge_type {
|
||||
ff {
|
||||
if {$mrb eq $new} {
|
||||
# The current branch is actually newer.
|
||||
#
|
||||
set new $cur
|
||||
} elseif {$mrb eq $cur} {
|
||||
catch {set merge_base [git merge-base $new $cur]}
|
||||
if {$merge_base eq $cur} {
|
||||
# The current branch is older.
|
||||
#
|
||||
set reflog_msg "merge $new_expr: Fast-forward"
|
||||
} else {
|
||||
switch -- $merge_type {
|
||||
ff {
|
||||
if {$merge_base eq $new} {
|
||||
# The current branch is actually newer.
|
||||
#
|
||||
set new $cur
|
||||
set new_hash $cur
|
||||
} else {
|
||||
_error $this "Branch '$newbranch' already exists.\n\nIt cannot fast-forward to $new_expr.\nA merge is required."
|
||||
return 0
|
||||
}
|
||||
}
|
||||
reset {
|
||||
if {$mrb eq $cur} {
|
||||
# The current branch is older.
|
||||
#
|
||||
set reflog_msg "merge $new_expr: Fast-forward"
|
||||
} else {
|
||||
# The current branch will lose things.
|
||||
#
|
||||
if {[_confirm_reset $this $cur]} {
|
||||
@ -211,13 +216,13 @@ method _update_ref {} {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
}
|
||||
default {
|
||||
_error $this "Only 'ff' and 'reset' merge is currently supported."
|
||||
_error $this "Merge strategy '$merge_type' not supported."
|
||||
return 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if {$new ne $cur} {
|
||||
if {$is_current} {
|
||||
@ -243,7 +248,7 @@ method _checkout {} {
|
||||
if {[lock_index checkout_op]} {
|
||||
after idle [cb _start_checkout]
|
||||
} else {
|
||||
_error $this "Index is already locked."
|
||||
_error $this "Staging area (index) is already locked."
|
||||
delete_this
|
||||
}
|
||||
}
|
||||
@ -270,7 +275,9 @@ The rescan will be automatically started now.
|
||||
return
|
||||
}
|
||||
|
||||
if {[is_config_true gui.trustmtime]} {
|
||||
if {$curHEAD eq $new_hash} {
|
||||
_after_readtree $this
|
||||
} elseif {[is_config_true gui.trustmtime]} {
|
||||
_readtree $this
|
||||
} else {
|
||||
ui_status {Refreshing file status...}
|
||||
@ -378,8 +385,8 @@ method _after_readtree {} {
|
||||
set rn [string length $rh]
|
||||
if {[string equal -length $rn $rh $new_ref]} {
|
||||
set new_branch [string range $new_ref $rn end]
|
||||
if {$is_detached || $current_branch ne $new_branch} {
|
||||
append log " to $new_branch"
|
||||
|
||||
if {[catch {
|
||||
git symbolic-ref -m $log HEAD $new_ref
|
||||
} err]} {
|
||||
@ -387,14 +394,16 @@ method _after_readtree {} {
|
||||
}
|
||||
set current_branch $new_branch
|
||||
set is_detached 0
|
||||
}
|
||||
} else {
|
||||
if {$new_hash ne $HEAD} {
|
||||
append log " to $new_expr"
|
||||
|
||||
if {[catch {
|
||||
_detach_HEAD $log $new_hash
|
||||
} err]} {
|
||||
_fatal $this $err
|
||||
}
|
||||
}
|
||||
set current_branch HEAD
|
||||
set is_detached 1
|
||||
}
|
||||
|
@ -16,10 +16,28 @@ field cur_specs [list]; # list of specs for $revtype
|
||||
field spec_head ; # list of all head specs
|
||||
field spec_trck ; # list of all tracking branch specs
|
||||
field spec_tag ; # list of all tag specs
|
||||
field tip_data ; # array of tip commit info by refname
|
||||
field log_last ; # array of reflog date by refname
|
||||
|
||||
constructor new {path {title {}}} {
|
||||
field tooltip_wm {} ; # Current tooltip toplevel, if open
|
||||
field tooltip_t {} ; # Text widget in $tooltip_wm
|
||||
field tooltip_timer {} ; # Current timer event for our tooltip
|
||||
|
||||
proc new {path {title {}}} {
|
||||
return [_new $path 0 $title]
|
||||
}
|
||||
|
||||
proc new_unmerged {path {title {}}} {
|
||||
return [_new $path 1 $title]
|
||||
}
|
||||
|
||||
constructor _new {path unmerged_only title} {
|
||||
global current_branch is_detached
|
||||
|
||||
if {![info exists ::all_remotes]} {
|
||||
load_all_remotes
|
||||
}
|
||||
|
||||
set w $path
|
||||
|
||||
if {$title ne {}} {
|
||||
@ -86,13 +104,17 @@ constructor new {path {title {}}} {
|
||||
listbox $w_list \
|
||||
-font font_diff \
|
||||
-width 50 \
|
||||
-height 5 \
|
||||
-height 10 \
|
||||
-selectmode browse \
|
||||
-exportselection false \
|
||||
-xscrollcommand [cb _sb_set $w.list.sbx h] \
|
||||
-yscrollcommand [cb _sb_set $w.list.sby v]
|
||||
pack $w_list -fill both -expand 1
|
||||
grid $w.list -sticky nswe -padx {20 5} -columnspan 2
|
||||
bind $w_list <Any-Motion> [cb _show_tooltip @%x,%y]
|
||||
bind $w_list <Any-Enter> [cb _hide_tooltip]
|
||||
bind $w_list <Any-Leave> [cb _hide_tooltip]
|
||||
bind $w_list <Destroy> [cb _hide_tooltip]
|
||||
|
||||
grid columnconfigure $w 1 -weight 1
|
||||
if {$is_detached} {
|
||||
@ -105,21 +127,89 @@ constructor new {path {title {}}} {
|
||||
bind $w_filter <Key-Return> [list focus $w_list]\;break
|
||||
bind $w_filter <Key-Down> [list focus $w_list]
|
||||
|
||||
set fmt list
|
||||
append fmt { %(refname)}
|
||||
append fmt { [list}
|
||||
append fmt { %(objecttype)}
|
||||
append fmt { %(objectname)}
|
||||
append fmt { [concat %(taggername) %(authorname)]}
|
||||
append fmt { [concat %(taggerdate) %(authordate)]}
|
||||
append fmt { %(subject)}
|
||||
append fmt {] [list}
|
||||
append fmt { %(*objecttype)}
|
||||
append fmt { %(*objectname)}
|
||||
append fmt { %(*authorname)}
|
||||
append fmt { %(*authordate)}
|
||||
append fmt { %(*subject)}
|
||||
append fmt {]}
|
||||
set all_refn [list]
|
||||
set fr_fd [git_read for-each-ref \
|
||||
--tcl \
|
||||
--sort=-taggerdate \
|
||||
--format=$fmt \
|
||||
refs/heads \
|
||||
refs/remotes \
|
||||
refs/tags \
|
||||
]
|
||||
fconfigure $fr_fd -translation lf -encoding utf-8
|
||||
while {[gets $fr_fd line] > 0} {
|
||||
set line [eval $line]
|
||||
if {[lindex $line 1 0] eq {tag}} {
|
||||
if {[lindex $line 2 0] eq {commit}} {
|
||||
set sha1 [lindex $line 2 1]
|
||||
} else {
|
||||
continue
|
||||
}
|
||||
} elseif {[lindex $line 1 0] eq {commit}} {
|
||||
set sha1 [lindex $line 1 1]
|
||||
} else {
|
||||
continue
|
||||
}
|
||||
set refn [lindex $line 0]
|
||||
set tip_data($refn) [lrange $line 1 end]
|
||||
lappend cmt_refn($sha1) $refn
|
||||
lappend all_refn $refn
|
||||
}
|
||||
close $fr_fd
|
||||
|
||||
if {$unmerged_only} {
|
||||
set fr_fd [git_read rev-list --all ^$::HEAD]
|
||||
while {[gets $fr_fd sha1] > 0} {
|
||||
if {[catch {set rlst $cmt_refn($sha1)}]} continue
|
||||
foreach refn $rlst {
|
||||
set inc($refn) 1
|
||||
}
|
||||
}
|
||||
close $fr_fd
|
||||
} else {
|
||||
foreach refn $all_refn {
|
||||
set inc($refn) 1
|
||||
}
|
||||
}
|
||||
|
||||
set spec_head [list]
|
||||
foreach name [load_all_heads] {
|
||||
lappend spec_head [list $name refs/heads/$name]
|
||||
set refn refs/heads/$name
|
||||
if {[info exists inc($refn)]} {
|
||||
lappend spec_head [list $name $refn]
|
||||
}
|
||||
}
|
||||
|
||||
set spec_trck [list]
|
||||
foreach spec [all_tracking_branches] {
|
||||
set name [lindex $spec 0]
|
||||
regsub ^refs/(heads|remotes)/ $name {} name
|
||||
set refn [lindex $spec 0]
|
||||
if {[info exists inc($refn)]} {
|
||||
regsub ^refs/(heads|remotes)/ $refn {} name
|
||||
lappend spec_trck [concat $name $spec]
|
||||
}
|
||||
}
|
||||
|
||||
set spec_tag [list]
|
||||
foreach name [load_all_tags] {
|
||||
lappend spec_tag [list $name refs/tags/$name]
|
||||
set refn refs/tags/$name
|
||||
if {[info exists inc($refn)]} {
|
||||
lappend spec_tag [list $name $refn]
|
||||
}
|
||||
}
|
||||
|
||||
if {$is_detached} { set revtype HEAD
|
||||
@ -364,4 +454,174 @@ method _sb_set {sb orient first last} {
|
||||
$sb set $first $last
|
||||
}
|
||||
|
||||
method _show_tooltip {pos} {
|
||||
if {$tooltip_wm ne {}} {
|
||||
_open_tooltip $this
|
||||
} elseif {$tooltip_timer eq {}} {
|
||||
set tooltip_timer [after 1000 [cb _open_tooltip]]
|
||||
}
|
||||
}
|
||||
|
||||
method _open_tooltip {} {
|
||||
global remote_url
|
||||
|
||||
set tooltip_timer {}
|
||||
set pos_x [winfo pointerx $w_list]
|
||||
set pos_y [winfo pointery $w_list]
|
||||
if {[winfo containing $pos_x $pos_y] ne $w_list} {
|
||||
_hide_tooltip $this
|
||||
return
|
||||
}
|
||||
|
||||
set pos @[join [list \
|
||||
[expr {$pos_x - [winfo rootx $w_list]}] \
|
||||
[expr {$pos_y - [winfo rooty $w_list]}]] ,]
|
||||
set lno [$w_list index $pos]
|
||||
if {$lno eq {}} {
|
||||
_hide_tooltip $this
|
||||
return
|
||||
}
|
||||
|
||||
set spec [lindex $cur_specs $lno]
|
||||
set refn [lindex $spec 1]
|
||||
if {$refn eq {}} {
|
||||
_hide_tooltip $this
|
||||
return
|
||||
}
|
||||
|
||||
if {$tooltip_wm eq {}} {
|
||||
set tooltip_wm [toplevel $w_list.tooltip -borderwidth 1]
|
||||
wm overrideredirect $tooltip_wm 1
|
||||
wm transient $tooltip_wm [winfo toplevel $w_list]
|
||||
set tooltip_t $tooltip_wm.label
|
||||
text $tooltip_t \
|
||||
-takefocus 0 \
|
||||
-highlightthickness 0 \
|
||||
-relief flat \
|
||||
-borderwidth 0 \
|
||||
-wrap none \
|
||||
-background lightyellow \
|
||||
-foreground black
|
||||
$tooltip_t tag conf section_header -font font_uibold
|
||||
bind $tooltip_wm <Escape> [cb _hide_tooltip]
|
||||
pack $tooltip_t
|
||||
} else {
|
||||
$tooltip_t conf -state normal
|
||||
$tooltip_t delete 0.0 end
|
||||
}
|
||||
|
||||
set data $tip_data($refn)
|
||||
if {[lindex $data 0 0] eq {tag}} {
|
||||
set tag [lindex $data 0]
|
||||
if {[lindex $data 1 0] eq {commit}} {
|
||||
set cmit [lindex $data 1]
|
||||
} else {
|
||||
set cmit {}
|
||||
}
|
||||
} elseif {[lindex $data 0 0] eq {commit}} {
|
||||
set tag {}
|
||||
set cmit [lindex $data 0]
|
||||
}
|
||||
|
||||
$tooltip_t insert end [lindex $spec 0]
|
||||
set last [_reflog_last $this [lindex $spec 1]]
|
||||
if {$last ne {}} {
|
||||
$tooltip_t insert end "\n"
|
||||
$tooltip_t insert end "updated"
|
||||
$tooltip_t insert end " $last"
|
||||
}
|
||||
$tooltip_t insert end "\n"
|
||||
|
||||
if {$tag ne {}} {
|
||||
$tooltip_t insert end "\n"
|
||||
$tooltip_t insert end "tag" section_header
|
||||
$tooltip_t insert end " [lindex $tag 1]\n"
|
||||
$tooltip_t insert end [lindex $tag 2]
|
||||
$tooltip_t insert end " ([lindex $tag 3])\n"
|
||||
$tooltip_t insert end [lindex $tag 4]
|
||||
$tooltip_t insert end "\n"
|
||||
}
|
||||
|
||||
if {$cmit ne {}} {
|
||||
$tooltip_t insert end "\n"
|
||||
$tooltip_t insert end "commit" section_header
|
||||
$tooltip_t insert end " [lindex $cmit 1]\n"
|
||||
$tooltip_t insert end [lindex $cmit 2]
|
||||
$tooltip_t insert end " ([lindex $cmit 3])\n"
|
||||
$tooltip_t insert end [lindex $cmit 4]
|
||||
}
|
||||
|
||||
if {[llength $spec] > 2} {
|
||||
$tooltip_t insert end "\n"
|
||||
$tooltip_t insert end "remote" section_header
|
||||
$tooltip_t insert end " [lindex $spec 2]\n"
|
||||
$tooltip_t insert end "url"
|
||||
$tooltip_t insert end " $remote_url([lindex $spec 2])\n"
|
||||
$tooltip_t insert end "branch"
|
||||
$tooltip_t insert end " [lindex $spec 3]"
|
||||
}
|
||||
|
||||
$tooltip_t conf -state disabled
|
||||
_position_tooltip $this
|
||||
}
|
||||
|
||||
method _reflog_last {name} {
|
||||
if {[info exists reflog_last($name)]} {
|
||||
return reflog_last($name)
|
||||
}
|
||||
|
||||
set last {}
|
||||
if {[catch {set last [file mtime [gitdir $name]]}]
|
||||
&& ![catch {set g [open [gitdir logs $name] r]}]} {
|
||||
fconfigure $g -translation binary
|
||||
while {[gets $g line] >= 0} {
|
||||
if {[regexp {> ([1-9][0-9]*) } $line line when]} {
|
||||
set last $when
|
||||
}
|
||||
}
|
||||
close $g
|
||||
}
|
||||
|
||||
if {$last ne {}} {
|
||||
set last [clock format $last -format {%a %b %e %H:%M:%S %Y}]
|
||||
}
|
||||
set reflog_last($name) $last
|
||||
return $last
|
||||
}
|
||||
|
||||
method _position_tooltip {} {
|
||||
set max_h [lindex [split [$tooltip_t index end] .] 0]
|
||||
set max_w 0
|
||||
for {set i 1} {$i <= $max_h} {incr i} {
|
||||
set c [lindex [split [$tooltip_t index "$i.0 lineend"] .] 1]
|
||||
if {$c > $max_w} {set max_w $c}
|
||||
}
|
||||
$tooltip_t conf -width $max_w -height $max_h
|
||||
|
||||
set req_w [winfo reqwidth $tooltip_t]
|
||||
set req_h [winfo reqheight $tooltip_t]
|
||||
set pos_x [expr {[winfo pointerx .] + 5}]
|
||||
set pos_y [expr {[winfo pointery .] + 10}]
|
||||
|
||||
set g "${req_w}x${req_h}"
|
||||
if {$pos_x >= 0} {append g +}
|
||||
append g $pos_x
|
||||
if {$pos_y >= 0} {append g +}
|
||||
append g $pos_y
|
||||
|
||||
wm geometry $tooltip_wm $g
|
||||
raise $tooltip_wm
|
||||
}
|
||||
|
||||
method _hide_tooltip {} {
|
||||
if {$tooltip_wm ne {}} {
|
||||
destroy $tooltip_wm
|
||||
set tooltip_wm {}
|
||||
}
|
||||
if {$tooltip_timer ne {}} {
|
||||
after cancel $tooltip_timer
|
||||
set tooltip_timer {}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -37,9 +37,14 @@ You are currently in the middle of a merge that has not been fully completed. Y
|
||||
set enc [string tolower [string range $line 9 end]]
|
||||
}
|
||||
}
|
||||
set msg [encoding convertfrom $enc [read $fd]]
|
||||
set msg [string trim $msg]
|
||||
set msg [read $fd]
|
||||
close $fd
|
||||
|
||||
set enc [tcl_encoding $enc]
|
||||
if {$enc ne {}} {
|
||||
set msg [encoding convertfrom $enc $msg]
|
||||
}
|
||||
set msg [string trim $msg]
|
||||
} err]} {
|
||||
error_popup "Error loading commit data for amend:\n\n$err"
|
||||
return
|
||||
@ -148,7 +153,7 @@ The rescan will be automatically started now.
|
||||
U? {
|
||||
error_popup "Unmerged files cannot be committed.
|
||||
|
||||
File [short_path $path] has merge conflicts. You must resolve them and add the file before committing.
|
||||
File [short_path $path] has merge conflicts. You must resolve them and stage the file before committing.
|
||||
"
|
||||
unlock_index
|
||||
return
|
||||
@ -164,7 +169,7 @@ File [short_path $path] cannot be committed by this program.
|
||||
if {!$files_ready && ![string match *merge $curType]} {
|
||||
info_popup {No changes to commit.
|
||||
|
||||
You must add at least 1 file before you can commit.
|
||||
You must stage at least 1 file before you can commit.
|
||||
}
|
||||
unlock_index
|
||||
return
|
||||
@ -209,7 +214,7 @@ A good commit message has the following format:
|
||||
ui_status {Calling pre-commit hook...}
|
||||
set pch_error {}
|
||||
set fd_ph [open "| $pchook" r]
|
||||
fconfigure $fd_ph -blocking 0 -translation binary
|
||||
fconfigure $fd_ph -blocking 0 -translation binary -eofchar {}
|
||||
fileevent $fd_ph readable \
|
||||
[list commit_prehook_wait $fd_ph $curHEAD $msg]
|
||||
}
|
||||
@ -287,11 +292,18 @@ A rescan will be automatically started now.
|
||||
#
|
||||
set msg_p [gitdir COMMIT_EDITMSG]
|
||||
set msg_wt [open $msg_p w]
|
||||
fconfigure $msg_wt -translation lf
|
||||
if {[catch {set enc $repo_config(i18n.commitencoding)}]} {
|
||||
set enc utf-8
|
||||
}
|
||||
fconfigure $msg_wt -encoding binary -translation binary
|
||||
puts -nonewline $msg_wt [encoding convertto $enc $msg]
|
||||
set use_enc [tcl_encoding $enc]
|
||||
if {$use_enc ne {}} {
|
||||
fconfigure $msg_wt -encoding $use_enc
|
||||
} else {
|
||||
puts stderr "warning: Tcl does not support encoding '$enc'."
|
||||
fconfigure $msg_wt -encoding utf-8
|
||||
}
|
||||
puts -nonewline $msg_wt $msg
|
||||
close $msg_wt
|
||||
|
||||
# -- Create the commit.
|
||||
@ -367,6 +379,10 @@ A rescan will be automatically started now.
|
||||
$ui_comm delete 0.0 end
|
||||
$ui_comm edit reset
|
||||
$ui_comm edit modified false
|
||||
if {$::GITGUI_BCK_exists} {
|
||||
catch {file delete [gitdir GITGUI_BCK]}
|
||||
set ::GITGUI_BCK_exists 0
|
||||
}
|
||||
|
||||
if {[is_enabled singlecommit]} do_quit
|
||||
|
||||
|
@ -87,3 +87,30 @@ proc do_fsck_objects {} {
|
||||
lappend cmd --strict
|
||||
console::exec $w $cmd
|
||||
}
|
||||
|
||||
proc hint_gc {} {
|
||||
set object_limit 8
|
||||
if {[is_Windows]} {
|
||||
set object_limit 1
|
||||
}
|
||||
|
||||
set objects_current [llength [glob \
|
||||
-directory [gitdir objects 42] \
|
||||
-nocomplain \
|
||||
-tails \
|
||||
-- \
|
||||
*]]
|
||||
|
||||
if {$objects_current >= $object_limit} {
|
||||
set objects_current [expr {$objects_current * 256}]
|
||||
set object_limit [expr {$object_limit * 256}]
|
||||
if {[ask_popup \
|
||||
"This repository currently has approximately $objects_current loose objects.
|
||||
|
||||
To maintain optimal performance it is strongly recommended that you compress the database when more than $object_limit loose objects exist.
|
||||
|
||||
Compress the database now?"] eq yes} {
|
||||
do_gc
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -86,6 +86,7 @@ proc show_diff {path w {lno {}}} {
|
||||
set max_sz [expr {128 * 1024}]
|
||||
if {[catch {
|
||||
set fd [open $path r]
|
||||
fconfigure $fd -eofchar {}
|
||||
set content [read $fd $max_sz]
|
||||
close $fd
|
||||
set sz [file size $path]
|
||||
|
276
git-gui/lib/encoding.tcl
Normal file
276
git-gui/lib/encoding.tcl
Normal file
@ -0,0 +1,276 @@
|
||||
# git-gui encoding support
|
||||
# Copyright (C) 2005 Paul Mackerras <paulus@samba.org>
|
||||
# (Copied from gitk, commit fd8ccbec4f0161)
|
||||
|
||||
# This list of encoding names and aliases is distilled from
|
||||
# http://www.iana.org/assignments/character-sets.
|
||||
# Not all of them are supported by Tcl.
|
||||
set encoding_aliases {
|
||||
{ ANSI_X3.4-1968 iso-ir-6 ANSI_X3.4-1986 ISO_646.irv:1991 ASCII
|
||||
ISO646-US US-ASCII us IBM367 cp367 csASCII }
|
||||
{ ISO-10646-UTF-1 csISO10646UTF1 }
|
||||
{ ISO_646.basic:1983 ref csISO646basic1983 }
|
||||
{ INVARIANT csINVARIANT }
|
||||
{ ISO_646.irv:1983 iso-ir-2 irv csISO2IntlRefVersion }
|
||||
{ BS_4730 iso-ir-4 ISO646-GB gb uk csISO4UnitedKingdom }
|
||||
{ NATS-SEFI iso-ir-8-1 csNATSSEFI }
|
||||
{ NATS-SEFI-ADD iso-ir-8-2 csNATSSEFIADD }
|
||||
{ NATS-DANO iso-ir-9-1 csNATSDANO }
|
||||
{ NATS-DANO-ADD iso-ir-9-2 csNATSDANOADD }
|
||||
{ SEN_850200_B iso-ir-10 FI ISO646-FI ISO646-SE se csISO10Swedish }
|
||||
{ SEN_850200_C iso-ir-11 ISO646-SE2 se2 csISO11SwedishForNames }
|
||||
{ KS_C_5601-1987 iso-ir-149 KS_C_5601-1989 KSC_5601 korean csKSC56011987 }
|
||||
{ ISO-2022-KR csISO2022KR }
|
||||
{ EUC-KR csEUCKR }
|
||||
{ ISO-2022-JP csISO2022JP }
|
||||
{ ISO-2022-JP-2 csISO2022JP2 }
|
||||
{ JIS_C6220-1969-jp JIS_C6220-1969 iso-ir-13 katakana x0201-7
|
||||
csISO13JISC6220jp }
|
||||
{ JIS_C6220-1969-ro iso-ir-14 jp ISO646-JP csISO14JISC6220ro }
|
||||
{ IT iso-ir-15 ISO646-IT csISO15Italian }
|
||||
{ PT iso-ir-16 ISO646-PT csISO16Portuguese }
|
||||
{ ES iso-ir-17 ISO646-ES csISO17Spanish }
|
||||
{ greek7-old iso-ir-18 csISO18Greek7Old }
|
||||
{ latin-greek iso-ir-19 csISO19LatinGreek }
|
||||
{ DIN_66003 iso-ir-21 de ISO646-DE csISO21German }
|
||||
{ NF_Z_62-010_(1973) iso-ir-25 ISO646-FR1 csISO25French }
|
||||
{ Latin-greek-1 iso-ir-27 csISO27LatinGreek1 }
|
||||
{ ISO_5427 iso-ir-37 csISO5427Cyrillic }
|
||||
{ JIS_C6226-1978 iso-ir-42 csISO42JISC62261978 }
|
||||
{ BS_viewdata iso-ir-47 csISO47BSViewdata }
|
||||
{ INIS iso-ir-49 csISO49INIS }
|
||||
{ INIS-8 iso-ir-50 csISO50INIS8 }
|
||||
{ INIS-cyrillic iso-ir-51 csISO51INISCyrillic }
|
||||
{ ISO_5427:1981 iso-ir-54 ISO5427Cyrillic1981 }
|
||||
{ ISO_5428:1980 iso-ir-55 csISO5428Greek }
|
||||
{ GB_1988-80 iso-ir-57 cn ISO646-CN csISO57GB1988 }
|
||||
{ GB_2312-80 iso-ir-58 chinese csISO58GB231280 }
|
||||
{ NS_4551-1 iso-ir-60 ISO646-NO no csISO60DanishNorwegian
|
||||
csISO60Norwegian1 }
|
||||
{ NS_4551-2 ISO646-NO2 iso-ir-61 no2 csISO61Norwegian2 }
|
||||
{ NF_Z_62-010 iso-ir-69 ISO646-FR fr csISO69French }
|
||||
{ videotex-suppl iso-ir-70 csISO70VideotexSupp1 }
|
||||
{ PT2 iso-ir-84 ISO646-PT2 csISO84Portuguese2 }
|
||||
{ ES2 iso-ir-85 ISO646-ES2 csISO85Spanish2 }
|
||||
{ MSZ_7795.3 iso-ir-86 ISO646-HU hu csISO86Hungarian }
|
||||
{ JIS_C6226-1983 iso-ir-87 x0208 JIS_X0208-1983 csISO87JISX0208 }
|
||||
{ greek7 iso-ir-88 csISO88Greek7 }
|
||||
{ ASMO_449 ISO_9036 arabic7 iso-ir-89 csISO89ASMO449 }
|
||||
{ iso-ir-90 csISO90 }
|
||||
{ JIS_C6229-1984-a iso-ir-91 jp-ocr-a csISO91JISC62291984a }
|
||||
{ JIS_C6229-1984-b iso-ir-92 ISO646-JP-OCR-B jp-ocr-b
|
||||
csISO92JISC62991984b }
|
||||
{ JIS_C6229-1984-b-add iso-ir-93 jp-ocr-b-add csISO93JIS62291984badd }
|
||||
{ JIS_C6229-1984-hand iso-ir-94 jp-ocr-hand csISO94JIS62291984hand }
|
||||
{ JIS_C6229-1984-hand-add iso-ir-95 jp-ocr-hand-add
|
||||
csISO95JIS62291984handadd }
|
||||
{ JIS_C6229-1984-kana iso-ir-96 csISO96JISC62291984kana }
|
||||
{ ISO_2033-1983 iso-ir-98 e13b csISO2033 }
|
||||
{ ANSI_X3.110-1983 iso-ir-99 CSA_T500-1983 NAPLPS csISO99NAPLPS }
|
||||
{ ISO_8859-1:1987 iso-ir-100 ISO_8859-1 ISO-8859-1 latin1 l1 IBM819
|
||||
CP819 csISOLatin1 }
|
||||
{ ISO_8859-2:1987 iso-ir-101 ISO_8859-2 ISO-8859-2 latin2 l2 csISOLatin2 }
|
||||
{ T.61-7bit iso-ir-102 csISO102T617bit }
|
||||
{ T.61-8bit T.61 iso-ir-103 csISO103T618bit }
|
||||
{ ISO_8859-3:1988 iso-ir-109 ISO_8859-3 ISO-8859-3 latin3 l3 csISOLatin3 }
|
||||
{ ISO_8859-4:1988 iso-ir-110 ISO_8859-4 ISO-8859-4 latin4 l4 csISOLatin4 }
|
||||
{ ECMA-cyrillic iso-ir-111 KOI8-E csISO111ECMACyrillic }
|
||||
{ CSA_Z243.4-1985-1 iso-ir-121 ISO646-CA csa7-1 ca csISO121Canadian1 }
|
||||
{ CSA_Z243.4-1985-2 iso-ir-122 ISO646-CA2 csa7-2 csISO122Canadian2 }
|
||||
{ CSA_Z243.4-1985-gr iso-ir-123 csISO123CSAZ24341985gr }
|
||||
{ ISO_8859-6:1987 iso-ir-127 ISO_8859-6 ISO-8859-6 ECMA-114 ASMO-708
|
||||
arabic csISOLatinArabic }
|
||||
{ ISO_8859-6-E csISO88596E ISO-8859-6-E }
|
||||
{ ISO_8859-6-I csISO88596I ISO-8859-6-I }
|
||||
{ ISO_8859-7:1987 iso-ir-126 ISO_8859-7 ISO-8859-7 ELOT_928 ECMA-118
|
||||
greek greek8 csISOLatinGreek }
|
||||
{ T.101-G2 iso-ir-128 csISO128T101G2 }
|
||||
{ ISO_8859-8:1988 iso-ir-138 ISO_8859-8 ISO-8859-8 hebrew
|
||||
csISOLatinHebrew }
|
||||
{ ISO_8859-8-E csISO88598E ISO-8859-8-E }
|
||||
{ ISO_8859-8-I csISO88598I ISO-8859-8-I }
|
||||
{ CSN_369103 iso-ir-139 csISO139CSN369103 }
|
||||
{ JUS_I.B1.002 iso-ir-141 ISO646-YU js yu csISO141JUSIB1002 }
|
||||
{ ISO_6937-2-add iso-ir-142 csISOTextComm }
|
||||
{ IEC_P27-1 iso-ir-143 csISO143IECP271 }
|
||||
{ ISO_8859-5:1988 iso-ir-144 ISO_8859-5 ISO-8859-5 cyrillic
|
||||
csISOLatinCyrillic }
|
||||
{ JUS_I.B1.003-serb iso-ir-146 serbian csISO146Serbian }
|
||||
{ JUS_I.B1.003-mac macedonian iso-ir-147 csISO147Macedonian }
|
||||
{ ISO_8859-9:1989 iso-ir-148 ISO_8859-9 ISO-8859-9 latin5 l5 csISOLatin5 }
|
||||
{ greek-ccitt iso-ir-150 csISO150 csISO150GreekCCITT }
|
||||
{ NC_NC00-10:81 cuba iso-ir-151 ISO646-CU csISO151Cuba }
|
||||
{ ISO_6937-2-25 iso-ir-152 csISO6937Add }
|
||||
{ GOST_19768-74 ST_SEV_358-88 iso-ir-153 csISO153GOST1976874 }
|
||||
{ ISO_8859-supp iso-ir-154 latin1-2-5 csISO8859Supp }
|
||||
{ ISO_10367-box iso-ir-155 csISO10367Box }
|
||||
{ ISO-8859-10 iso-ir-157 l6 ISO_8859-10:1992 csISOLatin6 latin6 }
|
||||
{ latin-lap lap iso-ir-158 csISO158Lap }
|
||||
{ JIS_X0212-1990 x0212 iso-ir-159 csISO159JISX02121990 }
|
||||
{ DS_2089 DS2089 ISO646-DK dk csISO646Danish }
|
||||
{ us-dk csUSDK }
|
||||
{ dk-us csDKUS }
|
||||
{ JIS_X0201 X0201 csHalfWidthKatakana }
|
||||
{ KSC5636 ISO646-KR csKSC5636 }
|
||||
{ ISO-10646-UCS-2 csUnicode }
|
||||
{ ISO-10646-UCS-4 csUCS4 }
|
||||
{ DEC-MCS dec csDECMCS }
|
||||
{ hp-roman8 roman8 r8 csHPRoman8 }
|
||||
{ macintosh mac csMacintosh }
|
||||
{ IBM037 cp037 ebcdic-cp-us ebcdic-cp-ca ebcdic-cp-wt ebcdic-cp-nl
|
||||
csIBM037 }
|
||||
{ IBM038 EBCDIC-INT cp038 csIBM038 }
|
||||
{ IBM273 CP273 csIBM273 }
|
||||
{ IBM274 EBCDIC-BE CP274 csIBM274 }
|
||||
{ IBM275 EBCDIC-BR cp275 csIBM275 }
|
||||
{ IBM277 EBCDIC-CP-DK EBCDIC-CP-NO csIBM277 }
|
||||
{ IBM278 CP278 ebcdic-cp-fi ebcdic-cp-se csIBM278 }
|
||||
{ IBM280 CP280 ebcdic-cp-it csIBM280 }
|
||||
{ IBM281 EBCDIC-JP-E cp281 csIBM281 }
|
||||
{ IBM284 CP284 ebcdic-cp-es csIBM284 }
|
||||
{ IBM285 CP285 ebcdic-cp-gb csIBM285 }
|
||||
{ IBM290 cp290 EBCDIC-JP-kana csIBM290 }
|
||||
{ IBM297 cp297 ebcdic-cp-fr csIBM297 }
|
||||
{ IBM420 cp420 ebcdic-cp-ar1 csIBM420 }
|
||||
{ IBM423 cp423 ebcdic-cp-gr csIBM423 }
|
||||
{ IBM424 cp424 ebcdic-cp-he csIBM424 }
|
||||
{ IBM437 cp437 437 csPC8CodePage437 }
|
||||
{ IBM500 CP500 ebcdic-cp-be ebcdic-cp-ch csIBM500 }
|
||||
{ IBM775 cp775 csPC775Baltic }
|
||||
{ IBM850 cp850 850 csPC850Multilingual }
|
||||
{ IBM851 cp851 851 csIBM851 }
|
||||
{ IBM852 cp852 852 csPCp852 }
|
||||
{ IBM855 cp855 855 csIBM855 }
|
||||
{ IBM857 cp857 857 csIBM857 }
|
||||
{ IBM860 cp860 860 csIBM860 }
|
||||
{ IBM861 cp861 861 cp-is csIBM861 }
|
||||
{ IBM862 cp862 862 csPC862LatinHebrew }
|
||||
{ IBM863 cp863 863 csIBM863 }
|
||||
{ IBM864 cp864 csIBM864 }
|
||||
{ IBM865 cp865 865 csIBM865 }
|
||||
{ IBM866 cp866 866 csIBM866 }
|
||||
{ IBM868 CP868 cp-ar csIBM868 }
|
||||
{ IBM869 cp869 869 cp-gr csIBM869 }
|
||||
{ IBM870 CP870 ebcdic-cp-roece ebcdic-cp-yu csIBM870 }
|
||||
{ IBM871 CP871 ebcdic-cp-is csIBM871 }
|
||||
{ IBM880 cp880 EBCDIC-Cyrillic csIBM880 }
|
||||
{ IBM891 cp891 csIBM891 }
|
||||
{ IBM903 cp903 csIBM903 }
|
||||
{ IBM904 cp904 904 csIBBM904 }
|
||||
{ IBM905 CP905 ebcdic-cp-tr csIBM905 }
|
||||
{ IBM918 CP918 ebcdic-cp-ar2 csIBM918 }
|
||||
{ IBM1026 CP1026 csIBM1026 }
|
||||
{ EBCDIC-AT-DE csIBMEBCDICATDE }
|
||||
{ EBCDIC-AT-DE-A csEBCDICATDEA }
|
||||
{ EBCDIC-CA-FR csEBCDICCAFR }
|
||||
{ EBCDIC-DK-NO csEBCDICDKNO }
|
||||
{ EBCDIC-DK-NO-A csEBCDICDKNOA }
|
||||
{ EBCDIC-FI-SE csEBCDICFISE }
|
||||
{ EBCDIC-FI-SE-A csEBCDICFISEA }
|
||||
{ EBCDIC-FR csEBCDICFR }
|
||||
{ EBCDIC-IT csEBCDICIT }
|
||||
{ EBCDIC-PT csEBCDICPT }
|
||||
{ EBCDIC-ES csEBCDICES }
|
||||
{ EBCDIC-ES-A csEBCDICESA }
|
||||
{ EBCDIC-ES-S csEBCDICESS }
|
||||
{ EBCDIC-UK csEBCDICUK }
|
||||
{ EBCDIC-US csEBCDICUS }
|
||||
{ UNKNOWN-8BIT csUnknown8BiT }
|
||||
{ MNEMONIC csMnemonic }
|
||||
{ MNEM csMnem }
|
||||
{ VISCII csVISCII }
|
||||
{ VIQR csVIQR }
|
||||
{ KOI8-R csKOI8R }
|
||||
{ IBM00858 CCSID00858 CP00858 PC-Multilingual-850+euro }
|
||||
{ IBM00924 CCSID00924 CP00924 ebcdic-Latin9--euro }
|
||||
{ IBM01140 CCSID01140 CP01140 ebcdic-us-37+euro }
|
||||
{ IBM01141 CCSID01141 CP01141 ebcdic-de-273+euro }
|
||||
{ IBM01142 CCSID01142 CP01142 ebcdic-dk-277+euro ebcdic-no-277+euro }
|
||||
{ IBM01143 CCSID01143 CP01143 ebcdic-fi-278+euro ebcdic-se-278+euro }
|
||||
{ IBM01144 CCSID01144 CP01144 ebcdic-it-280+euro }
|
||||
{ IBM01145 CCSID01145 CP01145 ebcdic-es-284+euro }
|
||||
{ IBM01146 CCSID01146 CP01146 ebcdic-gb-285+euro }
|
||||
{ IBM01147 CCSID01147 CP01147 ebcdic-fr-297+euro }
|
||||
{ IBM01148 CCSID01148 CP01148 ebcdic-international-500+euro }
|
||||
{ IBM01149 CCSID01149 CP01149 ebcdic-is-871+euro }
|
||||
{ IBM1047 IBM-1047 }
|
||||
{ PTCP154 csPTCP154 PT154 CP154 Cyrillic-Asian }
|
||||
{ Amiga-1251 Ami1251 Amiga1251 Ami-1251 }
|
||||
{ UNICODE-1-1 csUnicode11 }
|
||||
{ CESU-8 csCESU-8 }
|
||||
{ BOCU-1 csBOCU-1 }
|
||||
{ UNICODE-1-1-UTF-7 csUnicode11UTF7 }
|
||||
{ ISO-8859-14 iso-ir-199 ISO_8859-14:1998 ISO_8859-14 latin8 iso-celtic
|
||||
l8 }
|
||||
{ ISO-8859-15 ISO_8859-15 Latin-9 }
|
||||
{ ISO-8859-16 iso-ir-226 ISO_8859-16:2001 ISO_8859-16 latin10 l10 }
|
||||
{ GBK CP936 MS936 windows-936 }
|
||||
{ JIS_Encoding csJISEncoding }
|
||||
{ Shift_JIS MS_Kanji csShiftJIS }
|
||||
{ Extended_UNIX_Code_Packed_Format_for_Japanese csEUCPkdFmtJapanese
|
||||
EUC-JP }
|
||||
{ Extended_UNIX_Code_Fixed_Width_for_Japanese csEUCFixWidJapanese }
|
||||
{ ISO-10646-UCS-Basic csUnicodeASCII }
|
||||
{ ISO-10646-Unicode-Latin1 csUnicodeLatin1 ISO-10646 }
|
||||
{ ISO-Unicode-IBM-1261 csUnicodeIBM1261 }
|
||||
{ ISO-Unicode-IBM-1268 csUnicodeIBM1268 }
|
||||
{ ISO-Unicode-IBM-1276 csUnicodeIBM1276 }
|
||||
{ ISO-Unicode-IBM-1264 csUnicodeIBM1264 }
|
||||
{ ISO-Unicode-IBM-1265 csUnicodeIBM1265 }
|
||||
{ ISO-8859-1-Windows-3.0-Latin-1 csWindows30Latin1 }
|
||||
{ ISO-8859-1-Windows-3.1-Latin-1 csWindows31Latin1 }
|
||||
{ ISO-8859-2-Windows-Latin-2 csWindows31Latin2 }
|
||||
{ ISO-8859-9-Windows-Latin-5 csWindows31Latin5 }
|
||||
{ Adobe-Standard-Encoding csAdobeStandardEncoding }
|
||||
{ Ventura-US csVenturaUS }
|
||||
{ Ventura-International csVenturaInternational }
|
||||
{ PC8-Danish-Norwegian csPC8DanishNorwegian }
|
||||
{ PC8-Turkish csPC8Turkish }
|
||||
{ IBM-Symbols csIBMSymbols }
|
||||
{ IBM-Thai csIBMThai }
|
||||
{ HP-Legal csHPLegal }
|
||||
{ HP-Pi-font csHPPiFont }
|
||||
{ HP-Math8 csHPMath8 }
|
||||
{ Adobe-Symbol-Encoding csHPPSMath }
|
||||
{ HP-DeskTop csHPDesktop }
|
||||
{ Ventura-Math csVenturaMath }
|
||||
{ Microsoft-Publishing csMicrosoftPublishing }
|
||||
{ Windows-31J csWindows31J }
|
||||
{ GB2312 csGB2312 }
|
||||
{ Big5 csBig5 }
|
||||
}
|
||||
|
||||
proc tcl_encoding {enc} {
|
||||
global encoding_aliases
|
||||
set names [encoding names]
|
||||
set lcnames [string tolower $names]
|
||||
set enc [string tolower $enc]
|
||||
set i [lsearch -exact $lcnames $enc]
|
||||
if {$i < 0} {
|
||||
# look for "isonnn" instead of "iso-nnn" or "iso_nnn"
|
||||
if {[regsub {^iso[-_]} $enc iso encx]} {
|
||||
set i [lsearch -exact $lcnames $encx]
|
||||
}
|
||||
}
|
||||
if {$i < 0} {
|
||||
foreach l $encoding_aliases {
|
||||
set ll [string tolower $l]
|
||||
if {[lsearch -exact $ll $enc] < 0} continue
|
||||
# look through the aliases for one that tcl knows about
|
||||
foreach e $ll {
|
||||
set i [lsearch -exact $lcnames $e]
|
||||
if {$i < 0} {
|
||||
if {[regsub {^iso[-_]} $e iso ex]} {
|
||||
set i [lsearch -exact $lcnames $ex]
|
||||
}
|
||||
}
|
||||
if {$i >= 0} break
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
if {$i >= 0} {
|
||||
return [lindex $names $i]
|
||||
}
|
||||
return {}
|
||||
}
|
@ -51,12 +51,15 @@ proc ask_popup {msg} {
|
||||
if {[reponame] ne {}} {
|
||||
append title " ([reponame])"
|
||||
}
|
||||
return [tk_messageBox \
|
||||
-parent . \
|
||||
set cmd [list tk_messageBox \
|
||||
-icon question \
|
||||
-type yesno \
|
||||
-title $title \
|
||||
-message $msg]
|
||||
if {[winfo ismapped .]} {
|
||||
lappend cmd -parent .
|
||||
}
|
||||
eval $cmd
|
||||
}
|
||||
|
||||
proc hook_failed_popup {hook msg} {
|
||||
|
@ -360,7 +360,7 @@ proc revert_helper {txt paths} {
|
||||
"[appname] ([reponame])" \
|
||||
"Revert changes in $s?
|
||||
|
||||
Any unadded changes will be permanently lost by the revert." \
|
||||
Any unstaged changes will be permanently lost by the revert." \
|
||||
question \
|
||||
1 \
|
||||
{Do Nothing} \
|
||||
|
@ -1,9 +1,12 @@
|
||||
# git-gui branch merge support
|
||||
# Copyright (C) 2006, 2007 Shawn Pearce
|
||||
|
||||
namespace eval merge {
|
||||
class merge {
|
||||
|
||||
proc _can_merge {} {
|
||||
field w ; # top level window
|
||||
field w_rev ; # mega-widget to pick the revision to merge
|
||||
|
||||
method _can_merge {} {
|
||||
global HEAD commit_type file_states
|
||||
|
||||
if {[string match amend* $commit_type]} {
|
||||
@ -42,7 +45,7 @@ The rescan will be automatically started now.
|
||||
|
||||
File [short_path $path] has merge conflicts.
|
||||
|
||||
You must resolve them, add the file, and commit to complete the current merge. Only then can you begin another merge.
|
||||
You must resolve them, stage the file, and commit to complete the current merge. Only then can you begin another merge.
|
||||
"
|
||||
unlock_index
|
||||
return 0
|
||||
@ -63,147 +66,93 @@ You should complete the current commit before starting a merge. Doing so will h
|
||||
return 1
|
||||
}
|
||||
|
||||
proc _refs {w list} {
|
||||
set r {}
|
||||
foreach i [$w.source.l curselection] {
|
||||
lappend r [lindex [lindex $list $i] 0]
|
||||
method _rev {} {
|
||||
if {[catch {$w_rev commit_or_die}]} {
|
||||
return {}
|
||||
}
|
||||
return $r
|
||||
return [$w_rev get]
|
||||
}
|
||||
|
||||
proc _visualize {w list} {
|
||||
set revs [_refs $w $list]
|
||||
if {$revs eq {}} return
|
||||
lappend revs --not HEAD
|
||||
do_gitk $revs
|
||||
method _visualize {} {
|
||||
set rev [_rev $this]
|
||||
if {$rev ne {}} {
|
||||
do_gitk [list $rev --not HEAD]
|
||||
}
|
||||
}
|
||||
|
||||
proc _start {w list} {
|
||||
global HEAD current_branch
|
||||
method _start {} {
|
||||
global HEAD current_branch remote_url
|
||||
|
||||
set cmd [list git merge]
|
||||
set names [_refs $w $list]
|
||||
set revcnt [llength $names]
|
||||
append cmd { } $names
|
||||
|
||||
if {$revcnt == 0} {
|
||||
set name [_rev $this]
|
||||
if {$name eq {}} {
|
||||
return
|
||||
} elseif {$revcnt == 1} {
|
||||
set unit branch
|
||||
} elseif {$revcnt <= 15} {
|
||||
set unit branches
|
||||
}
|
||||
|
||||
if {[tk_dialog \
|
||||
$w.confirm_octopus \
|
||||
[wm title $w] \
|
||||
"Use octopus merge strategy?
|
||||
set spec [$w_rev get_tracking_branch]
|
||||
set cmit [$w_rev get_commit]
|
||||
|
||||
You are merging $revcnt branches at once. This requires using the octopus merge driver, which may not succeed if there are file-level conflicts.
|
||||
" \
|
||||
question \
|
||||
0 \
|
||||
{Cancel} \
|
||||
{Use octopus} \
|
||||
] != 1} return
|
||||
set fh [open [gitdir FETCH_HEAD] w]
|
||||
fconfigure $fh -translation lf
|
||||
if {$spec eq {}} {
|
||||
set remote .
|
||||
set branch $name
|
||||
set stitle $branch
|
||||
} else {
|
||||
tk_messageBox \
|
||||
-icon error \
|
||||
-type ok \
|
||||
-title [wm title $w] \
|
||||
-parent $w \
|
||||
-message "Too many branches selected.
|
||||
|
||||
You have requested to merge $revcnt branches in an octopus merge. This exceeds Git's internal limit of 15 branches per merge.
|
||||
|
||||
Please select fewer branches. To merge more than 15 branches, merge the branches in batches.
|
||||
"
|
||||
return
|
||||
set remote $remote_url([lindex $spec 1])
|
||||
if {[regexp {^[^:@]*@[^:]*:/} $remote]} {
|
||||
regsub {^[^:@]*@} $remote {} remote
|
||||
}
|
||||
set branch [lindex $spec 2]
|
||||
set stitle "$branch of $remote"
|
||||
}
|
||||
regsub ^refs/heads/ $branch {} branch
|
||||
puts $fh "$cmit\t\tbranch '$branch' of $remote"
|
||||
close $fh
|
||||
|
||||
set msg "Merging $current_branch, [join $names {, }]"
|
||||
set cmd [list git]
|
||||
lappend cmd merge
|
||||
lappend cmd --strategy=recursive
|
||||
lappend cmd [git fmt-merge-msg <[gitdir FETCH_HEAD]]
|
||||
lappend cmd HEAD
|
||||
lappend cmd $cmit
|
||||
|
||||
set msg "Merging $current_branch and $stitle"
|
||||
ui_status "$msg..."
|
||||
set cons [console::new "Merge" $msg]
|
||||
console::exec $cons $cmd \
|
||||
[namespace code [list _finish $revcnt $cons]]
|
||||
set cons [console::new "Merge" "merge $stitle"]
|
||||
console::exec $cons $cmd [cb _finish $cons]
|
||||
|
||||
wm protocol $w WM_DELETE_WINDOW {}
|
||||
destroy $w
|
||||
}
|
||||
|
||||
proc _finish {revcnt w ok} {
|
||||
console::done $w $ok
|
||||
method _finish {cons ok} {
|
||||
console::done $cons $ok
|
||||
if {$ok} {
|
||||
set msg {Merge completed successfully.}
|
||||
} else {
|
||||
if {$revcnt != 1} {
|
||||
info_popup "Octopus merge failed.
|
||||
|
||||
Your merge of $revcnt branches has failed.
|
||||
|
||||
There are file-level conflicts between the branches which must be resolved manually.
|
||||
|
||||
The working directory will now be reset.
|
||||
|
||||
You can attempt this merge again by merging only one branch at a time." $w
|
||||
|
||||
set fd [git_read read-tree --reset -u HEAD]
|
||||
fconfigure $fd -blocking 0 -translation binary
|
||||
fileevent $fd readable \
|
||||
[namespace code [list _reset_wait $fd]]
|
||||
ui_status {Aborting... please wait...}
|
||||
return
|
||||
}
|
||||
|
||||
set msg {Merge failed. Conflict resolution is required.}
|
||||
}
|
||||
unlock_index
|
||||
rescan [list ui_status $msg]
|
||||
delete_this
|
||||
}
|
||||
|
||||
proc dialog {} {
|
||||
constructor dialog {} {
|
||||
global current_branch
|
||||
global M1B
|
||||
|
||||
if {![_can_merge]} return
|
||||
|
||||
set fmt {list %(objectname) %(*objectname) %(refname) %(subject)}
|
||||
set fr_fd [git_read for-each-ref \
|
||||
--tcl \
|
||||
--format=$fmt \
|
||||
refs/heads \
|
||||
refs/remotes \
|
||||
refs/tags \
|
||||
]
|
||||
fconfigure $fr_fd -translation binary
|
||||
while {[gets $fr_fd line] > 0} {
|
||||
set line [eval $line]
|
||||
set ref [lindex $line 2]
|
||||
regsub ^refs/(heads|remotes|tags)/ $ref {} ref
|
||||
set subj($ref) [lindex $line 3]
|
||||
lappend sha1([lindex $line 0]) $ref
|
||||
if {[lindex $line 1] ne {}} {
|
||||
lappend sha1([lindex $line 1]) $ref
|
||||
if {![_can_merge $this]} {
|
||||
delete_this
|
||||
return
|
||||
}
|
||||
}
|
||||
close $fr_fd
|
||||
|
||||
set to_show {}
|
||||
set fr_fd [git_read rev-list --all --not HEAD]
|
||||
while {[gets $fr_fd line] > 0} {
|
||||
if {[catch {set ref $sha1($line)}]} continue
|
||||
foreach n $ref {
|
||||
lappend to_show [list $n $line]
|
||||
make_toplevel top w
|
||||
wm title $top "[appname] ([reponame]): Merge"
|
||||
if {$top ne {.}} {
|
||||
wm geometry $top "+[winfo rootx .]+[winfo rooty .]"
|
||||
}
|
||||
}
|
||||
close $fr_fd
|
||||
set to_show [lsort -unique $to_show]
|
||||
|
||||
set w .merge_setup
|
||||
toplevel $w
|
||||
wm geometry $w "+[winfo rootx .]+[winfo rooty .]"
|
||||
|
||||
set _visualize [namespace code [list _visualize $w $to_show]]
|
||||
set _start [namespace code [list _start $w $to_show]]
|
||||
set _start [cb _start]
|
||||
|
||||
label $w.header \
|
||||
-text "Merge Into $current_branch" \
|
||||
@ -211,55 +160,51 @@ proc dialog {} {
|
||||
pack $w.header -side top -fill x
|
||||
|
||||
frame $w.buttons
|
||||
button $w.buttons.visualize -text Visualize -command $_visualize
|
||||
button $w.buttons.visualize \
|
||||
-text Visualize \
|
||||
-command [cb _visualize]
|
||||
pack $w.buttons.visualize -side left
|
||||
button $w.buttons.create -text Merge -command $_start
|
||||
pack $w.buttons.create -side right
|
||||
button $w.buttons.merge \
|
||||
-text Merge \
|
||||
-command $_start
|
||||
pack $w.buttons.merge -side right
|
||||
button $w.buttons.cancel \
|
||||
-text {Cancel} \
|
||||
-command "unlock_index;destroy $w"
|
||||
-command [cb _cancel]
|
||||
pack $w.buttons.cancel -side right -padx 5
|
||||
pack $w.buttons -side bottom -fill x -pady 10 -padx 10
|
||||
|
||||
labelframe $w.source -text {Source Branches}
|
||||
listbox $w.source.l \
|
||||
-height 10 \
|
||||
-width 70 \
|
||||
-font font_diff \
|
||||
-selectmode extended \
|
||||
-yscrollcommand [list $w.source.sby set]
|
||||
scrollbar $w.source.sby -command [list $w.source.l yview]
|
||||
pack $w.source.sby -side right -fill y
|
||||
pack $w.source.l -side left -fill both -expand 1
|
||||
pack $w.source -fill both -expand 1 -pady 5 -padx 5
|
||||
|
||||
foreach ref $to_show {
|
||||
set n [lindex $ref 0]
|
||||
if {[string length $n] > 20} {
|
||||
set n "[string range $n 0 16]..."
|
||||
}
|
||||
$w.source.l insert end [format {%s %-20s %s} \
|
||||
[string range [lindex $ref 1] 0 5] \
|
||||
$n \
|
||||
$subj([lindex $ref 0])]
|
||||
}
|
||||
|
||||
bind $w.source.l <Key-K> [list event generate %W <Shift-Key-Up>]
|
||||
bind $w.source.l <Key-J> [list event generate %W <Shift-Key-Down>]
|
||||
bind $w.source.l <Key-k> [list event generate %W <Key-Up>]
|
||||
bind $w.source.l <Key-j> [list event generate %W <Key-Down>]
|
||||
bind $w.source.l <Key-h> [list event generate %W <Key-Left>]
|
||||
bind $w.source.l <Key-l> [list event generate %W <Key-Right>]
|
||||
bind $w.source.l <Key-v> $_visualize
|
||||
set w_rev [::choose_rev::new_unmerged $w.rev {Revision To Merge}]
|
||||
pack $w.rev -anchor nw -fill both -expand 1 -pady 5 -padx 5
|
||||
|
||||
bind $w <$M1B-Key-Return> $_start
|
||||
bind $w <Visibility> "grab $w; focus $w.source.l"
|
||||
bind $w <Key-Escape> "unlock_index;destroy $w"
|
||||
wm protocol $w WM_DELETE_WINDOW "unlock_index;destroy $w"
|
||||
wm title $w "[appname] ([reponame]): Merge"
|
||||
bind $w <Key-Return> $_start
|
||||
bind $w <Key-Escape> [cb _cancel]
|
||||
wm protocol $w WM_DELETE_WINDOW [cb _cancel]
|
||||
|
||||
bind $w.buttons.merge <Visibility> [cb _visible]
|
||||
tkwait window $w
|
||||
}
|
||||
|
||||
method _visible {} {
|
||||
grab $w
|
||||
if {[is_config_true gui.matchtrackingbranch]} {
|
||||
$w_rev pick_tracking_branch
|
||||
}
|
||||
$w_rev focus_filter
|
||||
}
|
||||
|
||||
method _cancel {} {
|
||||
wm protocol $w WM_DELETE_WINDOW {}
|
||||
unlock_index
|
||||
destroy $w
|
||||
delete_this
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace eval merge {
|
||||
|
||||
proc reset_hard {} {
|
||||
global HEAD commit_type file_states
|
||||
|
||||
@ -274,20 +219,24 @@ You must finish amending this commit.
|
||||
if {![lock_index abort]} return
|
||||
|
||||
if {[string match *merge* $commit_type]} {
|
||||
set op merge
|
||||
set op_question "Abort merge?
|
||||
|
||||
Aborting the current merge will cause *ALL* uncommitted changes to be lost.
|
||||
|
||||
Continue with aborting the current merge?"
|
||||
} else {
|
||||
set op commit
|
||||
set op_question "Reset changes?
|
||||
|
||||
Resetting the changes will cause *ALL* uncommitted changes to be lost.
|
||||
|
||||
Continue with resetting the current changes?"
|
||||
}
|
||||
|
||||
if {[ask_popup "Abort $op?
|
||||
|
||||
Aborting the current $op will cause *ALL* uncommitted changes to be lost.
|
||||
|
||||
Continue with aborting the current $op?"] eq {yes}} {
|
||||
set fd [git_read read-tree --reset -u HEAD]
|
||||
if {[ask_popup $op_question] eq {yes}} {
|
||||
set fd [git_read --stderr read-tree --reset -u -v HEAD]
|
||||
fconfigure $fd -blocking 0 -translation binary
|
||||
fileevent $fd readable [namespace code [list _reset_wait $fd]]
|
||||
ui_status {Aborting... please wait...}
|
||||
$::main_status start {Aborting} {files reset}
|
||||
} else {
|
||||
unlock_index
|
||||
}
|
||||
@ -296,9 +245,12 @@ Continue with aborting the current $op?"] eq {yes}} {
|
||||
proc _reset_wait {fd} {
|
||||
global ui_comm
|
||||
|
||||
read $fd
|
||||
$::main_status update_meter [read $fd]
|
||||
|
||||
fconfigure $fd -blocking 1
|
||||
if {[eof $fd]} {
|
||||
close $fd
|
||||
set fail [catch {close $fd} err]
|
||||
$::main_status stop
|
||||
unlock_index
|
||||
|
||||
$ui_comm delete 0.0 end
|
||||
@ -310,7 +262,12 @@ proc _reset_wait {fd} {
|
||||
catch {file delete [gitdir MERGE_MSG]}
|
||||
catch {file delete [gitdir GITGUI_MSG]}
|
||||
|
||||
if {$fail} {
|
||||
warn_popup "Abort failed.\n\n$err"
|
||||
}
|
||||
rescan {ui_status {Abort completed. Ready.}}
|
||||
} else {
|
||||
fconfigure $fd -blocking 0
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,6 +57,7 @@ proc all_tracking_branches {} {
|
||||
proc load_all_remotes {} {
|
||||
global repo_config
|
||||
global all_remotes tracking_branches some_heads_tracking
|
||||
global remote_url
|
||||
|
||||
set some_heads_tracking 0
|
||||
set all_remotes [list]
|
||||
@ -76,6 +77,10 @@ proc load_all_remotes {} {
|
||||
catch {
|
||||
set fd [open [file join $rm_dir $name] r]
|
||||
while {[gets $fd line] >= 0} {
|
||||
if {[regexp {^URL:[ ]*(.+)$} $line line url]} {
|
||||
set remote_url($name) $url
|
||||
continue
|
||||
}
|
||||
if {![regexp {^Pull:[ ]*([^:]+):(.+)$} \
|
||||
$line line src dst]} continue
|
||||
if {[string index $src 0] eq {+}} {
|
||||
@ -100,6 +105,7 @@ proc load_all_remotes {} {
|
||||
foreach line [array names repo_config remote.*.url] {
|
||||
if {![regexp ^remote\.(.*)\.url\$ $line line name]} continue
|
||||
lappend all_remotes $name
|
||||
set remote_url($name) $repo_config(remote.$name.url)
|
||||
|
||||
if {[catch {set fl $repo_config(remote.$name.fetch)}]} {
|
||||
set fl {}
|
||||
|
Loading…
Reference in New Issue
Block a user