git-upload-pack: perintah tidak ditemukan, ketika kloning repo Git jarak jauh

170

Saya telah menggunakan git untuk menyimpan dua salinan proyek saya dalam sinkronisasi, satu adalah kotak lokal saya, yang lain server uji. Ini adalah masalah yang terjadi ketika saya masuk ke server pengembangan jarak jauh kami menggunakan 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.

(nama-file telah diubah untuk melindungi yang bersalah ...!)

Kedua kotak menjalankan Solaris 10 AMD. Saya telah melakukan beberapa penggalian, jika saya menambahkan --upload-pack=$(which git-upload-pack)perintah berfungsi, (dan membuktikan bahwa $PATHberisi path ke 'git-upload-pack' sesuai solusi RTFM) tetapi ini benar-benar menjengkelkan, ditambah 'git push' tidak berfungsi, karena saya tidak berpikir ada --unpack=pilihan.

Kebetulan, semua perintah git bekerja dengan baik dari kotak lokal saya, itu adalah versi yang sama dari perangkat lunak (1.5.4.2), diinstal pada NFS mount yang sama di /usr/local/bin.

Adakah yang bisa membantu?

Chris Huang-Leaver
sumber

Jawaban:

169

Pastikan git-upload-packberada di jalur dari shell non-login. (Di mesin saya ada di /usr/bin).

Untuk melihat seperti apa jalan Anda di mesin jarak jauh dari shell non-login, coba ini:

ssh you@remotemachine echo \$PATH

(Itu bekerja di Bash, Zsh, dan tcsh, dan mungkin juga kerang lainnya.)

Jika jalur yang diberikannya tidak menyertakan direktori yang ada git-upload-pack, Anda harus memperbaikinya dengan menyetelnya di .bashrc(untuk Bash), .zshenv(untuk Zsh), .cshrc(untuk tcsh) atau setara dengan shell Anda.

Anda harus melakukan perubahan ini pada mesin jarak jauh.

Jika Anda tidak yakin jalur mana yang perlu Anda tambahkan ke remote PATHAnda, Anda dapat menemukannya dengan perintah ini (Anda perlu menjalankan ini di mesin remote):

which git-upload-pack

Di mesin saya yang mencetak /usr/bin/git-upload-pack. Jadi dalam hal ini, /usr/binapakah jalur yang perlu Anda pastikan ada di shell non-login jauh Anda PATH.

Matt Curtis
sumber
2
Jalan itu benar jika saya menjalankan perintah pada mesin saya, tetapi salah jika saya menjalankannya sebaliknya. (dari mesin jarak jauh kembali ke tambang) Mengedit .bashrc lokal saya memperbaikinya. Terima kasih
Chris Huang-Leaver
6
Bekerja di OSX Leopard
Noah Campbell
1
Dalam kasus saya, perintah tidak ditemukan karena git diinstal melalui MacPorts, yang memasukkannya /opt/local/bin. Menambahkan ini ke .bashrcvia saya PATH=$PATH:/new/path/hereberfungsi untuk saya.
Ben Scheirman
1
@ranReloaded Backslash seharusnya lepas dari tanda dolar dan mencegah ekspansi $ PATH pada mesin lokal, dan alih-alih memberikan "echo $ PATH" secara harfiah ke mesin jarak jauh. Ini mungkin tergantung pada shell apa yang Anda gunakan; itu bekerja untuk saya di zsh dan bash. Anda mungkin bisa mendapatkan hasil yang tepat menggunakan tanda kutip tunggal, misalnya "ssh you @ remotemachine 'echo $ PATH'" - cobalah. Jika tidak, shell apa yang Anda gunakan? Mungkin orang lain di sini menggunakan cangkang itu dan bisa memberi Anda solusinya.
Matt Curtis
3
@ranReloaded: Ketika Anda mengatakan "path git tidak tercetak", apakah maksud Anda ssh menunjukkan banyak hal tetapi bukan path tempat git aktif? Jika demikian maka Anda memiliki masalah yang sama dengan yang dimiliki OP, dan menggunakan symlink hanyalah bandaid. The "ssh .. echo \$PATH" perintah akan menunjukkan jalan pada mesin remote, yang mungkin berbeda dengan jalur login Anda, tapi ini adalah hal penting untuk mendapatkan hak untuk membuatnya bekerja, dan Anda dapat melakukannya dengan menetapkan PATH untuk memasukkan git di .bashrcatas mesin jarak jauh. Menurut halaman manual, .profile/ .bash_profilehanya dibaca untuk login interaktif.
Matt Curtis
66

Anda juga dapat menggunakan opsi "-u" untuk menentukan lintasan. Saya menemukan ini membantu pada mesin di mana. Bashrc saya tidak bersumber di sesi non-interaktif. Sebagai contoh,

git clone -u /home/you/bin/git-upload-pack you@machine:code
Brian Hawkins
sumber
2
Terima kasih untuk itu. Saya benar-benar tidak ingin mengubah file ~ / .bashrc.
Luis
2
Sebagai catatan: berikut adalah petunjuk tentang cara membuat .bashrc bersumber pada sesi ssh.
sp3ctum
58

Berdasarkan jawaban Brian , jalur unggah-paket dapat ditetapkan secara permanen dengan menjalankan perintah berikut setelah kloning, yang menghilangkan kebutuhan untuk --upload-packpermintaan tarik / pengambilan berikutnya. Demikian pula, pengaturan paket terima menghilangkan kebutuhan untuk --receive-packpermintaan push.

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

Kedua perintah ini setara dengan menambahkan baris berikut ke repo .git/config.

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

Pengguna yang sering clone -udapat tertarik dengan alias berikut ini. myclone harus jelas. myfetch / mypull / mypush dapat digunakan pada repo yang konfigurasinya belum dimodifikasi seperti dijelaskan di atas dengan mengganti git pushdengan git mypush, dan seterusnya.

[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
sumber
Terima kasih telah menyebutkan --receive-packopsi untuk git-push!
Axel
1
Terima kasih telah menyebutkan opsi konfigurasi, itu sentuhan yang bermanfaat dari ruang pengguna.
Aron Ahmadia
Saya mencoba saran Anda, juga menambahkan "paket git-accept-pack" ke path di .bashrc tapi entah bagaimana git push masih tidak berfungsi untuk saya, meskipun unggahan repo berfungsi dengan baik. Adakah yang tahu mengapa ini bisa terjadi?
coredump
@coredump, pengaturan "remote.origin.receivepack" harus menghilangkan kebutuhan untuk memodifikasi PATH di .bashrc Anda. Coba git push --receive-pack /full/path/to/git-receive-packsendiri, atur sampai berhasil, kemudian modifikasi .git / config (atau jalankan "git config") untuk secara permanen mengatur jalur paket-terima.
Garrett
Terima kasih semuanya atas tanggapan Anda! Dalam kasus saya server fetch dan server push berbeda dan server fetch tidak memiliki izin menulis. ketika saya menggunakan git push <push-server> <branch> semuanya berfungsi dengan baik.
coredump
30

Saya menemukan dan menggunakan (berhasil) perbaikan ini:

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

Terima kasih kepada Paul Johnston .

Andy
sumber
diperbaiki untuk saya juga. Terima kasih!
John Ballinger
12

Mac OS X dan beberapa Unix lainnya setidaknya memiliki jalur pengguna dikompilasi ke sshd untuk alasan keamanan sehingga kita yang menginstal git sebagai / usr / local / git / {bin, lib, ...} dapat mengalami masalah seperti git executable tidak dalam jalur yang dikompilasi. Untuk menimpanya, saya lebih suka mengedit / etc / sshd_config saya yang berubah:

#PermitUserEnvironment no

untuk

PermitUserEnvironment yes

dan kemudian buat file ~ / .ssh / environment sesuai kebutuhan. Pengguna git saya memiliki yang berikut di file ~ / .ssh / environment mereka:

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

Catatan ekspansi variabel tidak terjadi ketika file ~ / .ssh / environment dibaca jadi:

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

tidak akan berfungsi.

tom
sumber
Ini sepertinya tip yang sempurna, tetapi tidak bekerja di sini untuk 10.6.6. ssh user @ host echo \ $ PATH masih menunjukkan lintasan pembuatan kode keras. Tambahkan .ssh / lingkungan dengan jalur yang diperlukan tidak meluas. Diubah / etc / sshd_config PermitUserEnvironment ya. tidak ada dadu. Ada saran? Terima kasih.
Ayah
Juga mencoba mengatur BASH_ENV = '~ / .nibashrc' pada mesin klien dan membuat file di dalamnya dengan jalur yang diperluas di dalamnya. juga tidak ada dadu.
Ayah
Baik. jadi letakkan path di .bashrc pada mesin yang Anda sambungkan bekerja untuk saya.
Ayah
terima kasih atas tip tentang ekspansi variabel yang tidak berfungsi untuk .ssh / environment
Denis
Suara positif untuk menjelaskan bahwa ekspansi var berfungsi.
XMAN
7

Solusi Matt tidak bekerja untuk saya di OS X, tetapi Paul berhasil.

Versi singkat dari tautan Paul adalah:

Dibuat /usr/local/bin/ssh_sessiondengan teks berikut:

#!/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

Menjalankan:

chmod +x /usr/local/bin/ssh_session

Tambahkan yang berikut ke /etc/sshd_config:

ForceCommand / usr / local / bin / ssh_session

Kerangka
sumber
Menarik mendengarnya tidak bekerja untuk Anda. Apakah Anda keberatan mengatakan apa yang dikatakan PATH pada mesin jarak jauh, ketika Anda menjalankan "ssh you @ remote \ $ PATH"?
Matt Curtis
7

Untuk bash, perlu dimasukkan ke .bashrc bukan .bash_profile (.bash_profile juga hanya untuk shell login).

Andrew Grimm
sumber
5

Saya mendapat kesalahan ini dengan versi MsysGit.

Setelah mengikuti semua saran yang bisa saya temukan di sini dan di tempat lain, saya akhirnya:

menginstal versi Cygwin dari Git

di server (Win XP dengan Cygwin SSHD), ini akhirnya memperbaikinya.

Saya masih menggunakan sisi klien versi MsysGit

pada kenyataannya, itu satu-satunya cara kerjanya bagi saya, karena saya mendapatkan kesalahan POSIX dengan tarikan Cygwin Git dari server sshd yang sama

Saya menduga beberapa pekerjaan masih diperlukan sisi penggunaan Git ini .. (ssh + kemudahan tarik / push di Windows)

Ric Tokyo
sumber
1

Seperti yang ditunjukkan Johan berkali-kali .bashrc yang dibutuhkan:

ln -s .bash_profile .bashrc

Stefan Lundström
sumber
1

Anda harus menambahkan

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

sebelum baris ini di .bashrc:

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

Kalau tidak, semua pernyataan ekspor tidak akan dieksekusi ( lihat di sini ).

Dennis
sumber
1

Kasing saya ada di Win 10 dengan GIT bash dan saya tidak punya GIT di bawah lokasi standar. Sebaliknya saya memiliki git di / app / local / bin. Saya menggunakan perintah yang disediakan oleh @Garrett tetapi perlu mengubah path untuk memulai dengan double /:

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

Kalau tidak, GIT akan menambahkan jalur Windows GIT Anda di depan.

felixc
sumber
0

Untuk zsh Anda harus memasukkannya ke file ini: ~ / .zshenv

Misalnya, pada OS X menggunakan paket git-core dari MacPorts:

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

miknight
sumber
0

Saya mengalami masalah saat menyambung ke repo Gitolite menggunakan SSH dari Windows dan ternyata masalah saya adalah PLINK! Itu terus meminta saya untuk kata sandi, tetapi ssh gitolite @ [host] akan mengembalikan daftar repo.

Periksa variabel lingkungan Anda: GIT_SSH. Jika disetel ke Plink, cobalah tanpa nilai apa pun ("set GIT_SSH =") dan lihat apakah itu berfungsi.

RAVolt
sumber
0

Tambahkan lokasi Anda git-upload-packke file .bashrc pengguna git jarak jauh.

Yeison
sumber
0

Mungkin sesederhana menginstal git pada host jarak jauh (seperti dalam kasus saya).

sudo apt-get install git

Atau setara dengan sistem manajemen paket lainnya.

truefusion
sumber