All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] maintenance: fix incorrect `maintenance.repo` path with bare repository
@ 2021-02-23  7:31 Eric Sunshine
  2021-02-23 12:25 ` Derrick Stolee
  0 siblings, 1 reply; 3+ messages in thread
From: Eric Sunshine @ 2021-02-23  7:31 UTC (permalink / raw)
  To: git; +Cc: Derrick Stolee, Clement Moyroud, Eric Sunshine

The periodic maintenance tasks configured by `git maintenance start`
invoke `git for-each-repo` to run `git maintenance run` on each path
specified by the multi-value global configuration variable
`maintenance.repo`. Because `git for-each-repo` will likely be run
outside of the repositories which require periodic maintenance, it is
mandatory that the repository paths specified by `maintenance.repo` are
absolute.

Unfortunately, however, `git maintenance register` does nothing to
ensure that the paths it assigns to `maintenance.repo` are indeed
absolute, and may in fact -- especially in the case of a bare repository
-- assign a relative path to `maintenance.repo` instead. Fix this
problem by converting all paths to absolute before assigning them to
`maintenance.repo`.

While at it, also fix `git maintenance unregister` to convert paths to
absolute, as well, in order to ensure that it can correctly remove from
`maintenance.repo` a path assigned via `git maintenance register`.

Reported-by: Clement Moyroud <clement.moyroud@gmail.com>
Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
---

Reported by Clement here:
https://lore.kernel.org/git/CABXAcUzRhkeQhVtwtx-NBR0hbkoo=aCTwN464Dsj8680GPMDxw@mail.gmail.com/

builtin/gc.c           | 50 ++++++++++++++++++++++++++++--------------
 t/t7900-maintenance.sh | 13 +++++++++++
 2 files changed, 46 insertions(+), 17 deletions(-)

diff --git a/builtin/gc.c b/builtin/gc.c
index 6db9cb39e6..ef7226d7bc 100644
--- a/builtin/gc.c
+++ b/builtin/gc.c
@@ -1461,11 +1461,23 @@ static int maintenance_run(int argc, const char **argv, const char *prefix)
 	return maintenance_run_tasks(&opts);
 }
 
+static char *get_maintpath(void)
+{
+	struct strbuf sb = STRBUF_INIT;
+	const char *p = the_repository->worktree ?
+		the_repository->worktree : the_repository->gitdir;
+
+	strbuf_realpath(&sb, p, 1);
+	return strbuf_detach(&sb, NULL);
+}
+
 static int maintenance_register(void)
 {
+	int rc;
 	char *config_value;
 	struct child_process config_set = CHILD_PROCESS_INIT;
 	struct child_process config_get = CHILD_PROCESS_INIT;
+	char *maintpath = get_maintpath();
 
 	/* Disable foreground maintenance */
 	git_config_set("maintenance.auto", "false");
@@ -1478,40 +1490,44 @@ static int maintenance_register(void)
 
 	config_get.git_cmd = 1;
 	strvec_pushl(&config_get.args, "config", "--global", "--get",
-		     "--fixed-value", "maintenance.repo",
-		     the_repository->worktree ? the_repository->worktree
-					      : the_repository->gitdir,
-			 NULL);
+		     "--fixed-value", "maintenance.repo", maintpath, NULL);
 	config_get.out = -1;
 
-	if (start_command(&config_get))
-		return error(_("failed to run 'git config'"));
+	if (start_command(&config_get)) {
+		rc = error(_("failed to run 'git config'"));
+		goto done;
+	}
 
 	/* We already have this value in our config! */
-	if (!finish_command(&config_get))
-		return 0;
+	if (!finish_command(&config_get)) {
+		rc = 0;
+		goto done;
+	}
 
 	config_set.git_cmd = 1;
 	strvec_pushl(&config_set.args, "config", "--add", "--global", "maintenance.repo",
-		     the_repository->worktree ? the_repository->worktree
-					      : the_repository->gitdir,
-		     NULL);
+		     maintpath, NULL);
+
+	rc = run_command(&config_set);
 
-	return run_command(&config_set);
+done:
+	free(maintpath);
+	return rc;
 }
 
 static int maintenance_unregister(void)
 {
+	int rc;
 	struct child_process config_unset = CHILD_PROCESS_INIT;
+	char *maintpath = get_maintpath();
 
 	config_unset.git_cmd = 1;
 	strvec_pushl(&config_unset.args, "config", "--global", "--unset",
-		     "--fixed-value", "maintenance.repo",
-		     the_repository->worktree ? the_repository->worktree
-					      : the_repository->gitdir,
-		     NULL);
+		     "--fixed-value", "maintenance.repo", maintpath, NULL);
 
-	return run_command(&config_unset);
+	rc = run_command(&config_unset);
+	free(maintpath);
+	return rc;
 }
 
 static const char *get_frequency(enum schedule_priority schedule)
diff --git a/t/t7900-maintenance.sh b/t/t7900-maintenance.sh
index 286b18db3c..2412d8c5c0 100755
--- a/t/t7900-maintenance.sh
+++ b/t/t7900-maintenance.sh
@@ -632,4 +632,17 @@ test_expect_success 'fails when running outside of a repository' '
 	nongit test_must_fail git maintenance unregister
 '
 
+test_expect_success 'register and unregister bare repo' '
+	test_when_finished "git config --global --unset-all maintenance.repo || :" &&
+	test_might_fail git config --global --unset-all maintenance.repo &&
+	git init --bare barerepo &&
+	(
+		cd barerepo &&
+		git maintenance register &&
+		git config --get --global --fixed-value maintenance.repo "$(pwd)" &&
+		git maintenance unregister &&
+		test_must_fail git config --global --get-all maintenance.repo
+	)
+'
+
 test_done
-- 
2.30.1.766.gb4fecdf3b7


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] maintenance: fix incorrect `maintenance.repo` path with bare repository
  2021-02-23  7:31 [PATCH] maintenance: fix incorrect `maintenance.repo` path with bare repository Eric Sunshine
@ 2021-02-23 12:25 ` Derrick Stolee
  2021-02-23 16:21   ` Eric Sunshine
  0 siblings, 1 reply; 3+ messages in thread
From: Derrick Stolee @ 2021-02-23 12:25 UTC (permalink / raw)
  To: Eric Sunshine, git; +Cc: Clement Moyroud

On 2/23/2021 2:31 AM, Eric Sunshine wrote:
> The periodic maintenance tasks configured by `git maintenance start`
> invoke `git for-each-repo` to run `git maintenance run` on each path
> specified by the multi-value global configuration variable
> `maintenance.repo`. Because `git for-each-repo` will likely be run
> outside of the repositories which require periodic maintenance, it is
> mandatory that the repository paths specified by `maintenance.repo` are
> absolute.
> 
> Unfortunately, however, `git maintenance register` does nothing to
> ensure that the paths it assigns to `maintenance.repo` are indeed
> absolute, and may in fact -- especially in the case of a bare repository
> -- assign a relative path to `maintenance.repo` instead. Fix this
> problem by converting all paths to absolute before assigning them to
> `maintenance.repo`.
> 
> While at it, also fix `git maintenance unregister` to convert paths to
> absolute, as well, in order to ensure that it can correctly remove from
> `maintenance.repo` a path assigned via `git maintenance register`.

Thanks for the report and the fix!

> +static char *get_maintpath(void)
> +{
> +	struct strbuf sb = STRBUF_INIT;
> +	const char *p = the_repository->worktree ?
> +		the_repository->worktree : the_repository->gitdir;
> +
> +	strbuf_realpath(&sb, p, 1);
> +	return strbuf_detach(&sb, NULL);
> +}
> +

This looks right.

>  static int maintenance_register(void)
>  {
> +	int rc;
>  	char *config_value;
>  	struct child_process config_set = CHILD_PROCESS_INIT;
>  	struct child_process config_get = CHILD_PROCESS_INIT;
> +	char *maintpath = get_maintpath();

I'm sorry that this diff looks more complicated than seems necessary,
but your creation of the "done:" label is important for cleaning up
the string. Thanks.

> +test_expect_success 'register and unregister bare repo' '
> +	test_when_finished "git config --global --unset-all maintenance.repo || :" &&
> +	test_might_fail git config --global --unset-all maintenance.repo &&
> +	git init --bare barerepo &&
> +	(
> +		cd barerepo &&
> +		git maintenance register &&
> +		git config --get --global --fixed-value maintenance.repo "$(pwd)" &&

I'm concerned about this test passing on Windows, but if the CI build is happy,
then I'm happy.

> +		git maintenance unregister &&
> +		test_must_fail git config --global --get-all maintenance.repo
> +	)
> +'

Thanks!

Reviewed-by: Derrick Stolee <dstolee@microsoft.com>

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] maintenance: fix incorrect `maintenance.repo` path with bare repository
  2021-02-23 12:25 ` Derrick Stolee
@ 2021-02-23 16:21   ` Eric Sunshine
  0 siblings, 0 replies; 3+ messages in thread
From: Eric Sunshine @ 2021-02-23 16:21 UTC (permalink / raw)
  To: Derrick Stolee; +Cc: Git List, Clement Moyroud

On Tue, Feb 23, 2021 at 7:26 AM Derrick Stolee <stolee@gmail.com> wrote:
> On 2/23/2021 2:31 AM, Eric Sunshine wrote:
> > +test_expect_success 'register and unregister bare repo' '
> > +     test_when_finished "git config --global --unset-all maintenance.repo || :" &&
> > +     test_might_fail git config --global --unset-all maintenance.repo &&
> > +     git init --bare barerepo &&
> > +     (
> > +             cd barerepo &&
> > +             git maintenance register &&
> > +             git config --get --global --fixed-value maintenance.repo "$(pwd)" &&
>
> I'm concerned about this test passing on Windows, but if the CI build is happy,
> then I'm happy.

I had a slight worry about Windows, as well, but (1) this is copied
directly from an earlier test in this script which does pass on
Windows, and (2) I tested on Windows, and it works fine. So, all is
good.

> Reviewed-by: Derrick Stolee <dstolee@microsoft.com>

Thanks.

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2021-02-23 16:22 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-02-23  7:31 [PATCH] maintenance: fix incorrect `maintenance.repo` path with bare repository Eric Sunshine
2021-02-23 12:25 ` Derrick Stolee
2021-02-23 16:21   ` Eric Sunshine

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.