git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: "Johannes Schindelin via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: Pratyush Yadav <me@yadavpratyush.com>,
	Bert Wesarg <bert.wesarg@googlemail.com>,
	Johannes Schindelin <johannes.schindelin@gmx.de>,
	Pratyush Yadav <me@yadavpratyush.com>,
	Johannes Schindelin <Johannes.Schindelin@gmx.de>
Subject: [PATCH v4 1/1] Make gitdir work with worktrees, respect core.hooksPath, etc
Date: Tue, 08 Oct 2019 04:33:26 -0700 (PDT)	[thread overview]
Message-ID: <2f55d6fb2a158c5b26b93ddb9c144ce1af5d9c32.1570534405.git.gitgitgadget@gmail.com> (raw)
In-Reply-To: <pull.361.v4.git.gitgitgadget@gmail.com>

From: Johannes Schindelin <Johannes.Schindelin@gmx.de>

Since v2.9.0, Git knows about the config variable core.hookspath that
allows overriding the path to the directory containing the Git hooks.

Since v2.10.0, the `--git-path` option respects that config variable,
too, so we may just as well use that command.

Other paths inside `.git` are equally subject to differ from
`<gitdir>/<path>`, i.e. inside worktrees, where _some_ paths live in the
"gitdir" and some live in the "commondir" (i.e. the "gitdir" of the main
worktree).

For Git versions older than v2.5.0 (which was the first version to
support the `--git-path` option for the `rev-parse` command), we simply
fall back to the previous code.

An original patch handled only the hooksPath setting, however, during
the code submission it was deemed better to fix all call to the `gitdir`
function.

To avoid spawning a gazillion `git rev-parse --git-path` instances, we
cache the returned paths, priming the cache upon startup in a single
`git rev-parse invocation` with some paths (that have been
determined via a typical startup and via grepping the source code for
calls to the `gitdir` function).

This fixes https://github.com/git-for-windows/git/issues/1755

Initial-patch-by: Philipp Gortan <philipp@gortan.org>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 git-gui.sh | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 58 insertions(+), 4 deletions(-)

diff --git a/git-gui.sh b/git-gui.sh
index fd476b6999..c684dc7ae1 100755
--- a/git-gui.sh
+++ b/git-gui.sh
@@ -158,6 +158,7 @@ if {[tk windowingsystem] eq "aqua"} {
 
 set _appname {Git Gui}
 set _gitdir {}
+array set _gitdir_cache {}
 set _gitworktree {}
 set _isbare {}
 set _gitexec {}
@@ -197,12 +198,59 @@ proc appname {} {
 	return $_appname
 }
 
+proc prime_gitdir_cache {} {
+	global _gitdir _gitdir_cache
+
+	set gitdir_cmd [list git rev-parse --git-dir]
+
+	# `--git-path` is only supported since Git v2.5.0
+	if {[package vcompare $::_git_version 2.5.0] >= 0} {
+		# This list was generated from a typical startup as well as from
+		# grepping through Git GUI's source code.
+		set gitdir_keys [list \
+			CHERRY_PICK_HEAD FETCH_HEAD GITGUI_BCK GITGUI_EDITMSG \
+			GITGUI_MSG HEAD hooks hooks/prepare-commit-msg \
+			index.lock info info/exclude logs MERGE_HEAD MERGE_MSG \
+			MERGE_RR objects "objects/4\[0-1\]/*" \
+			"objects/4\[0-3\]/*" objects/info \
+			objects/info/alternates objects/pack packed-refs \
+			PREPARE_COMMIT_MSG rebase-merge/head-name remotes \
+			rr-cache rr-cache/MERGE_RR SQUASH_MSG \
+		]
+
+		foreach key $gitdir_keys {
+			lappend gitdir_cmd --git-path $key
+		}
+	}
+
+	set i -1
+	foreach path [split [eval $gitdir_cmd] "\n"] {
+		if {$i eq -1} {
+			set _gitdir $path
+		} else {
+			set _gitdir_cache([lindex $gitdir_keys $i]) $path
+		}
+		incr i
+	}
+}
+
 proc gitdir {args} {
-	global _gitdir
+	global _gitdir _gitdir_cache
+
 	if {$args eq {}} {
 		return $_gitdir
 	}
-	return [eval [list file join $_gitdir] $args]
+
+	set args [eval [list file join] $args]
+	if {![info exists _gitdir_cache($args)]} {
+		if {[package vcompare $::_git_version 2.5.0] >= 0} {
+			set _gitdir_cache($args) [git rev-parse --git-path $args]
+		} else {
+			set _gitdir_cache($args) [file join $_gitdir $args]
+		}
+	}
+
+	return $_gitdir_cache($args)
 }
 
 proc gitexec {args} {
@@ -1242,7 +1290,7 @@ if {[catch {
 	&& [catch {
 		# beware that from the .git dir this sets _gitdir to .
 		# and _prefix to the empty string
-		set _gitdir [git rev-parse --git-dir]
+		prime_gitdir_cache
 		set _prefix [git rev-parse --show-prefix]
 	} err]} {
 	load_config 1
@@ -1453,10 +1501,16 @@ proc rescan {after {honor_trustmtime 1}} {
 	global HEAD PARENT MERGE_HEAD commit_type
 	global ui_index ui_workdir ui_comm
 	global rescan_active file_states
-	global repo_config
+	global repo_config _gitdir_cache
 
 	if {$rescan_active > 0 || ![lock_index read]} return
 
+	# Only re-prime gitdir cache on a full rescan
+	if {$after ne "ui_ready"} {
+		array unset _gitdir_cache
+		prime_gitdir_cache
+	}
+
 	repository_state newType newHEAD newMERGE_HEAD
 	if {[string match amend* $commit_type]
 		&& $newType eq {normal}
-- 
gitgitgadget

  reply	other threads:[~2019-10-08 11:33 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-09-26 21:17 [PATCH 0/1] git-gui: respect core.hooksPath, falling back to .git/hooks Johannes Schindelin via GitGitGadget
2019-09-26 21:17 ` [PATCH 1/1] " Johannes Schindelin via GitGitGadget
2019-09-26 22:36   ` Pratyush Yadav
2019-09-27  6:10     ` Bert Wesarg
2019-09-27 13:05       ` Pratyush Yadav
2019-09-30  9:42         ` Johannes Schindelin
2019-10-01 13:31           ` Pratyush Yadav
2019-10-01 17:38             ` Johannes Schindelin
2019-10-04 16:48               ` Pratyush Yadav
2019-10-04 19:56                 ` Johannes Schindelin
2019-09-30  9:45 ` [PATCH v2 0/1] git-gui: " Johannes Schindelin via GitGitGadget
2019-09-30  9:45   ` [PATCH v2 1/1] " Johannes Schindelin via GitGitGadget
2019-10-04 21:41   ` [PATCH v3 0/1] git-gui: " Johannes Schindelin via GitGitGadget
2019-10-04 21:41     ` [PATCH v3 1/1] Fix gitdir e.g. to respect core.hooksPath Johannes Schindelin via GitGitGadget
2019-10-08  0:29       ` Pratyush Yadav
2019-10-08 11:30         ` Johannes Schindelin
2019-10-08 11:33     ` [PATCH v4 0/1] git-gui: respect core.hooksPath, falling back to .git/hooks Johannes Schindelin via GitGitGadget
2019-10-08 11:33       ` Johannes Schindelin via GitGitGadget [this message]
2019-10-11 22:26         ` [PATCH v4 1/1] Make gitdir work with worktrees, respect core.hooksPath, etc Pratyush Yadav
2019-10-12 21:24           ` Johannes Schindelin
2019-10-13 18:55             ` Pratyush Yadav
2019-10-13 22:18               ` Johannes Schindelin
2019-10-17 18:34                 ` Pratyush Yadav
2019-10-14  8:14               ` Johannes Schindelin

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

  List information: http://vger.kernel.org/majordomo-info.html

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

  git send-email \
    --in-reply-to=2f55d6fb2a158c5b26b93ddb9c144ce1af5d9c32.1570534405.git.gitgitgadget@gmail.com \
    --to=gitgitgadget@gmail.com \
    --cc=bert.wesarg@googlemail.com \
    --cc=git@vger.kernel.org \
    --cc=johannes.schindelin@gmx.de \
    --cc=me@yadavpratyush.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.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).