git-upload-pack: comando não encontrado, ao clonar repositório Git remoto

170

Eu tenho usado o git para manter duas cópias do meu projeto sincronizadas, uma é a minha caixa local e a outra o servidor de teste. Esse é um problema que ocorre quando eu faço logon no servidor de desenvolvimento remoto usando ssh;

git clone [email protected]:/home/chris/myproject
Initialized empty Git repository in /tmp/myproject/.git/
Password:
bash: git-upload-pack: command not found
fatal: The remote end hung up unexpectedly
fetch-pack from '[email protected]:/home/chris/myproject' failed.

(os nomes dos arquivos foram alterados para proteger os culpados ...!)

Ambas as caixas executam o Solaris 10 AMD. Eu fiz algumas pesquisas, se eu adicionar --upload-pack=$(which git-upload-pack)o comando funciona (e prova que $PATHcontém o caminho para 'git-upload-pack' conforme a solução RTFM), mas isso é realmente irritante, mais 'git push' não funciona, porque não acho que exista uma --unpack=opção.

Aliás, todos os comandos git funcionam bem na minha caixa local, é a mesma versão do software (1.5.4.2), instalada na mesma montagem NFS em /usr/local/bin.

Alguém pode ajudar?

Chris Huang-Leaver
fonte

Respostas:

169

Verifique se git-upload-packestá no caminho a partir de um shell que não é de login. (Na minha máquina está /usr/bin).

Para ver como é o seu caminho na máquina remota a partir de um shell que não é de login, tente o seguinte:

ssh you@remotemachine echo \$PATH

(Isso funciona em Bash, Zsh e tcsh, e provavelmente em outras conchas também.)

Se o caminho retornado não incluir o diretório que possui git-upload-pack, você precisará corrigi-lo configurando-o .bashrc(para Bash), .zshenv(para Zsh), .cshrc(para tcsh) ou equivalente para seu shell.

Você precisará fazer essa alteração na máquina remota.

Se você não tiver certeza de qual caminho precisa adicionar ao seu controle remoto PATH, poderá encontrá-lo com este comando (é necessário executar isso na máquina remota):

which git-upload-pack

Na minha máquina que imprime /usr/bin/git-upload-pack. Portanto, neste caso, /usr/biné o caminho que você precisa para garantir que está no seu shell remoto sem login PATH.

Matt Curtis
fonte
2
O caminho estava correto se eu executar o comando na minha máquina, mas errado se eu o executar ao contrário. (da máquina remota de volta à minha) A edição do meu .bashrc local o corrigiu. Obrigado
Chris Huang-Leaver,
6
Trabalhou no OSX Leopard
Noah Campbell
1
No meu caso, o comando não foi encontrado porque o git foi instalado via MacPorts, o que o coloca /opt/local/bin. Adicionando isso à minha .bashrcvia PATH=$PATH:/new/path/herefuncionou para mim.
Ben Scheirman
1
@ranReloaded A barra invertida deve escapar do cifrão e impedir a expansão de $ PATH na máquina local e, em vez disso, passar "echo $ PATH" literalmente para a máquina remota. Pode depender de qual shell você está usando; funciona para mim no zsh e no bash. Você pode obter o resultado certo usando aspas simples, por exemplo, "ssh you @ remotemachine 'echo $ PATH'" - experimente. Caso contrário, qual shell você está usando? Talvez alguém aqui use esse shell e possa fornecer a solução alternativa.
Matt Curtis
3
@ranReloaded: Quando você diz "o caminho do git não é impresso", você quer dizer que o ssh mostra muitas coisas, mas não o caminho em que o git está? Nesse caso, você tem o mesmo problema que o OP tinha e usar um link simbólico é apenas um bandaid. O "ssh .. echo \$PATH" comando irá mostrar-lhe o caminho na máquina remota, que pode ser diferente ao seu caminho de login, mas isso é a coisa crucial para obter direito de fazê-lo funcionar, e você pode fazer isso através da criação PATH para incluir git na .bashrcna máquina remota. De acordo com a página de manual, .profile/ .bash_profilesão lidos apenas para logins interativos.
Matt Curtis
66

Você também pode usar a opção "-u" para especificar o caminho. Acho isso útil em máquinas onde meu .bashrc não é obtido em sessões não interativas. Por exemplo,

git clone -u /home/you/bin/git-upload-pack you@machine:code
Brian Hawkins
fonte
2
Obrigado por isso. Eu realmente não queria mudar o arquivo ~ / .bashrc.
Luis
2
Apenas observe: aqui estão as instruções sobre como fazer com que o .bashrc seja originado em sessões ssh.
Sp3ctum
58

Com base na resposta de Brian , o caminho do pacote de upload pode ser definido permanentemente executando os seguintes comandos após a clonagem, o que elimina a necessidade de --upload-packsolicitações subsequentes de recebimento / retirada. Da mesma forma, a configuração do pacote de recebimento elimina a necessidade de --receive-packsolicitações push.

git config remote.origin.uploadpack /path/to/git-upload-pack
git config remote.origin.receivepack /path/to/git-receive-pack

Esses dois comandos são equivalentes a adicionar as seguintes linhas a um repo .git/config.

[remote "origin"]
    uploadpack = /path/to/git-upload-pack
    receivepack = /path/to/git-receive-pack

Usuários frequentes de clone -upodem estar interessados ​​nos seguintes aliases. myclone deve ser auto-explicativo. myfetch / mypull / mypush pode ser usado em repositórios cuja configuração não foi modificada conforme descrito acima, substituindo git pushpor git mypush, e assim por diante.

[alias]
    myclone = clone --upload-pack /path/to/git-upload-pack
    myfetch = fetch --upload-pack /path/to/git-upload-pack
    mypull  = pull --upload-pack /path/to/git-upload-pack
    mypush  = push --receive-pack /path/to/git-receive-pack
Garrett
fonte
Obrigado por mencionar a --receive-packopção git-push!
Axel
1
Obrigado por mencionar as opções de configuração, esse é um toque útil do espaço do usuário.
Aron Ahmadia 29/05
Tentei sua sugestão, também adicionei "what git-receive-pack" para localizar o .bashrc, mas de alguma forma o git push ainda não funciona para mim, embora o repo upload funcione bem. Alguma idéia de por que isso poderia acontecer?
Coredump12 /
@coredump, definir "remote.origin.receivepack" deve eliminar a necessidade de modificar PATH no seu .bashrc. Tente git push --receive-pack /full/path/to/git-receive-packpor conta própria, ajuste até obter êxito e modifique .git / config (ou execute "git config") para definir permanentemente o caminho do pacote de recebimento.
Garrett
Obrigado a todos por suas respostas! No meu caso, o servidor de busca e o servidor de envio eram diferentes e o servidor de busca não tinha permissões de gravação. quando eu uso git push <push-server> <branch> tudo funciona bem.
Coredump #
30

Encontrei e usei (com êxito) esta correção:

# Fix it with symlinks in /usr/bin
$ cd /usr/bin/
$ sudo ln -s /[path/to/git]/bin/git* .

Graças a Paul Johnston .

Andy
fonte
consertado para mim também. Obrigado!
John Ballinger
12

O Mac OS X e alguns outros Unixes têm pelo menos o caminho do usuário compilado no sshd por motivos de segurança, para que aqueles que instalam o git como / usr / local / git / {bin, lib, ...} possam ter problemas, pois o git executáveis ​​não estão no caminho pré-compilado. Para substituir isso, prefiro editar minha alteração do / etc / sshd_config:

#PermitUserEnvironment no

para

PermitUserEnvironment yes

e crie arquivos ~ / .ssh / environment conforme necessário. Meus usuários git têm o seguinte em seu arquivo ~ / .ssh / environment:

PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/git/bin

Observe que a expansão da variável não ocorre quando o arquivo ~ / .ssh / environment é lido, portanto:

PATH=$PATH:/usr/local/git/bin

não funciona.

tom
fonte
Parece a dica perfeita, mas não está funcionando aqui para 10.6.6. ssh user @ host echo \ $ PATH ainda mostra o caminho de construção codificado. .Ssh / ambiente adicionado com caminho necessário não expansível. Alterado / etc / sshd_config PermitUserEnvironment yes. sem dados. Alguma sugestão? Obrigado.
6114 Dad
Também tentei definir BASH_ENV = '~ / .nibashrc' na máquina cliente e criar um arquivo com o caminho expandido. também não há dados.
6117 Dad
Está bem. então, colocar o caminho em .bashrc na máquina à qual você está se conectando funcionou para mim.
6114 Dad
obrigado pela dica sobre a expansão variável não trabalhar para .ssh / environment
Denis
Voto positivo por explicar que a expansão var funciona.
XMAN 2/08/19
7

A solução de Matt não funcionou para mim no OS X, mas a de Paul funcionou.

A versão curta do link de Paul é:

Criado /usr/local/bin/ssh_sessioncom o seguinte texto:

#!/bin/bash
export SSH_SESSION=1
if [ -z "$SSH_ORIGINAL_COMMAND" ] ; then
    export SSH_LOGIN=1
    exec login -fp "$USER"
else
    export SSH_LOGIN=
    [ -r /etc/profile ] && source /etc/profile
    [ -r ~/.profile ] && source ~/.profile
    eval exec "$SSH_ORIGINAL_COMMAND"
fi

Executar:

chmod +x /usr/local/bin/ssh_session

Adicione o seguinte a /etc/sshd_config:

ForceCommand / usr / local / bin / ssh_session

Skeletron
fonte
Interessante saber que não funcionou para você. Você se importa em dizer o que dizia PATH na máquina remota quando executou "ssh you @ remote \ $ PATH"?
22810 Matt Curtis
7

Para o bash, ele precisa ser colocado em .bashrc e não em .bash_profile (.bash_profile também é apenas para shells de login).

Andrew Grimm
fonte
5

Eu recebi esses erros com a versão MsysGit.

Depois de seguir todos os conselhos que encontrei aqui e em outros lugares, acabei:

instalando a versão Cygwin do Git

no servidor (Win XP com Cygwin SSHD), isso finalmente foi corrigido.

Eu ainda uso o lado do cliente da versão MsysGit

..de fato, é a única maneira que funciona para mim, já que recebo erros POSIX com o Cygwin Git pull desse mesmo servidor sshd

Eu suspeito que ainda é necessário algum trabalho deste lado do uso do Git .. (ssh + facilidade de puxar / empurrar no Windows)

Ric Tokyo
fonte
1

Como Johan apontou muitas vezes, seu .bashrc é necessário:

ln -s .bash_profile .bashrc

Stefan Lundström
fonte
1

Você deve adicionar o

export PATH=/opt/git/bin:$PATH

antes desta linha no .bashrc:

# If not running interactively, don't do anything
[ -z "$PS1" ] && return

Caso contrário, todas as instruções de exportação não serão executadas ( veja aqui ).

Dennis
fonte
1

Meu caso está no Win 10 com o GIT bash e não tenho um GIT no local padrão. Em vez disso, tenho o git em / app / local / bin. Usei os comandos fornecidos pelo @Garrett, mas preciso alterar o caminho para começar com o dobro /:

git config remote.origin.uploadpack //path/to/git-upload-pack
git config remote.origin.receivepack //path/to/git-receive-pack

Caso contrário, o GIT adicionará o caminho do Windows GIT na frente.

felixc
fonte
0

Para o zsh, você precisa colocá-lo neste arquivo: ~ / .zshenv

Por exemplo, no OS X usando o pacote git-core do MacPorts:

$ echo 'exportar PATH = / opt / local / sbin: / opt / local / bin: $ PATH'> ~ / .zshenv

miknight
fonte
0

Estou tendo problemas para conectar-me a um repositório Gitolite usando SSH do Windows e o problema foi PLINK! Ele ficava me pedindo uma senha, mas o ssh gitolite @ [host] retornava a lista de recompra.

Verifique sua variável de ambiente: GIT_SSH. Se estiver definido como Plink, tente-o sem nenhum valor ("defina GIT_SSH =") e veja se isso funciona.

RAVolt
fonte
0

Adicione o local do seu git-upload-packarquivo .bashrc do usuário remoto do git.

Yeison
fonte
0

Pode ser tão simples quanto instalar o git no host remoto (como no meu caso).

sudo apt-get install git

Ou equivalente para outros sistemas de gerenciamento de pacotes.

fusão verdadeira
fonte