Git development
 help / color / mirror / Atom feed
From: Shroom Moo <egg_mushroomcow@foxmail.com>
To: git@vger.kernel.org
Cc: Johannes Sixt <j6t@kdbg.org>, Mark Levedahl <mlevedahl@gmail.com>,
	Shroom Moo <egg_mushroomcow@foxmail.com>
Subject: [PATCH v6 1/3] git-gui: restructure repository startup
Date: Thu,  7 May 2026 04:27:49 +0800	[thread overview]
Message-ID: <tencent_E834EEF92D17298D51E74F26219DCA807007@qq.com> (raw)
In-Reply-To: <20260506202751.3294-1-egg_mushroomcow@foxmail.com>

When git-gui is started inside a .git directory of a non-bare
repository, it should treat the parent directory as the worktree,
as it did before commit 2d92ab32fd (rev-parse: make --show-toplevel
without a worktree an error, 2019-11-19).  However, a bare repository
or a separated gitdir without a worktree must be rejected early.

Protect the previously unguarded calls to `git rev-parse
--show-object-format` and `--show-toplevel`.  Restructure the startup
sequence to:

- Check for a bare repository right after loading the config.  If the
  repository is bare and the current subcommand does not allow bare
  repos (e.g. normal commit mode), show "Cannot use bare repository"
  and exit.

- When `rev-parse --show-toplevel` fails and the repository is
  non-bare, the gitdir path ends with ".git", and we are inside that
  gitdir, use the parent directory as the worktree.  This preserves
  the ability to start git-gui from within a regular repository’s
  .git directory, which was intentionally supported since 87cd09f43e56
  (git-gui: work from the .git dir, 2010-01-23).

- Otherwise, show a descriptive error and exit.

- Wrap `rev-parse --show-object-format` in a catch to avoid a crash
  when the repository configuration is broken (e.g. core.worktree
  pointing to an invalid path).

Also removes the old `_prefix`‑based fallback that computed a relative
path to the worktree top from a subdirectory, and the unconditional
`[file dirname $_gitdir]` guess.  Both are unnecessary now that
`rev‑parse --show‑toplevel` directly provides the absolute top‑level
path and we can `cd` to it.  The guess is further unsafe in
multi‑worktree setups, where a gitdir may have more than one worktree.
The only remaining fallback is the explicit “.git directory” rule for
non‑bare repositories, which mirrors the historical behaviour.

This fixes the fatal Tcl error when the working tree is missing, while
keeping the .git startup feature and avoiding any automatic directory
switching that could be dangerous in multi‑worktree setups.

Helped-by: Johannes Sixt <j6t@kdbg.org>
Helped-by: Mark Levedahl <mlevedahl@gmail.com>
Signed-off-by: Shroom Moo <egg_mushroomcow@foxmail.com>
---
 git-gui/git-gui.sh | 72 +++++++++++++++++++++++++++++-----------------
 1 file changed, 46 insertions(+), 26 deletions(-)

diff --git a/git-gui/git-gui.sh b/git-gui/git-gui.sh
index 23fe76e498..fbdc0b2a41 100755
--- a/git-gui/git-gui.sh
+++ b/git-gui/git-gui.sh
@@ -1129,7 +1129,8 @@ if {[catch {
 		}]
 	&& [catch {
 		# beware that from the .git dir this sets _gitdir to .
-		# and _prefix to the empty string
+		# and _prefix to the empty string; this is handled by
+		# the startup safety checks below
 		set _gitdir [git rev-parse --git-dir]
 		set _prefix [git rev-parse --show-prefix]
 	} err]} {
@@ -1142,8 +1143,20 @@ if {[catch {
 	set picked 1
 }
 
+if {![file isdirectory $_gitdir]} {
+	catch {wm withdraw .}
+	error_popup [strcat 
+		[mc "Git directory not found:"] "\n\n$_gitdir\n\n" \
+		[mc "Please ensure GIT_DIR points to a valid Git repository"]]
+	exit 1
+}
+
 # Use object format as hash algorithm (either "sha1" or "sha256")
-set hashalgorithm [git rev-parse --show-object-format]
+if {[catch {set hashalgorithm [git rev-parse --show-object-format]} err]} {
+	catch {wm withdraw .}
+	error_popup [strcat [mc "Failed to determine hash algorithm:"] "\n\n$err"]
+	exit 1
+}
 if {$hashalgorithm eq "sha1"} {
 	set hashlength 40
 } elseif {$hashalgorithm eq "sha256"} {
@@ -1160,46 +1173,52 @@ if {$_gitdir eq "."} {
 	set _gitdir [pwd]
 }
 
-if {![file isdirectory $_gitdir]} {
-	catch {wm withdraw .}
-	error_popup [strcat [mc "Git directory not found:"] "\n\n$_gitdir"]
-	exit 1
-}
 # _gitdir exists, so try loading the config
 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]} {
+# Handle bare repository and determine working tree
+if {[is_bare]} {
+	# Bare repository: only allowed for certain subcommands
+	if {![is_enabled bare]} {
 		catch {wm withdraw .}
-		error_popup [strcat [mc "Cannot move to top of working directory:"] "\n\n$err"]
+		error_popup [strcat [mc "Cannot use bare repository:"] "\n\n" [file normalize $_gitdir]]
 		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
+	# Allowed bare repo does not have a worktree
+	set _gitworktree {}
+} else {
+	# Non-bare repository: we must find a worktree
+	if {[catch {set _gitworktree [git rev-parse --show-toplevel]} err]} {
+		# The only acceptable failure is when we are inside
+		# the .git directory of a regular repository.
+		set inside_gitdir 0
+		catch {set inside_gitdir [git rev-parse --is-inside-git-dir]}
+		if {$inside_gitdir eq {true} && [file tail $_gitdir] eq {.git}} {
+			# Use the parent directory as worktree (historic behavior)
+			set _gitworktree [file normalize [file dirname $_gitdir]]
+		} else {
+			catch {wm withdraw .}
+			error_popup [strcat [mc "Cannot determine working tree:"] "\n\n$err"]
+			exit 1
+		}
 	}
+
 	if {$_gitworktree eq {}} {
-		set _gitworktree [file dirname $_gitdir]
+		catch {wm withdraw .}
+		error_popup [mc "Cannot determine working tree (unexpected empty result)"]
+		exit 1
 	}
+
 	if {[catch {cd $_gitworktree} err]} {
 		catch {wm withdraw .}
-		error_popup [strcat [mc "No working directory"] " $_gitworktree:\n\n$err"]
+		error_popup [strcat [mc "Cannot move to working directory:"] "\n\n$err"]
 		exit 1
 	}
 	set _gitworktree [pwd]
 }
+
+# Derive a human-readable repository name
 set _reponame [file split [file normalize $_gitdir]]
 if {[lindex $_reponame end] eq {.git}} {
 	set _reponame [lindex $_reponame end-1]
@@ -1207,6 +1226,7 @@ if {[lindex $_reponame end] eq {.git}} {
 	set _reponame [lindex $_reponame end]
 }
 
+# Export the final paths
 set env(GIT_DIR) $_gitdir
 set env(GIT_WORK_TREE) $_gitworktree
 
-- 
2.52.0.windows.1


  parent reply	other threads:[~2026-05-06 20:29 UTC|newest]

Thread overview: 57+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-04-21 16:28 [PATCH] git-gui: handle bare repo or missing worktree Shroom Moo
2026-04-29  6:58 ` Johannes Sixt
2026-04-29 17:32   ` [PATCH v2 1/1] git-gui: protect rev-parse --show-toplevel call Shroom Moo
2026-04-29 20:14     ` Mark Levedahl
2026-04-30 10:02     ` [PATCH v3 1/1] git-gui: handle missing worktree and separated gitdir Shroom Moo
2026-04-30 16:18       ` Mark Levedahl
2026-05-01 10:22         ` [PATCH v3 1/1] git-gui: handle missing worktree and separated Shroom Moo
2026-05-01 13:13         ` [PATCH v3 1/1] git-gui: handle missing worktree and separated gitdir Johannes Sixt
2026-05-01 16:42           ` Mark Levedahl
2026-05-02 21:51             ` Mark Levedahl
2026-05-03  8:53               ` Johannes Sixt
2026-05-04 15:13                 ` Mark Levedahl
2026-05-05  3:40                   ` Mark Levedahl
2026-05-06  7:32                   ` Johannes Sixt
2026-05-06 11:27                     ` Mark Levedahl
2026-05-06 12:57                       ` Johannes Sixt
2026-05-06 14:05                         ` Mark Levedahl
2026-05-07  5:09                           ` Mark Levedahl
2026-05-01 10:54       ` [PATCH v4 " Shroom Moo
2026-05-04 14:59         ` [PATCH v5 1/1] git-gui: restructure repository startup Shroom Moo
2026-05-06  7:15           ` Johannes Sixt
2026-05-06 20:27           ` [PATCH v6 0/3] git-gui: robustify startup and fix environment handling Shroom Moo
2026-05-09 13:37             ` [PATCH v7 " Shroom Moo
2026-05-14 14:28               ` Mark Levedahl
2026-05-14 14:33                 ` [PATCH v1 00/11] Improve git gui operation without a worktree Mark Levedahl
2026-05-14 14:33                   ` [PATCH v1 01/11] git-gui: allow specifying path '.' to the browser Mark Levedahl
2026-05-15 15:54                     ` Johannes Sixt
2026-05-14 14:33                   ` [PATCH v1 02/11] git-gui: refactor browser / blame argument parsing Mark Levedahl
2026-05-15 15:56                     ` Johannes Sixt
2026-05-14 14:33                   ` [PATCH v1 03/11] git-gui: guard set/unset of GIT_DIR and GIT_WORK_TREE Mark Levedahl
2026-05-15 15:58                     ` Johannes Sixt
2026-05-14 14:33                   ` [PATCH v1 04/11] git-gui: put choose_repository::pick in a proc Mark Levedahl
2026-05-15 11:00                     ` Aina Boot
2026-05-15 13:33                       ` Mark Levedahl
2026-05-15 15:59                     ` Johannes Sixt
2026-05-14 14:33                   ` [PATCH v1 05/11] git-gui: use --absolute-git-dir Mark Levedahl
2026-05-15 16:00                     ` Johannes Sixt
2026-05-14 14:33                   ` [PATCH v1 06/11] git gui: GIT_DIR / GIT_WORK_TREE make any discovery error fatal Mark Levedahl
2026-05-14 14:33                   ` [PATCH v1 07/11] git-gui: use rev-parse exclusively to find a repository Mark Levedahl
2026-05-15 16:06                     ` Johannes Sixt
2026-05-14 14:33                   ` [PATCH v1 08/11] git-gui: simplify [is_bare] to report if a worktree is known Mark Levedahl
2026-05-14 14:33                   ` [PATCH v1 09/11] git-gui: support using repository parent dir as a worktree Mark Levedahl
2026-05-14 14:33                   ` [PATCH v1 10/11] git-gui: improve worktree discovery Mark Levedahl
2026-05-14 14:33                   ` [PATCH v1 11/11] git-gui: add gui and pick as explicit subcommands Mark Levedahl
     [not found]             ` <20260509133756.1367-1-egg_mushroomcow@foxmail.com>
2026-05-09 13:37               ` [PATCH v7 1/3] git-gui: restructure repository startup Shroom Moo
2026-05-15  8:26                 ` Johannes Sixt
2026-05-09 13:37               ` [PATCH v7 2/3] git-gui: disable gitk visualization when no worktree available Shroom Moo
2026-05-15  8:28                 ` Johannes Sixt
2026-05-09 13:37               ` [PATCH v7 3/3] git-gui: handle GIT_DIR and GIT_WORK_TREE early Shroom Moo
2026-05-15  8:28                 ` Johannes Sixt
     [not found]           ` <20260506202751.3294-1-egg_mushroomcow@foxmail.com>
2026-05-06 20:27             ` Shroom Moo [this message]
2026-05-06 20:27             ` [PATCH v6 2/3] git-gui: disable gitk visualization when no worktree available Shroom Moo
2026-05-06 20:27             ` [PATCH v6 3/3] git-gui: handle GIT_DIR and GIT_WORK_TREE early Shroom Moo
2026-05-07 15:50               ` Mark Levedahl
2026-05-09  8:46                 ` Aina Boot
2026-05-09  9:55                   ` Shroom Moo
2026-04-29 18:28   ` [PATCH] git-gui: handle bare repo or missing worktree Shroom Moo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=tencent_E834EEF92D17298D51E74F26219DCA807007@qq.com \
    --to=egg_mushroomcow@foxmail.com \
    --cc=git@vger.kernel.org \
    --cc=j6t@kdbg.org \
    --cc=mlevedahl@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox