Rsync menyertakan opsi bagus --cvs-exclude
untuk "mengabaikan file dengan cara yang sama seperti CVS", tetapi CVS sudah usang selama bertahun-tahun. Apakah ada cara untuk membuatnya juga mengecualikan file yang akan diabaikan oleh sistem kontrol versi modern (Git, Mercurial, Subversion)?
Misalnya, saya memiliki banyak proyek Maven yang diperiksa dari GitHub. Biasanya mereka menyertakan .gitignore
daftar setidaknya target
, direktori build Maven default (yang mungkin ada di tingkat atas atau di submodul). Karena isi dari direktori ini sepenuhnya dapat dibuang, dan mereka bisa jauh lebih besar dari kode sumber, saya ingin mengecualikannya saat menggunakan rsync untuk backup.
Tentu saja saya bisa secara eksplisit --exclude=target/
tetapi itu akan secara tidak sengaja menekan direktori yang tidak terkait yang kebetulan diberi nama target
dan tidak seharusnya diabaikan.
Dan saya bisa memasok daftar lengkap path absolut untuk semua nama file dan pola disebutkan dalam .gitignore
, .hgignore
atau svn:ignore
properti pada disk saya, tetapi ini akan menjadi daftar besar yang harus diproduksi oleh semacam script.
Karena rsync tidak memiliki dukungan bawaan untuk pemeriksaan VCS selain CVS, apakah ada trik bagus untuk memberinya pola pengabaian mereka? Atau sejenis sistem panggilan balik di mana skrip pengguna dapat ditanyai apakah file / direktori tertentu harus disertakan atau tidak?
Pembaruan : --filter=':- .gitignore'
seperti yang disarankan oleh LordJavac tampaknya berfungsi dengan baik untuk Git seperti --filter=:C
halnya untuk CVS, setidaknya pada contoh yang saya temukan, meskipun tidak jelas apakah sintaksnya sama persis. --filter=':- .hgignore'
tidak bekerja dengan baik untuk Mercurial; misalnya sebuah .hgignore
baris yang mengandung seperti ^target$
(Mercurial equivalent dari Git /target/
) tidak dikenali oleh rsync sebagai ekspresi reguler. Dan sepertinya tidak ada yang berhasil untuk Subversion, yang harus Anda parse .svn/dir-prop-base
untuk copy pekerjaan 1.6 atau sebelumnya, dan angkat tangan Anda dengan cemas untuk copy pekerjaan 1.7 atau yang lebih baru.
:-
artinya? Apa maksud dari titik dua? Apa dasbornya?check-ignore
subperintah yang dapat menangani kerja keras parsing berbagai file "abaikan", jika Anda ingin menggunakan opsi "buat daftar semua file yang tidak diabaikan". Jawaban saya di sini memberikan detail bagaimana melakukan itu.Jawaban:
Seperti yang disebutkan oleh luksan, Anda dapat melakukan ini dengan
--filter
tombol kersync
. Saya mencapai ini dengan--filter=':- .gitignore'
(ada spasi sebelum ".gitignore") yang memberitahursync
untuk melakukan penggabungan direktori dengan.gitignore
file dan meminta mereka mengecualikan sesuai aturan git. Anda mungkin juga ingin menambahkan file abaikan global Anda, jika ada. Untuk membuatnya lebih mudah digunakan, saya membuat aliasrsync
yang menyertakan filter.sumber
--exclude='/.git' --filter="dir-merge,- .gitignore"
rsync -rvv --exclude='.git*' --exclude='/rsync-to-dev.sh' --filter='dir-merge,-n /.gitignore' $DIR/ development.foobar.com:~/test/
.. tetapi meskipun dikatakan[sender] hiding file .gitignore because of pattern .git*
, file tersebut masih dikirim ke tujuan--delete
pilihan, di sini adalah baris perintah kerja:rsync --delete-after --filter=":e- .gitignore" --filter "- .git/" -v -a ...
. Ini butuh waktu beberapa saat ...e
dalam filter dan--delete-after
keduanya penting. Saya sarankan membaca bab "PER-DIRECTORY RULES AND DELETE" darirsync
halaman manual.--delete-after
ke versi perintah @ VasiliNovikov. (Ini tampaknya setara dengan versi perintah @ dboliton, kecuali @db menggunakan: e yang menurut saya tidak termasuk file .gitignore dari penyalinan, yang bukan itu yang saya inginkan.)Anda dapat menggunakan
git ls-files
untuk membuat daftar file yang dikecualikan oleh file repositori.gitignore
. https://git-scm.com/docs/git-ls-filesPilihan:
--exclude-standard
Pertimbangkan semua.gitignore
file.-o
Jangan abaikan perubahan tidak bertahap.-i
Hanya mengeluarkan file yang diabaikan.--directory
Hanya mengeluarkan jalur direktori jika seluruh direktori diabaikan.Satu-satunya hal yang saya abaikan adalah
.git
.sumber
rsync -azP --exclude-from="$(git -C SRC ls-files --exclude-standard -oi --directory > /tmp/excludes; echo /tmp/excludes)" SRC DEST
.gitignore
(yaitu baris yang dimulai dengan!
). Ini juga menyinkronkan file yang Anda--force
tambahkan ke repo, yang biasanya merupakan hal yang baik.bagaimana
rsync --exclude-from='path/.gitignore' --exclude-from='path/myignore.txt' source destination
?Itu berhasil untuk saya.
Saya yakin Anda juga dapat memiliki lebih banyak
--exclude-from
parameter.sumber
.gitignore
file Anda kebetulan menggunakan sintaks yang kompatibel denganrsync
.Solusi 2018 dikonfirmasi
Detail:
--exclude-from
adalah wajib daripada --exclude karena kemungkinan kasus yang mengecualikan daftar tidak akan diuraikan sebagai argumen. Kecualikan dari membutuhkan file dan tidak dapat bekerja dengan pipa.Solusi saat ini menyimpan file kecualikan di dalam folder .git untuk memastikan itu tidak akan mempengaruhi
git status
sementara menyimpannya sendiri. Jika mau, Anda dapat menggunakan / tmp.sumber
SRC
sini — tetapi tidak untuk masalah asli yang saya nyatakan, yang merupakan direktori luas dengan ribuan repositori Git sebagai subdirektori di berbagai kedalaman, banyak di antaranya memiliki.gitignore
s keistimewaan .--exclude-from=<(git -C SRC ls-files --exclude-standard -oi --directory)
Untuk lincah Anda mungkin menggunakan
untuk mengumpulkan daftar file yang TIDAK berada di bawah kendali lincah karena pembatasan .hgignore dan kemudian jalankan
untuk rsync semua file kecuali yang diabaikan. Perhatikan -m flag di rsync yang akan mengecualikan direktori kosong dari sinkronisasi karena hg status -i hanya akan mencantumkan file yang dikecualikan, bukan dirs
sumber
Coba ini:
rsync -azP --delete --filter=":- .gitignore" <SRC> <DEST>
Itu dapat menyalin semua file ke direktori jarak jauh tidak termasuk file di '.gitignore', dan menghapus file yang tidak ada di direktori Anda saat ini.
sumber
Sesuai
rsync
halaman manual, selain daftar standar pola file:Jadi, file $ HOME / .cvsignore saya terlihat seperti ini:
untuk mengecualikan .git dan file yang dihasilkan oleh Sass .
sumber
.git/
direktori, bahkan mungkin lebih kuat daripada copy pekerjaan. Yang ingin saya kecualikan adalah produk build.rsync
halaman manual yang dikutip dalam jawaban ini menjelaskan--cvs-exclude
opsi, jadi Anda harus menggunakannya secara eksplisit. 2 / Anda dapat membuat.cvsignore
file di direktori manapun untuk mendapatkan pengabaian khusus proyek, itu juga dibaca. 3 /.git
sudah diabaikan saat Anda menggunakan--cvs-exclude
, menurut manual, jadi memilikinya di$HOME/.cvsignore
tampaknya mubazir.Saya memiliki sejumlah
.gitignore
file yang sangat besar dan tidak ada solusi "rsync murni" yang berhasil untuk saya. Saya menulis skrip pembungkus rsync ini , itu sepenuhnya menghormati.gitignore
aturan (termasuk!
pengecualian -style dan.gitignore
file di subdirektori) dan telah bekerja seperti pesona bagi saya.sumber
locate -0e .gitignore | (while read -d '' x; do process_git_ignore "$x"; done)
, tetapi memiliki banyak masalah. File dalam direktori yang sama.gitignore
tidak dipisahkan dengan benar dari nama direktori dengan/
. Baris kosong dan komentar salah ditafsirkan. Tersedak.gitignore
file di jalur dengan spasi (apalagi yang jahat/opt/vagrant/embedded/gems/gems/rb-fsevent-0.9.4/spec/fixtures/custom 'path/.gitignore
darivagrant
paket untuk Ubuntu). Mungkin lebih baik dilakukan sebagai skrip Perl.rsync
, karena alasan spesifik bahwa menangani quoting / whitespace sangat menyebalkan. Jika Anda memiliki contohgsync
baris perintah yang gagal, dan.gitignore
file yang terkait dengannya, saya akan dengan senang hati melihat lebih dekat.rsync
seluruh sistem file, dengan berbagai repositori Git yang tersebar di sekitarnya. Mungkin skrip Anda berfungsi dengan baik untuk kasus sinkronisasi satu repositori.Lihat bagian ATURAN FILTER GABUNGAN di rsync (1).
Sepertinya dimungkinkan untuk membuat aturan rsync --filter yang akan menyertakan file .gitignore saat melintasi struktur direktori.
sumber
Alih-alih membuat filter pengecualian, Anda dapat menggunakan
git ls-files
untuk memilih setiap file untuk rsync:Ini berfungsi meskipun
git ls-files
mengembalikan jalur yang dipisahkan baris baru. Mungkin tidak akan berfungsi jika Anda memiliki file berversi dengan spasi di nama file.sumber
Alternatif:
git ls-files -zi --exclude-standard |rsync -0 --exclude-from=- ...
git ls-files -zi --exclude-per-directory=".gitignore" |...
(rsync hanya memahami sebagian .gitignore)
sumber
Jawaban singkat
Parameter arti:
-r
: rekursif--info=...
: tunjukkan kemajuan--filter=...
: kecualikan menurut aturan yang tercantum pada file .gitignoresumber