mirror of
https://github.com/git/git.git
synced 2024-10-30 05:47:53 +01:00
git-gui: Show a progress meter for checking out files
Sometimes switching between branches can take more than a second or two, in which case `git checkout` would normally have shown a small progress meter to the user on the terminal to let them know that we are in fact working, and give them a reasonable idea of when we may finish. We now do obtain that progress meter from read-tree -v and include it in our main window's status bar. This allows users to see how many files we have checked out, how many remain, and what percentage of the operation is completed. It should help to keep users from getting bored during a large checkout operation. Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
This commit is contained in:
parent
51530d1722
commit
b79223064e
2 changed files with 55 additions and 18 deletions
|
@ -19,6 +19,7 @@ field create 0; # create the branch if it doesn't exist?
|
|||
field reset_ok 0; # did the user agree to reset?
|
||||
field fetch_ok 0; # did the fetch succeed?
|
||||
|
||||
field readtree_d {}; # buffered output from read-tree
|
||||
field update_old {}; # was the update-ref call deferred?
|
||||
field reflog_msg {}; # log message for the update-ref call
|
||||
|
||||
|
@ -309,51 +310,69 @@ method _name {} {
|
|||
method _readtree {} {
|
||||
global HEAD
|
||||
|
||||
ui_status "Updating working directory to '[_name $this]'..."
|
||||
set readtree_d {}
|
||||
$::main_status start \
|
||||
"Updating working directory to '[_name $this]'..." \
|
||||
{files checked out}
|
||||
|
||||
set cmd [list git read-tree]
|
||||
lappend cmd -m
|
||||
lappend cmd -u
|
||||
lappend cmd -v
|
||||
lappend cmd --exclude-per-directory=.gitignore
|
||||
lappend cmd $HEAD
|
||||
lappend cmd $new_hash
|
||||
set fd [open "| $cmd" r]
|
||||
|
||||
if {[catch {
|
||||
set fd [open "| $cmd 2>@1" r]
|
||||
} err]} {
|
||||
# Older versions of Tcl 8.4 don't have this 2>@1 IO
|
||||
# redirect operator. Fallback to |& cat for those.
|
||||
#
|
||||
set fd [open "| $cmd |& cat" r]
|
||||
}
|
||||
|
||||
fconfigure $fd -blocking 0 -translation binary
|
||||
fileevent $fd readable [cb _readtree_wait $fd]
|
||||
}
|
||||
|
||||
method _readtree_wait {fd} {
|
||||
global selected_commit_type commit_type HEAD MERGE_HEAD PARENT
|
||||
global current_branch is_detached
|
||||
global ui_comm
|
||||
global current_branch
|
||||
|
||||
set buf [read $fd]
|
||||
$::main_status update_meter $buf
|
||||
append readtree_d $buf
|
||||
|
||||
# -- We never get interesting output on stdout; only stderr.
|
||||
#
|
||||
read $fd
|
||||
fconfigure $fd -blocking 1
|
||||
if {![eof $fd]} {
|
||||
fconfigure $fd -blocking 0
|
||||
return
|
||||
}
|
||||
|
||||
set name [_name $this]
|
||||
|
||||
# -- The working directory wasn't in sync with the index and
|
||||
# we'd have to overwrite something to make the switch. A
|
||||
# merge is required.
|
||||
#
|
||||
if {[catch {close $fd} err]} {
|
||||
if {[catch {close $fd}]} {
|
||||
set err $readtree_d
|
||||
regsub {^fatal: } $err {} err
|
||||
$::main_status stop "Aborted checkout of '[_name $this]' (file level merging is required)."
|
||||
warn_popup "File level merge required.
|
||||
|
||||
$err
|
||||
|
||||
Staying on branch '$current_branch'."
|
||||
ui_status "Aborted checkout of '$name' (file level merging is required)."
|
||||
unlock_index
|
||||
delete_this
|
||||
return
|
||||
}
|
||||
|
||||
$::main_status stop
|
||||
_after_readtree $this
|
||||
}
|
||||
|
||||
method _after_readtree {} {
|
||||
global selected_commit_type commit_type HEAD MERGE_HEAD PARENT
|
||||
global current_branch is_detached
|
||||
global ui_comm
|
||||
|
||||
set name [_name $this]
|
||||
set log "checkout: moving"
|
||||
if {!$is_detached} {
|
||||
append log " from $current_branch"
|
||||
|
|
|
@ -9,6 +9,7 @@ field w_c ; # canvas we draw a progress bar into
|
|||
field status {}; # single line of text we show
|
||||
field prefix {}; # text we format into status
|
||||
field units {}; # unit of progress
|
||||
field meter {}; # current core git progress meter (if active)
|
||||
|
||||
constructor new {path} {
|
||||
set w $path
|
||||
|
@ -45,6 +46,7 @@ method start {msg uds} {
|
|||
set status $msg
|
||||
set prefix $msg
|
||||
set units $uds
|
||||
set meter {}
|
||||
}
|
||||
|
||||
method update {have total} {
|
||||
|
@ -58,9 +60,25 @@ method update {have total} {
|
|||
$w_c coords bar 0 0 $pdone 20
|
||||
}
|
||||
|
||||
method stop {msg} {
|
||||
method update_meter {buf} {
|
||||
append meter $buf
|
||||
set r [string last "\r" $meter]
|
||||
if {$r == -1} {
|
||||
return
|
||||
}
|
||||
|
||||
set prior [string range $meter 0 $r]
|
||||
set meter [string range $meter [expr {$r + 1}] end]
|
||||
if {[regexp "\\((\\d+)/(\\d+)\\)\\s+done\r\$" $prior _j a b]} {
|
||||
update $this $a $b
|
||||
}
|
||||
}
|
||||
|
||||
method stop {{msg {}}} {
|
||||
destroy $w_c
|
||||
set status $msg
|
||||
if {$msg ne {}} {
|
||||
set status $msg
|
||||
}
|
||||
}
|
||||
|
||||
method show {msg {test {}}} {
|
||||
|
|
Loading…
Reference in a new issue