From: Mark Levedahl Date: Sun, 31 May 2026 23:02:20 +0000 (-0400) Subject: git-gui: use git rev-parse for worktree discovery X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=80b7207e68ffaf56077d9b7d00eb31490fb48cc5;p=thirdparty%2Fgit.git git-gui: use git rev-parse for worktree discovery git gui uses a combination of tcl code and git invocations to determine the worktree and the location with respect to the worktree root (_prefix). But, git rev-parse provides all of this information directly, and assures full error and configuration checking are done by git itself. The entirety of discovery in normal configurations involves git rev-parse --show-toplevel (gets worktree root) git rev-parse --show-prefix (shows location wrt the root) An error thrown on either of these lines means the worktree discovered by git is unusable, or git did not discover a worktree because the current directory is inside the repository. If the user has defined GIT_DIR or GIT_WORK_TREE, this is a user configuration error and git-gui should stop. Otherwise, the blame or browser subcommands can be used without a worktree. A separate error might occur when changing to the root of the discovered worktree. The cause would be file system related and completely outside of git's control, so trap that independently. Discovery of the repository and the worktree must be guarded to trap errors: the intent is that any configuration problems are caught during discovery, and later processing need not include error trapping and recovery. So, move all worktree discovery code to be immediately after repository discovery. This does move configuration loading to occur after worktree discovery rather than before. None of the code executed in worktree discovery has any option controlled by a git-gui configuration variable, so no impact is expected. git itself will always read the repository configuration, including worktree specific configuration data if that exists, so this is unaffected by when git-gui loads its own config data. Also, we cannot be sure the worktree dependent configuration can be loaded before full discovery is complete. Signed-off-by: Mark Levedahl Signed-off-by: Johannes Sixt --- diff --git a/git-gui.sh b/git-gui.sh index a057b3f675..66379f290f 100755 --- a/git-gui.sh +++ b/git-gui.sh @@ -1187,6 +1187,33 @@ if {$_gitdir eq {}} { set picked 1 } +# find worktree, continue without if not required +if {[catch { + set _gitworktree [git rev-parse --show-toplevel] + set _prefix [git rev-parse --show-prefix] + } err]} { + if {[is_gitvars_error $err]} { + exit 1 + } + set _gitworktree {} + set _prefix {} +} + +if {![is_bare]} { + if {[catch {cd $_gitworktree} err]} { + catch {wm withdraw .} + error_popup [strcat [mc "No working directory"] " $_gitworktree:\n\n$err"] + exit 1 + } +} elseif {![is_enabled bare]} { + catch {wm withdraw .} + error_popup [strcat [mc "Cannot use bare repository:"] "\n\n$_gitdir"] + exit 1 +} + +# repository and worktree config are complete, export them +set_gitdir_vars + # Use object format as hash algorithm (either "sha1" or "sha256") set hashalgorithm [git rev-parse --show-object-format] if {$hashalgorithm eq "sha1"} { @@ -1202,37 +1229,6 @@ if {$hashalgorithm eq "sha1"} { load_config 0 apply_config -set _gitworktree [git rev-parse --show-toplevel] - -if {$_prefix ne {}} { - if {$_gitworktree eq {}} { - regsub -all {[^/]+/} $_prefix ../ cdup - } else { - set cdup $_gitworktree - } - if {[catch {cd $cdup} err]} { - catch {wm withdraw .} - error_popup [strcat [mc "Cannot move to top of working directory:"] "\n\n$err"] - exit 1 - } - set _gitworktree [pwd] - unset cdup -} elseif {![is_enabled bare]} { - if {[is_bare]} { - catch {wm withdraw .} - error_popup [strcat [mc "Cannot use bare repository:"] "\n\n$_gitdir"] - exit 1 - } - if {$_gitworktree eq {}} { - set _gitworktree [file dirname $_gitdir] - } - if {[catch {cd $_gitworktree} err]} { - catch {wm withdraw .} - error_popup [strcat [mc "No working directory"] " $_gitworktree:\n\n$err"] - exit 1 - } - set _gitworktree [pwd] -} set _reponame [file split [file normalize $_gitdir]] if {[lindex $_reponame end] eq {.git}} { set _reponame [lindex $_reponame end-1] @@ -1240,9 +1236,6 @@ if {[lindex $_reponame end] eq {.git}} { set _reponame [lindex $_reponame end] } -# Export the final paths -set_gitdir_vars - ###################################################################### ## ## global init