git-gui: Make initial commits work properly.

Apparently I never really tested the logic for making or amending an
initial commit, so although most of the code was here in git-gui it
didn't quite work as it was intended to.

So this is all just bug fixes to make initial commits correctly
generate the list of files going into the initial commit, or to
show a newly added file's diff, and to amend an initial commit.

Because we really want to diff the index against a tree-ish and
there is no such tree-ish on an initial commit we create an empty
tree through git-mktree and diff against that.  This unfortunately
creates a dangling tree, which may confuse a new user who uses
git-gui to make a new commit and then immediately afterwards runs
git fsck-objects to see if their object database is corrupt or not.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
This commit is contained in:
Shawn O. Pearce 2006-11-18 02:50:58 -05:00
parent cbbaa28bc0
commit 4539eacd6d

74
git-gui
View File

@ -205,6 +205,7 @@ set index_lock_type none
set HEAD {} set HEAD {}
set PARENT {} set PARENT {}
set commit_type {} set commit_type {}
set empty_tree {}
proc lock_index {type} { proc lock_index {type} {
global index_lock_type disable_on_lock global index_lock_type disable_on_lock
@ -240,6 +241,7 @@ proc repository_state {hdvar ctvar} {
upvar $hdvar hd $ctvar ct upvar $hdvar hd $ctvar ct
if {[catch {set hd [exec git rev-parse --verify HEAD]}]} { if {[catch {set hd [exec git rev-parse --verify HEAD]}]} {
set hd {}
set ct initial set ct initial
} elseif {[file exists [file join $gitdir MERGE_HEAD]]} { } elseif {[file exists [file join $gitdir MERGE_HEAD]]} {
set ct merge set ct merge
@ -248,6 +250,18 @@ proc repository_state {hdvar ctvar} {
} }
} }
proc PARENT {} {
global PARENT empty_tree
if {$PARENT ne {}} {
return $PARENT
}
if {$empty_tree eq {}} {
set empty_tree [exec git mktree << {}]
}
return $empty_tree
}
proc rescan {after} { proc rescan {after} {
global HEAD PARENT commit_type global HEAD PARENT commit_type
global ui_index ui_other ui_status_value ui_comm global ui_index ui_other ui_status_value ui_comm
@ -257,7 +271,7 @@ proc rescan {after} {
if {$rescan_active > 0 || ![lock_index read]} return if {$rescan_active > 0 || ![lock_index read]} return
repository_state new_HEAD new_type repository_state new_HEAD new_type
if {$commit_type eq {amend} if {[string match amend* $commit_type]
&& $new_type eq {normal} && $new_type eq {normal}
&& $new_HEAD eq $HEAD} { && $new_HEAD eq $HEAD} {
} else { } else {
@ -296,10 +310,8 @@ proc rescan {after} {
} }
proc rescan_stage2 {fd after} { proc rescan_stage2 {fd after} {
global gitdir PARENT commit_type global gitdir ui_status_value
global ui_index ui_other ui_status_value ui_comm global rescan_active buf_rdi buf_rdf buf_rlo
global rescan_active
global buf_rdi buf_rdf buf_rlo
if {$fd ne {}} { if {$fd ne {}} {
read $fd read $fd
@ -320,7 +332,7 @@ proc rescan_stage2 {fd after} {
set rescan_active 3 set rescan_active 3
set ui_status_value {Scanning for modified files ...} set ui_status_value {Scanning for modified files ...}
set fd_di [open "| git diff-index --cached -z $PARENT" r] set fd_di [open "| git diff-index --cached -z [PARENT]" r]
set fd_df [open "| git diff-files -z" r] set fd_df [open "| git diff-files -z" r]
set fd_lo [open $ls_others r] set fd_lo [open $ls_others r]
@ -532,7 +544,7 @@ files list, to prevent possible confusion.
proc show_diff {path {w {}} {lno {}}} { proc show_diff {path {w {}} {lno {}}} {
global file_states file_lists global file_states file_lists
global PARENT diff_3way diff_active repo_config global diff_3way diff_active repo_config
global ui_diff current_diff ui_status_value global ui_diff current_diff ui_status_value
if {$diff_active || ![lock_index read]} return if {$diff_active || ![lock_index read]} return
@ -591,7 +603,7 @@ proc show_diff {path {w {}} {lno {}}} {
} }
} }
lappend cmd $PARENT lappend cmd [PARENT]
lappend cmd -- lappend cmd --
lappend cmd $path lappend cmd $path
@ -671,7 +683,7 @@ proc read_diff {fd} {
proc load_last_commit {} { proc load_last_commit {} {
global HEAD PARENT commit_type ui_comm global HEAD PARENT commit_type ui_comm
if {$commit_type eq {amend}} return if {[string match amend* $commit_type]} return
if {$commit_type ne {normal}} { if {$commit_type ne {normal}} {
error_popup "Can't amend a $commit_type commit." error_popup "Can't amend a $commit_type commit."
return return
@ -695,23 +707,24 @@ proc load_last_commit {} {
return return
} }
if {$parent_count > 1} {
error_popup {Can't amend a merge commit.}
return
}
if {$parent_count == 0} { if {$parent_count == 0} {
set commit_type amend set commit_type amend-initial
set HEAD {}
set PARENT {} set PARENT {}
rescan {set ui_status_value {Ready.}}
} elseif {$parent_count == 1} { } elseif {$parent_count == 1} {
set commit_type amend set commit_type amend
set PARENT $parent set PARENT $parent
$ui_comm delete 0.0 end
$ui_comm insert end $msg
$ui_comm edit modified false
$ui_comm edit reset
rescan {set ui_status_value {Ready.}}
} else {
error_popup {You can't amend a merge commit.}
return
} }
$ui_comm delete 0.0 end
$ui_comm insert end $msg
$ui_comm edit modified false
$ui_comm edit reset
rescan {set ui_status_value {Ready.}}
} }
proc commit_tree {} { proc commit_tree {} {
@ -722,7 +735,7 @@ proc commit_tree {} {
# -- Our in memory state should match the repository. # -- Our in memory state should match the repository.
# #
repository_state curHEAD cur_type repository_state curHEAD cur_type
if {$commit_type eq {amend} if {[string match amend* $commit_type]
&& $cur_type eq {normal} && $cur_type eq {normal}
&& $curHEAD eq $HEAD} { && $curHEAD eq $HEAD} {
} elseif {$commit_type ne $cur_type || $HEAD ne $curHEAD} { } elseif {$commit_type ne $cur_type || $HEAD ne $curHEAD} {
@ -2559,13 +2572,18 @@ label $ui_coml -text {Commit Message:} \
-anchor w \ -anchor w \
-justify left \ -justify left \
-font font_ui -font font_ui
trace add variable commit_type write {uplevel #0 { proc trace_commit_type {varname args} {
switch -glob $commit_type \ global ui_coml commit_type
initial {$ui_coml conf -text {Initial Commit Message:}} \ switch -glob -- $commit_type {
amend {$ui_coml conf -text {Amended Commit Message:}} \ initial {set txt {Initial Commit Message:}}
merge {$ui_coml conf -text {Merge Commit Message:}} \ amend {set txt {Amended Commit Message:}}
* {$ui_coml conf -text {Commit Message:}} amend-initial {set txt {Amended Initial Commit Message:}}
}} merge {set txt {Merge Commit Message:}}
* {set txt {Commit Message:}}
}
$ui_coml conf -text $txt
}
trace add variable commit_type write trace_commit_type
text $ui_comm -background white -borderwidth 1 \ text $ui_comm -background white -borderwidth 1 \
-undo true \ -undo true \
-maxundo 20 \ -maxundo 20 \