ฉันสามารถแบ่งก้อนใหญ่ที่แบ่งแล้วด้วย git ได้ไหม


204

ฉันเพิ่งค้นพบpatchตัวเลือกคอมไพล์ของaddคำสั่งและฉันต้องบอกว่ามันเป็นคุณสมบัติที่ยอดเยี่ยมจริงๆ ฉันยังค้นพบว่าก้อนใหญ่ก้อนใหญ่สามารถแบ่งออกเป็นกลุ่มย่อยขนาดเล็กได้ด้วยการกดปุ่มsซึ่งเพิ่มความแม่นยำของความมุ่งมั่น แต่ถ้าฉันต้องการความแม่นยำมากขึ้นถ้าก้อนใหญ่ที่แยกไม่เล็กพอ?

ตัวอย่างเช่นให้พิจารณาก้อนใหญ่ที่แบ่งแล้ว:

@@ -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;
 }

ฉันจะเพิ่มการลบความคิดเห็น CSS ไปยังการส่งครั้งต่อไปได้อย่างไร sตัวเลือกที่ไม่สามารถใช้ได้อีกต่อไป!

คำตอบ:


253

หากคุณกำลังใช้งานgit add -pและแม้หลังจากแยกsแล้วคุณยังไม่มีการเปลี่ยนแปลงเล็กน้อยพอคุณสามารถใช้eเพื่อแก้ไขโปรแกรมแก้ไขได้โดยตรง

สิ่งนี้อาจสร้างความสับสนเล็กน้อย แต่ถ้าคุณทำตามคำแนะนำอย่างระมัดระวังในหน้าต่างตัวแก้ไขที่จะเปิดขึ้นหลังจากกดeคุณจะไม่เป็นไร ในกรณีที่คุณยกมาคุณจะต้องการแทนที่-ด้วยช่องว่างที่จุดเริ่มต้นของบรรทัดเหล่านี้:

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

... +และลบบรรทัดต่อไปนี้คือหนึ่งที่เริ่มต้นด้วย หากคุณบันทึกและออกจากเครื่องมือแก้ไขการลบความคิดเห็น CSS จะถูกจัดฉาก


9
ทางออกที่ยอดเยี่ยม! ฉันเห็นสิ่งนั้น แต่เข้าใจผิด ... ฉันว่าการเปลี่ยนแปลงจะถูกลบออกจากแผนผังการทำงานด้วย
greg0ire

7
อันที่จริงมันไม่ชัดเจนจากข้อความช่วยเหลือ ฉันคิดว่าตัวเองใช้สิ่งนี้เยอะจริงๆเพราะฉันคิดว่า git สนับสนุนให้คุณทำให้แต่ละคนมีความแม่นยำและสวยงามที่สุดเท่าที่จะเป็นไปได้ :)
Mark Longair

27
โปรดทราบว่าคุณจริงๆต้องแทนที่ด้วยพื้นที่ ฉันลองคิดดูว่าฉันสามารถลบ-ตัวละครได้และ Git บ่นว่าแพทช์ของฉันไม่ได้ใช้
Ryan Lundy

3
ฉันคาดเดาสาเหตุที่คุณลบบรรทัดด้วย '-' และแทนที่ '+' ด้วยช่องว่างนั่นคือคุณกำลังสร้างแพทช์โดยที่บรรทัดเหล่านั้นที่มีเครื่องหมาย '-' ถูกลบไปแล้วและบรรทัดที่มี ' เพิ่ม + ของแล้ว (ในสายตาของแพทช์) หรืออีกวิธีหนึ่งในการดูมันคือการกระทำที่ตัวละครเหล่านั้น (-, +) เป็นตัวแทน (เพิ่มบรรทัดหรือลบมัน) เฉพาะบรรทัดที่เหลือที่มี '-' และ '+' s เท่านั้นที่จะถูกบันทึกเป็นการเปลี่ยนแปลงและส่วนที่เหลือคือ "วิธีเป็นไฟล์"
atomictom

3
@ ฟิลิป: ฉันไม่รู้ว่าจะเกิดอะไรขึ้นฉันกลัว - ถ้าคุณกำลังวิ่งgit add -pและแก้ไขก้อนใหญ่ด้วยeสิ่งนั้นจะส่งผลกระทบต่อสิ่งที่ถูกจัดฉากไม่ใช่ต้นไม้ทำงานของคุณ
Mark Longair

60

สมมติว่าexample.cssหน้าตาของคุณเป็นแบบนี้:

.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;
}

ทีนี้มาเปลี่ยนตัวเลือกสไตล์ในบล็อกตรงกลางและในขณะที่เราอยู่ที่นั่นลบสไตล์เก่า ๆ ที่เราไม่ต้องการอีกต่อไป

.classname {
  width: 440px;
}

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

.another {
  width: 420px;
}

นั่นเป็นเรื่องง่ายตอนนี้เรามากระทำกัน แต่เดี๋ยวก่อนฉันต้องการรักษาการแยกลอจิคัลของการเปลี่ยนแปลงในการควบคุมเวอร์ชันสำหรับการตรวจสอบโค้ดขั้นตอนง่าย ๆ และเพื่อให้ทีมของฉันและฉันสามารถค้นหาคอมมิชชันประวัติสำหรับข้อมูลเฉพาะได้อย่างง่ายดาย

การลบรหัสเก่าจะแยกเชิงตรรกะออกจากการเปลี่ยนแปลงตัวเลือกลักษณะอื่น เราจะต้องใช้ความมุ่งมั่นที่แตกต่างกันสองอย่างดังนั้นเรามาเพิ่มนักล่าเพื่อหาปะ

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,?]?

อ๊ะดูเหมือนว่าการเปลี่ยนแปลงจะอยู่ใกล้เกินไปดังนั้นคอมไพล์ก็รวมมันเข้าด้วยกัน

แม้แต่การพยายามแยกมันด้วยการกดsก็ให้ผลเหมือนกันเพราะการแบ่งไม่ละเอียดพอสำหรับการเปลี่ยนแปลงที่แม่นยำของเรา บรรทัดที่ไม่เปลี่ยนแปลงจำเป็นต้องใช้ระหว่างบรรทัดที่มีการเปลี่ยนแปลงเพื่อให้คอมไพล์สามารถแบ่งแพทช์ได้โดยอัตโนมัติ

ดังนั้นเรามาแก้ไขด้วยตนเองโดยกดe

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

git จะเปิดโปรแกรมปะแก้ในตัวเลือกที่เราเลือก

# 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.

ลองทบทวนเป้าหมาย:

ฉันจะเพิ่มการลบความคิดเห็น CSS ไปยังการส่งครั้งต่อไปได้อย่างไร

เราต้องการแบ่งออกเป็นสองคอมมิชชัน:

  1. การคอมมิชชันแรกเกี่ยวข้องกับการลบบางบรรทัด (การลบความคิดเห็น)

    ในการลบบรรทัดที่ใส่เครื่องหมายคอมเม้นท์เพียงปล่อยไว้ตามลำพังพวกเขาจะถูกทำเครื่องหมายเพื่อติดตามการลบในการควบคุมเวอร์ชันเช่นเดียวกับที่เราต้องการ

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

  2. การกระทำที่สองคือการเปลี่ยนแปลงซึ่งถูกติดตามโดยการบันทึกทั้งการลบและการเพิ่มเติม:

    • การลบ (ลบบรรทัดตัวเลือกเดิม)

      ในการคงบรรทัดตัวเลือกเดิมไว้ (อย่าลบในระหว่างการคอมมิทนี้) เราต้องการ ...

      หากต้องการลบบรรทัด '-' ให้ตั้งบรรทัด ''

      ... ซึ่งมีความหมายเปลี่ยนลบ-สัญญาณด้วยช่องว่างของตัวละคร

      ดังนั้นสามบรรทัดนี้ ...

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

      ... จะกลายเป็น ( สังเกตเห็นช่องว่างเดียวในช่วงแรกของ 3 บรรทัด):


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

    • การเพิ่มเติม (เพิ่มตัวเลือกบรรทัดใหม่)

      หากไม่สนใจบรรทัดตัวเลือกใหม่ที่เพิ่มระหว่างการคอมมิชชันนี้เราต้องการ ...

      หากต้องการลบบรรทัด '+' ให้ลบออก

      ... ซึ่งหมายถึงการลบทั้งบรรทัด:

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

      (โบนัส: หากคุณใช้vimเป็นตัวแก้ไขกดddเพื่อลบบรรทัดผู้ใช้NanoกดCtrl+ K)

เครื่องมือแก้ไขของคุณควรมีลักษณะเช่นนี้เมื่อคุณบันทึก:

# 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.

ตอนนี้มากระทำกัน

git commit -m "remove old code"

และเพื่อให้แน่ใจว่าเรามาดูการเปลี่ยนแปลงจากการกระทำครั้งล่าสุด

git show
commit 572ecbc7beecca495c8965ce54fbccabdd085112
Author: Jeff Puckett <jeff@jeffpuckett.com>
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 {

สมบูรณ์แบบ - คุณจะเห็นได้ว่ามีเพียงการลบเท่านั้นที่รวมอยู่ในการกระทำปรมาณู ตอนนี้เรามาทำงานให้เสร็จ

git add .
git commit -m "change selectors"
git show
commit 83ec3c16b73bca799e4ed525148cf303e0bd39f9
Author: Jeff Puckett <jeff@jeffpuckett.com>
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;
 }

ในที่สุดคุณสามารถเห็นการกระทำล่าสุดรวมเฉพาะการเปลี่ยนแปลงตัวเลือก


1
โบนัส # 2: ถ้าคุณบังเอิญใช้ VIM เป็นตัวแก้ไขคุณต้องกด "d" สองครั้งบนคีย์บอร์ดเพื่อลบบรรทัด: D
Alexxus

3
นอกจากนี้แทนการลบเส้นเพิ่มที่คุณไม่ต้องการที่จะเพิ่มคุณสามารถแทนที่ด้วย+ #ผลลัพธ์เหมือนกัน แต่บางทีคุณอาจรู้สึกอึดอัดกับการลบ (และไม่สามารถเปลี่ยนกลับ) หรือคุณต้องการทดลองก่อนบันทึก
ob-ivan

และนั่นสำหรับเสียงเรียกเข้าอยู่r #เหนือเครื่องหมายบวก xD
aksh1618

เป้าหมายคือ "ฉันจะเพิ่มการลบความคิดเห็น CSS เฉพาะการกระทำครั้งต่อไปได้อย่างไร" แต่ขั้นตอนต่าง ๆ ทำให้เกิดความสับสนว่าเป็นสิ่งที่สำเร็จหรือไม่ (เราต้องการที่จะ "เพิ่ม" เพียงแค่ "ลบ" ของสองสามบรรทัดในการส่งครั้งต่อไป) ดังนั้นเพียงแค่การพูดว่าการลบหรือเพิ่มนั้นสร้างความสับสนมาก การระบุสิ่งที่สำเร็จในแต่ละขั้นตอนจะช่วยชี้แจงให้ชัดเจน
ahnbizcad

9

หากคุณสามารถใช้ git gui ได้จะช่วยให้คุณสามารถทำการเปลี่ยนทีละบรรทัด น่าเสียดายที่ฉันไม่รู้ว่าจะทำอย่างไรจากบรรทัดคำสั่ง - หรือแม้ว่าจะเป็นไปได้ก็ตาม

อีกตัวเลือกหนึ่งที่ฉันเคยใช้ในอดีตคือย้อนกลับส่วนหนึ่งของการเปลี่ยนแปลง (เปิดตัวแก้ไขไว้) ยอมรับบิตที่ฉันต้องการเลิกทำและบันทึกซ้ำจากตัวแก้ไข ไม่สวยมาก แต่ทำงานเสร็จแล้ว :)


แก้ไข (การใช้งาน git-gui):

ฉันไม่แน่ใจว่า git-gui นั้นเหมือนกันในรุ่น msysgit และ linux หรือไม่ฉันใช้ msysgit เพียงตัวเดียวเท่านั้น แต่สมมติว่ามันเหมือนกันเมื่อคุณเรียกใช้มีสี่บานหน้าต่าง: ด้านซ้ายบนคือการเปลี่ยนแปลงไดเรกทอรีการทำงานของคุณด้านล่างซ้ายคือการเปลี่ยนแปลงขั้นตอนของคุณด้านบนขวาคือความแตกต่างสำหรับไฟล์ที่เลือก หรือฉาก) และด้านล่างขวาเป็นคำอธิบายของการกระทำ (ฉันสงสัยว่าคุณไม่ต้องการมัน) เมื่อคุณคลิกไฟล์ที่อยู่ด้านบนขวาคุณจะเห็นส่วนต่าง หากคุณคลิกขวาที่บรรทัดต่างคุณจะเห็นเมนูบริบท ตัวเลือกสองตัวที่ควรทราบคือ "ขั้นตอนใหญ่สำหรับการส่ง" และ "ขั้นตอนสำหรับการส่ง" คุณยังคงเลือก "ลำดับขั้นตอนของการส่งข้อความ" ในบรรทัดที่คุณต้องการส่งมอบและดำเนินการเสร็จสิ้น คุณสามารถเลือกหลายบรรทัดและจัดลำดับได้หากต้องการ

สำหรับการยืนยันคุณสามารถใช้เครื่องมือ gui หรือบรรทัดคำสั่ง


ข้อเสนอที่สองของคุณค่อนข้างชัดเจน แต่ข้อแรกน่าสนใจคุณสามารถให้รายละเอียดเพิ่มขึ้นอีกเล็กน้อย ฉันติดตั้งแล้วgit-guiแต่ฉันไม่มีเงื่อนงำว่าจะบรรลุสิ่งที่คุณอธิบายได้อย่างไร
greg0ire

ขอบคุณมาก! มันใช้งานได้! ฉันสามารถเลือกบรรทัดที่ฉันต้องการจัดลำดับและจัดทำดัชนีได้ด้วยคลิกเดียว
greg0ire

0

วิธีหนึ่งในการทำคือข้ามก้อนgit addสิ่งอื่นที่คุณต้องการแล้วเรียกใช้git addอีกครั้ง ถ้านี่เป็นอันเดียวคุณจะสามารถแยกมันได้

git rebase -iหากคุณกำลังกังวลเกี่ยวกับคำสั่งของการกระทำเพียงการใช้งาน


นี่คือสิ่งที่ฉันพยายามและก้อนใหญ่ในคำถามของฉันเป็นเพียงหนึ่งเดียวเมื่อฉันวิ่งgit add -pอีกครั้ง แต่ฉันไม่สามารถแยกมันได้ ฉันได้สิ่งนี้Stage this hunk [y,n,q,a,d,/,e,?]?แล้วกดปุ่มพิมพ์ความช่วยเหลือ BTW, คุณหมายถึงadd patchไม่patch add? หรือมีgit patchปลั๊กอินที่ฉันควรติดตั้ง?
greg0ire

คุณเคยแสดงละครเวทีก่อนที่จะวิ่งอีกครั้งหรือไม่? และไม่ Mercurial มีปลั๊กอิน Git ไม่มี
Abizern

ไม่ฉันไม่ได้ต้องการให้พวกเขาอยู่ในความมุ่งมั่นเดียวกัน (แต่ฉันเดาว่าวิธีแก้ปัญหาของคุณใช้ได้หรือไม่ฉันสามารถใช้ - แก้ไขเพื่อให้ได้สิ่งนี้) ฉันจะลองดู
greg0ire

git rebase -iในฐานะที่เป็นคำตอบของฉันกล่าว→ ซึ่งยืดหยุ่นกว่าcommit --amend
Abizern
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.