[PATCH 1/2] Refactor, adding prepare_git_cmd(const char **argv)

Subsystems: the rest

STALE3714d

9 messages, 4 authors, 2016-06-15 · open the first message on its own page

[PATCH 1/2] Refactor, adding prepare_git_cmd(const char **argv)

From: Steffen Prohaska <hidden>
Date: 2016-06-15 22:45:03

prepare_git_cmd(const char **argv) adds a first entry "git" to
the array argv.  The new array is allocated on the heap.  It's
the caller's responsibility to release it with free().  The code
was already present in execv_git_cmd() but could not be used from
outside.  Now it can also be called for preparing the command list
in the MinGW codepath in run-command.c.

Signed-off-by: Steffen Prohaska <redacted>
---
 exec_cmd.c |    7 ++++++-
 exec_cmd.h |    1 +
 2 files changed, 7 insertions(+), 1 deletions(-)
diff --git a/exec_cmd.c b/exec_cmd.c
index 0ed768d..ce6741e 100644
--- a/exec_cmd.c
+++ b/exec_cmd.c
@@ -78,7 +78,7 @@ void setup_path(void)
 	strbuf_release(&new_path);
 }
 
-int execv_git_cmd(const char **argv)
+const char **prepare_git_cmd(const char **argv)
 {
 	int argc;
 	const char **nargv;
@@ -91,6 +91,11 @@ int execv_git_cmd(const char **argv)
 	for (argc = 0; argv[argc]; argc++)
 		nargv[argc + 1] = argv[argc];
 	nargv[argc + 1] = NULL;
+	return nargv;
+}
+
+int execv_git_cmd(const char **argv) {
+	const char **nargv = prepare_git_cmd(argv);
 	trace_argv_printf(nargv, "trace: exec:");
 
 	/* execvp() can only ever return if it fails */
diff --git a/exec_cmd.h b/exec_cmd.h
index 0c46cd5..594f961 100644
--- a/exec_cmd.h
+++ b/exec_cmd.h
@@ -5,6 +5,7 @@ extern void git_set_argv_exec_path(const char *exec_path);
 extern void git_set_argv0_path(const char *path);
 extern const char* git_exec_path(void);
 extern void setup_path(void);
+extern const char **prepare_git_cmd(const char **argv);
 extern int execv_git_cmd(const char **argv); /* NULL terminated */
 extern int execl_git_cmd(const char *cmd, ...);
 extern const char *system_path(const char *path);
-- 
1.6.0.rc0.79.gb0320

[Fundamental problem with relative system paths] [PATCH 2/2] run-command (Windows): Run dashless "git <cmd>"

From: Steffen Prohaska <hidden>
Date: 2016-06-15 22:45:03

This might solve a fundamental problem we have with the
computation of system directories based on relative paths
in combination with the new gitexecpath 'libexec/git-core'.
The problem is that the program 'git' is hardlinked to
directories with different depth.  It is either used as
'bin/git' (1 directory) or as 'libexec/git-core/git-*'
(2 directories).  Thus, using the same relative path
in system_path() yields different results when starting from the
two locations.  I recognized the problem because /etc/gitconfig
is no longer be read.

The patch below might fix the problem by always calling 'bin/git'
for builtin commands.  The computation in system_path() would
always start from 'bin' and thus yields predictable results.  I
am not sure however if it fully solves the problem because other
code paths might run the dashed forms directly.

I think the only way to verify correctness would be to stop
installing the dashed forms for builtins.  If they were not
installed they could not be called.  The only entry point for all
builtins would be 'bin/git'.  I don't think we want to stop
installing the dashed forms right away.

So what shall we do?

	Steffen

-- 8< --
We prefer running the dashless form, so we should use it in
MinGW's start_command(), too.

Signed-off-by: Steffen Prohaska <redacted>
---
 run-command.c |   11 ++++-------
 1 files changed, 4 insertions(+), 7 deletions(-)
diff --git a/run-command.c b/run-command.c
index 6e29fdf..a3b28a6 100644
--- a/run-command.c
+++ b/run-command.c
@@ -119,9 +119,8 @@ int start_command(struct child_process *cmd)
 	}
 #else
 	int s0 = -1, s1 = -1, s2 = -1;	/* backups of stdin, stdout, stderr */
-	const char *sargv0 = cmd->argv[0];
+	const char **sargv = cmd->argv;
 	char **env = environ;
-	struct strbuf git_cmd;
 
 	if (cmd->no_stdin) {
 		s0 = dup(0);
@@ -165,9 +164,7 @@ int start_command(struct child_process *cmd)
 	}
 
 	if (cmd->git_cmd) {
-		strbuf_init(&git_cmd, 0);
-		strbuf_addf(&git_cmd, "git-%s", cmd->argv[0]);
-		cmd->argv[0] = git_cmd.buf;
+		cmd->argv = prepare_git_cmd(cmd->argv);
 	}
 
 	cmd->pid = mingw_spawnvpe(cmd->argv[0], cmd->argv, env);
@@ -175,9 +172,9 @@ int start_command(struct child_process *cmd)
 	if (cmd->env)
 		free_environ(env);
 	if (cmd->git_cmd)
-		strbuf_release(&git_cmd);
+		free(cmd->argv);
 
-	cmd->argv[0] = sargv0;
+	cmd->argv = sargv;
 	if (s0 >= 0)
 		dup2(s0, 0), close(s0);
 	if (s1 >= 0)
-- 
1.6.0.rc0.79.gb0320

Re: [Fundamental problem with relative system paths] [PATCH 2/2] run-command (Windows): Run dashless "git <cmd>"

From: Johannes Schindelin <hidden>
Date: 2016-06-15 22:45:03

Hi,

On Mon, 28 Jul 2008, Steffen Prohaska wrote:
This might solve a fundamental problem we have with the computation of 
system directories based on relative paths in combination with the new 
gitexecpath 'libexec/git-core'. The problem is that the program 'git' is 
hardlinked to directories with different depth.  It is either used as 
'bin/git' (1 directory) or as 'libexec/git-core/git-*' (2 directories).  
Thus, using the same relative path in system_path() yields different 
results when starting from the two locations.  I recognized the problem 
because /etc/gitconfig is no longer be read.
I seem to recall that I already suggested stripping 
"/libexec/git-core/<name>" if it is found, and fall back to 
stripping one directory level (catching "/bin/<name>").

IMHO system_path() should really be that intelligent.

(Of course, the way it is set up now, the _caller_ of git_set_argv0_path() 
has to do the intelligent thing...)

Ciao,
Dscho

Re: [Fundamental problem with relative system paths] [PATCH 2/2] run-command (Windows): Run dashless "git <cmd>"

From: Johannes Sixt <hidden>
Date: 2016-06-15 22:45:04

Zitat von Steffen Prohaska [off-list ref]:
This might solve a fundamental problem we have with the
computation of system directories based on relative paths
in combination with the new gitexecpath 'libexec/git-core'.
The problem is that the program 'git' is hardlinked to
directories with different depth.  It is either used as
'bin/git' (1 directory) or as 'libexec/git-core/git-*'
(2 directories).  Thus, using the same relative path
in system_path() yields different results when starting from the
two locations.  I recognized the problem because /etc/gitconfig
is no longer be read.

The patch below might fix the problem by always calling 'bin/git'
for builtin commands.  The computation in system_path() would
always start from 'bin' and thus yields predictable results.  I
am not sure however if it fully solves the problem because other
code paths might run the dashed forms directly.
This paragraph should go into the commit message.
I think the only way to verify correctness would be to stop
installing the dashed forms for builtins.  If they were not
installed they could not be called.  The only entry point for all
builtins would be 'bin/git'.  I don't think we want to stop
installing the dashed forms right away.

So what shall we do?
Your patches make a lot of sense.
-- 8< --
We prefer running the dashless form, so we should use it in
MinGW's start_command(), too.

Signed-off-by: Steffen Prohaska <redacted>
Acked-by: Johannes Sixt <redacted>

-- Hannes

Re: [Fundamental problem with relative system paths] [PATCH 2/2] run-command (Windows): Run dashless "git <cmd>"

From: Steffen Prohaska <hidden>
Date: 2016-06-15 22:45:04

On Jul 28, 2008, at 10:37 PM, Johannes Sixt wrote:
Zitat von Steffen Prohaska [off-list ref]:
quoted
This might solve a fundamental problem we have with the
computation of system directories based on relative paths
in combination with the new gitexecpath 'libexec/git-core'.
The problem is that the program 'git' is hardlinked to
directories with different depth.  It is either used as
'bin/git' (1 directory) or as 'libexec/git-core/git-*'
(2 directories).  Thus, using the same relative path
in system_path() yields different results when starting from the
two locations.  I recognized the problem because /etc/gitconfig
is no longer be read.

The patch below might fix the problem by always calling 'bin/git'
for builtin commands.  The computation in system_path() would
always start from 'bin' and thus yields predictable results.  I
am not sure however if it fully solves the problem because other
code paths might run the dashed forms directly.
This paragraph should go into the commit message.
I'll send an updated patch including a commit message defending
the change more offensively.

quoted
I think the only way to verify correctness would be to stop
installing the dashed forms for builtins.  If they were not
installed they could not be called.  The only entry point for all
builtins would be 'bin/git'.  I don't think we want to stop
installing the dashed forms right away.

So what shall we do?
Your patches make a lot of sense.
Unfortunately, I am sure that they do not solve the problem fully, even
if we removed the dashed forms completely.  I'll send a second patch  
that
modifies the Makefile to stop installing the BUILT_INS.  It might be
useful for debugging.

	Steffen

[FOR DEBUGGING] Stop installing BUILT_INS

From: Steffen Prohaska <hidden>
Date: 2016-06-15 22:45:04

---
 Makefile |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/Makefile b/Makefile
index b2bc0ef..e416ec7 100644
--- a/Makefile
+++ b/Makefile
@@ -1366,7 +1366,7 @@ endif
 		ln -f "$$bindir/git$X" "$$execdir/git$X" || \
 		cp "$$bindir/git$X" "$$execdir/git$X"; \
 	fi && \
-	{ $(foreach p,$(BUILT_INS), $(RM) "$$execdir/$p" && ln "$$execdir/git$X" "$$execdir/$p" ;) } && \
+	{ $(foreach p,$(BUILT_INS), $(RM) "$$execdir/$p" ;) } && \
 	$(RM) "$$execdir/git$X" && \
 	./check_bindir "z$$bindir" "z$$execdir" "$$bindir/git-add$X"
 
-- 
1.6.0.rc0.79.gb0320

[PATCH 2/2 v2] run-command (Windows): Run dashless "git <cmd>" (solves part of problem with system_path)

From: Steffen Prohaska <hidden>
Date: 2016-06-15 22:45:04

We prefer running the dashless form, so we should use it in MinGW's
start_command(), too.

This solves a fundamental problem we have with the computation of system
directories based on relative paths in combination with the new
gitexecpath 'libexec/git-core'.  The problem is that the program 'git'
is hardlinked to directories with different depth.  It is either used as
'bin/git' (1 directory) or as 'libexec/git-core/git-*' (2 directories).
Thus, using the same relative path in system_path() yields different
results when starting from the two locations.  I recognized the problem
because /etc/gitconfig is no longer read.

This commit fixes the problem by always calling 'bin/git' for builtin
commands.  The computation in system_path() thus always starts from
'bin' and yields predictable results.  This is however only part of a
full solution to the problem outlined above.  Remaining problems are:

 - Other code paths might run the dashed forms directly.

 - We have non-builtins that are implemented in C, e.g. fast-import.c.
   These non-builtins will still compute wrong paths.

Signed-off-by: Steffen Prohaska <redacted>
Acked-by: Johannes Sixt <redacted>
---
 run-command.c |   11 ++++-------
 1 files changed, 4 insertions(+), 7 deletions(-)

My previous mail was in the wrong thread.  Apologies.  This one
will be correctly threaded.

    Steffen
diff --git a/run-command.c b/run-command.c
index 6e29fdf..a3b28a6 100644
--- a/run-command.c
+++ b/run-command.c
@@ -119,9 +119,8 @@ int start_command(struct child_process *cmd)
 	}
 #else
 	int s0 = -1, s1 = -1, s2 = -1;	/* backups of stdin, stdout, stderr */
-	const char *sargv0 = cmd->argv[0];
+	const char **sargv = cmd->argv;
 	char **env = environ;
-	struct strbuf git_cmd;
 
 	if (cmd->no_stdin) {
 		s0 = dup(0);
@@ -165,9 +164,7 @@ int start_command(struct child_process *cmd)
 	}
 
 	if (cmd->git_cmd) {
-		strbuf_init(&git_cmd, 0);
-		strbuf_addf(&git_cmd, "git-%s", cmd->argv[0]);
-		cmd->argv[0] = git_cmd.buf;
+		cmd->argv = prepare_git_cmd(cmd->argv);
 	}
 
 	cmd->pid = mingw_spawnvpe(cmd->argv[0], cmd->argv, env);
@@ -175,9 +172,9 @@ int start_command(struct child_process *cmd)
 	if (cmd->env)
 		free_environ(env);
 	if (cmd->git_cmd)
-		strbuf_release(&git_cmd);
+		free(cmd->argv);
 
-	cmd->argv[0] = sargv0;
+	cmd->argv = sargv;
 	if (s0 >= 0)
 		dup2(s0, 0), close(s0);
 	if (s1 >= 0)
-- 
1.6.0.rc0.79.gb0320

Re: [Fundamental problem with relative system paths] [PATCH 2/2] run-command (Windows): Run dashless "git <cmd>"

From: Junio C Hamano <hidden>
Date: 2016-06-15 22:45:04

Johannes Sixt [off-list ref] writes:
Zitat von Steffen Prohaska [off-list ref]:
...
quoted
The patch below might fix the problem by always calling 'bin/git'
for builtin commands.  The computation in system_path() would
always start from 'bin' and thus yields predictable results.  I
am not sure however if it fully solves the problem because other
code paths might run the dashed forms directly.
This paragraph should go into the commit message.
...
Your patches make a lot of sense.
I was almost going to suggest doing this everywhere not just on Windows,
but execv_git_cmd() on the POSIX side already runs "git" wrapper, so this
patch makes them in line, finally.
quoted
-- 8< --
We prefer running the dashless form, so we should use it in
MinGW's start_command(), too.

Signed-off-by: Steffen Prohaska <redacted>
Acked-by: Johannes Sixt <redacted>

-- Hannes

Re: [Fundamental problem with relative system paths] [PATCH 2/2] run-command (Windows): Run dashless "git <cmd>"

From: Johannes Sixt <hidden>
Date: 2016-06-15 22:45:04

Zitat von Junio C Hamano [off-list ref]:
Johannes Sixt [off-list ref] writes:
quoted
Zitat von Steffen Prohaska [off-list ref]:
...
quoted
The patch below might fix the problem by always calling 'bin/git'
for builtin commands.  The computation in system_path() would
always start from 'bin' and thus yields predictable results.  I
am not sure however if it fully solves the problem because other
code paths might run the dashed forms directly.
This paragraph should go into the commit message.
quoted
...
Your patches make a lot of sense.
I was almost going to suggest doing this everywhere not just on Windows,
but execv_git_cmd() on the POSIX side already runs "git" wrapper, so this
patch makes them in line, finally.
For this reason I'm in favor of these patches. I didn't run the full test suite
with them, yet, (you know, that takes a while on Windows), but "make *clone*
*fetch* *pack*" worked out OK.

-- Hannes
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help