mirror of
https://github.com/git/git.git
synced 2024-10-30 05:47:53 +01:00
git-gui: Implement basic branch switching through read-tree.
If the user selects a different branch from the Branch menu, or asks us to create a new branch and immediately checkout that branch we now perform the update of the working directory by way of a 2 way read-tree invocation. This emulates the behavior of `git checkout branch` or the behavior of `git checkout -b branch initrev`. We don't however support the -m style behavior, where a switch can occur with file level merging performed by merge-recursive. Support for this is planned for a future update. Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
This commit is contained in:
parent
0fd49d0a7d
commit
b5b6b43452
1 changed files with 101 additions and 15 deletions
116
git-gui.sh
116
git-gui.sh
|
@ -2155,16 +2155,11 @@ proc do_delete_branch {} {
|
||||||
tkwait window $w
|
tkwait window $w
|
||||||
}
|
}
|
||||||
|
|
||||||
proc switch_branch {b} {
|
proc switch_branch {new_branch} {
|
||||||
global HEAD commit_type file_states current_branch
|
global HEAD commit_type current_branch repo_config
|
||||||
global selected_commit_type ui_comm
|
|
||||||
|
|
||||||
if {![lock_index switch]} return
|
if {![lock_index switch]} return
|
||||||
|
|
||||||
# -- Backup the selected branch (repository_state resets it)
|
|
||||||
#
|
|
||||||
set new_branch $current_branch
|
|
||||||
|
|
||||||
# -- Our in memory state should match the repository.
|
# -- Our in memory state should match the repository.
|
||||||
#
|
#
|
||||||
repository_state curType curHEAD curMERGE_HEAD
|
repository_state curType curHEAD curMERGE_HEAD
|
||||||
|
@ -2185,19 +2180,110 @@ The rescan will be automatically started now.
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
# -- Toss the message buffer if we are in amend mode.
|
if {$repo_config(gui.trustmtime) eq {true}} {
|
||||||
|
switch_branch_stage2 {} $new_branch
|
||||||
|
} else {
|
||||||
|
set ui_status_value {Refreshing file status...}
|
||||||
|
set cmd [list git update-index]
|
||||||
|
lappend cmd -q
|
||||||
|
lappend cmd --unmerged
|
||||||
|
lappend cmd --ignore-missing
|
||||||
|
lappend cmd --refresh
|
||||||
|
set fd_rf [open "| $cmd" r]
|
||||||
|
fconfigure $fd_rf -blocking 0 -translation binary
|
||||||
|
fileevent $fd_rf readable \
|
||||||
|
[list switch_branch_stage2 $fd_rf $new_branch]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
proc switch_branch_stage2 {fd_rf new_branch} {
|
||||||
|
global ui_status_value HEAD
|
||||||
|
|
||||||
|
if {$fd_rf ne {}} {
|
||||||
|
read $fd_rf
|
||||||
|
if {![eof $fd_rf]} return
|
||||||
|
close $fd_rf
|
||||||
|
}
|
||||||
|
|
||||||
|
set ui_status_value "Updating working directory to '$new_branch'..."
|
||||||
|
set cmd [list git read-tree]
|
||||||
|
lappend cmd -m
|
||||||
|
lappend cmd -u
|
||||||
|
lappend cmd --exclude-per-directory=.gitignore
|
||||||
|
lappend cmd $HEAD
|
||||||
|
lappend cmd $new_branch
|
||||||
|
set fd_rt [open "| $cmd" r]
|
||||||
|
fconfigure $fd_rt -blocking 0 -translation binary
|
||||||
|
fileevent $fd_rt readable \
|
||||||
|
[list switch_branch_readtree_wait $fd_rt $new_branch]
|
||||||
|
}
|
||||||
|
|
||||||
|
proc switch_branch_readtree_wait {fd_rt new_branch} {
|
||||||
|
global selected_commit_type commit_type HEAD MERGE_HEAD PARENT
|
||||||
|
global current_branch
|
||||||
|
global ui_comm ui_status_value
|
||||||
|
|
||||||
|
# -- We never get interesting output on stdout; only stderr.
|
||||||
#
|
#
|
||||||
if {[string match amend* $curType]} {
|
read $fd_rt
|
||||||
|
fconfigure $fd_rt -blocking 1
|
||||||
|
if {![eof $fd_rt]} {
|
||||||
|
fconfigure $fd_rt -blocking 0
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
# -- 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_rt} err]} {
|
||||||
|
regsub {^fatal: } $err {} err
|
||||||
|
warn_popup "File level merge required.
|
||||||
|
|
||||||
|
$err
|
||||||
|
|
||||||
|
Staying on branch '$current_branch'."
|
||||||
|
set ui_status_value "Aborted checkout of '$new_branch' (file level merging is required)."
|
||||||
|
unlock_index
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
# -- Update the symbolic ref. Core git doesn't even check for failure
|
||||||
|
# here, it Just Works(tm). If it doesn't we are in some really ugly
|
||||||
|
# state that is difficult to recover from within git-gui.
|
||||||
|
#
|
||||||
|
if {[catch {exec git symbolic-ref HEAD "refs/heads/$new_branch"} err]} {
|
||||||
|
error_popup "Failed to set current branch.
|
||||||
|
|
||||||
|
This working directory is only partially switched.
|
||||||
|
We successfully updated your files, but failed to
|
||||||
|
update an internal Git file.
|
||||||
|
|
||||||
|
This should not have occurred. [appname] will now
|
||||||
|
close and give up.
|
||||||
|
|
||||||
|
$err"
|
||||||
|
do_quit
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
# -- Update our repository state. If we were previously in amend mode
|
||||||
|
# we need to toss the current buffer and do a full rescan to update
|
||||||
|
# our file lists. If we weren't in amend mode our file lists are
|
||||||
|
# accurate and we can avoid the rescan.
|
||||||
|
#
|
||||||
|
unlock_index
|
||||||
|
set selected_commit_type new
|
||||||
|
if {[string match amend* $commit_type]} {
|
||||||
$ui_comm delete 0.0 end
|
$ui_comm delete 0.0 end
|
||||||
$ui_comm edit reset
|
$ui_comm edit reset
|
||||||
$ui_comm edit modified false
|
$ui_comm edit modified false
|
||||||
|
rescan {set ui_status_value "Checked out branch '$current_branch'."}
|
||||||
|
} else {
|
||||||
|
repository_state commit_type HEAD MERGE_HEAD
|
||||||
|
set PARENT $HEAD
|
||||||
|
set ui_status_value "Checked out branch '$current_branch'."
|
||||||
}
|
}
|
||||||
|
|
||||||
set selected_commit_type new
|
|
||||||
set current_branch $new_branch
|
|
||||||
|
|
||||||
unlock_index
|
|
||||||
error "NOT FINISHED"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
######################################################################
|
######################################################################
|
||||||
|
|
Loading…
Reference in a new issue