Git Clone: ​​Tolong hanya file-nya saja?

141

Saya ingin mengkloning GIT repo dan TIDAK berakhir dengan .gitdirektori. Dengan kata lain saya hanya ingin file. Apakah ada cara untuk melakukan ini?

git clone --no-checkoutmelakukan kebalikan dari apa yang saya inginkan (memberi saya hanya .gitdirektori).

Saya mencoba melakukan itu untuk repo jarak jauh , bukan repo lokal, yang berarti ini bukan duplikat dari " Bagaimana melakukan" ekspor git "(seperti" ekspor svn ") " (meskipun solusi mungkin akhirnya menjadi sama).

Dan Rosenstark
sumber
5
kemungkinan rangkap dari Bagaimana melakukan "ekspor git" (seperti "ekspor svn")
Greg Hewgill
@Greg Hewgill Saya mencoba melakukan ini dari repo jarak jauh. Namun, tidak yakin apakah itu membuat pertanyaan ini unik.
Dan Rosenstark
1
Meskipun ini adalah pertanyaan yang lebih baru, tapi saya pikir ini layak untuk dicoba: stackoverflow.com/questions/11497457/…
eonil
1
Lihat jawaban pembaruan saya : git archivesekarang (Q4 2017) lebih tepat dan tidak akan menyertakan folder kosong.
VonC
1
Sama sama. Rupanya, komentar Anda ditandai dan dihapus ... chat.stackoverflow.com/transcript/134259?m=39402889#39402889
VonC

Jawaban:

75

Perintah git yang akan menjadi terdekat dari apa yang Anda cari akan lewat git archive.
Lihat mencadangkan proyek yang menggunakan git : ia akan memasukkan dalam arsip semua file (termasuk submodul jika Anda menggunakan git-archive-allskrip)

Anda kemudian dapat menggunakan arsip itu di mana saja, memberikan Anda hanya file, tanpa .gitdirektori.

git archive --remote=<repository URL> | tar -t

Jika Anda memerlukan folder dan file hanya dari tingkat pertama:

git archive --remote=<repository URL> | tar -t --exclude="*/*"

Untuk daftar hanya folder tingkat pertama dari repo jarak jauh:

git archive --remote=<repository URL> | tar -t --exclude="*/*" | grep "/"

Catatan: itu tidak berfungsi untuk GitHub (tidak didukung)

Jadi, Anda perlu mengkloning (dangkal untuk mempercepat langkah klon), dan kemudian mengarsipkan secara lokal :

git clone --depth=1 [email protected]:xxx/yyy.git
cd yyy
git archive --format=tar aTag -o aTag.tar

Pilihan lain adalah melakukan klon dangkal (seperti yang disebutkan di bawah), tetapi menemukan folder .git di tempat lain.

git --git-dir=/path/to/another/folder.git clone --depth=1 /url/to/repo

Folder repo hanya akan menyertakan file, tanpa .git.

Catatan: git --git-dir adalah opsi perintahgit , bukan git clone.


Perbarui dengan Git 2.14.X / 2.15 (Q4 2017): itu akan memastikan untuk menghindari menambahkan folder kosong .

" git archive", terutama ketika digunakan dengan pathspec, menyimpan direktori kosong dalam hasilnya, meskipun Git sendiri tidak pernah melakukannya.
Ini sudah diperbaiki.

Lihat komit 4318094 (12 Sep 2017) oleh René Scharfe (``) .
Disarankan oleh: Jeff King ( peff) .
(Digabung oleh Junio ​​C Hamano - gitster- dalam komit 62b1cb7 , 25 Sep 2017)

archive: jangan tambahkan direktori kosong ke arsip

Sementara git tidak melacak direktori kosong, git archivebisa diakali untuk memasukkan beberapa ke dalam arsip.
Sementara itu didukung oleh objek database, itu tidak dapat diwakili dalam indeks dan karenanya tidak mungkin terjadi di alam liar.

Karena direktori kosong tidak didukung oleh git, direktori tersebut juga tidak boleh ditulis ke dalam arsip.
Jika direktori kosong benar-benar dibutuhkan, maka itu dapat dilacak dan diarsipkan dengan menempatkan .gitignorefile kosong di dalamnya.

VONC
sumber
4
Ini berhasil untuk saya. Saya akan menambahkan satu hal lagi. Jika Anda sama sekali tidak peduli dengan folder .git, maka saya akan menggunakan perintah ini:git --git-dir=/dev/null clone --depth=1 /url/to/repo
HumanSky
Ini tidak menghapus folder .git
aliasav
@VonC Saya mencoba: git - git-dir = / dev / null clone --depth = 1 / url / to / repo
aliasav
1
Lari, git archive --remote=https://github.com/pornel/dssim.git @ | tar -tsaya mengerti tar: This does not look like a tar archive. Tidakkah itu bekerja dengan GitHub? Juga, apa @artinya itu?
André Werlang
2
@ AndréWerlang 7 tahun kemudian ... Saya tidak terlalu yakin dengan @: Saya telah menghapusnya. Juga GitHub tidak mendukung remote git archive: Saya telah mengedit jawaban untuk mengusulkan alternatif.
VonC
59
git archive --format=tar --remote=<repository URL> HEAD | tar xf -

diambil dari sini

Jon Penn
sumber
2
--format=tartidak perlu. "tar" adalah output default, tidak perlu ditentukan.
VasiliNovikov
1
perpipaan tar xsudah mencukupi
Jens Bannmann
42

Anda dapat membuat klon dangkal untuk hanya mendapatkan beberapa revisi terakhir:

 git clone --depth 1 git://url

maka cukup hapus direktori .git atau gunakan git archiveuntuk mengekspor pohon Anda.

rajutan
sumber
Bagaimana mencegah kesalahan ini ketika saya memperbaruinya dengan mengulangi klon: "fatal: path tujuan 'XYZ' sudah ada dan bukan direktori kosong."
Sohail Si
1
@SohailSi: baik mengkloning ke lokasi baru atau menghapus direktori lama. Anda mungkin lebih baik hanya mengambil revisi baru, jika Anda ingin memperbarui salinan lokal Anda.
knittl
3

Mengapa tidak melakukan kloning dan kemudian menghapus .gitdirektori sehingga Anda hanya memiliki copy pekerjaan kosong?

Sunting: Atau sebenarnya mengapa menggunakan clone sama sekali? Agak membingungkan ketika Anda mengatakan bahwa Anda ingin git repo tetapi tanpa .gitdirektori. Jika Anda bermaksud bahwa Anda hanya ingin salinan beberapa keadaan pohon lalu mengapa tidak lakukan cp -Rdi shell daripada git clone dan kemudian hapus .gitsetelahnya.

Andrew
sumber
Terima kasih untuk itu. File-file tersebut dalam git repo. Saya berharap dapat mengarahkan pengguna Mac untuk mendapatkan salinan repo dalam satu baris, tanpa menjadi repo GIT.
Dan Rosenstark
Anda seharusnya tidak meminta orang langsung mendapatkan kode dari repo jika mereka tidak dapat menggunakannya (mis. Tidak memiliki repositori Git).
alternatif
@Amoss Melepaskan tarball sehingga orang tidak terus-menerus meraih kode terbaru?
alternatif
1
@ mathepic: dan untuk merilis tarball Anda memerlukan cara untuk mendapatkan salinan yang bersih dari repositori - yang merupakan pertanyaan yang diajukan.
Andrew
1
Membaca jawaban di bawah ini dan kemudian melakukan sedikit googling mengarah ke pertanyaan lain: stackoverflow.com/questions/160608/… Jika Anda melihat penggunaan arsip git - lepaskan kemudian lakukan apa yang Anda lakukan (dan poster aslinya) ) mencari. Sunting: itulah yang dijawab Jon lebih rendah.
Andrew
2

Sepertinya Anda hanya ingin menyalin kode sumber. Jika demikian mengapa tidak menyalin direktori saja dan mengecualikan direktori .git dari salinan?

JaredPar
sumber
5
Itulah yang saya tanyakan: bagaimana cara melakukannya dengan git ... Saya sudah bisa mengatakan bahwa tidak ada cara untuk melakukannya dari jawaban yang saya dapatkan. Bagaimanapun, terima kasih!
Dan Rosenstark
2

git checkout -f

Ada cara lain untuk melakukan ini dengan memisahkan repo dari pohon yang berfungsi.

Metode ini berguna jika Anda perlu memperbarui file-file git-less git ini secara teratur. Sebagai contoh, saya menggunakannya ketika saya perlu memeriksa file sumber dan membangun artefak, lalu menyalin artefak ke repo yang berbeda hanya untuk penyebaran ke server, dan saya juga menggunakannya ketika mendorong kode sumber ke server ketika saya ingin kode sumber untuk checkout dan membangun ke direktori www.

Kami akan membuat dua folder, satu untuk git satu untuk file yang berfungsi:

mkdir workingfiles
mkdir barerepo.git

inisialisasi repo telanjang:

cd barerepo.git
git --bare init 

Kemudian buat kait pasca-terima:

touch hooks/post-receive
chmod ug+x hooks/post-receive

Edit pos-terima di editor favorit Anda:

GIT_WORK_TREE=/path/to/workingfiles git checkout -f
# optional stuff:
cd down/to/some/directory
[do some stuff]

Tambahkan ini sebagai remote:

git remote add myserver ssh://user@host:/path/to/barerepo.git

Sekarang setiap kali Anda mendorong ke repo telanjang ini akan checkout pohon kerja /workingfiles/. Tapi /workingfiles/itu sendiri tidak di bawah kontrol versi; berjalan git statusdi /workingfiles/akan memberikan kesalahan fatal: Not a git repository (or any parent up to mount point /data). Ini hanya file biasa.

Tidak seperti solusi solusi lainnya, rm -r .gitperintah tidak diperlukan, jadi jika /workingfiles/ada repo git lain, Anda tidak perlu khawatir dengan perintah yang digunakan untuk menghapus file git repo lainnya.

membanting
sumber
1
Sepakat. Kait pasca-menerima pada repo telanjang mungkin di sini. +1
VonC
banyak pekerjaan jika Anda hanya mencoba untuk mendapatkan file
Rainb
Tidak banyak pekerjaan jika Anda hanya menginginkan file secara teratur.
Slam