Saya telah bertanya-tanya apakah ada solusi "git export" yang baik yang membuat salinan pohon tanpa .git
direktori repositori. Setidaknya ada tiga metode yang saya tahu:
git clone
diikuti dengan menghapus.git
direktori repositori.git checkout-index
menyinggung fungsi ini tetapi dimulai dengan "Baca saja pohon yang diinginkan ke dalam indeks ..." yang saya tidak sepenuhnya yakin bagaimana melakukannya.git-export
adalah skrip pihak ketiga yang pada dasarnya melakukan agit clone
ke lokasi sementara diikuti olehrsync --exclude='.git'
ke tujuan akhir.
Tak satu pun dari solusi ini yang menurut saya memuaskan. Yang terdekat svn export
mungkin adalah opsi 1, karena keduanya memerlukan direktori target menjadi kosong terlebih dahulu. Tetapi opsi 2 tampaknya lebih baik, dengan asumsi saya bisa mencari tahu apa artinya membaca pohon ke dalam indeks.
git
export
git-archive
svn-export
Greg Hewgill
sumber
sumber
git archive --format zip --output "output.zip" master -0
akan memberi Anda arsip yang tidak terkompresi (-0 adalah bendera untuk yang tidak terkompresi). git-scm.com/docs/git-archive .export
subdirektori 250 kB langsung dari repositori jarak jauh (yang bisa berukuran 200 MB, tidak termasuk revisi) - dan saya hanya akan menekan jaringan untuk transfer unduhan 250 kB (atau lebih). Dengangit
,archive
harus diaktifkan di server (jadi saya tidak bisa mencobanya) -clone --depth 1
dari server masih dapat mengambil repo katakanlah 25 MB, di mana.git
subfolder sendiri membutuhkan 15MB. Karena itu, saya masih mengatakan jawabannya "tidak".git checkout-index
git archive -o latest.zip HEAD
Jawaban:
Mungkin cara paling sederhana untuk mencapai ini adalah dengan
git archive
. Jika Anda benar-benar membutuhkan hanya pohon yang diperluas, Anda dapat melakukan sesuatu seperti ini.Sebagian besar waktu saya perlu 'mengekspor' sesuatu dari git, saya ingin arsip terkompresi dalam hal apa pun jadi saya melakukan sesuatu seperti ini.
Arsip ZIP:
git help archive
untuk lebih jelasnya cukup fleksibel.Ketahuilah bahwa meskipun arsip tidak akan berisi direktori .git, namun, arsip itu akan berisi file tersembunyi khusus git seperti .gitignore, .gitattributes, dll. Jika Anda tidak menginginkannya di arsip, pastikan Anda gunakan atribut ekspor-abaikan dalam file .gitattributes dan lakukan ini sebelum melakukan arsip Anda. Baca lebih banyak...
Catatan: Jika Anda tertarik untuk mengekspor indeks, perintahnya adalah
(Lihat jawaban Greg untuk lebih jelasnya)
sumber
git archive --format zip --output /full/path master
git archive --format zip --output /path/to/file.zip --prefix=newdir/ master
output akan disebut 'file.zip' tetapi ketika Anda membukanya, direktori tingkat atas akan menjadi 'newdir'. (Jika Anda menghilangkan atribut --prefix, direktori level atas adalah 'file'.)git archive -o latest.zip HEAD
Ini membuat arsip Zip yang berisi isi dari komit terbaru pada cabang saat ini. Perhatikan bahwa format output disimpulkan oleh ekstensi file output.Saya menemukan apa artinya opsi 2. Dari repositori, Anda dapat melakukan:
Slash pada akhir path penting, jika tidak maka akan menghasilkan file / tujuan dengan awalan 'path'.
Karena dalam situasi normal indeks berisi isi repositori, tidak ada yang istimewa untuk dilakukan "membaca pohon yang diinginkan ke dalam indeks". Sudah ada di sana.
The
-a
flag diperlukan untuk memeriksa semua file dalam indeks (saya tidak yakin apa artinya untuk menghilangkan bendera ini dalam situasi ini, karena tidak melakukan apa yang saya inginkan). The-f
pasukan bendera Timpa file yang ada dalam output, yang perintah ini tidak biasanya melakukan.Tampaknya ini semacam "ekspor git" yang saya cari.
sumber
git add
perintah mengubah konten dalam indeks, sehingga apa pun yanggit status
menunjukkan sebagai "berkomitmen" adalah perbedaan antara KEPALA dan isi indeks.~
(tidak'~'
!) Akan dibuat di dir yang berfungsi. Tidak ada yang istimewagit checkout-index
dalam hal ini: Hal yang sama berlaku untukmkdir '~/dest'
( jangan lakukan itu! ). Namun alasan lain yang baik untuk menghindari nama file yang perlu dikutip (misalnya yang memiliki spasi di dalamnya) :-)git archive
juga bekerja dengan repositori jarak jauh.Untuk mengekspor path tertentu di dalam repo, tambahkan path sebanyak yang Anda inginkan sebagai argumen terakhir ke git, misalnya:
sumber
git archive --format=tar --prefix=PROJECT_NAME/ --remote=USER@SERVER:PROJECT_NAME.git master | tar -xf -
(memastikan arsip Anda ada di folder)git archive --format=zip --output foo.zip --remote=https://github.com/xxx.git master
Dan menjadi fatal: Operasi tidak didukung oleh protokol. Akhir dari aliran perintah yang tidak terduga.curl -L https://api.github.com/repos/VENDOR/PROJECT/tarball | tar xzf -
per dokumenJawaban kasus khusus jika repositori di-host di GitHub.
Gunakan saja
svn export
.Sejauh yang saya tahu Github tidak mengizinkan
archive --remote
. Meskipun GitHub kompatibel dengan svn dan mereka memiliki semua repositori gitsvn
dapat diakses sehingga Anda bisa menggunakannyasvn export
seperti biasanya dengan beberapa penyesuaian pada url GitHub Anda.Misalnya untuk mengekspor seluruh repositori, perhatikan bagaimana
trunk
URL menggantikanmaster
(atau apa pun cabang HEAD proyek diatur ke ):Dan Anda dapat mengekspor satu file atau bahkan path atau folder tertentu:
Contoh dengan jQuery JavaScript Library
The
HEAD
cabang atau Master cabang akan menggunakan tersediatrunk
:Non-
HEAD
cabang akan dapat diakses di bawah/branches/
:Semua tag dengan
/tags/
cara yang sama:sumber
git archive
berfungsi baik dengan GitHub, selama Anda menggunakan protokol git, Cukup gantihttps://
dengangit://
di URL. Saya tidak tahu mengapa GitHub tidak mengiklankan fitur tersembunyi ini.fatal: The remote end hung up unexpectedly
. Mencoba di dua server berbeda dengan repo jQuery github.git config url.<base>.insteadOf
cache repositori jarak jauh. Karena itu saya menggunakanfile://
URL pada kenyataannya. Saya ragu apakah itugit archive
bisa berfungsi dengangit://
URL karena harus dapat berjalangit-upload-archive
di ujung yang jauh. Seharusnya dimungkinkan menggunakanssh
protokol, kecuali bahwa github tidak mengizinkannya (Invalid command: 'git-upload-archive'
).Dari Manual Git :
Menggunakan git-checkout-index untuk "mengekspor seluruh pohon"
Kemampuan awalan pada dasarnya membuatnya sepele untuk menggunakan git-checkout-index sebagai fungsi "ekspor sebagai pohon". Baca saja pohon yang diinginkan ke dalam indeks, dan lakukan:
$ git checkout-index --prefix=git-export-dir/ -a
sumber
git read-tree bar:foo
Dan kemudiangit checkout-index --prefix=export_dir/ -a
setelah itu mungkin Anda harus melakukannyagit update-index master
Saya telah menulis pembungkus sederhana
git-checkout-index
yang dapat Anda gunakan seperti ini:Jika direktori tujuan sudah ada, Anda harus menambahkan
-f
atau--force
.Instalasi sederhana; cukup letakkan script di suatu tempat di Anda
PATH
, dan pastikan itu dapat dieksekusi.Repositori github untuk
git-export
sumber
Tampaknya ini bukan masalah dengan Git daripada SVN. Git hanya menempatkan folder .git di root repositori, sedangkan SVN menempatkan folder .svn di setiap subdirektori. Jadi "ekspor svn" menghindari sihir baris perintah rekursif, sedangkan dengan rekursi Git tidak diperlukan.
sumber
Setara dengan
di dalam repo yang ada adalah
Setara dengan
adalah
sumber
git archive --format=tar --prefix=junk/ HEAD | (tar -t -v --full-time -f -)
... Namun, pengarsipan dengan stempel waktu tidak sepenuhnya sepele, jadi saya memposting contoh di bawah ini .git archive branchname | tar xC otherpath
C
opsi untuk tar adalah GNU Tar saja.Jika Anda tidak termasuk file dengan
.gitattributes
export-ignore
maka cobagit checkout
dan
Selain itu Anda bisa mendapatkan Cabang atau Tag atau dari Revisi Komit tertentu seperti di SVN hanya menambahkan SHA1 (SHA1 di Git adalah setara dengan Nomor Revisi di SVN)
The
/path/to/checkout/
harus kosong, Git tidak akan menghapus file apapun, tetapi akan menimpa file-file dengan nama yang sama tanpa peringatanPEMBARUAN: Untuk menghindari masalah pemenggalan kepala atau meninggalkan repositori yang berfungsi saat menggunakan checkout untuk ekspor dengan tag, cabang atau SHA1, Anda perlu menambahkan
-- ./
di bagian akhirTanda hubung ganda
--
memberitahu git bahwa segala sesuatu setelah tanda hubung adalah path atau file, dan juga dalam hal ini memberitahugit checkout
untuk tidak mengubahHEAD
Contoh:
Perintah ini hanya akan mendapatkan direktori libs dan juga
readme.txt
file dari commit tersebutIni akan membuat (menimpa)
my_file_2_behind_HEAD.txt
dua komit di belakang kepalaHEAD^2
Untuk mendapatkan ekspor cabang lain
Perhatikan bahwa
./
itu relatif terhadap akar repositorisumber
Saya menggunakan git-submodules secara ekstensif. Yang ini bekerja untuk saya:
sumber
.htaccess
?rsync
daftar argumen saya sebagai--cvs-exclude
. Selain itu, masih menyalin.gitattributes
dan.gitignore
Saya sering mengenai halaman ini ketika mencari cara untuk mengekspor repositori git. Jawaban saya untuk pertanyaan ini mempertimbangkan tiga properti yang svn ekspor telah desain dibandingkan dengan git, karena svn mengikuti pendekatan repositori terpusat:
Mengekspor cabang tertentu menggunakan svn dilakukan dengan menentukan jalur yang sesuai
Saat membuat rilis tertentu, penting untuk mengkloning cabang stabil seperti misalnya
--branch stable
atau--branch release/0.9
.sumber
git archive | tar
pendekatan tidak dapat diterapkan untuk lingkungan shell POSIX-kompatibel (misalnya, AppVeyor ini CMD- atau CI berbasis PowerShell), yang merupakan non-ideal. Thegit checkout
Pendekatan memodifikasi indeks dari pohon kerja utama, yang mengerikan. Thegit checkout-index
Pendekatan membutuhkan indeks pohon kerja utama untuk dimodifikasi terlebih dahulu, yang bahkan mengerikan-er.git clone
Pendekatan tradisional mengkloning keseluruhan sejarah repositori sebelum menghapus sejarah itu, yang sia-sia. Ini adalah satu-satunya solusi waras yang tersisa.file://
protokol (misalnya,git clone --depth 1 --branch v3.14.15 file:///home/me/src_repo trg_repo
). Gagal melakukannya akan memancarkan"warning: --depth is ignored in local clones; use file:// instead."
dan melakukan standar daripada klon dangkal, mengalahkan seluruh tujuan jawaban ini. Salud!Ini akan menyalin semua konten, minus file .dot. Saya menggunakan ini untuk mengekspor proyek klon git ke repo git aplikasi web saya tanpa barang .git.
Pesta tua polos bekerja sangat bagus :)
sumber
.gitignore
, ini tidak akan terjadi.Sesederhana klon kemudian hapus folder .git:
git clone url_of_your_repo path_to_export && rm -rf path_to_export/.git
sumber
Untuk pengguna GitHub,
git archive --remote
metode ini tidak akan berfungsi secara langsung, karena URL ekspor bersifat sementara . Anda harus meminta URL GitHub, lalu unduh URL itu.curl
membuatnya mudah:Ini akan memberi Anda kode yang diekspor di direktori lokal. Contoh:
Sunting
Jika Anda ingin kode dimasukkan ke direktori tertentu yang ada (bukan yang acak dari github):
sumber
Ya, ini adalah perintah yang bersih dan rapi untuk mengarsipkan kode Anda tanpa ada git yang dimasukkan dalam arsip dan baik untuk diedarkan tanpa khawatir tentang riwayat git commit.
sumber
Saya hanya ingin menunjukkan bahwa dalam kasus Anda
Maka Anda bisa menggunakan
cp foo [destination]
bukan yang disebutkangit-archive master foo | -x -C [destination]
.sumber
Anda dapat mengarsipkan repo jarak jauh di komit apa pun sebagai file zip.
sumber
Bash-implementasi git-ekspor.
Saya telah mensegmentasi proses pembuatan dan penghapusan file .empty pada fungsinya sendiri, dengan tujuan untuk menggunakannya kembali dalam implementasi 'git-archive' (akan diposting nanti).
Saya juga telah menambahkan file '.gitattributes' ke proses untuk menghapus file yang tidak diinginkan dari folder ekspor target. Termasuk verbosity ke proses sementara membuat fungsi 'git-ekspor' lebih efisien.
EMPTY_FILE = ". Empty";
sumber
Jika Anda menginginkan sesuatu yang berfungsi dengan submodula, ini mungkin layak untuk dicoba.
catatan:
Asumsi:
sumber
Preferensi saya sebenarnya adalah memiliki dist target di Makefile Anda (atau sistem build lain) yang mengekspor arsip yang dapat didistribusikan kode Anda (.tar.bz2, .zip, .jar, atau apa pun yang sesuai). Jika Anda menggunakan autotools GNU atau sistem MakeMaker Perl, saya pikir ini ada untuk Anda secara otomatis. Jika tidak, saya sangat merekomendasikan untuk menambahkannya.
ETA (2012-09-06): Wow, downvotes yang keras. Saya masih percaya bahwa lebih baik untuk membangun distribusi Anda dengan alat membangun Anda daripada alat kontrol kode sumber Anda. Saya percaya dalam membangun artefak dengan alat membangun. Dalam pekerjaan saya saat ini, produk utama kami dibangun dengan target semut. Kami berada di tengah-tengah beralih sistem kontrol kode sumber, dan keberadaan target semut ini berarti satu kerumitan dalam migrasi.
sumber
Ini akan menyalin file dalam rentang komit (C ke G) ke file tar. Catatan: ini hanya akan membuat file berkomitmen. Bukan seluruh repositori. Sedikit dimodifikasi dari sini
Contoh Sejarah Komit
A -> B -> C -> D -> E -> F -> G -> H -> I
Halaman Manual git-diff-tree
-r -> recurse menjadi sub-tree
--no-commit-id -> git diff-tree menampilkan baris dengan ID komit jika berlaku. Bendera ini menekan output ID komit.
--nama-saja -> Tampilkan hanya nama file yang diubah.
--diff-filter = ACMRT -> Pilih hanya file-file ini. Lihat di sini untuk daftar lengkap file
C..G -> File dalam rentang komit ini
C ~ -> Sertakan file dari Komit C. Bukan hanya file sejak Komit C.
| xargs tar -rf myTarFile -> output ke tar
sumber
Seperti yang saya pahami pertanyaannya, ini lebih tentang mengunduh keadaan tertentu dari server, tanpa riwayat, dan tanpa data cabang lain, daripada mengekstraksi keadaan dari repositori lokal (seperti yang dilakukan banyak penjawab di sini).
Itu bisa dilakukan seperti ini:
--single-branch
tersedia sejak Git 1.7.10 (April 2012).--depth
apakah (ternyata?) dilaporkan salah, tetapi untuk kasus ekspor, masalah yang disebutkan seharusnya tidak menjadi masalah.sumber
--depth
, yang menyiratkan--single-branch
kecuali--no-single-branch
diberikan, yang berarti ini mungkin memiliki efek yang sama. Namun tidak yakin, beberapa pakar mungkin mengonfirmasi?Saya membutuhkan ini untuk skrip penyebaran dan saya tidak bisa menggunakan salah satu pendekatan yang disebutkan di atas. Sebaliknya saya menemukan solusi yang berbeda:
sumber
mkdir -p "$2" && git --git-dir="$1" archive HEAD | tar -x -C "$2"
tetapi agak panjang lebar.Melakukannya dengan cara mudah, ini adalah fungsi untuk .bash_profile, secara langsung membuka ritsleting arsip di lokasi saat ini, konfigurasikan dulu [url: path] Anda yang biasa. CATATAN: Dengan fungsi ini Anda menghindari operasi klon, itu langsung dari repo jarak jauh.
Alias untuk .gitconfig, konfigurasi yang sama diperlukan (TAKE CARE menjalankan perintah di dalam proyek .git, SELALU melompat ke dir basis sebelumnya seperti yang dikatakan di sini , sampai ini diperbaiki, saya pribadi lebih suka fungsi
sumber
Sejauh ini cara termudah yang pernah saya lihat untuk melakukannya (dan bekerja di windows juga) adalah
git bundle
:git bundle create /some/bundle/path.bundle --all
Lihat jawaban ini untuk lebih jelasnya: Bagaimana saya bisa menyalin repositori git saya dari mesin windows saya ke mesin linux via usb drive?
sumber
git bundle
termasuk.git
folder, yang tidak diinginkan OP;git archive
tampaknya cara yang lebih tepat--all
saklar?Saya punya solusi lain yang berfungsi dengan baik jika Anda memiliki salinan lokal repositori di mesin tempat Anda ingin membuat ekspor. Dalam hal ini, pindah ke direktori repositori ini, dan masukkan perintah ini:
GIT_WORK_TREE=outputdirectory git checkout -f
Ini sangat berguna jika Anda mengelola situs web dengan repositori git dan ingin checkout versi bersih di
/var/www/
. Dalam hal ini, tambahkan perintah ini dalam.git/hooks/post-receive
skrip (hooks/post-receive
pada repositori kosong, yang lebih cocok dalam situasi ini)sumber
Saya pikir posting @Aredridel adalah yang terdekat, tetapi ada sedikit lebih dari itu - jadi saya akan menambahkan ini di sini; masalahnya adalah, di
svn
, jika Anda berada dalam subfolder dari repo, dan Anda melakukannya:kemudian
svn
akan mengekspor semua file yang berada di bawah kendali revisi (mereka mungkin juga baru saja ditambahkan; atau status yang dimodifikasi) - dan jika Anda memiliki "sampah" lain di direktori itu (dan saya tidak menghitung.svn
subfolder di sini, tetapi hal-hal yang terlihat seperti.o
file) , itu tidak akan diekspor; hanya file-file yang terdaftar oleh repo SVN yang akan diekspor. Bagi saya, satu hal yang menyenangkan adalah bahwa ekspor ini juga menyertakan file dengan perubahan lokal yang belum dilakukan; dan satu lagi yang menyenangkan adalah bahwa cap waktu dari file yang diekspor sama dengan yang asli. Atau, seperti yangsvn help export
dikatakan:Untuk menyadari bahwa
git
tidak akan menyimpan stempel waktu, bandingkan output dari perintah-perintah ini (dalam subfolder darigit
repo pilihan Anda):... dan:
... dan saya, dalam hal apapun, pemberitahuan yang
git archive
menyebabkan semua cap waktu dari file yang diarsipkan sama!git help archive
mengatakan:... tetapi ternyata kedua kasus mengatur "waktu modifikasi setiap file"; dengan demikian tidak menjaga cap waktu yang sebenarnya dari file-file itu!
Jadi, untuk menjaga stempel waktu, berikut adalah
bash
skrip, yang sebenarnya adalah "satu-liner", meskipun agak rumit - jadi di bawah ini diposting dalam beberapa baris:Perhatikan bahwa diasumsikan bahwa Anda mengekspor konten dalam direktori "saat ini" (di atas,
/media/disk/git_svn/subdir
) - dan tujuan tujuan Anda mengekspornya agak tidak nyaman, tetapi berada dalamDEST
variabel lingkungan. Perhatikan bahwa dengan skrip ini; Anda harus membuatDEST
direktori sendiri secara manual, sebelum menjalankan skrip di atas.Setelah skrip dijalankan, Anda harus dapat membandingkan:
... dan semoga melihat cap waktu yang sama (untuk file-file yang berada di bawah kontrol versi).
Semoga ini bisa membantu seseorang,
Ceria!
sumber
git mengekspor ke arsip zip sambil menambahkan awalan (mis. nama direktori):
sumber
Jika Anda memerlukan submodula juga, ini harus melakukan trik: https://github.com/meitar/git-archive-all.sh/wiki
sumber
saya memiliki fungsi utilitas berikut dalam file .bashrc saya: ini membuat arsip cabang saat ini di repositori git.
sumber