'git pull origin mybranch' ออกจาก mybranch N ในท้องถิ่นที่กระทำก่อนต้นกำเนิด ทำไม?


92

ฉันเพิ่งสังเกตเห็นบางอย่างแปลก ๆgit pullซึ่งฉันไม่เข้าใจ

เมื่อวันศุกร์ฉันทำงานในสาขาในพื้นที่ mybranchขอเรียกว่า ก่อนที่จะออกจากสำนักงานฉันผลักไปยังต้นกำเนิด (ซึ่งเป็น repo GitHub git push origin mybranchของฉัน):

เมื่อวานที่บ้านฉันpullแก้ไขสาขาของฉันลงในแล็ปท็อปของฉันทำการเข้ารหัสเพิ่มเติมจากนั้นจึงส่งการเปลี่ยนแปลงของฉันกลับไปที่ github (ต้นทาง)

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

git pull origin mybranch

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

# On branch mybranch
# Your branch is ahead of 'origin/mybranch' by 6 commits.
#
nothing to commit (working directory clean)

ฮะ? จะเป็นไปได้อย่างไรที่จะกระทำ 6 ครั้งข้างหน้าเมื่อฉันไม่ได้แตะมันในช่วงสุดสัปดาห์และเพิ่งถูกดึงออกมาจากจุดเริ่มต้น? ดังนั้นฉันจึงวิ่ง a git diff origin/mybranchและความแตกต่างคือการเปลี่ยนแปลง 6 ประการที่ฉันเพิ่งดึงมาจากรีโมท

ฉันสามารถ "แก้ไข" สิ่งนี้ได้โดยเรียกใช้git fetch origin:

From git@github.com:me/project
af8be00..88b0738  mybranch -> origin/mybranch

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

ฉันควรใช้git pull originแทนgit pull origin branchnameหรือไม่

ฉันสับสน.


ฉันก็สังเกตเห็นเช่นกัน git pushยังจะดูเหมือนจะแก้ปัญหาได้ (รายงาน "ทั้งหมดถึงวัน")
Ben James

4
git config --get-regexp br.*สามารถบอกคุณได้ว่า config ของคุณมี aa สาขาในประเทศกำลังติดตามสาขาอื่นอยู่หรือไม่
VonC

3
คุณสามารถพิมพ์git config branch.master.remote yourGitHubRepo.gitworkRepo ของคุณและตรวจสอบ (ในรายการถัดไปgit pull origin) ได้หรือไม่หากสถานะยังคงมีคำเตือน "ข้างหน้า"
VonC

ยังไม่ได้ตั้งค่า (เอาต์พุตว่าง) แต่git remote show originแสดงให้ฉันเห็นว่าจุดเริ่มต้นชี้ไปที่ที่เก็บ GitHub ของฉันฉันเดาว่าน่าจะโอเค?
Matthias

1
คอมไพล์ระยะไกลเพียงอย่างเดียว (แสดงที่อยู่ที่เหมาะสมสำหรับ GitHub repo) ไม่เพียงพอ เพื่อหลีกเลี่ยงการมี " Your branch is ahead" ข้อความแจ้งเตือนหลังจากที่git pullคุณจะต้องแรกที่ยัง กำหนดชื่อระยะไกลสำหรับสาขา ดังนั้นคำแนะนำของฉัน: พิมพ์git config branch.master.remote yourGitHubRepo.gitจากนั้นลอง a git pullและ a git statusและดูว่าปัญหายังคงอยู่หรือไม่
VonC

คำตอบ:


115

git pullเรียกgit fetchด้วยพารามิเตอร์ที่เหมาะสมก่อนที่จะรวมส่วนหัวที่ดึงมาอย่างชัดเจน (หรือหากไม่มีสาขาระยะไกลที่กำหนดค่าสำหรับการผสาน) เข้ากับสาขาปัจจุบัน

ไวยากรณ์: git fetch <repository> <ref>โดยที่<ref>เป็นเพียงชื่อสาขาที่ไม่มีเครื่องหมายโคลอนคือการดึงข้อมูลแบบ 'one shot' ที่ไม่ได้ทำการดึงข้อมูลมาตรฐานของสาขาที่ติดตามทั้งหมดของรีโมตที่ระบุ แต่จะดึงเฉพาะสาขาที่มีชื่อเข้ามาFETCH_HEADแทน

ปรับปรุง:สำหรับรุ่น Git ตั้งแต่ 1.8.4 fetchถ้ามีสาขาที่ห่างไกลการติดตามซึ่งติดตามเตะที่คุณถามว่าจะสามารถดึงข้อมูลแล้วสาขาการติดตามจะได้รับการปรับปรุงในขณะนี้โดย การเปลี่ยนแปลงนี้จัดทำขึ้นโดยเฉพาะเพื่อหลีกเลี่ยงความสับสนที่พฤติกรรมก่อนหน้านี้ก่อให้เกิด

เมื่อคุณดำเนินการgit pull <repository> <ref>, FETCH_HEADมีการปรับปรุงดังกล่าวแล้วรวมเข้าเป็นของคุณตรวจสอบออกมาHEADแต่ไม่มีสาขาติดตามมาตรฐานสำหรับพื้นที่เก็บข้อมูลระยะไกลจะมีการปรับปรุง (Git <1.8.4) ซึ่งหมายความว่าในพื้นที่ดูเหมือนว่าคุณจะนำหน้าสาขาระยะไกลในขณะที่ในความเป็นจริงคุณได้รับข้อมูลล่าสุดแล้ว

โดยส่วนตัวแล้วฉันมักจะทำgit fetchตามด้วยgit merge <remote>/<branch>เพราะฉันได้เห็นคำเตือนเกี่ยวกับการอัปเดตที่บังคับก่อนที่จะรวมและฉันสามารถดูตัวอย่างสิ่งที่ฉันรวมเข้าด้วยกันถ้าฉันใช้git pullมากกว่าที่ฉันทำฉันจะทำแบบธรรมดาgit pullโดยไม่มีพารามิเตอร์มากที่สุด ของเวลาพึ่งพาbranch.<branch>.remoteและbranch.<branch>.merge'ทำในสิ่งที่ถูกต้อง'


4
+1 นั่นเป็นคำอธิบายที่ดีจริงๆ! ฉันรู้ว่าคำอธิบายซ่อนอยู่ที่ไหนสักแห่งใน 'git help fetch' แต่ไม่สามารถเอาออกได้ ...
Stefan Näwe

1
+1. โพสต์ดีๆมีแนวทางคล้ายกับgitster.livejournal.com/28309.html
VonC

1
ดังนั้นจะgit fetchหลังจากgit pull <repository> <ref>แก้ไขปัญหาตั้งแต่การดึงข้อมูลจะปรับปรุงสาขาติดตามมาตรฐาน? นอกจากนี้ขอบคุณสำหรับคำตอบนี้เริ่มสมเหตุสมผล :)
Bart Jedrocha

1
ฉันวิ่งเข้าไปในปัญหานี้เกินไปและคุณจะต้องทำตามด้วยgit fetch git merge origin/master master
user1027169

3

สิ่งที่git remote -v showส่งคืนเมื่อมาถึงแหล่งกำเนิด?

หากจุดเริ่มต้นชี้ไปที่ github สถานะควรเป็นปัจจุบันและไม่นำหน้า repo ระยะไกลใด ๆ อย่างน้อยด้วย Git1.6.5 ฉันใช้สำหรับการทดสอบอย่างรวดเร็ว

อย่างไรก็ตามเพื่อหลีกเลี่ยงสิ่งนี้ให้กำหนด repo ระยะไกลของสาขาหลักอย่างชัดเจน:

$ git config branch.master.remote yourGitHubRepo.git

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


ฉันสามารถทดสอบสิ่งนี้ด้วย git1.6.5:

ก่อนอื่นฉันสร้าง workrepo:

PS D:\git\tests> cd pullahead
PS D:\git\tests\pullahead> git init workrepo
Initialized empty Git repository in D:/git/tests/pullahead/workrepo/.git/
PS D:\git\tests\pullahead> cd workrepo
PS D:\git\tests\pullahead\workrepo> echo firstContent > afile.txt
PS D:\git\tests\pullahead\workrepo> git add -A 
PS D:\git\tests\pullahead\workrepo> git commit -m "first commit"

ฉันจำลอง GitHub repo โดยการสร้าง repo เปล่า (อันที่สามารถรับการผลักดันได้จากทุกที่)

PS D:\git\tests\pullahead\workrepo> cd ..
PS D:\git\tests\pullahead> git clone --bare workrepo github

ฉันเพิ่มโมดิฟใน repo ที่ใช้งานได้ซึ่งฉันส่งไปยัง github repo (เพิ่มเป็นรีโมต)

PS D:\git\tests\pullahead> cd workrepo
PS D:\git\tests\pullahead\workrepo> echo aModif >> afile.txt
PS D:\git\tests\pullahead\workrepo> git ci -a -m "a modif to send to github"
PS D:\git\tests\pullahead\workrepo> git remote add github d:/git/tests/pullahead/github
PS D:\git\tests\pullahead\workrepo> git push github

ฉันสร้าง home repo โคลนของ GitHub ซึ่งฉันทำการปรับเปลี่ยนสองสามอย่างผลักไปที่ GitHub:

PS D:\git\tests\pullahead\workrepo> cd ..
PS D:\git\tests\pullahead> git clone github homerepo
PS D:\git\tests\pullahead> cd homerepo
PS D:\git\tests\pullahead\homerepo> type afile.txt
firstContent
aModif

PS D:\git\tests\pullahead\homerepo> echo aHomeModif1  >> afile.txt
PS D:\git\tests\pullahead\homerepo> git ci -a -m "a first home modif"
PS D:\git\tests\pullahead\homerepo> echo aHomeModif2  >> afile.txt
PS D:\git\tests\pullahead\homerepo> git ci -a -m "a second home modif"
PS D:\git\tests\pullahead\homerepo> git push github

จากนั้นฉันก็โคลน workrepo สำหรับการทดลองครั้งแรก

PS D:\git\tests\pullahead\workrepo4> cd ..
PS D:\git\tests\pullahead> git clone workrepo workrepo2
Initialized empty Git repository in D:/git/tests/pullahead/workrepo2/.git/
PS D:\git\tests\pullahead> cd workrepo2
PS D:\git\tests\pullahead\workrepo2> git remote add github d:/git/tests/pullahead/github
PS D:\git\tests\pullahead\workrepo2> git pull github master
remote: Counting objects: 8, done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 6 (delta 1), reused 0 (delta 0)
Unpacking objects: 100% (6/6), done.
From d:/git/tests/pullahead/github
 * branch            master     -> FETCH_HEAD
Updating c2763f2..75ad279
Fast forward
 afile.txt |  Bin 46 -> 98 bytes
 1 files changed, 0 insertions(+), 0 deletions(-)

ใน repo นั้นสถานะ git จะกล่าวถึง master geing ข้างหน้า ' origin':

PS D:\git\tests\pullahead\workrepo5> git status
# On branch master
# Your branch is ahead of 'origin/master' by 2 commits.
#
nothing to commit (working directory clean)

แต่นั่นoriginไม่ใช่ github เท่านั้น:

PS D:\git\tests\pullahead\workrepo2> git remote -v show
github  d:/git/tests/pullahead/github (fetch)
github  d:/git/tests/pullahead/github (push)
origin  D:/git/tests/pullahead/workrepo (fetch)
origin  D:/git/tests/pullahead/workrepo (push)

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

PS D:\git\tests\pullahead\workrepo2> cd ..
PS D:\git\tests\pullahead> git clone workrepo workrepo4
PS D:\git\tests\pullahead> cd workrepo4
PS D:\git\tests\pullahead\workrepo4> git remote rm origin
PS D:\git\tests\pullahead\workrepo4> git remote add github d:/git/tests/pullahead/github
PS D:\git\tests\pullahead\workrepo4> git pull github master
remote: Counting objects: 8, done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 6 (delta 1), reused 0 (delta 0)
Unpacking objects: 100% (6/6), done.
From d:/git/tests/pullahead/github
 * branch            master     -> FETCH_HEAD
Updating c2763f2..75ad279
Fast forward
 afile.txt |  Bin 46 -> 98 bytes
 1 files changed, 0 insertions(+), 0 deletions(-)
PS D:\git\tests\pullahead\workrepo4> git status
# On branch master
nothing to commit (working directory clean)

ถ้าฉันได้เพียงoriginชี้บนgithub, statusจะสะอาดสำหรับ git1.6.5
อาจมีคำเตือน 'ล่วงหน้า' สำหรับคอมไพล์ก่อนหน้านี้ แต่อย่างไรก็ตามคำเตือนที่git config branch.master.remote yourGitHubRepo.gitกำหนดไว้อย่างชัดเจนควรสามารถดูแลสิ่งนั้นได้แม้จะมี Git เวอร์ชันแรกก็ตาม


ขอขอบคุณที่สละเวลาตรวจสอบเรื่องนี้ รีโมตต้นทางชี้ไปที่ repo GitHub ของฉันแล้ว ฉันโคลนโครงการนั้นจาก URL GitHub และสาขาหลักในพื้นที่ของฉันกำลังติดตามต้นทาง / ต้นแบบ สำหรับ mybranch ฉันค่อนข้างมั่นใจว่าฉันสร้างมันขึ้นจากสาขาต้นทาง / สาขา mybranch ซึ่งควรติดตามโดยอัตโนมัติ แต่ถึงกระนั้นอาจเป็นปัญหา? mybranch ท้องถิ่นไม่ได้ติดตามต้นทาง / mybranch จริงหรือ? PS: ฉันใช้ git 1.6.1 (ผ่าน MacPorts)
Matthias

มีคำสั่ง git ที่ให้ฉันดูว่าสาขาในพื้นที่กำลังติดตามสาขาอื่นหรือไม่? หาในเพจคนไม่เจอ
Matthias

คุณสามารถดูว่ามีการติดตามสาขาระยะไกลใดgit remote show originบ้าง
Ted Percival

2

คุณระมัดระวังในการเพิ่มรีโมททั้งหมดของคุณ (ยกเว้นoriginที่มาพร้อมกับโคลนดั้งเดิมของคุณ) โดยใช้git remote add NAME URLหรือไม่? ฉันเคยเห็นข้อผิดพลาดนี้เมื่อพวกเขาเพิ่งถูกเพิ่มเข้าไปในการกำหนดค่าคอมไพล์


ฉันทำสิ่งนี้เมื่อโคลน repo อย่างไรก็ตามฉันไม่ได้ทำสิ่งนี้กับแต่ละสาขา สำหรับเช่น mybranch git checkout -b mybranch origin/mybranchครั้งแรกที่ผมจะสามารถดึงข้อมูลจากแหล่งกำเนิดแล้ว ตามหน้าคนของ git-branch จุดเริ่มต้น / mybranch คือจุดเริ่มต้นและนอกจากนี้ยังระบุสำหรับ --track: "... ใช้สิ่งนี้หากคุณดึงจากสาขาต้นน้ำเดียวกันไปยังสาขาใหม่เสมอและ หากคุณไม่ต้องการใช้ "git pull <repository> <refspec>" อย่างชัดเจนลักษณะการทำงานนี้เป็นค่าเริ่มต้นเมื่อจุดเริ่มต้นเป็นสาขาระยะไกล "
Matthias
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.