Bisakah saya membagi cowok yang sudah terpecah dengan git?

205

Saya baru-baru ini menemukan patchopsi git untuk addperintah, dan saya harus mengatakan itu benar-benar fitur yang fantastis. Saya juga menemukan bahwa sebongkah besar dapat dibagi menjadi bakhil yang lebih kecil dengan menekan stombol, yang menambah presisi komit. Tetapi bagaimana jika saya ingin lebih presisi, jika split hunk tidak cukup kecil?

Sebagai contoh, pertimbangkan ini sudah split cowok:

@@ -34,12 +34,7 @@
   width: 440px;
 }

-/*#field_teacher_id {
-  display: block;
-} */
-
-form.table-form #field_teacher + label,
-form.table-form #field_producer_distributor + label {
+#user-register form.table-form .field-type-checkbox label {
   width: 300px;
 }

Bagaimana saya bisa menambahkan penghapusan komentar CSS hanya untuk komit berikutnya? The sopsi ini tidak tersedia lagi!

greg0ire
sumber

Jawaban:

254

Jika Anda menggunakan git add -pdan bahkan setelah berpisah s, Anda tidak memiliki perubahan yang cukup kecil, Anda dapat menggunakannya euntuk mengedit tambalan secara langsung.

Ini bisa menjadi sedikit membingungkan, tetapi jika Anda hati-hati mengikuti petunjuk dalam jendela editor yang akan dibuka setelah menekan emaka Anda akan baik-baik. Jika Anda mengutip, Anda ingin mengganti -dengan spasi di awal baris ini:

-
-form.table-form #field_teacher + label,
-form.table-form #field_producer_distributor + label {

... dan hapus baris berikut, yaitu yang dimulai dengan +. Jika Anda kemudian menyimpan dan keluar dari editor Anda, hanya penghapusan komentar CSS akan dipentaskan.

Mark Longair
sumber
9
Solusi keren! Saya melihat itu tetapi disalahpahami ... Saya pikir perubahan juga akan dihapus dari pohon yang berfungsi.
greg0ire
7
Memang, itu tidak terlalu jelas dari teks bantuan. Saya menemukan diri saya banyak menggunakan ini, sebenarnya, karena saya pikir git benar-benar mendorong Anda untuk membuat setiap commit
setepat
27
Perhatikan bahwa Anda benar-benar harus menggantinya dengan spasi . Saya mencoba mengira saya hanya bisa menghapus -karakter, dan Git mengeluh bahwa tambalan saya tidak berlaku.
Ryan Lundy
3
Saya menduga alasan Anda menghapus baris dengan tanda '-' dan mengganti tanda '+ dengan spasi adalah bahwa Anda membuat tambalan di mana garis dengan tanda' - 'telah dihapus dan garis dengan tanda' + sudah ditambahkan (sesuai dengan tambalan). Atau cara lain untuk melihatnya, adalah Anda benar-benar melakukan tindakan yang mewakili karakter tersebut (-, +) (menambahkan garis atau menghapusnya). Hanya baris yang tersisa dengan tanda '-'s dan' + dicatat sebagai perubahan dan sisanya adalah "hanya bagaimana file itu".
atomictom
3
@Filype: Saya tidak tahu mengapa itu bisa terjadi, saya khawatir - jika Anda menjalankan git add -pdan mengedit sepotong dengan eitu hanya akan mempengaruhi apa yang dipentaskan, bukan pohon kerja Anda.
Mark Longair
60

Katakanlah example.csspenampilan Anda seperti ini:

.classname {
  width: 440px;
}

/*#field_teacher_id {
  display: block;
} */

form.table-form #field_teacher + label,
form.table-form #field_producer_distributor + label {
  width: 300px;
}

.another {
  width: 420px;
}

Sekarang mari kita ubah penyeleksi gaya di blok tengah, dan sementara kita melakukannya, hapus beberapa gaya komentar lama yang tidak kita perlukan lagi.

.classname {
  width: 440px;
}

#user-register form.table-form .field-type-checkbox label {
  width: 300px;
}

.another {
  width: 420px;
}

Itu mudah, sekarang mari kita komit. Tapi tunggu, saya ingin mempertahankan pemisahan logis dari perubahan dalam kontrol versi untuk peninjauan kode langkah-sederhana, dan agar tim saya dan saya dapat dengan mudah mencari riwayat komit untuk spesifik.

Menghapus kode lama secara logis terpisah dari perubahan pemilih gaya lainnya. Kita akan membutuhkan dua komitmen berbeda, jadi mari kita tambahkan bakhil untuk tambalan.

git add --patch
diff --git a/example.css b/example.css
index 426449d..50ecff9 100644
--- a/example.css
+++ b/example.css
@@ -2,12 +2,7 @@
   width: 440px;
 }

-/*#field_teacher_id {
-  display: block;
-} */
-
-form.table-form #field_teacher + label,
-form.table-form #field_producer_distributor + label {
+#user-register form.table-form .field-type-checkbox label {
   width: 300px;
 }

Stage this hunk [y,n,q,a,d,/,e,?]?

Ups, sepertinya perubahannya terlalu dekat, jadi git telah mencampurkan keduanya.

Bahkan mencoba membaginya dengan menekan smemiliki hasil yang sama karena pemisahan itu tidak cukup granular untuk perubahan presisi kami. Diperlukan garis yang tidak berubah di antara garis yang diubah agar git dapat membagi patch secara otomatis.

Jadi, mari kita edit secara manual dengan menekane

Stage this hunk [y,n,q,a,d,/,e,?]? e

git akan membuka tambalan di editor pilihan kami.

# Manual hunk edit mode -- see bottom for a quick guide
@@ -2,12 +2,7 @@
   width: 440px;
 }

-/*#field_teacher_id {
-  display: block;
-} */
-
-form.table-form #field_teacher + label,
-form.table-form #field_producer_distributor + label {
+#user-register form.table-form .field-type-checkbox label {
   width: 300px;
 }

# ---
# To remove '-' lines, make them ' ' lines (context).
# To remove '+' lines, delete them.
# Lines starting with # will be removed.
#
# If the patch applies cleanly, the edited hunk will immediately be
# marked for staging. If it does not apply cleanly, you will be given
# an opportunity to edit again. If all lines of the hunk are removed,
# then the edit is aborted and the hunk is left unchanged.

Mari kita tinjau tujuannya:

Bagaimana saya bisa menambahkan penghapusan komentar CSS hanya untuk komit berikutnya?

Kami ingin membaginya menjadi dua komitmen:

  1. Komit pertama melibatkan penghapusan beberapa baris (penghapusan komentar).

    Untuk menghapus baris yang dikomentari, biarkan saja, mereka sudah ditandai untuk melacak penghapusan dalam kontrol versi seperti yang kita inginkan.

    -/*#field_teacher_id {
    - display: block;
    -} */

  2. Komit kedua adalah perubahan, yang dilacak dengan merekam penghapusan dan penambahan:

    • Penghapusan (garis pemilih lama dihapus)

      Untuk menjaga garis pemilih yang lama (jangan hapus mereka selama komit ini), kami ingin ...

      Untuk menghapus '-' garis, buatlah ''

      ... yang secara harfiah berarti mengganti -tanda minus dengan karakter spasi .

      Jadi tiga baris ini ...

      -
      -form.table-form #field_teacher + label,
      -form.table-form #field_producer_distributor + label {

      ... akan menjadi ( perhatikan spasi tunggal pada yang pertama dari semua 3 baris):


      form.table-form #field_teacher + label,
      form.table-form #field_producer_distributor + label {

    • Tambahan (garis pemilih baru ditambahkan)

      Agar tidak memperhatikan garis pemilih baru yang ditambahkan selama komit ini, kami ingin ...

      Untuk menghapus garis '+', hapuslah.

      ... yang secara harfiah berarti menghapus seluruh baris:

      +#user-register form.table-form .field-type-checkbox label {

      (Bonus: Jika Anda menggunakan vim sebagai editor Anda, tekan dduntuk menghapus baris. Pengguna Nano tekan Ctrl+ K)

Editor Anda akan terlihat seperti ini ketika Anda menyimpan:

# Manual hunk edit mode -- see bottom for a quick guide
@@ -2,12 +2,7 @@
   width: 440px;
 }

-/*#field_teacher_id {
-  display: block;
-} */

 form.table-form #field_teacher + label,
 form.table-form #field_producer_distributor + label {
   width: 300px;
 }

# ---
# To remove '-' lines, make them ' ' lines (context).
# To remove '+' lines, delete them.
# Lines starting with # will be removed.
#
# If the patch applies cleanly, the edited hunk will immediately be
# marked for staging. If it does not apply cleanly, you will be given
# an opportunity to edit again. If all lines of the hunk are removed,
# then the edit is aborted and the hunk is left unchanged.

Sekarang mari kita komit.

git commit -m "remove old code"

Dan untuk memastikan, mari kita lihat perubahan dari komit terakhir.

git show
commit 572ecbc7beecca495c8965ce54fbccabdd085112
Author: Jeff Puckett <[email protected]>
Date:   Sat Jun 11 17:06:48 2016 -0500

    remove old code

diff --git a/example.css b/example.css
index 426449d..d04c832 100644
--- a/example.css
+++ b/example.css
@@ -2,9 +2,6 @@
   width: 440px;
 }

-/*#field_teacher_id {
-  display: block;
-} */

 form.table-form #field_teacher + label,
 form.table-form #field_producer_distributor + label {

Sempurna - Anda dapat melihat bahwa hanya penghapusan yang dimasukkan dalam komit atom. Sekarang mari kita selesaikan pekerjaan dan lakukan sisanya.

git add .
git commit -m "change selectors"
git show
commit 83ec3c16b73bca799e4ed525148cf303e0bd39f9
Author: Jeff Puckett <[email protected]>
Date:   Sat Jun 11 17:09:12 2016 -0500

    change selectors

diff --git a/example.css b/example.css
index d04c832..50ecff9 100644
--- a/example.css
+++ b/example.css
@@ -2,9 +2,7 @@
   width: 440px;
 }

-
-form.table-form #field_teacher + label,
-form.table-form #field_producer_distributor + label {
+#user-register form.table-form .field-type-checkbox label {
   width: 300px;
 }

Akhirnya Anda dapat melihat komit terakhir hanya mencakup perubahan pemilih.

Jeff Puckett
sumber
1
Bonus # 2: Jika Anda menggunakan VIM sebagai editor, Anda harus menekan "d" dua kali di papan ketik untuk menghapus satu baris: D
Alexxus
3
Selain itu, alih-alih menghapus baris tambahan yang tidak ingin Anda tambahkan, Anda dapat mengganti +dengan #. Hasilnya sama, tetapi mungkin Anda merasa tidak nyaman dengan penghapusan (dan tidak dapat kembali) atau Anda ingin bereksperimen sebelum menyimpan.
ob-ivan
Dan itu, untuk vim r #lebih dari plus xD
aksh1618
Tujuannya adalah "Bagaimana saya bisa menambahkan penghapusan komentar CSS hanya untuk komit berikutnya?", Tetapi langkah-langkahnya benar-benar membingungkan mengenai apa yang dicapai. (kami ingin "menambahkan" hanya "penghapusan" dari beberapa baris ke komit berikutnya.) Jadi hanya mengatakan hapus atau tambahkan sangat membingungkan. Menyatakan apa yang dicapai pada setiap langkah akan membantu memperjelas.
ahnbizcad
9

Jika Anda dapat menggunakan git gui, ini memungkinkan Anda untuk melakukan perubahan baris demi baris. Sayangnya, saya tidak tahu bagaimana melakukannya dari baris perintah - atau bahkan jika itu mungkin.

Satu opsi lain yang saya gunakan di masa lalu adalah memutar kembali bagian dari perubahan (biarkan editor tetap terbuka), komit bit yang saya inginkan, batalkan dan simpan kembali dari editor. Tidak terlalu elegan, tetapi menyelesaikan pekerjaan. :)


EDIT (penggunaan git-gui):

Saya tidak yakin apakah git-gui sama dalam versi msysgit dan linux, saya hanya menggunakan satu msysgit. Tetapi dengan asumsi itu sama, ketika Anda menjalankannya, ada empat panel: panel kiri atas adalah perubahan direktori kerja Anda, kiri bawah adalah tahapan Anda berubah, kanan atas adalah diff untuk file yang dipilih (baik itu bekerja dir atau dipentaskan), dan kanan bawah adalah untuk deskripsi komit (saya kira Anda tidak akan membutuhkannya). Ketika Anda mengklik file di kanan atas, Anda akan melihat perbedaannya. Jika Anda mengklik kanan pada garis diff, Anda akan melihat menu konteks. Dua opsi yang perlu diperhatikan adalah "stage hunk for commit" dan "stage line for commit". Anda tetap memilih "garis panggung untuk komit" pada garis yang ingin Anda komit, dan Anda selesai. Anda bahkan dapat memilih beberapa garis dan mengaturnya jika Anda mau.

Untuk melakukan, Anda bisa menggunakan alat gui atau baris perintah.

vhallac
sumber
Proposisi kedua Anda cukup jelas, tetapi yang pertama menarik, bisakah Anda merinci lebih banyak? Saya menginstal git-guitetapi saya tidak tahu bagaimana mencapai apa yang Anda gambarkan.
greg0ire
Terima kasih banyak! Ini bekerja! Saya bahkan dapat memilih jalur yang ingin saya tampilkan dan indeks dengan satu klik.
greg0ire
0

Salah satu cara untuk melakukannya adalah dengan melewatkan bagian, git addapa pun yang Anda butuhkan, dan kemudian jalankan git addlagi. Jika ini adalah satu-satunya potongan, Anda dapat membaginya.

Jika Anda khawatir tentang urutan komitmen, gunakan saja git rebase -i.

Abizern
sumber
Inilah yang saya coba, dan bingkah dalam pertanyaan saya adalah satu-satunya ketika saya berlari git add -plagi, tetapi saya tidak dapat membaginya. Saya mendapatkan ini: Stage this hunk [y,n,q,a,d,/,e,?]?dan kemudian menekan 's' mencetak bantuan. BTW, maksudmu add patch, bukan patch add? Atau ada git patchplugin yang harus saya instal?
greg0ire
Apakah Anda melakukan dipentaskan bakhil sebelum Anda menjalankan ini lagi? Dan tidak, Mercurial memiliki plugins, Git tidak.
Abizern
Tidak saya tidak, saya ingin mereka berada di komit yang sama (tapi saya kira jika solusi Anda bekerja, saya dapat menggunakan - ubah untuk mencapai ini). Saya akan mencobanya.
greg0ire
Seperti jawaban saya → git rebase -i. Yang lebih fleksibel daripadacommit --amend
Abizern