Code

git-gui: Don't let the user pull into an uncommitted working directory.
authorShawn O. Pearce <spearce@spearce.org>
Wed, 8 Nov 2006 03:00:38 +0000 (22:00 -0500)
committerShawn O. Pearce <spearce@spearce.org>
Wed, 8 Nov 2006 04:48:22 +0000 (23:48 -0500)
If there are modified files present in the working directory then we
should not let the user perform a pull as it may fail due to the modified
files being uncommitted but needing to be merged at the file level.

Yes there are many cases where a merge will complete successfully even
though there are modified or untracked files sitting in the working
directory.  But users generally shouldn't be attempting merges like that,
and if they are they probably are advanced enough to just use the command
line and bypass this little safety check.

We also no longer run a rescan after a successful pull has completed.
Usually this is unnecessary as a successful pull won't leave modified
files laying around.  Instead we just update our HEAD and PARENT values
with the new commit, if there is one.

Unfortunately this does let the user get into an insane state as there
are bugs in core Git's git-pull and git-merge programs where the exit
status is sent back as a 0 rather than non-0 when a failure is detected.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
git-gui

diff --git a/git-gui b/git-gui
index 4041aaacd9ff6d82010b1344372192bfdcc3b04b..d405008d2c7f85598f6d6dcac4c978a6906a1f7c 100755 (executable)
--- a/git-gui
+++ b/git-gui
@@ -642,7 +642,40 @@ proc fetch_from {remote} {
 }
 
 proc pull_remote {remote branch} {
+       global HEAD commit_type
+       global file_states
+
        if {![lock_index update]} return
+
+       # -- Our in memory state should match the repository.
+       #
+       repository_state curHEAD cur_type
+       if {$commit_type != $cur_type || $HEAD != $curHEAD} {
+               error_popup {Last scanned state does not match repository state.
+
+Its highly likely that another Git program modified the
+repository since our last scan.  A rescan is required
+before a pull can be started.
+}
+               unlock_index
+               update_status
+               return
+       }
+
+       # -- No differences should exist before a pull.
+       #
+       if {[array size file_states] != 0} {
+               error_popup {Uncommitted but modified files are present.
+
+You should not perform a pull with unmodified files in your working
+directory as Git would be unable to recover from an incorrect merge.
+
+Commit or throw away all changes before starting a pull operation.
+}
+               unlock_index
+               return
+       }
+
        set w [new_console "pull $remote $branch" \
                "Pulling new changes from branch $branch in $remote"]
        set cmd [list git pull]
@@ -652,9 +685,14 @@ proc pull_remote {remote branch} {
 }
 
 proc post_pull_remote {remote branch success} {
+       global HEAD PARENT commit_type
+       global ui_status_value
+
        unlock_index
        if {$success} {
-               update_status "Successfully pulled $branch from $remote."
+               repository_state HEAD commit_type
+               set PARENT $HEAD
+               set $ui_status_value {Ready.}
        } else {
                update_status "Conflicts detected while pulling $branch from $remote."
        }