เหตุใดฉันจึงรวม“ สาขาการติดตามระยะไกล 'ต้นทาง / พัฒนา' เข้ากับการพัฒนา”


126

ฉันเป็นคนเดียวในองค์กรของฉันที่ทำตามข้อความต่อไปนี้:

รวมสาขาการติดตามระยะไกล 'ต้นทาง / พัฒนา' เข้ากับการพัฒนา

ไม่แน่ใจว่าฉันทำอะไรเพื่อทำให้พวกเขา แต่ฉันอยากจะหยุด

ฉันกำลังออกคำสั่งใดเพื่อสร้างคอมมิตนี้และคำสั่งที่เหมาะสมที่ฉันควรใช้เพื่อไม่ให้เกิดคำสั่งคืออะไร?


1
คำตอบของ Richard Hansen นั้นใช้ได้ แต่ฉันคิดว่ามันอาจจะสับสนสำหรับผู้เริ่มต้น วิธีแก้ปัญหาของฉันคือทำแบบ pull --rebase ต่อไป แต่เพื่อหลีกเลี่ยงอันตรายฉันซ่อนการเปลี่ยนแปลงของฉันไว้ก่อนที่จะดึง จากนั้นหลังจากดึงผมก็ใช้มัน ฉันแก้ไขความขัดแย้ง ในที่สุดฉันก็สามารถกระทำและผลักดัน
Johnjohn

ไม่git pull --autostash --rebaseทำงานสำหรับคุณ @Johnjohn?
sourcecedelica

คำตอบ:


206

git pullอาจเป็นการสร้างคอมมิต หากคุณทำการคอมมิตในเครื่องแล้วเรียกใช้git pullหลังจากมีคนอื่นดันคอมมิตไปยังที่เก็บ Git จะดาวน์โหลดคอมมิตของนักพัฒนาคนอื่น ๆ แล้วรวมเข้ากับสาขาในพื้นที่ของคุณ

วิธีหลีกเลี่ยงการรวมการกระทำเหล่านี้ในอนาคต

คุณสามารถใช้git pull --rebaseเพื่อป้องกันไม่ให้เกิดขึ้นในอนาคต แต่ rebasing มีอันตรายของมันและผมขอแนะนำให้หลีกเลี่ยงการpullออกไปโดยสิ้นเชิง

แต่ขอแนะนำให้คุณทำตามรูปแบบการใช้งานนี้:

# download the latest commits
git remote update -p

# update the local branch
git merge --ff-only @{u}

# if the above fails with a complaint that the local branch has
# diverged:
git rebase -p @{u}

คำอธิบาย

  • git remote update -pดาวน์โหลดคอมมิตทั้งหมดในที่เก็บระยะไกลและอัพเดตสาขาการติดตามระยะไกล (เช่นorigin/master) ไม่ได้สัมผัสกับไดเรกทอรีการทำงานดัชนีหรือสาขาในพื้นที่ของคุณ

    -pพรุนอาร์กิวเมนต์ลบสาขาต้นน้ำ ดังนั้นหากfooสาขาถูกลบในที่originเก็บgit remote update -pจะลบการorigin/fooอ้างอิงของคุณโดยอัตโนมัติ

  • git merge --ff-only @{u}บอกให้ Git รวมสาขาต้นน้ำ ( @{u}อาร์กิวเมนต์) เข้ากับสาขาในพื้นที่ของคุณ แต่เฉพาะในกรณีที่สาขาในพื้นที่ของคุณสามารถ "ส่งต่ออย่างรวดเร็ว" ไปยังสาขาต้นน้ำได้ (หรืออีกนัยหนึ่งก็คือหากไม่ได้แยกสาขา)

  • git rebase -p @{u}ย้ายคอมมิตที่คุณทำไปได้อย่างมีประสิทธิภาพ แต่ยังไม่ได้ผลักดันไปที่ด้านบนของสาขาต้นน้ำซึ่งช่วยลดความจำเป็นในการสร้างการผสานที่โง่เขลาที่คุณพยายามหลีกเลี่ยง สิ่งนี้ช่วยปรับปรุงความเป็นเชิงเส้นของประวัติการพัฒนาทำให้ง่ายต่อการตรวจสอบ

    -pตัวเลือกบอก Git เพื่อรักษาผสาน สิ่งนี้จะป้องกันไม่ให้ Git เป็นเส้นตรงของคอมมิตที่ถูก rebased masterนี้เป็นสิ่งสำคัญตัวอย่างเช่นถ้าคุณรวมสาขาคุณลักษณะลง โดยไม่ต้อง-pทุกกระทำในสาขาคุณลักษณะจะซ้ำกันในฐานะเป็นส่วนหนึ่งของการเชิงเส้นที่ทำโดยmaster git rebaseสิ่งนี้จะทำให้การตรวจสอบประวัติการพัฒนายากขึ้นไม่ใช่เรื่องง่าย

    ระวัง : git rebaseอาจไม่ทำในสิ่งที่คุณคาดหวังดังนั้นควรตรวจสอบผลลัพธ์ก่อนที่จะผลักดัน ตัวอย่างเช่น:

    git log --graph --oneline --decorate --date-order --color --boundary @{u}..
    

ฉันชอบแนวทางนี้มากกว่าgit pull --rebaseด้วยเหตุผลต่อไปนี้:

  • ช่วยให้คุณเห็นการกระทำต้นน้ำที่เข้ามาก่อนที่คุณจะแก้ไขประวัติเพื่อรวมเข้าด้วยกัน
  • ช่วยให้คุณสามารถส่งผ่านตัวเลือก-p( --preserve-merges) ไปยังgit rebaseในกรณีที่คุณต้องการสร้างฐานการผสานใหม่โดยเจตนา (เช่นการรวมสาขาคุณลักษณะที่ผลักไปแล้วเข้าไปmaster)

ชวเลข: git upแทนgit pull

เพื่อให้ง่ายต่อการดำเนินการข้างต้นฉันขอแนะนำให้สร้างนามแฝงที่เรียกว่าup:

git config --global alias.up '!git remote update -p; git merge --ff-only @{u}'

ตอนนี้สิ่งที่คุณต้องทำเพื่อทำให้สาขาของคุณทันสมัยคือการเรียกใช้:

git up

git pullแทน หากคุณได้รับข้อผิดพลาดเนื่องจากสาขาในพื้นที่ของคุณแตกต่างจากสาขาต้นน้ำนั่นคือจุดเริ่มต้นของคุณในการปรับฐาน

ทำไมไม่git pull --rebase?

ทำงานgit pull --rebaseเทียบเท่ากับการทำงานตามgit fetch git rebaseการดำเนินการนี้จะพยายามกรอไปข้างหน้าไปยังการคอมมิตต้นน้ำใหม่ แต่ถ้าทำไม่ได้มันจะสร้างฐานการคอมมิชชันในเครื่องของคุณใหม่ในการคอมมิตต้นน้ำใหม่ โดยปกติจะใช้ได้ แต่ระวัง:

  • Rebase เป็นหัวข้อขั้นสูงและคุณควรเข้าใจผลกระทบก่อนที่จะทำการรีเบส
  • git pull --rebaseไม่เปิดโอกาสให้คุณตรวจสอบการกระทำก่อนที่จะรวมเข้าด้วยกัน ทั้งนี้ขึ้นอยู่กับว่ามีอะไรเปลี่ยนแปลงต้นน้ำก็เป็นไปได้มากที่ rebase คือการดำเนินงานผิดrebase --onto, merge, resetหรืออาจจะเหมาะสมกว่าธรรมดาpush -frebase
  • (ในปัจจุบัน) ไม่สามารถส่งผ่าน--preserve-mergesไปยังการดำเนินการ rebase ได้ดังนั้นการรวมสาขาคุณลักษณะโดยเจตนาใด ๆ จะถูกทำให้เป็นเชิงเส้นการเล่นซ้ำ (และการทำซ้ำ) ทั้งหมดของสาขาคุณลักษณะจะกระทำ

"แก้ไข" คอมมิตการผสานที่มีอยู่ที่สร้างขึ้นโดย git pull

หากคุณยังไม่ได้พุชการรวมคอมมิตที่สร้างโดยgit pullคุณสามารถกำหนดฐานข้อมูลการผสานใหม่ได้ สมมติว่าคุณไม่ได้ทำการผสานโดยเจตนาใด ๆ (เช่นการรวมสาขาฟีเจอร์ที่ผลักไปแล้วเข้ากับสาขาปัจจุบันของคุณ) สิ่งต่อไปนี้ควรทำ:

git rebase @{u}

คำสั่งด้านบนบอกให้ Git เลือกคอมHEADมิตที่ไม่ผสานทั้งหมดที่เข้าถึงได้จาก(คอมมิตปัจจุบัน) ลบคอมมิตทั้งหมดที่เข้าถึงได้@{u}(ซึ่งเป็นชวเลขสำหรับ "สาขาต้นน้ำ" คือorigin/masterถ้าHEADเป็นmaster) เล่นซ้ำ (เชอร์รี่ - รับ ) ไว้ที่ด้านบนของสาขาต้นน้ำจากนั้นย้ายการอ้างอิงสาขาปัจจุบันเพื่อชี้ไปที่ผลลัพธ์ของการเล่นคอมมิตซ้ำ git pullได้อย่างมีประสิทธิภาพย้ายกระทำที่ไม่ตัดเข้าสู่ต้นน้ำล่าสุดกระทำซึ่งช่วยขจัดผสานที่สร้างขึ้นโดย

หากคุณมีการรวมคอมมิตโดยเจตนาคุณไม่ต้องการเรียกใช้git rebase @{u}เพราะจะเล่นซ้ำทุกอย่างจากอีกสาขา การจัดการกับกรณีนี้มีความซับซ้อนมากขึ้นซึ่งเป็นเหตุผลว่าทำไมจึงควรใช้git upและหลีกเลี่ยงgit pullโดยสิ้นเชิง คุณอาจจะต้องใช้resetในการยกเลิกการผสานสร้างขึ้นโดยแล้วทำpull อาร์กิวเมนต์ไม่ได้ทำงานได้อย่างน่าเชื่อถือสำหรับฉันดังนั้นคุณอาจท้ายต้องใช้เพื่อยกเลิกการผสานเจตนาปรับปรุงสาขาท้องถิ่นของคุณและจากนั้นทำซ้ำผสานเจตนา (ซึ่งเป็นความเจ็บปวดถ้ามีจำนวนมากของการผสานขน ความขัดแย้ง)git rebase -p @{u}-pgit rebasereset@{u}


+1 สำหรับการพูดคุย - สงวน - ผสานยกเว้นว่าคุณไม่ได้บันทึกไว้ในคำสั่งที่คุณบอกให้เขาเรียกใช้ดังนั้น -1 สำหรับสิ่งนั้น
Seth Robertson

@Seth: ขอบคุณสำหรับความคิดเห็น; -pฉันปรับปรุงคำตอบที่จะแนะนำ ฉันหลีกเลี่ยงที่จะแนะนำมาก่อนเพราะมันไม่จำเป็นบ่อยนักและพฤติกรรมของมันก็ไม่ได้รับการบันทึกไว้อย่างดี
Richard Hansen

3
อะไรคือความแตกต่างระหว่างgit remote update -pและgit fetch?
eckes

3
@eckes: git remote update -pเหมือนกับgit fetch --all -p. ฉันติดนิสัยgit remote update -pกลับมาใช้เมื่อfetchไม่มี-pตัวเลือก
Richard Hansen

1
@ user1914692: เมื่อการผสานเสร็จสมบูรณ์ Git จะอัปเดตสาขาในเครื่องเพื่อชี้ไปที่การผสานรวมที่สร้างขึ้นใหม่ไม่ใช่การคอมมิตเดียวกับสาขาระยะไกล การรวมคอมมิตใหม่นี้เป็นปัญหาโดยเฉพาะอย่างยิ่งเมื่อถูกผลัก
Richard Hansen

18
git fetch
git rebase origin/master

ที่ควรทำ. หรือถ้าคุณต้องการใช้ต่อไปเพื่อดึง

git pull --rebase

คุณยังสามารถตั้งค่าสาขานั้นในการกำหนดค่าของคุณเพื่อสร้างฐานใหม่โดยอัตโนมัติหรือตั้งค่าแบบนั้นโดยอัตโนมัติสำหรับสาขาการติดตามอื่น ๆ ในอนาคตที่คุณทำ จากนั้นคุณสามารถกลับไปใช้

git pull

ข้อมูลเพิ่มเติมในส่วน "ดึงด้วย rebase แทนการผสาน" ของหน้านี้:

http://mislav.uniqpath.com/2010/07/git-tips/

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