จะ 'git pull' เข้าไปในสาขาที่ไม่ใช่สาขาปัจจุบันได้อย่างไร?


126

เมื่อคุณเรียกใช้git pullในสาขาก็มักจะดึงจากmaster origin/masterฉันอยู่ในสาขาอื่นที่เรียกว่าnewbranchแต่ฉันต้องการเรียกใช้คำสั่งที่ทำgit pullจากorigin/masterเข้าmasterแต่ฉันไม่สามารถเรียกใช้git checkoutเพื่อเปลี่ยนสาขาที่เลือกได้จนกว่าการดึงจะเสร็จสมบูรณ์ มีวิธีทำไหม?

เพื่อให้พื้นหลังบางส่วนพื้นที่เก็บข้อมูลจะจัดเก็บเว็บไซต์ ฉันได้ทำการเปลี่ยนแปลงบางอย่างในและใช้งานพวกเขาโดยการเปลี่ยนเว็บไซต์เพื่อnewbranch newbranchตอนนี้การเปลี่ยนแปลงเหล่านั้นได้รวมเข้ากับmasterสาขาแล้วฉันกำลังพยายามเปลี่ยนเว็บไซต์กลับไปที่masterสาขาด้วย ณ จุดนี้newbranchและorigin/masterเหมือนกัน แต่masterล้าหลังorigin/masterและจำเป็นต้องได้รับการอัปเดต ปัญหาคือถ้าฉันทำแบบดั้งเดิม:

$ git checkout master
   # Uh oh, production website has now reverted back to old version in master
$ git pull
   # Website is now up to date again

ฉันต้องการบรรลุเช่นเดียวกับด้านบน ( git checkout master && git pull) แต่ไม่ต้องเปลี่ยนไดเร็กทอรีการทำงานเป็นการแก้ไขก่อนหน้านี้ในระหว่างกระบวนการ


@phi: ฉันไม่คิดว่ามันจะได้ผลเพราะฉันอยู่ในnewbranchนั้นและไม่มีอะไรจะซ่อน!
Malvineous

ฉันจะโคลนลงในไดเร็กทอรีใหม่รวม newbranch เป็น master รวม master กลับไปที่ newbranch จากนั้น git ดึงจากที่ที่คุณอยู่ ปริญญาโทและสาขาใหม่จะเหมือนกัน
aet

@aet เขาก็สามารถดำเนินการได้ในขณะนี้ในไดเรกทอรีปัจจุบันของเขาด้วยการทำจากภายในgit fetch; git merge origin/master newbranchไม่มีประโยชน์ที่จะโคลนสำเนาที่สองทั้งหมดของที่เก็บ
meagar

3
เกี่ยวข้องกันอย่างใกล้ชิด: stackoverflow.com/questions/3216360/…
Ciro Santilli 郝海东冠状病六四事件法轮功

คำตอบ:


5

คุณมีเวิร์กทรีที่คุณไม่ต้องการแตะต้องดังนั้นให้ใช้อันอื่น โคลนมีราคาถูกสร้างขึ้นเพื่อสิ่งนี้

git fetch origin master       # nice linear tree
git clone . ../wip -b master  # wip's `origin/master` is my `master`
cd ../wip                     # .
git pull origin origin/master # merge origin's origin/master
git push origin master        # job's done, turn it in.
cd ../main
rm -rf ../wip                 # wip was pushed here, wip's done

git checkout master           # payload

ปัญหาของคำตอบอื่น ๆ ทั้งหมดที่นี่คือพวกเขาไม่ได้ดึง หากคุณต้องการการผสานหรือฐานข้อมูลใหม่ที่คุณได้ตั้งค่าไว้คุณต้องมี worktree อื่นและขั้นตอนข้างต้น มิฉะนั้นก็git fetch; git checkout -B master origin/masterจะทำ


2
เมื่อคุณเรียกใช้git checkout masterคุณจะชำระเงินmasterสาขาเก่าเนื่องจากคุณยังไม่ได้ทำgit pullในmainโฟลเดอร์เพื่อซิงโครไนซ์กับต้นทาง / ต้นแบบ นี่คือสิ่งที่ฉันพยายามหลีกเลี่ยง
Malvineous

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

On line ที่ 6 คุณผลักดันรวม (ปรับปรุง) masterกลับไปแต่ผมไม่เชื่อว่าการเช็คเอาต์สุดท้ายของคุณเป็นของการปรับปรุงนี้origin masterไม่มีgit pullการอัปเดตmasterสาขาในmainไดเร็กทอรีดังนั้นเว้นแต่ฉันจะพลาดบางสิ่งบางอย่างคำสั่งของคุณก็ไม่ต่างจากการรันgit checkout masterด้วยตัวเองและรับmasterต้นไม้เก่า หากคุณมองอย่างใกล้ชิดคุณไม่ได้เรียกใช้คำสั่งใด ๆ ในmainไดเร็กทอรีที่สื่อสารกับต้นน้ำ (นอกเหนือจากบรรทัดที่ 1 ซึ่งทำงานก่อนที่คุณจะทำการเปลี่ยนแปลงใด ๆ กับ repo ต้นน้ำ)
Malvineous

คุณสามารถลองใช้ repo ทดสอบหรือตรวจสอบเอกสารพุช
jthill

1
@jwg เทียบกับอะไรเอ่ย? อย่าลืมตอบสนองความต้องการที่ระบุไว้ทั้งหมดของ OP
jthill

163

ตรงไปตรงมา: การอัปเดตจากสาขาระยะไกลไปยังสาขาหลักที่ไม่ได้เช็คเอาต์ในปัจจุบัน:

git fetch origin master:master

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

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

git pull origin master:master

4
ดูเหมือนว่ามันจะไม่ได้ผลเสมอไป ฉันเพิ่งได้รับแจ้งให้รวมกับสาขา WIP ของฉัน
underscore_d

@underscore_d เหมือนกันสำหรับฉัน
Greg

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

2
มันควรจะทำงานอย่างไร? มันไม่ได้ผลสำหรับฉันเพียงแค่พยายามรวมต้นทาง / ต้นแบบเข้ากับสาขาที่เช็คเอาต์ในปัจจุบัน
mhogerheijde

3
สิ่งนี้จะดึงต้นแบบเข้าสู่สาขาปัจจุบัน นี่ไม่ใช่สิ่งที่ถูกถามอย่างแน่นอน หากคุณเปลี่ยน pull เพื่อดึงข้อมูลนี่จะเป็นสิ่งที่ถูกขอ
Jeff Wolski

90

มีคำตอบที่นี่: ผสานอัปเดตและดึงสาขา Git โดยไม่ต้องใช้การชำระเงิน

# Merge local branch foo into local branch master,
# without having to checkout master first.
# Here `.` means to use the local repository as the "remote":
git fetch . foo:master

# Merge remote branch origin/foo into local branch foo,
# without having to checkout foo first:
git fetch origin foo:foo

2
นี่เป็นวิธีที่ดีที่สุดเนื่องจากใช้ได้กับการเปลี่ยนแปลงภายในเครื่องที่ไม่ได้ผูกมัด
Tomasz Gandor

2
git fetch origin master:masterถ้าคุณเพียงต้องการที่จะจับขึ้นกับการเปลี่ยนแปลงล่าสุดที่คุณต้องการจะทำอย่างไร git fetchโดยตัวมันเองจะถือว่าคุณตั้งใจจะอัปเดตสาขาปัจจุบันไม่ใช่สาขาอื่น
John Leidegren

2
นี่คือคำตอบที่ง่ายและตรงที่สุด นี่ควรเป็นคำตอบที่ได้รับการยอมรับ IMO
Keego

@JohnLeidegren - ยกเว้นว่าจะไม่ได้ผลตามที่ตั้งใจไว้เสมอไป ดูความคิดเห็นที่stackoverflow.com/a/42902058/274579คำตอบ
ysap

22

ตามที่ปรากฎคำตอบนั้นง่ายหลอกลวง:

$ git fetch                           # Update without changing any files
$ git branch -d master                # Remove out-of-date 'master' branch
$ git checkout --track origin/master  # Create and check out up-to-date 'master' branch

นี้ช่วยให้คุณปรับปรุงmasterสาขาโดยไม่ต้องเปลี่ยนไปจนกระทั่งหลังจากที่มันได้รับการปรับปรุง


11
สิ่งนี้ไม่ได้ทำตามที่คุณถามว่าต้องทำอย่างไร
jthill

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

1
เป็นคำตอบที่ฉันมาที่นี่เพื่อค้นหา :)
Sophistifunk

1
ไม่ใช่สิ่งที่ OP ต้องการ แต่ช่วยฉันด้วยความซื่อสัตย์
Marcel Bro

1
@anoniim ไม่ใช่สิ่งที่ OP ต้องการ? คุณหมายถึง OP ที่เพิ่งตอบคำถามนี้?
smac89

12

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

เนื่องจากคุณไม่ได้ใส่รหัสในสภาพแวดล้อมการใช้งานจริงของคุณ (ฉันหวังว่า) คุณไม่จำเป็นต้องมีการตรวจสอบสาขา คุณก็สามารถทำได้git fetchในการปรับปรุง refs ระยะไกลของคุณและจากนั้นgit checkout origin/masterจะย้ายไดเรกทอรีการทำงานโดยตรงorigin/masterกับการกระทำชี้ปัจจุบันโดย สิ่งนี้จะทำให้คุณอยู่ในสถานะหัวแยก แต่อีกครั้งเนื่องจากคุณไม่ได้ป้อนรหัสจึงไม่สำคัญ

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


ฉันเข้าใจข้อ จำกัด ของการใช้ git สำหรับการปรับใช้ปัญหาคือรูในกรณีนี้จะยาวเป็นนาทีแทนที่จะน้อยกว่าหนึ่งวินาที ความคิดที่ดีเกี่ยวกับการตรวจสอบorigin/masterแต่นั่นอาจเป็นเคล็ดลับ
Malvineous

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

มันยาวไม่กี่นาทีเพราะไฟล์ที่ไม่ได้ติดตาม (ตอนนี้) จะถูกเขียนทับโดยคอมมิตก่อนหน้านี้ เลยต้อง copy ไฟล์ทำ git แล้วใส่กลับเข้าไป "นาทีที่ยาว" มาจากความเร็วในการพิมพ์ของฉัน (ใช่ฉันสามารถเขียนสคริปต์ได้ แต่มันเป็นเพียงเพื่อชี้ให้เห็นว่าการมีคอมไพล์ทำทุกอย่างเร็วขึ้นเท่านั้น)
Malvineous

3

คุณสามารถใช้ update-ref สำหรับสิ่งนี้:

git fetch
git update-ref refs/heads/master origin/master
git checkout master

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


สิ่งนี้จะเทียบเท่ากับgit branch --force master origin/master? สิ่งนี้บังคับให้หัวหน้าท้องถิ่นmasterชี้ไปที่หัวของoriginsmaster
Keego

2

วิธีแก้ปัญหาของ Malvineous ใช้ได้ผลสำหรับฉัน

$ git fetch                           # Update without changing any files
$ git branch -d master                # Remove out-of-date 'master' branch
$ git checkout --track origin/master  # Create and check out up-to-date 'master' branch

เพียงแค่ให้ข้อผิดพลาด


warning: not deleting branch 'master' that is not yet merged to
         'refs/remotes/origin/master', even though it is merged to HEAD.
error: The branch 'master' is not fully merged.
If you are sure you want to delete it, run 'git branch -D master'.

ดังนั้นฉันจึงใช้ตัวเลือก -D

ขอบคุณ


0

git fetch origin master:master

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