All of lore.kernel.org
 help / color / mirror / Atom feed
From: Johannes Sixt <j6t@kdbg.org>
To: Shroom Moo <egg_mushroomcow@foxmail.com>
Cc: Mark Levedahl <mlevedahl@gmail.com>, git@vger.kernel.org
Subject: Re: [PATCH v5 1/1] git-gui: restructure repository startup
Date: Wed, 6 May 2026 09:15:33 +0200	[thread overview]
Message-ID: <28db8297-c995-4e29-ae44-ade304b2aad5@kdbg.org> (raw)
In-Reply-To: <tencent_78B80FB7A0A42E464B3EF1841E2AF3C39509@qq.com>

Am 04.05.26 um 16:59 schrieb Shroom Moo:
> 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.

Very good. This does things in the right order, IMO.

> 
> - 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).

Nice catch. This could be moved into its own patch. But it is acceptable
in this patch as it loosely fits the topic.

> 
> 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.

Nice cleanup.

> 
> 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.

Good!

However, this doesn't fix `git gui blame HEAD file` in a bare
repository, because `git branch --show-current` fails with an empty
GIT_WORK_TREE value. Fixing this needs to consider whether to set
GIT_DIR and GIT_WORK_TREE at all, as alluded to by Mark in a near-by
message. This is a separate topic.

> 
> Signed-off-by: Shroom Moo <egg_mushroomcow@foxmail.com>
> ---
>  git-gui/git-gui.sh | 72 +++++++++++++++++++++++++++++-----------------
>  1 file changed, 45 insertions(+), 27 deletions(-)
> 
> diff --git a/git-gui/git-gui.sh b/git-gui/git-gui.sh
> index 23fe76e498..c06d85b8d9 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,50 @@ 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]
> +# Handle bare repository early: if not allowed, abort
> +if {[is_bare] && ![is_enabled bare]} {
> +	catch {wm withdraw .}
> +	error_popup [strcat [mc "Cannot use bare repository:"] "\n\n" [file normalize $_gitdir]]
> +	exit 1
> +}
>  
> -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
> +# Determine the working tree
> +if {[is_bare] && [is_enabled bare]} {
> +	set _gitworktree {}

I strongly suggest to collapse this branch and the previous 'if
{[is_bare] && ![is_enabled bare]}' into a single 'if {[is_bare]}',
because then in the else-branch below we can be sure not to have a bare
repository.

> +} else {
> +	if {[catch {set _gitworktree [git rev-parse --show-toplevel]} err]} {
> +		# If we are inside a .git directory of a non-bare repo,
> +		# the worktree is the parent directory
> +		set inside_gitdir 0
> +		catch {set inside_gitdir [git rev-parse --is-inside-git-dir]}
> +		if {![is_bare] && $inside_gitdir eq {true} && [file tail [file normalize $_gitdir]] eq {.git}} {

Do we need to 'file normalize' before taking the 'file tail'? If not,
then the line would be shorter.

> +			set _gitworktree [file normalize [file dirname $_gitdir]]
> +		} else {
> +			catch {wm withdraw .}
> +			error_popup [strcat [mc "Cannot determine working tree:"] "\n\n$err"]
> +			exit 1
> +		}
>  	}
> -	set _gitworktree [pwd]
> -	unset cdup
> -} elseif {![is_enabled bare]} {
> -	if {[is_bare]} {
> +
> +	if {$_gitworktree eq {}} {
>  		catch {wm withdraw .}
> -		error_popup [strcat [mc "Cannot use bare repository:"] "\n\n$_gitdir"]
> +		error_popup [mc "Cannot determine working tree (unexpected empty result)"]
>  		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"]
> +		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 +1224,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
>  

-- Hannes


  reply	other threads:[~2026-05-06  7:15 UTC|newest]

Thread overview: 62+ 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 [this message]
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-16  8:12                     ` Johannes Sixt
2026-05-14 14:33                   ` [PATCH v1 09/11] git-gui: support using repository parent dir as a worktree Mark Levedahl
2026-05-16  8:14                     ` Johannes Sixt
2026-05-14 14:33                   ` [PATCH v1 10/11] git-gui: improve worktree discovery Mark Levedahl
2026-05-16  8:16                     ` Johannes Sixt
2026-05-14 14:33                   ` [PATCH v1 11/11] git-gui: add gui and pick as explicit subcommands Mark Levedahl
2026-05-16  8:18                     ` Johannes Sixt
2026-05-16  8:28                   ` [PATCH v1 00/11] Improve git gui operation without a worktree Johannes Sixt
     [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             ` [PATCH v6 1/3] git-gui: restructure repository startup Shroom Moo
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=28db8297-c995-4e29-ae44-ade304b2aad5@kdbg.org \
    --to=j6t@kdbg.org \
    --cc=egg_mushroomcow@foxmail.com \
    --cc=git@vger.kernel.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.