Unable to clone an ssh repository (with ugly installation-specific workaround)
Hi,
I'm pretty sure this worked before, but with git-1.5.4, when trying to clone a repository via ssh from a machine that does not have git installed in a standard system path, I get the following:
$ git clone -u /home/enewren/software/install/linux/git/bin/git-upload-pack ssh://enewren@remote/var/scratch/enewren/votd Initialized empty Git repository in /home/newren/devel/votd/.git/ remote: fatal: exec pack-objects failed. remote: aborting due to possible repository corruption on the remote side. fatal: early EOF fatal: index-pack failed fetch-pack from 'ssh://enewren@remote/var/scratch/enewren/votd' failed.
I tried doing a local clone of the same repository (worked fine), a 'git fsck -full' on the relevant repository (reported no errors), and a few other things. After a bit of digging, I found a really ugly hack that works around my problem. After recompiling git on the remote machine with the attached patch, the clone operation succeeded.
Thanks,
Elijah
exec_cmd.c renamed from exec_cmd.c~ +1 -1
@@ -69,7 +69,7 @@const char *tmp;strbuf_init (&cmd,0 ); -strbuf_addf (&cmd,"git-%s" , argv[0 ]); +strbuf_addf (&cmd,"/home/enewren/software/install/linux/git/bin/git-%s" , argv[0 ]);/* * argv[0] must be the git command, but the argv array
Quoted 5 lines · Elijah Newren
Hi,
I'm pretty sure this worked before, but with git-1.5.4, when trying to clone a repository via ssh from a machine that does not have git installed in a standard system path, I get the following:
Please post patches inline, not attached.
The problem you've encountered is to do with the PATH setup on the remote end. See a previous thread
(http://thread.gmane.org/gmane.comp.version-control.git/72673/focus=72805)
for some solutions.
Dave.
Quoted 8 lines · Elijah Newren
I'm pretty sure this worked before, but with git-1.5.4, when trying to clone a repository via ssh from a machine that does not have git installed in a standard system path, I get the following:
$ git clone -u /home/enewren/software/install/linux/git/bin/git-upload-pack ssh://enewren@remote/var/scratch/enewren/votd Initialized empty Git repository in /home/newren/devel/votd/.git/ remote: fatal: exec pack-objects failed.
git-pull(1)
[...]
--upload-pack <upload-pack>
When given, and the repository to fetch from is handled by git-fetch-pack, --exec=<upload-pack> is passed to the command to specify non-default path for the command run on the other end.
Signature · 3 lines
Jakub Narebski Poland ShadeHawk on #git
Quoted 11 lines · Jakub Narebski
Quoted 8 lines · Elijah Newren
I'm pretty sure this worked before, but with git-1.5.4, when trying to clone a repository via ssh from a machine that does not have git installed in a standard system path, I get the following:
$ git clone -u /home/enewren/software/install/linux/git/bin/git-upload-pack ssh://enewren@remote/var/scratch/enewren/votd Initialized empty Git repository in /home/newren/devel/votd/.git/ remote: fatal: exec pack-objects failed.
Quoted 7 lines
git-pull(1)
[...]
--upload-pack <upload-pack>
When given, and the repository to fetch from is handled by git-fetch-pack, --exec=<upload-pack> is passed to the command to specify non-default path for the command run on the other end.
The OP *did* use this option (rather, its short form, -u), see above.
The problem is that git-upload-pack (which is not a built-in) does not call setup_path() and so does not extend PATH to contain the special installation location. Now, when git-upload-pack tries to exec git-pack-objects, it fails since this is not in PATH.
A quick work-around for Elijah is to add
GIT_EXEC_PATH=/home/enewren/software/install/linux/git/bin
to .profile on the remote host.
-- Hannes
Hi,
Quoted 20 lines · Johannes Sixt
Quoted 11 lines · Jakub Narebski
Quoted 8 lines · Elijah Newren
I'm pretty sure this worked before, but with git-1.5.4, when trying to clone a repository via ssh from a machine that does not have git installed in a standard system path, I get the following:
$ git clone -u /home/enewren/software/install/linux/git/bin/git-upload-pack ssh://enewren@remote/var/scratch/enewren/votd Initialized empty Git repository in /home/newren/devel/votd/.git/ remote: fatal: exec pack-objects failed.Quoted 7 lines
git-pull(1)
[...]
--upload-pack <upload-pack>
When given, and the repository to fetch from is handled by git-fetch-pack, --exec=<upload-pack> is passed to the command to specify non-default path for the command run on the other end.
Quoted 6 lines
The OP *did* use this option (rather, its short form, -u), see above.
The problem is that git-upload-pack (which is not a built-in) does not call
setup_path()and so does not extend PATH to contain the special installation location. Now, when git-upload-pack tries to exec git-pack-objects, it fails since this is not in PATH.
So, let's make git-upload-pack a builtin, no?
Quoted 5 lines
A quick work-around for Elijah is to add
GIT_EXEC_PATH=/home/enewren/software/install/linux/git/bin
to .profile on the remote host.
I guess you meant .bashrc, as .profile is not sourced when using ssh transport (it does not spawn a shell) AFAIR.
Ciao,
Dscho
PATCH 1/1 upload-pack: Initialize the exec-path.
From: Johannes Sixt <[email protected]>
Since git-upload-pack has to spawn git-pack-objects, it has to make sure that the latter can be found in the PATH. Without this patch an attempt to clone or pull via ssh from a server fails if the git tools are not in the standard PATH on the server even though git clone or git pull were invoked with --upload-pack=/path/to/git-upload-pack.
---
Quoted 9 lines · Johannes Schindelin
Hi,
Quoted 4 lines · Johannes Sixt
The problem is that git-upload-pack (which is not a built-in) does not call
setup_path()and so does not extend PATH to contain the special installation location. Now, when git-upload-pack tries to exec git-pack-objects, it fails since this is not in PATH.So, let's make git-upload-pack a builtin, no?
How about this (almost) one-liner instead?
-- Hannes
upload-pack.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-)
upload-pack.c +3 -0
@@ -620,6 +620,9 @@ int main(int argc, char **argv)if (i != argc-1 )usage (upload_pack_usage); + +setup_path (NULL ); + dir = argv[i];if (!enter_repo (dir, strict))
Signature · 1 line
1.5.4.rc3.24.g25a9a
Re: [PATCH] upload-pack: Initialize the exec-path.
Hi,
Quoted 4 lines · Johannes Sixt
Quoted 3 lines · Johannes Schindelin
Hi,
On Tue, 12 Feb 2008, Johannes Sixt wrote:
Quoted 8 lines
Quoted 6 lines
Quoted 4 lines
The problem is that git-upload-pack (which is not a built-in) does not call
setup_path()and so does not extend PATH to contain the special installation location. Now, when git-upload-pack tries to exec git-pack-objects, it fails since this is not in PATH.So, let's make git-upload-pack a builtin, no?
How about this (almost) one-liner instead?
I'm fine with it.
Ciao,
Dscho
Re: [PATCH] upload-pack: Initialize the exec-path.
Hi,
Quoted 9 lines · Johannes Schindelin
Quoted 5 lines · Johannes Sixt
Quoted 1 line · Johannes Schindelin
So, let's make git-upload-pack a builtin, no?
How about this (almost) one-liner instead?
I'm fine with it.
But I also made this:
-- snipsnap --
[PATCH] Make upload-pack a builtin
--- Makefile | 2 +- upload-pack.c => builtin-upload-pack.c | 8 +++++--- builtin.h | 1 + git.c | 1 + 4 files changed, 8 insertions(+), 4 deletions(-) rename upload-pack.c => builtin-upload-pack.c (98%)
Makefile +1 -1
@@ -259,7 +259,6 @@ PROGRAMS = \ git-show-index$X \ git-unpack-file$X \ git-update-server-info$X \ - git-upload-pack$X \ git-pack-redundant$X git-var$X \ git-merge-tree$X git-imap-send$X \ git-merge-recursive$X \
@@ -392,6 +391,7 @@ BUILTIN_OBJS = \ builtin-update-index.o \ builtin-update-ref.o \ builtin-upload-archive.o \ + builtin-upload-pack.o \ builtin-verify-pack.o \ builtin-verify-tag.o \ builtin-write-tree.o \
builtin-upload-pack.c renamed from upload-pack.c +5 -3
@@ -10,6 +10,7 @@#include "revision.h" #include "list-objects.h" #include "run-command.h" +#include "builtin.h" static const char upload_pack_usage[] ="git-upload-pack [--strict] [--timeout=nn] <dir>" ;
@@ -593,14 +594,14 @@ static void upload_pack(void) } } -int main (int argc,char **argv) +int cmd_upload_pack (int argc,const char **argv,const char *prefix) {char *dir;int i;int strict =0 ;for (i =1 ; i < argc; i++) { -char *arg = argv[i]; +const char *arg = argv[i];if (arg[0 ] !='-' )break ;
@@ -620,12 +621,13 @@ int main(int argc, char **argv)if (i != argc-1 )usage (upload_pack_usage); - dir = argv[i]; + dir =xstrdup (argv[i]);if (!enter_repo (dir, strict))die ("'%s': unable to chdir or not a git archive" , dir);if (is_repository_shallow ())die ("attempt to fetch/clone from a shallow repository" );upload_pack (); +free (dir);return 0 ; }
builtin.h +1 -0
@@ -85,6 +85,7 @@ extern int cmd_unpack_objects(int argc, const char **argv, const char *prefix);extern int cmd_update_index (int argc,const char **argv,const char *prefix);extern int cmd_update_ref (int argc,const char **argv,const char *prefix);extern int cmd_upload_archive (int argc,const char **argv,const char *prefix); +extern int cmd_upload_pack (int argc,const char **argv,const char *prefix);extern int cmd_upload_tar (int argc,const char **argv,const char *prefix);extern int cmd_verify_tag (int argc,const char **argv,const char *prefix);extern int cmd_version (int argc,const char **argv,const char *prefix);
git.c +1 -0
@@ -362,6 +362,7 @@ static void handle_internal_command(int argc, const char **argv) { "update-index", cmd_update_index, RUN_SETUP }, { "update-ref", cmd_update_ref, RUN_SETUP }, { "upload-archive", cmd_upload_archive }, + { "upload-pack", cmd_upload_pack }, { "verify-tag", cmd_verify_tag, RUN_SETUP }, { "version", cmd_version }, { "whatchanged", cmd_whatchanged, RUN_SETUP | USE_PAGER },
Signature · 1 line
1.5.4.1.1276.g92036
Re: [PATCH] upload-pack: Initialize the exec-path.
Quoted 7 lines · Johannes Schindelin
Quoted 6 lines · Johannes Schindelin
Quoted 4 lines · Johannes Sixt
Quoted 1 line · Johannes Schindelin
So, let's make git-upload-pack a builtin, no?
How about this (almost) one-liner instead?
Quoted 8 lines
Quoted 1 line
I'm fine with it.
But I also made this:
-- snipsnap --
[PATCH] Make upload-pack a builtinSigned-off-by Johannes Schindelin <[email protected]>
<snip>
I tried this patch yesterday, but it seems to suffer from the same problem? I had to manually apply the patch from Johannes Sixt on top of this ("manually" since there was a trivial conflict) in order for it to solve the problem.
Anyway, it works for me now. Thanks for the quick fixes!
Elijah
Quoted 8 lines · Johannes Schindelin
Quoted 5 lines
A quick work-around for Elijah is to add
GIT_EXEC_PATH=/home/enewren/software/install/linux/git/bin
to .profile on the remote host.
I guess you meant .bashrc, as .profile is not sourced when using ssh transport (it does not spawn a shell) AFAIR.
As far as I can tell, setting paths in .bashrc doesn't really work (or else I'm just doing it wrong). If it did, I would have never hit this bug. Observe the difference between (feel free to replace PATH with GIT_EXEC_PATH; same general result occurs):
$ ssh localhost # Wait for connection to be made, then run $ echo $PATH
AND
$ ssh localhost 'echo $PATH'
AND
$ ssh localhost 'source .bashrc echo $PATH'
The first and the third give the same result, but the second gives something different. It is the second form that git uses, meaning that my paths never get set up.
In my little git wrapper script, I put in some code to work around this little issue and find git-upload-pack for the user if it can (by ssh'ing to the machine and sourcing their .bashrc in the ssh command if necessary; might be a hack, but it makes things nicer for me than always specifying the -u flag).
Cheers,
Elijah
Quoted 23 lines · Elijah Newren
Quoted 8 lines · Johannes Schindelin
Quoted 5 lines
A quick work-around for Elijah is to add
GIT_EXEC_PATH=/home/enewren/software/install/linux/git/bin
to .profile on the remote host.
I guess you meant .bashrc, as .profile is not sourced when using ssh transport (it does not spawn a shell) AFAIR.
As far as I can tell, setting paths in .bashrc doesn't really work (or else I'm just doing it wrong). If it did, I would have never hit this bug. Observe the difference between (feel free to replace PATH with
GIT_EXEC_PATH; same general result occurs):$ ssh localhost # Wait for connection to be made, then run $ echo $PATHAND
$ ssh localhost 'echo $PATH'
Quoted 8 lines
AND
$ ssh localhost 'source .bashrc echo $PATH'The first and the third give the same result, but the second gives something different. It is the second form that git uses, meaning that my paths never get set up.
I had this problem as well, and the only solution I found was setting up my .ssh/environment file.
I guess when you specify a command for ssh, it executes this command by itself, not within a shell environment. Usually it is bash that sources .bashrc and .profile, so you don't get your paths set up. Unfortunately .ssh/environment is not a scripting environment, so you have to just specify your full path there, based on what you get when you echo $PATH from the shell.
Also, this requires putting the following in sshd_config:
PermitUserEnvironment yes
Which, and this is the biter, is not usually a default on most systems, as far as I can see.. so it could mean bugging the sysadmin if it's not your machine, which is not always convenient. Can't see any alternative though.
Steve