ไม่ว่าอาจารย์และสาขาต้นกำเนิด / หลักของฉันจะแยกกัน
จริง ๆ แล้วฉันไม่ต้องการให้พวกเขาแตกต่าง
ฉันจะดูความแตกต่างเหล่านี้และ 'รวม' พวกเขาได้อย่างไร
ไม่ว่าอาจารย์และสาขาต้นกำเนิด / หลักของฉันจะแยกกัน
จริง ๆ แล้วฉันไม่ต้องการให้พวกเขาแตกต่าง
ฉันจะดูความแตกต่างเหล่านี้และ 'รวม' พวกเขาได้อย่างไร
คำตอบ:
คุณสามารถตรวจสอบความแตกต่างด้วย:
git log HEAD..origin/master
ก่อนที่จะดึงมัน (ดึงข้อมูล + ผสาน) (ดูเพิ่มเติมที่"คุณจะทำให้ git ดึงจากสาขาที่ต้องการได้อย่างไร" )
เมื่อคุณมีข้อความเช่น:
"สาขาและ 'ต้นกำเนิด / ปรมาจารย์ของคุณ' ถูกแยกแล้ว # และมีการกระทำที่แตกต่างกัน 1 และ 1 รายการตามลำดับ"
ให้ตรวจสอบว่าคุณจำเป็นต้องปรับปรุง origin
หากorigin
เป็นข้อมูลล่าสุดแสดงว่าคอมมิชชันบางตัวได้รับการผลักดันorigin
จาก repo อื่นในขณะที่คุณทำการคอมมิทเองในพื้นที่
... o ---- o ---- A ---- B origin/master (upstream work)
\
C master (your work)
คุณใช้คอมมิชชัน C ในการส่งมอบ A เนื่องจากนั่นเป็นงานล่าสุดที่คุณดึงมาจากอัปสตรีมในเวลานั้น
อย่างไรก็ตามก่อนที่คุณจะพยายามย้อนกลับไปที่จุดเริ่มต้นจะมีคนผลักดัน
ประวัติการพัฒนาB. แยกออกเป็นเส้นทางแยกต่างหาก
จากนั้นคุณสามารถผสานหรือรีบูต ดูPro Git: Git Branching - การรีบูตสำหรับรายละเอียด
ผสาน
ใช้คำสั่ง git merge:
$ git merge origin/master
สิ่งนี้จะบอกให้ Git รวมการเปลี่ยนแปลงจากorigin/master
ในงานของคุณและสร้างการผสาน
กราฟของประวัติศาสตร์ตอนนี้มีลักษณะดังนี้:
... o ---- o ---- A ---- B origin/master (upstream work)
\ \
C ---- M master (your work)
การผสานใหม่กระทำ M มีผู้ปกครองสองคนแต่ละคนเป็นตัวแทนของเส้นทางการพัฒนาเดียวที่นำไปสู่เนื้อหาที่เก็บไว้ในการส่งข้อมูลนั้น
โปรดทราบว่าประวัติหลัง M อยู่ในขณะนี้ไม่ใช่เชิงเส้น
rebase
ใช้คำสั่ง git rebase:
$ git rebase origin/master
สิ่งนี้จะบอกให้ Git เล่นซ้ำกระทำ C (งานของคุณ) ราวกับว่าคุณอ้างอิงจากกระทำ B แทน A.
CVS และผู้ใช้ Subversion จะทำการ rebase การเปลี่ยนแปลงในเครื่องที่ด้านบนของงานอัปสตรีมเป็นประจำเมื่ออัปเดตก่อนส่งข้อมูล
Git เพิ่งเพิ่มการแยกที่ชัดเจนระหว่างขั้นตอนการส่งและส่งคืน
กราฟของประวัติศาสตร์ตอนนี้มีลักษณะดังนี้:
... o ---- o ---- A ---- B origin/master (upstream work)
\
C' master (your work)
Commit C 'เป็นคอมมิทใหม่ที่สร้างโดยคำสั่ง git rebase
มันแตกต่างจาก C ในสองวิธี:
โปรดทราบว่าประวัติเบื้องหลัง C 'ยังคงเป็นแบบเชิงเส้น
เราได้เลือก (ตอนนี้) cmake.org/cmake.git
เพื่อให้ประวัติศาสตร์เพียงเส้นตรง
วิธีนี้จะรักษาเวิร์กโฟลว์ที่ใช้ CVS ที่ใช้ก่อนหน้านี้และอาจช่วยให้เกิดการเปลี่ยนแปลงได้ง่ายขึ้น
ความพยายามที่จะผลักดัน C 'ลงในพื้นที่เก็บข้อมูลของเราจะใช้งานได้ (สมมติว่าคุณมีสิทธิ์และไม่มีใครผลักขณะที่คุณกำลังรีบูต)
คำสั่ง git pull จัดเตรียมวิธีชวเลขเพื่อดึงข้อมูลจากต้นทางและรีบูตงานโลคัลบน:
$ git pull --rebase
สิ่งนี้รวมการดึงข้อมูลและการทำซ้ำขั้นตอนเป็นคำสั่งเดียว
git reset --hard HEAD
เท่านั้นที่จะลบการปรับเปลี่ยนใด ๆ ในท้องถิ่นจัดทำดัชนีที่ไม่ใช่ความมุ่งมั่นและจะไม่ทำอะไรที่จะกระทบความแตกต่างระหว่างท้องถิ่นและระยะไกลกระทำ เฉพาะการผสานหรือการรีบูตเท่านั้นที่จะนำการกระทำสองชุด (รายการในเครื่องและชุดรีโมต) เข้าด้วยกัน
master
ชี้ไปB
ที่ตัวอย่างของคุณ
git reset --hard origin/master
เป็นดังกล่าวในคำตอบด้านล่าง: stackoverflow.com/a/8476004/6309
ฉันมีสิ่งนี้และฉันประหลาดใจเป็นสิ่งที่ทำให้มันแม้หลังจากอ่านคำตอบข้างต้น ทางออกของฉันคือการทำ
git reset --hard origin/master
จากนั้นเพียงแค่รีเซ็ตสำเนาต้นแบบ (ภายในเครื่อง) ของฉัน (ซึ่งฉันคิดว่าถูกทำให้แน่น) เป็นจุดที่ถูกต้องซึ่งแสดงโดยจุดกำเนิด / ต้นแบบ (ระยะไกล)
คำเตือน :
origin/master
คุณจะสูญเสียการเปลี่ยนแปลงทั้งหมดยังไม่ได้ผลักดันให้
git reflog
หรือดูพวกมันgitk --all
ได้ แต่แน่นอนว่าการรีเซ็ตฮาร์ดเป็นอีกสิ่งหนึ่งที่มากกว่าการรีบูต
git pull --rebase origin/master
เป็นคำสั่งเดียวที่สามารถช่วยคุณได้เกือบตลอดเวลา
แก้ไข:ดึงการกระทำจากที่มา / หลักและใช้การเปลี่ยนแปลงของคุณกับประวัติสาขาที่เพิ่งดึง
ฉันพบว่าตัวเองอยู่ในสถานการณ์เช่นนี้เมื่อฉันพยายามที่จะรีบูทสาขาที่ติดตามสาขาระยะไกลและฉันก็พยายามที่จะรีบูตสาขา ในสถานการณ์สมมตินี้หากคุณพยายามที่จะลดระดับใหม่ที่สุดคุณจะพบว่าสาขาของคุณแยกจากกันและสามารถสร้างระเบียบที่ไม่ได้สำหรับ gube nubees!
สมมติว่าคุณอยู่ในสาขา my_remote_tracking_branch ซึ่งแยกจากต้นแบบ
$ git status
# ในสาขา my_remote_tracking_branch
ไม่มีอะไรที่จะกระทำ (ทำความสะอาดไดเรกทอรีทำงาน)
และตอนนี้คุณกำลังพยายามลดระดับจากต้นแบบเป็น:
git rebase master
หยุดทันทีและช่วยตัวเองให้เดือดร้อน! ให้ใช้การผสานเป็น:
git merge master
ใช่คุณจะจบลงด้วยความมุ่งมั่นในสาขาของคุณ แต่ถ้าคุณไม่พร้อมสำหรับสาขา "ที่ไม่ได้แยกออก" นี่จะเป็นขั้นตอนการทำงานที่ราบรื่นกว่าการรีบูท ดูบล็อกนี้สำหรับคำอธิบายโดยละเอียดเพิ่มเติม
ในทางกลับกันหากสาขาของคุณเป็นเพียงสาขาในพื้นที่ (เช่นยังไม่ได้ผลักไปที่รีโมตใด ๆ ) คุณควรทำการ rebase (และสาขาของคุณจะไม่แยกออกในกรณีนี้)
ตอนนี้ถ้าคุณกำลังอ่านนี้เพราะคุณมีใน "แยก" สถานการณ์เนื่องจาก rebase เช่นนี้คุณจะได้รับกลับไปยังหน้าล่าสุดกระทำจากจุดกำเนิด (เช่นในรัฐยกเลิกการแยก) โดยใช้:
รีเซ็ต git - ต้นกำเนิด / my_remote_tracking_branch
rebase
ถ้าสาขาที่คุณกำลัง rebasing ยังไม่ได้เผยแพร่ (และคนอื่นใช้) merge
มิฉะนั้นการใช้งาน หากคุณรีบูทสาขา (และใช้แล้ว) ที่เผยแพร่แล้วคุณต้องประสานงานสมรู้ร่วมคิดเพื่อเขียนประวัติของนักพัฒนาทุกคนที่ใช้สาขาของคุณ
git rebase master
...
git reset --hard origin/my_remote_tracking_branch
ทำงานอะไรจริง ๆ
ในกรณีของฉันนี่คือสิ่งที่ฉันทำเพื่อทำให้ข้อความที่แยกออก : ฉันทำgit push
แต่แล้วก็git commit --amend
เพิ่มบางสิ่งบางอย่างในข้อความยืนยัน จากนั้นฉันก็ทำอีกอย่างหนึ่ง
ดังนั้นในกรณีของฉันที่หมายถึงต้นกำเนิด / หลักล้าสมัย เพราะฉันรู้ว่าไม่มีใครได้สัมผัสต้นกำเนิด / ต้นแบบการแก้ไขจึงเป็นเรื่องเล็กน้อย: git push -f
(ซึ่ง-f
หมายถึงแรง)
git push -f
เพื่อเขียนทับการเปลี่ยนแปลงที่ทำไว้ก่อนหน้านี้และผลักไปที่จุดเริ่มต้น ฉันยังมั่นใจว่าไม่มีใครแตะต้องที่เก็บ
ในกรณีของฉันฉันได้ผลักดันการเปลี่ยนแปลงไปorigin/master
แล้วก็รู้ว่าฉันไม่ควรทำเช่นนั้น :-( นี่ซับซ้อนเนื่องจากข้อเท็จจริงที่ว่าการเปลี่ยนแปลงในท้องถิ่นอยู่ในทรีย่อยดังนั้นฉันจึงกลับไปที่การกระทำสุดท้ายที่ดีก่อนท้องถิ่น "เลว" การเปลี่ยนแปลง (โดยใช้ SourceTree) จากนั้นฉันได้รับข้อความ "divergence"
หลังจากแก้ไขระเบียบภายในของฉัน (รายละเอียดไม่สำคัญที่นี่) ฉันต้องการ "ย้อนเวลากลับไป" origin/master
สาขาระยะไกลเพื่อที่จะซิงค์กับท้องถิ่นmaster
อีกครั้ง ทางออกในกรณีของฉันคือ:
git push origin master -f
สังเกต-f
สวิตช์ (บังคับ) สิ่งนี้ลบ "การเปลี่ยนแปลงที่ไม่ดี" ที่ถูกผลักไปorigin/master
โดยไม่ได้ตั้งใจและขณะนี้สาขาในพื้นที่และระยะไกลกำลังซิงค์กัน
โปรดทราบว่านี่เป็นการดำเนินการทำลายล้างที่อาจเกิดขึ้นดังนั้นให้ดำเนินการเฉพาะในกรณีที่คุณแน่ใจ 100% ว่า "การย้อนกลับ" ต้นแบบระยะไกลในเวลานั้นตกลง
You are not allowed to force push code to a protected branch on this project.
ฉันได้รับ ฉันพยายามที่จะผลักดันให้ส้อมของฉัน
ฉันรู้ว่ามีคำตอบมากมายที่นี่ แต่ฉันคิดว่าgit reset --soft HEAD~1
สมควรได้รับความสนใจเพราะช่วยให้คุณสามารถเปลี่ยนแปลงในท้องถิ่นล่าสุด(ไม่ผลัก) กระทำในขณะที่แก้ปัญหารัฐที่แตกต่าง ฉันคิดว่านี่เป็นวิธีแก้ปัญหาที่หลากหลายมากกว่าการดึงrebase
เพราะการมอบหมายในท้องถิ่นสามารถตรวจสอบได้และย้ายไปยังสาขาอื่น
ที่สำคัญคือการใช้แทนการที่รุนแรง--soft
--hard
หากมีมากกว่า 1 การกระทำรูปแบบของHEAD~x
ควรจะทำงาน ดังนั้นนี่คือขั้นตอนทั้งหมดที่แก้ไขสถานการณ์ของฉัน (ฉันมี 1 การกระทำในท้องถิ่นและ 8 การกระทำในระยะไกล):
1) git reset --soft HEAD~1
เพื่อยกเลิกการกระทำในท้องถิ่น สำหรับขั้นตอนต่อไปฉันใช้อินเทอร์เฟซใน SourceTree แต่ฉันคิดว่าคำสั่งต่อไปนี้ควรใช้งานได้:
2) git stash
เพื่อซ่อนการเปลี่ยนแปลงจาก 1) ตอนนี้การเปลี่ยนแปลงทั้งหมดมีความปลอดภัยและไม่มีความแตกต่างอีกต่อไป
3) git pull
เพื่อรับการเปลี่ยนแปลงจากระยะไกล
4) git stash pop
หรือgit stash apply
ใช้การเปลี่ยนแปลงที่ถูกเก็บครั้งล่าสุดตามด้วยคอมมิชชันใหม่หากต้องการ ขั้นตอนนี้เป็นทางเลือกพร้อมกับ2)เมื่อต้องการลบทิ้งการเปลี่ยนแปลงในคอมมิทท้องถิ่น นอกจากนี้เมื่อต้องการกระทำการกับสาขาอื่นขั้นตอนนี้ควรทำหลังจากเปลี่ยนเป็นสาขาที่ต้องการ
pull --rebase
จะซ่อนตัวโดยอัตโนมัติอยู่ดี stackoverflow.com/a/30209750/6309
วิธีดูความแตกต่าง:
git difftool --dir-diff master origin/master
สิ่งนี้จะแสดงการเปลี่ยนแปลงหรือความแตกต่างระหว่างสองสาขา ใน araxis (รายการโปรดของฉัน) มันจะแสดงในรูปแบบโฟลเดอร์ แสดงไฟล์ที่เปลี่ยนแปลงแต่ละไฟล์ ฉันสามารถคลิกที่ไฟล์เพื่อดูรายละเอียดของการเปลี่ยนแปลงในไฟล์
ในกรณีของฉันนี้เกิดจากการไม่ยอมรับการแก้ไขข้อขัดแย้งของฉัน
ปัญหาเกิดจากการรันgit pull
คำสั่ง การเปลี่ยนแปลงในที่มานำไปสู่ความขัดแย้งกับ repo ท้องถิ่นของฉันซึ่งฉันแก้ไข อย่างไรก็ตามฉันไม่ได้กระทำ วิธีแก้ปัญหา ณ จุดนี้คือการคอมมิตการเปลี่ยนแปลง ( git commit
ไฟล์ที่แก้ไขแล้ว)
หากคุณได้แก้ไขไฟล์บางไฟล์ตั้งแต่การแก้ไขข้อขัดแย้งgit status
คำสั่งจะแสดงการปรับเปลี่ยนในท้องถิ่นเป็นการแก้ไขแบบโลคัลและการรวมการแก้ไขเป็นการแก้ไขแบบโลคัลแบบฉาก สิ่งนี้สามารถแก้ไขได้อย่างถูกต้องโดยยอมรับการเปลี่ยนแปลงจากการผสานก่อนgit commit
แล้วจึงเพิ่มและกระทำการเปลี่ยนแปลงที่ไม่ได้ทำตามปกติ (เช่นโดยgit commit -a
)
ฉันมีข้อความเดียวกันเมื่อฉันพยายามที่จะแก้ไขข้อความยืนยันครั้งล่าสุดจากข้อความยืนยันแล้วโดยใช้: git commit --amend -m "New message"
เมื่อฉันผลักการเปลี่ยนแปลงที่ใช้git push --force-with-lease repo_name branch_name
ไม่มีปัญหา
พบปัญหานี้เมื่อฉันสร้างสาขาตามสาขา A โดย
git checkout -b a
แล้วฉันจะตั้งค่ากระแสของสาขา a ให้กำเนิดสาขา B โดย
git branch -u origin/B
จากนั้นฉันได้รับข้อความแสดงข้อผิดพลาดด้านบน
วิธีหนึ่งในการแก้ไขปัญหานี้สำหรับฉันคือ
git checkout -b b origin/B