Git: วิธีการสควอชทั้งหมดมุ่งมั่นที่สาขา


315

ฉันสร้างสาขาใหม่จากmasterด้วย:

git checkout -b testbranch

ฉันลงมือทำ 20 ข้อ

ตอนนี้ฉันต้องการสควอชทั้ง 20 คอมมิชชัน ฉันทำอย่างนั้นกับ:

git rebase -i HEAD~20

จะเป็นอย่างไรถ้าฉันไม่รู้ว่ามีคนผูกพันไปกี่คน? มีวิธีที่จะทำสิ่งที่ชอบ:

git rebase -i all on this branch

6
คุณสามารถทำอะไรก็ได้ที่git rebase -i 58333012713fc168bd70ad00d191b3bdc601fa2dจะให้การตอบโต้แบบโต้ตอบโดยที่จำนวนการส่งมอบครั้งสุดท้ายนั้นไม่เปลี่ยนแปลง
denns

@denns การใช้วิธีการนี้กับคอมมิชชันล่าสุดในสาขาที่คุณกำลังรีบูตจากการทำงานที่ยอดเยี่ยม ขอบคุณมาก!
Joshua Pinter

คำตอบ:


394

อีกวิธีในการกำจัดทุกสิ่งที่คุณกระทำคือการรีเซ็ตดัชนีให้เป็นมาสเตอร์:

 git checkout yourBranch
 git reset $(git merge-base master yourBranch)
 git add -A
 git commit -m "one commit on yourBranch"

สิ่งนี้ไม่สมบูรณ์แบบตามนัยที่คุณรู้จากสาขา "yourBranch" ซึ่งมาจากไหน
หมายเหตุ: การค้นหาสาขาต้นกำเนิดนั้นไม่ใช่เรื่องง่าย / เป็นไปได้ด้วย Git ( วิธีการแสดงมักจะง่ายที่สุดดังที่เห็นที่นี่ )


แก้ไข: คุณจะต้องใช้ git push --force


Karlotcha Hoaเพิ่มในความคิดเห็น :

สำหรับการรีเซ็ตคุณสามารถทำได้

git reset $(git merge-base master $(git rev-parse --abbrev-ref HEAD)) 

[นั่น] ใช้สาขาที่คุณเปิดอยู่โดยอัตโนมัติ
และถ้าคุณใช้นั้นคุณยังสามารถใช้นามแฝงเป็นคำสั่งไม่พึ่งพาชื่อสาขา


2
ดีกว่าที่จะชำระเงินเพื่อกระทำที่YourBranchปัจจุบัน สิ่งนี้จะYourBranchยังคงไม่บุบสลายเมื่อคุณทำreset
Eugen Konkov

1
@ Abdurrahim หรือเปิดทุบตีคอมไพล์และคุณสามารถคัดลอกคำสั่ง thos!
VonC

3
สำหรับการรีเซ็ตคุณสามารถทำได้git reset $(git merge-base master $(git rev-parse --abbrev-ref HEAD))เพื่อใช้สาขาที่คุณเปิดอยู่โดยอัตโนมัติ และถ้าคุณใช้สิ่งนั้นคุณยังสามารถใช้นามแฝงได้เนื่องจากคำสั่งไม่ขึ้นอยู่กับชื่อสาขา
Karlotcha Hoa

1
@Druska สำหรับกรณีการแยก Simlpe ไม่ควรทำงานได้ดี
VonC

1
@Shimmy ใช่ให้คุณบังคับให้กดหลังจากรีเซ็ต: git push --force(และเตือนเพื่อนร่วมงานของคุณหากคุณเป็นคนทำงานหลายคนในสาขานั้น)
VonC

112

ชำระเงินที่สาขาที่คุณต้องการกำจัดการกระทำทั้งหมดในที่เดียว feature_branchช่วยบอกเรียกว่าของมัน

git checkout feature_branch

ขั้นตอนที่ 1:

ทำการรีเซ็ตแบบซอฟต์ของorigin/feature_branchคุณในพื้นที่ของคุณmasterสาขา (ขึ้นอยู่กับความต้องการของคุณคุณสามารถรีเซ็ตด้วย Origin / Master เช่นกัน) การดำเนินการนี้จะรีเซ็ตค่าใช้จ่ายเพิ่มเติมทั้งหมดในของคุณfeature_branchแต่จะไม่ทำการเปลี่ยนแปลงไฟล์ใด ๆ ในเครื่องของคุณ

git reset --soft master

ขั้นตอนที่ 2:

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

git add -A && git commit -m "commit message goes here"


6
นี่เป็นทางออกที่น่าเชื่อถือที่สุดสำหรับฉัน - ไม่ก่อให้เกิดข้อผิดพลาดในการรีบูตหรือการรวมความขัดแย้ง
ANTARA

1
คำเตือน: git เพิ่ม -A เพิ่มทุกสิ่งที่คุณมีในโฟลเดอร์ท้องถิ่น - ไปยังสาขา
David H

รักทางออกนี้! นี่คือสิ่งที่ฉันต้องการ!
jacoballenwood

1
ทางออกที่ดีที่สุดสำหรับ noob - ไม่ทำลายและมีเพียงช่วงเวลาที่โอปส์อาจจะตรวจสอบมากเกินไปเช่นความลับของแอพ ฯลฯ ซึ่งไม่ควรสำคัญว่าคุณมีไฟล์ gitignore ที่เหมาะสมหรือไม่ #
4324

@NSduToit คำตอบสั้น ๆ : ไม่คุณไม่จำเป็นต้อง หลังจากทำตามขั้นตอนดังกล่าวข้างต้นในคำตอบของฉันคุณจะจบลงด้วยหนึ่งกระทำด้วยการเปลี่ยนแปลงรหัส คุณสามารถคิดได้เหมือนกับการกระทำอื่น ๆ ที่มีการเปลี่ยนแปลงรหัสบางอย่าง คุณสามารถผลักดันมันไปยังสาขาระยะไกลของคุณโดยไม่ต้อง-fตั้งค่าสถานะ
shanky

110

สิ่งที่คุณทำนั้นค่อนข้างจะผิดพลาดได้ง่าย แค่ทำ:

git rebase -i master

ซึ่งจะรีบูทโดยอัตโนมัติเฉพาะสาขาที่คุณมุ่งมั่นไปยังมาสเตอร์ล่าสุดในปัจจุบัน


5
ขอบคุณฉันได้รับ แต่ทำไมข้อผิดพลาดระบบของฉันมีแนวโน้มที่จะ
user3803850

10
อาจเป็นเพราะมันง่ายที่จะเข้าใจผิด
Daniel Scott

13
ตกลงนี้เป็นทางออกที่ดีที่สุดของคุณ แต่ไปที่ลิงค์นี้ตามที่อธิบายดีกว่าว่าคุณต้องทำอะไร
Christo

3
แทนที่จะบีบคอมมิทคุณสามารถรวมสาขาเป็นหลักและทำการรีเซ็ตคอมไพล์เป็นแหล่งกำเนิด / มาสเตอร์เพื่อยกเลิกการคอมมิททั้งหมด ซึ่งจะช่วยให้คุณสามารถใช้รหัสที่ไม่มีการกำหนดสถานะของคุณได้ด้วยcommit -am "the whole thing!"
nurettin

2
@nurettin ฉันคิดว่าreset origin/masterวิธีการนั้นแย่จริงๆเพราะมันเหมือนกับการทำคอมมิทบนมาสเตอร์โดยตรง - ไม่มีประวัติ 'merge branch' ไม่มีตัวเลือก pull pull คำตอบโดย @WaZaA มีมากขึ้นในการรักษาเวิร์กโฟลว์คอมไพล์ปกติฉันคิดว่า
Drenai

79

อีกวิธีที่ง่ายที่จะทำนี้: merge --squashการเดินทางบนกิ่งต้นกำเนิดและทำ คำสั่งนี้ไม่ได้ทำ "แบน" กระทำ เมื่อคุณดำเนินการข้อความยืนยันทั้งหมดของคุณจะถูกรวบรวม

$ git checkout master
$ git merge --squash yourBranch
$ git commit # all commit messages of yourBranch in one, really useful
 > [status 5007e77] Squashed commit of the following: ...

1
จริง ฉันพูดถึงความแตกต่างระหว่างการผสาน --squash และ rebase -i ในstackoverflow.com/a/2427520/6309
VonC

1
วิธีนี้ใช้ได้ผลถ้าคุณไม่ต้องการสควอชในสาขาพาเรนต์เพียงแค่สร้างและเปลี่ยนเป็นสาขาใหม่ตามสาขาหลักและทำการรวมสควอชเข้าด้วยกัน
Charlotte

ไชโยเพื่อนเคล็ดลับที่ดี!
Nestor Milyaev

ดี! ฉันสร้างสาขา "temp" ปิด "master" ก่อนเพื่อกำจัด "yourBranch" ลงในจากนั้นรวม "temp" เป็น "master"
lazieburd

34

สมมติว่าคุณแยกจากต้นแบบคุณไม่จำเป็นต้องเข้าyourBranchสู่ขั้นตอนการรีเซ็ตตลอดเวลา:

git checkout yourBranch
git reset --soft HEAD~$(git rev-list --count HEAD ^master)
git add -A
git commit -m "one commit on yourBranch"

คำอธิบาย :

  • git rev-list --count HEAD ^masterนับการกระทำนับตั้งแต่คุณสร้างสาขาคุณลักษณะของคุณจากต้นแบบ f.ex 20
  • git reset --soft HEAD~20จะทำการรีเซ็ตแบบซอฟต์ของการคอมมิท 20 ครั้งล่าสุด นี่จะเป็นการเปลี่ยนแปลงของคุณในไฟล์ แต่จะลบการกระทำ

การใช้งาน :

ใน. bash_profile ของฉันฉันได้เพิ่มนามแฝงสำหรับgisquashทำสิ่งนี้ด้วยคำสั่งเดียว:

# squash all commits into one
alias gisquash='git reset --soft HEAD~$(git rev-list --count HEAD ^master)'

หลังจาก reseting git push --forceและการกระทำที่คุณต้องทำ

คำแนะนำ :

หากคุณกำลังใช้ Gitlab> = 11.0 คุณไม่จำเป็นต้องทำเช่นนี้อีกต่อไปเนื่องจากมี ตัวเลือกการแบนเมื่อรวมสาขา ตัวเลือก Gitlab Squashing


15

จากการอ่านคำถามและคำตอบของสแต็คโอเวอร์โฟลว์หลายคำตอบเกี่ยวกับการสควอชฉันคิดว่านี่เป็นซับที่ดีสำหรับการสควอชทั้งหมดที่กระทำในสาขา:

git reset --soft $(git merge-base master YOUR_BRANCH) && git commit -am "YOUR COMMIT MESSAGE" && git rebase -i master

นี่คือการถือว่าต้นแบบเป็นสาขาฐาน


1
ขอบคุณมาก บริษัท มีข้อ จำกัด มากมายในสถานที่และไม่สามารถรีบูตวิธีปกติด้วยเครื่องมือแก้ไขเนื่องจากไม่ได้เสียงดังเพื่อบันทึก ไม่สามารถใช้คุณสมบัติสควอชและผสานในคอมไพล์ได้เนื่องจากสาขานี้ไปที่ Lead dev สำหรับการรวมและเขาไม่ชอบ 1 ซับนี้ทำงานและบันทึกอาการปวดหัว สุดยอดงาน
L1ghtk3ira

10

โซลูชันสำหรับผู้ที่ต้องการคลิก:

  1. ติดตั้งsourcetree (ฟรี)

  2. ตรวจสอบว่าการกระทำของคุณเป็นอย่างไร เป็นไปได้ว่าคุณมีสิ่งที่คล้ายกับสิ่งนี้ ป้อนคำอธิบายรูปภาพที่นี่

  3. คลิกขวาที่แม่กระทำ ในกรณีของเรามันเป็นสาขาหลัก

ป้อนคำอธิบายรูปภาพที่นี่

  1. คุณสามารถสควอชคอมมิชชันกับคอมมิชชันก่อนหน้าโดยคลิกที่ปุ่ม ในกรณีของเราเราต้องคลิก 2 ครั้ง คุณสามารถเปลี่ยนการส่งข้อความได้ ป้อนคำอธิบายรูปภาพที่นี่

  2. ผลลัพธ์นั้นยอดเยี่ยมและเราพร้อมที่จะผลักดัน! ป้อนคำอธิบายรูปภาพที่นี่

หมายเหตุด้านข้าง: หากคุณผลักดันบางส่วนของคุณมุ่งสู่ระยะไกลคุณต้องใช้แรงผลักหลังจากสควอช


ขอบคุณสำหรับสิ่งนี้!
คริสตัล

0

อีกวิธีหนึ่งคือบันทึกการส่งบันทึกทั้งหมดไปยังไฟล์

บันทึก git> branch.log

ตอนนี้ branch.log จะมีรหัสการกระทำทั้งหมดตั้งแต่เริ่มต้น .. เลื่อนลงและใช้การส่งครั้งแรก (ซึ่งจะยากในเทอร์มินัล) โดยใช้การส่งครั้งแรก

git รีเซ็ต - นุ่ม

การกระทำทั้งหมดจะถูกแบน


0

การรีเซ็ต Git ดังที่กล่าวไว้ในคำตอบมากมายก่อนหน้านั้นเป็นวิธีที่ดีที่สุดและง่ายที่สุดในการบรรลุสิ่งที่คุณต้องการ ฉันใช้ในเวิร์กโฟลว์ต่อไปนี้:

(ในสาขาการพัฒนา)

git fetch
git merge origin/master  #so development branch has all current changes from master
git reset origin/master  #will show all changes from development branch to master as unstaged
git gui # do a final review, stage all changes you really want
git commit # all changes in a single commit
git branch -f master #update local master branch
git push origin master #push it

0

การรีเซ็ตคอมไพล์ทั้งหมดนี้นุ่มนวลและทุกอย่างที่กล่าวถึงในที่นี้อาจใช้งานได้ (ไม่ใช่สำหรับฉัน) หากคุณทำตามขั้นตอนอย่างถูกต้องและเป็นจีนี่
หากคุณเฉลี่ย Joe smo ให้ลองสิ่งนี้:
วิธีใช้ git merge --squash?


บันทึกชีวิตของฉันและจะเป็นสควอชของฉันใช้งาน 4 ครั้งนี้ตั้งแต่ฉันพบเรื่องนี้ ง่ายสะอาดและโดยทั่วไป 1 comamnd กล่าวโดยย่อ:


หากคุณอยู่ในสาขาให้เรียกมันว่า "my_new_feature" ปิดการพัฒนาและคำขอดึงของคุณมี 35 คอมมิท (หรือหลาย ๆ อัน) และคุณต้องการให้เป็น 1

A. ตรวจสอบให้แน่ใจว่าสาขาของคุณทันสมัยแล้วไปที่ พัฒนารับล่าสุดและรวมและแก้ไขข้อขัดแย้งใด ๆ กับ "my_new_feature"
(ขั้นตอนนี้คุณควรทำทันทีที่ทำได้ตลอดเวลา)

B. รับการพัฒนาและสาขาล่าสุดไปยังสาขาใหม่เรียกว่า "my_new_feature_squashed"

C. เวทมนต์อยู่ที่นี่
คุณต้องการที่จะทำงานจาก "my_new_feature" ถึง "my_new_feature_squashed"
ดังนั้นทำ (ในขณะที่สาขาใหม่ของคุณเราได้สร้างการพัฒนา):
git merge - squash my_new_feature

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


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