}
}
+proc gitattr {path attr default} {
+ if {[catch {set r [git check-attr $attr -- $path]}]} {
+ set r unspecified
+ } else {
+ set r [join [lrange [split $r :] 2 end] :]
+ regsub {^ } $r {} r
+ }
+ if {$r eq {unspecified}} {
+ return $default
+ }
+ return $r
+}
+
proc sq {value} {
regsub -all ' $value "'\\''" value
return "'$value'"
if {[is_Windows]} {
wm iconbitmap . -default $oguilib/git-gui.ico
+ set ::tk::AlwaysShowSelection 1
}
######################################################################
set default_config(user.name) {}
set default_config(user.email) {}
+set default_config(gui.encoding) [encoding system]
set default_config(gui.matchtrackingbranch) false
set default_config(gui.pruneduringfetch) false
set default_config(gui.trustmtime) false
##
## repository setup
+set picked 0
if {[catch {
set _gitdir $env(GIT_DIR)
set _prefix {}
load_config 1
apply_config
choose_repository::pick
+ set picked 1
}
if {![file isdirectory $_gitdir] && [is_Cygwin]} {
catch {set _gitdir [exec cygpath --windows $_gitdir]}
set is_detached 0
set current_diff_path {}
set is_3way_diff 0
+set is_conflict_diff 0
set selected_commit_type new
set nullid "0000000000000000000000000000000000000000"
set nullid2 "0000000000000000000000000000000000000001"
+set have_tk85 [expr {[package vcompare $tk_version "8.5"] >= 0}]
+
######################################################################
##
## task management
|| [string trim [$ui_comm get 0.0 end]] eq {})} {
if {[string match amend* $commit_type]} {
} elseif {[load_message GITGUI_MSG]} {
+ } elseif {[run_prepare_commit_msg_hook]} {
} elseif {[load_message MERGE_MSG]} {
} elseif {[load_message SQUASH_MSG]} {
}
return 0
}
+proc run_prepare_commit_msg_hook {} {
+ global pch_error
+
+ # prepare-commit-msg requires PREPARE_COMMIT_MSG exist. From git-gui
+ # it will be .git/MERGE_MSG (merge), .git/SQUASH_MSG (squash), or an
+ # empty file but existant file.
+
+ set fd_pcm [open [gitdir PREPARE_COMMIT_MSG] a]
+
+ if {[file isfile [gitdir MERGE_MSG]]} {
+ set pcm_source "merge"
+ set fd_mm [open [gitdir MERGE_MSG] r]
+ puts -nonewline $fd_pcm [read $fd_mm]
+ close $fd_mm
+ } elseif {[file isfile [gitdir SQUASH_MSG]]} {
+ set pcm_source "squash"
+ set fd_sm [open [gitdir SQUASH_MSG] r]
+ puts -nonewline $fd_pcm [read $fd_sm]
+ close $fd_sm
+ } else {
+ set pcm_source ""
+ }
+
+ close $fd_pcm
+
+ set fd_ph [githook_read prepare-commit-msg \
+ [gitdir PREPARE_COMMIT_MSG] $pcm_source]
+ if {$fd_ph eq {}} {
+ catch {file delete [gitdir PREPARE_COMMIT_MSG]}
+ return 0;
+ }
+
+ ui_status [mc "Calling prepare-commit-msg hook..."]
+ set pch_error {}
+
+ fconfigure $fd_ph -blocking 0 -translation binary -eofchar {}
+ fileevent $fd_ph readable \
+ [list prepare_commit_msg_hook_wait $fd_ph]
+
+ return 1;
+}
+
+proc prepare_commit_msg_hook_wait {fd_ph} {
+ global pch_error
+
+ append pch_error [read $fd_ph]
+ fconfigure $fd_ph -blocking 1
+ if {[eof $fd_ph]} {
+ if {[catch {close $fd_ph}]} {
+ ui_status [mc "Commit declined by prepare-commit-msg hook."]
+ hook_failed_popup prepare-commit-msg $pch_error
+ catch {file delete [gitdir PREPARE_COMMIT_MSG]}
+ exit 1
+ } else {
+ load_message PREPARE_COMMIT_MSG
+ }
+ set pch_error {}
+ catch {file delete [gitdir PREPARE_COMMIT_MSG]}
+ return
+ }
+ fconfigure $fd_ph -blocking 0
+ catch {file delete [gitdir PREPARE_COMMIT_MSG]}
+}
+
proc read_diff_index {fd after} {
global buf_rdi
}
}
+proc do_explore {} {
+ set explorer {}
+ if {[is_Cygwin] || [is_Windows]} {
+ set explorer "explorer.exe"
+ } elseif {[is_MacOSX]} {
+ set explorer "open"
+ } else {
+ # freedesktop.org-conforming system is our best shot
+ set explorer "xdg-open"
+ }
+ eval exec $explorer [file dirname [gitdir]] &
+}
+
set is_quitting 0
set ret_code 1
$ui_index tag remove in_sel 0.0 end
$ui_workdir tag remove in_sel 0.0 end
- # Do not stage files with conflicts
+ # Determine the state of the file
if {[info exists file_states($path)]} {
set state [lindex $file_states($path) 0]
} else {
set state {__}
}
- if {[string first {U} $state] >= 0} {
- set col 1
- }
-
# Restage the file, or simply show the diff
if {$col == 0 && $y > 1} {
+ # Conflicts need special handling
+ if {[string first {U} $state] >= 0} {
+ # $w must always be $ui_workdir, but...
+ if {$w ne $ui_workdir} { set lno {} }
+ merge_stage_workdir $path $lno
+ return
+ }
+
if {[string index $state 1] eq {O}} {
set mmask {}
} else {
#
menu .mbar.repository
+.mbar.repository add command \
+ -label [mc "Explore Working Copy"] \
+ -command {do_explore}
+.mbar.repository add separator
+
.mbar.repository add command \
-label [mc "Browse Current Branch's Files"] \
-command {browser::new $current_branch}
if {[is_enabled multicommit] || [is_enabled singlecommit]} {
menu .mbar.commit
- .mbar.commit add radiobutton \
- -label [mc "New Commit"] \
- -command do_select_commit_type \
- -variable selected_commit_type \
- -value new
- lappend disable_on_lock \
- [list .mbar.commit entryconf [.mbar.commit index last] -state]
+ if {![is_enabled nocommit]} {
+ .mbar.commit add radiobutton \
+ -label [mc "New Commit"] \
+ -command do_select_commit_type \
+ -variable selected_commit_type \
+ -value new
+ lappend disable_on_lock \
+ [list .mbar.commit entryconf [.mbar.commit index last] -state]
- .mbar.commit add radiobutton \
- -label [mc "Amend Last Commit"] \
- -command do_select_commit_type \
- -variable selected_commit_type \
- -value amend
- lappend disable_on_lock \
- [list .mbar.commit entryconf [.mbar.commit index last] -state]
+ .mbar.commit add radiobutton \
+ -label [mc "Amend Last Commit"] \
+ -command do_select_commit_type \
+ -variable selected_commit_type \
+ -value amend
+ lappend disable_on_lock \
+ [list .mbar.commit entryconf [.mbar.commit index last] -state]
- .mbar.commit add separator
+ .mbar.commit add separator
+ }
.mbar.commit add command -label [mc Rescan] \
-command ui_do_rescan \
.mbar.commit add separator
- .mbar.commit add command -label [mc "Sign Off"] \
- -command do_signoff \
- -accelerator $M1T-S
+ if {![is_enabled nocommitmsg]} {
+ .mbar.commit add command -label [mc "Sign Off"] \
+ -command do_signoff \
+ -accelerator $M1T-S
+ }
.mbar.commit add command -label [commit_btn_caption] \
-command do_commit \
if {[is_enabled transport]} {
menu .mbar.remote
+ .mbar.remote add command \
+ -label [mc "Add..."] \
+ -command remote_add::dialog \
+ -accelerator $M1T-A
.mbar.remote add command \
-label [mc "Push..."] \
-command do_push_anywhere \
-accelerator $M1T-P
.mbar.remote add command \
- -label [mc "Delete..."] \
+ -label [mc "Delete Branch..."] \
-command remote_branch_delete::dialog
}
-command do_about
}
-set browser {}
-catch {set browser $repo_config(instaweb.browser)}
+
set doc_path [file dirname [gitexec]]
set doc_path [file join $doc_path Documentation index.html]
set doc_path [exec cygpath --mixed $doc_path]
}
-if {$browser eq {}} {
- if {[is_MacOSX]} {
- set browser open
- } elseif {[is_Cygwin]} {
- set program_files [file dirname [exec cygpath --windir]]
- set program_files [file join $program_files {Program Files}]
- set firefox [file join $program_files {Mozilla Firefox} firefox.exe]
- set ie [file join $program_files {Internet Explorer} IEXPLORE.EXE]
- if {[file exists $firefox]} {
- set browser $firefox
- } elseif {[file exists $ie]} {
- set browser $ie
- }
- unset program_files firefox ie
- }
-}
-
if {[file isfile $doc_path]} {
set doc_url "file:$doc_path"
} else {
set doc_url {http://www.kernel.org/pub/software/scm/git/docs/}
}
-if {$browser ne {}} {
- .mbar.help add command -label [mc "Online Documentation"] \
- -command [list exec $browser $doc_url &]
+proc start_browser {url} {
+ git "web--browse" $url
}
-unset browser doc_path doc_url
+
+.mbar.help add command -label [mc "Online Documentation"] \
+ -command [list start_browser $doc_url]
+unset doc_path doc_url
# -- Standard bindings
#
lappend disable_on_lock \
{.vpane.lower.commarea.buttons.incall conf -state}
-button .vpane.lower.commarea.buttons.signoff -text [mc "Sign Off"] \
- -command do_signoff
-pack .vpane.lower.commarea.buttons.signoff -side top -fill x
+if {![is_enabled nocommitmsg]} {
+ button .vpane.lower.commarea.buttons.signoff -text [mc "Sign Off"] \
+ -command do_signoff
+ pack .vpane.lower.commarea.buttons.signoff -side top -fill x
+}
button .vpane.lower.commarea.buttons.commit -text [commit_btn_caption] \
-command do_commit
lappend disable_on_lock \
{.vpane.lower.commarea.buttons.commit conf -state}
-button .vpane.lower.commarea.buttons.push -text [mc Push] \
- -command do_push_anywhere
-pack .vpane.lower.commarea.buttons.push -side top -fill x
-
-if {[is_enabled nocommitmsg]} {
- .vpane.lower.commarea.buttons.signoff configure -state disabled
-}
-if {[is_enabled nocommit]} {
- .vpane.lower.commarea.buttons.push configure -state disabled
+if {![is_enabled nocommit]} {
+ button .vpane.lower.commarea.buttons.push -text [mc Push] \
+ -command do_push_anywhere
+ pack .vpane.lower.commarea.buttons.push -side top -fill x
}
# -- Commit Message Buffer
frame .vpane.lower.commarea.buffer.header
set ui_comm .vpane.lower.commarea.buffer.t
set ui_coml .vpane.lower.commarea.buffer.header.l
-radiobutton .vpane.lower.commarea.buffer.header.new \
- -text [mc "New Commit"] \
- -command do_select_commit_type \
- -variable selected_commit_type \
- -value new
-lappend disable_on_lock \
- [list .vpane.lower.commarea.buffer.header.new conf -state]
-radiobutton .vpane.lower.commarea.buffer.header.amend \
- -text [mc "Amend Last Commit"] \
- -command do_select_commit_type \
- -variable selected_commit_type \
- -value amend
-lappend disable_on_lock \
- [list .vpane.lower.commarea.buffer.header.amend conf -state]
+
+if {![is_enabled nocommit]} {
+ radiobutton .vpane.lower.commarea.buffer.header.new \
+ -text [mc "New Commit"] \
+ -command do_select_commit_type \
+ -variable selected_commit_type \
+ -value new
+ lappend disable_on_lock \
+ [list .vpane.lower.commarea.buffer.header.new conf -state]
+ radiobutton .vpane.lower.commarea.buffer.header.amend \
+ -text [mc "Amend Last Commit"] \
+ -command do_select_commit_type \
+ -variable selected_commit_type \
+ -value amend
+ lappend disable_on_lock \
+ [list .vpane.lower.commarea.buffer.header.amend conf -state]
+}
+
label $ui_coml \
-anchor w \
-justify left
}
trace add variable commit_type write trace_commit_type
pack $ui_coml -side left -fill x
-pack .vpane.lower.commarea.buffer.header.amend -side right
-pack .vpane.lower.commarea.buffer.header.new -side right
+
+if {![is_enabled nocommit]} {
+ pack .vpane.lower.commarea.buffer.header.amend -side right
+ pack .vpane.lower.commarea.buffer.header.new -side right
+}
text $ui_comm -background white -foreground black \
-borderwidth 1 \
-command {incr_font_size font_diff 1}
lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
$ctxm add separator
+ set emenu $ctxm.enc
+ menu $emenu
+ build_encoding_menu $emenu [list force_diff_encoding]
+ $ctxm add cascade \
+ -label [mc "Encoding"] \
+ -menu $emenu
+ lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
+ $ctxm add separator
$ctxm add command -label [mc "Options..."] \
-command do_options
}
-command {merge_resolve_one 1}
lappend diff_actions [list $ctxmmg entryconf [$ctxmmg index last] -state]
$ctxmmg add separator
-$ctxmmg add command \
- -label [mc "Stage Working Copy"] \
- -command {merge_resolve_one 0}
-lappend diff_actions [list $ctxmmg entryconf [$ctxmmg index last] -state]
-$ctxmmg add separator
create_common_diff_popup $ctxmmg
proc popup_diff_menu {ctxm ctxmmg x y X Y} {
load_all_remotes
set n [.mbar.remote index end]
- populate_push_menu
- populate_fetch_menu
+ populate_remotes_menu
set n [expr {[.mbar.remote index end] - $n}]
if {$n > 0} {
if {[.mbar.remote type 0] eq "tearoff"} { incr n }
if {[is_enabled retcode]} {
bind . <Destroy> {+terminate_me %W}
}
+if {$picked && [is_config_true gui.autoexplore]} {
+ do_explore
+}