Git format-patch agar kompatibel dengan svn?


96

Apakah ada cara untuk mendapatkan tambalan yang dibuat dengan git format-patch agar kompatibel dengan svn sehingga saya dapat mengirimkannya ke repo svn?

Saya sedang mengerjakan repo svn di github dan ingin mengirimkan perubahan saya kembali ke repo utama. Saya perlu membuat tambalan untuk melakukan ini, namun tambalan tidak dapat diterapkan karena git memformat tambalan yang berbeda dari svn. Apakah ada rahasia yang belum saya temukan?

PEMBARUAN: Meskipun saat ini tidak ada skrip atau cara git asli untuk melakukan ini, saya berhasil menemukan posting dari awal tahun ini tentang cara melakukannya secara manual. Saya telah mengikuti instruksi dan berhasil mendapatkan tambalan git saya untuk bekerja dengan svn.

Jika seseorang dapat mencoba menulis skrip untuk mencapai ini dan berkontribusi pada proyek git, saya semua akan sangat dihargai.

http://kerneltrap.org/mailarchive/git/2008/1/15/570308/thread#mid-570308


Saya tidak bisa membuatnya berfungsi ... bisakah Anda memposting semua langkah yang diperlukan? Terima kasih!
Mauricio Scheffer

1
Hai Anthony. Apakah Anda akan mempertimbangkan untuk mengubah jawaban yang diterima menjadi jawaban Nicholas?
Simon East

Saya mendukung saran Simon, menerima jawaban Nicholas Smith sebagai jawaban yang diterima akan menguntungkan semua orang karena jauh lebih praktis.
Albireo

Jawaban:


90

Saya selalu harus Google ini, tetapi cara saya menemukan yang berfungsi dengan sempurna (untuk saya) adalah:

  • Buat tambalan dengan git diff --no-prefix master..branch > somefile.diff, bagian master dan cabang bersifat opsional, tergantung bagaimana Anda ingin mendapatkan diff.
  • Kirim ke mana saja dan lamar dengan patch -p0 < somefile.diff.

Tampaknya selalu berfungsi dengan baik bagi saya dan tampaknya metode paling sederhana yang pernah saya temui.


1
Ini adalah cara kanonik untuk menghasilkan patch yang kompatibel dengan SVN dengan Git. Itu harus ditandai sebagai jawabannya.
mloskot

--no-pagertidak lagi menjadi pilihan untuk git diff.
n nothing101

Ini awalnya diposting tanpa --no-pager, saya tidak yakin mengapa itu ditambahkan di edit. Itu selalu bekerja dengan baik untuk saya tanpanya --no-pager.
Nicholas Smith

2
Hanya untuk komit tertentu: git diff --no-prefix 056a1ba5140 7d939289b80 >my.patchberhasil untuk saya (di mana 056a1ba5140dan 7d939289b80apakah sha-1 dari komit sebelumnya dan khusus di git).
Ed Randall

@ Lilás ini adalah masalah dengan SVN. Diffs / patches di SVN tidak pernah mampu menangani file yang dihapus
Toofy


17

Berikut adalah skrip pembantu untuk membuat diff terhadap svn changeset terbaru dan komit yang diberikan: http://www.mail-archive.com/dev@trafficserver.apache.org/msg00864.html

#!/bin/sh
#
# git-svn-diff
# Generate an SVN-compatible diff against the tip of the tracking branch
TRACKING_BRANCH=`git config --get svn-remote.svn.fetch | sed -e 's/.*:refs\/remotes\///'`
REV=`git svn find-rev $(git rev-list --date-order --max-count=1 $TRACKING_BRANCH)`
git diff --no-prefix $(git rev-list --date-order --max-count=1 $TRACKING_BRANCH) $* |
sed -e "s/^+++ .*/&    (working copy)/" -e "s/^--- .*/&    (revision $REV)/" \
-e "s/^diff --git [^[:space:]]*/Index:/" \
-e "s/^index.*/===================================================================/"

1
Saya menemukan bahwa nilai REV salah jika Anda tidak bekerja dengan revisi svn terbaru. Saya mengoreksinya untuk menggunakan git svn infosebagai gantinya: REV=`git svn info | grep 'Last Changed Rev:' | sed -E 's/^.*: ([[:digit:]]*)/\1/'`
Sebastien Martin

1
Ini LUAR BIASA! Terima kasih banyak. Saya harus membuat satu perubahan agar berfungsi untuk mengimpor tambalan saya ke wadah Fisheye, dan itu adalah mengganti spasi sebelum "(revisi" dengan tab.
Zugwalt

10

SVN mungkin tidak dapat memahami keluaran dari git diff -p, tetapi Anda dapat menggunakan kekerasan:

  1. Buat dua klon dari repo Anda
  2. Dalam satu klon, periksa barang terbaru Anda
  3. Di klon lain checkout apapun yang setara dengan svn upstream. Jika Anda telah merencanakan sebelumnya, Anda memiliki salinan svn upstream di cabangnya sendiri, atau Anda telah menandai versi svn terakhir. Jika Anda belum merencanakan sebelumnya, gunakan date atau gitk untuk menemukan hash git SHA1 yang paling mendekati status svn.
  4. Sekarang hitung tambalan nyata dengan menjalankan diff -rdua klon.

12
Atau cukup ikuti saran @ Nicholas-smith dan jalankan git diff --no-prefix > somefile.diffdi repo git Anda dan kirimkan ke pengguna svn mana pun agar mereka dapat menerapkan tambalan patch -p0 < somefile.diffdi root proyek.
DavidG

10

Subversion <1.6 tidak memiliki dukungan patch. Sepertinya Subversion 1.7 akan mengizinkan penerapan tambalan dan ekstensi git / hg untuk unified diff ada di daftar TODO kami.


4

Ini memang permintaan fitur awal 2008

Linus Torvalds berkata pada saat itu:

Jadi saya berpendapat bahwa Anda memerlukan sesuatu yang lebih kuat untuk mengatakan "jangan lakukan git diff", dan itu juga harus melarang deteksi rename minimal.
Sejujurnya, program apa pun yang begitu bodoh sehingga tidak menerima tambalan git saat ini (yaitu TortoiseSVN), maka sebaiknya kita tidak hanya menonaktifkan bagian paling remeh darinya. Kita harus memastikan bahwa kita tidak mengaktifkan salah satu ekstensi yang agak penting:
bahkan jika ToirtoiseSVN akan mengabaikannya, jika mengabaikannya berarti salah memahami perbedaannya, itu seharusnya tidak diizinkan sama sekali.

Mungkin itu sebabnya

 git-format-patch: add --no-binary to omit binary changes in the patch.

telah diperkenalkan di Git1.5.6 pada Mei / Juli 2008 (meskipun saya belum mengujinya)


0

Pastikan perubahan Anda dilakukan dan didasarkan pada cabang git lokal Anda, dari git bash run:

git show --pretty >> myChangesFile.patch


0

Jawaban yang diterima yang diberikan oleh Nicholas berfungsi dengan baik, kecuali jika a) file biner ada di diff atau b) Anda bekerja di windows Git dan memiliki direktori dengan spasi. Untuk menyelesaikannya, saya harus menambahkan perintah git diff bersarang untuk mengabaikan binari dan perintah sed untuk keluar dari spasi. Agak rumit untuk menulis, jadi saya membuat alias:

[alias]
svnpatch = "!f() { git diff --name-only --no-prefix master...$1 | grep -Ev \"\\.sdf|\\.Doc|\\.dll|\\.zip|\\.exe\" | sed 's_\\s_\\\\\\\\ _g'  | xargs git diff --no-prefix master...$1 > $1.patch; echo "Created $1.patch"; }; f"

Jika Anda kemudian mengetik:

git svnpatch Feature123

... file patch Feature123.patch akan dibuat dengan perbedaan antara basis gabungan master cabang dan cabang Feature123.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.