Bagaimana cara saya menyimpan file yang diubah?

8

Saya punya dua folder:

  • ASLI/
  • ORIGINAL_AND_MY_CHANGES /

Teman saya punya salinan ASLI /. Saya ingin membuat MY_CHANGES.tgz - itu hanya boleh berisi file yang baru / diubah dari ORIGINAL_AND_MY_CHANGES / dibandingkan dengan ORIGINAL /. Jadi teman saya dapat membongkar ke salinannya ORIGINAL / dan mendapatkan ORIGINAL_AND_MY_CHANGES /. Bagaimana saya bisa melakukan ini?

PS Saya mencoba difftetapi tidak bisa menyimpan data biner dan rsync --link-dest- ini menghasilkan tautan keras yang tidak berguna dalam arsip.

PPS Dalam kasus modifikasi saya waktu tidak dapat digunakan untuk memutuskan file mana yang diubah.

Dmitry
sumber
1
Apakah Anda melihat Direktori "diff"? pertanyaan?
rozcietrzewiacz

Jawaban:

7

Dengan rsync

Apa yang Anda lakukan pada dasarnya adalah cadangan tambahan: teman Anda (cadangan Anda) sudah memiliki file asli, dan Anda ingin membuat arsip yang berisi file yang telah Anda ubah dari aslinya.

Rsync memiliki fitur untuk backup inkremental.

cd ORIGINAL_AND_MY_CHANGED
rsync -a -c --compare-dest=../ORIGINAL . ../CHANGES_ONLY
  • -a berarti melestarikan semua atribut (waktu, kepemilikan, dll.).
  • -c artinya membandingkan konten file dan tidak bergantung pada tanggal dan ukuran.
  • --compare-dest=/some/directoryberarti bahwa file yang identik di bawah direktori itu dan pohon sumber tidak disalin. Perhatikan bahwa jalur relatif ke direktori tujuan.

Rsync menyalin semua direktori, walaupun tidak ada file yang berakhir di sana. Untuk menyingkirkan direktori kosong ini, jalankan find -depth CHANGES_ONLY -type d -empty -delete(atau jika Anda findtidak memiliki -deletedan -empty, jalankan find -depth CHANGES_ONLY -exec rmdir {} + 2>/dev/null).

Kemudian buat arsip dari CHANGES_ONLYdirektori.

Jalan pejalan kaki

Lintasi direktori dengan file Anda. Lewati file yang identik dengan aslinya. Buat direktori di target sesuai kebutuhan. Salin file yang diubah.

cd ORIGINAL_AND_MY_CHANGES
find . \! -type d -exec sh -c '
  for x; do
    if cmp -s "$x" "../ORIGINAL/$x"; then continue; fi
    [ -d "../CHANGES_ONLY/$x" ] || mkdir -p "../CHANGES_ONLY/${%/*}"
    cp -p "$x" "../CHANGES_ONLY/$x"
  done
' {} +
Gilles 'SANGAT berhenti menjadi jahat'
sumber
Itu solusi yang lebih baik daripada enzotib karena saya dapat menempatkan MY_CHANGES dalam kontrol sumber dan memperbarui / melacak perubahan ini (jika saya memperbarui file batch rsync di bawah kontrol sumber, tidak mungkin untuk melihat file apa yang diubah)
Dmitry
@Dmitry Jika Anda menggunakan kontrol sumber, mengapa tidak meletakkan impor / lacak ORIGINALdan buat ORIGINAL_AND_MY_CHANGEScabang? Kemudian cari tahu CHANGESdengan perintah scm.
Gilles 'SANGAT berhenti menjadi jahat'
Dalam kasus saya ini ORIGINALsumber platform Android (3GB, 126000 file). Bahkan menjalankan rsync membutuhkan waktu ~ 15-20 menit. Saya pikir menambahkan semua hal ini di bawah kendali sumber akan memakan terlalu banyak ruang dan waktu.
Dmitry
@ Dmitry Itu menyelesaikannya kalau begitu. Jika itu sumber Android, gunakan repo dan git. Kerjakan di cabang Anda sendiri. Cukup sulit mengelola mereka yang memiliki kontrol versi, saya ngeri membayangkan seperti apa rasanya tanpa itu. Untungnya git sangat pandai mengelola cabang lokal.
Gilles 'SANGAT berhenti menjadi jahat'
Sayangnya itu adalah sumber Android khusus tanpa repo / git repositori di dalamnya.
Dmitry
5

Perintah

rsync --only-write-batch=FILE $other_options ORIGINAL_AND_MY_CHANGES/ ORIGINAL/

akan menghasilkan kumpulan FILE yang berisi perubahan yang diperlukan (tanpa memodifikasi apa pun).

Patch dapat diterapkan di situs lain, tempat Anda mengambil FILE kumpulan, dengan

rsync --read-batch=FILE ORIGINAL/
enzotib
sumber