Git ดึงจนถึงการกระทำที่เฉพาะเจาะจง


96

ฉันต้องการที่จะทำgit pullแต่จนถึงการกระทำที่เฉพาะเจาะจงเท่านั้น

 A->B->C->D->E->F (Remote master HEAD)

ดังนั้นคิดว่าฉันlocal masterจุดมุ่งหน้าไปและผมต้องการที่จะดึงจนB Eฉันควรทำอย่างไรดี ?

นี่ไม่ใช่การดึงคอมมิตเฉพาะ แต่เป็นการดึงคอมมิตเฉพาะไม่เกิน



3
git fetchและgit merge E.
โผล่

ตอนนี้ฉันอยู่ในตัวอย่าง B แต่ฉันต้องการดึง C, E และ F เท่านั้นฉันต้องการลบ D ขอบคุณ!
Frenkey

@Frenkey คุณสามารถผสานต้นแบบจากนั้นลบการกระทำสามครั้งสุดท้ายจากนั้นเชอร์รี่เลือกสองข้อสุดท้าย นอกจากนี้คุณสามารถลองใช้ rebase -i เพื่อการรวม git ที่ควบคุมได้มากขึ้น
Ninja420

จะเกิดอะไรขึ้นถ้าฉันต้องการดึงการเปลี่ยนแปลงจาก C เท่านั้นไม่รวมการเปลี่ยนแปลงของ A และ B เพียงแค่ C? ฉันจะทำเช่นนั้นได้อย่างไร?
Vikas Chauhan

คำตอบ:


113

git pullคืออะไร แต่ตามมาด้วยgit fetch git mergeสิ่งที่คุณทำได้คือ

git fetch remote example_branch

git merge <commit_hash>


"อ้างถึงสิ่งนี้" ควรจะเป็นอย่างไร
developerbmw

@Brett ลืมโพสต์ลิงค์ .. ลบออกทั้งหมด
Unrealsoul007

@ Unrealsoul007 สิ่งนี้จะรวมเฉพาะการกระทำที่เฉพาะเจาะจงใช่ไหม ดังนั้นในการดึงจาก B ขึ้นไปยัง E คำสั่งจะเป็น git merge <คอมมิต_hash C> <คอมมิต_hash D> <คอมมิต_hash E> ใช่ไหม
Wim Feijen

6
@WimFeijen git merge Eจะรวมเข้าEกับบรรพบุรุษทั้งหมดCและD(คอมไพล์รู้ดีAและBไม่จำเป็นต้องรวมเพราะพวกเขาอยู่ในสาขาของคุณแล้ว) หากคุณต้องการเพียงการเปลี่ยนแปลงEคุณควรทำgit cherry-pick Eแทน
neXus

ขอบคุณสำหรับคำตอบฉันกำลังมองหาปัญหาเดียวกัน
Akash Bisariya

21

ขั้นแรกดึงคอมมิตล่าสุดจาก repo ระยะไกล สิ่งนี้จะไม่ส่งผลกระทบต่อสาขาในพื้นที่ของคุณ

git fetch origin

จากนั้นชำระเงินสาขาการติดตามระยะไกลและบันทึกคอมไพล์เพื่อดูการคอมมิต

git checkout origin/master
git log

หยิบคอมมิตแฮชของคอมมิตที่คุณต้องการรวมเข้าด้วยกัน (หรือแค่ ~ 5 ตัวอักษรแรก) แล้วรวมคอมมิตเป็นมาสเตอร์

git checkout master
git merge <commit hash>

1
ฉันไม่ลงคะแนนให้คุณเนื่องจากไม่ได้ผลตามที่โฆษณาไว้ ก่อนอื่นด้วยวิธีของคุณ "git fetch origin" จะดึงข้อมูลสาขาระยะไกลทั้งหมด (ควรระบุให้ชัดเจนโดยเฉพาะอย่างยิ่งสำหรับผู้ที่ทำงานในโครงการที่มีสาขาจำนวนมากและขนาดใหญ่) ประการที่สองด้วยวิธีนี้ "ผสานคอมไพล์ <คอมมิตแฮช>" จะไม่รวมประวัติท้องถิ่นของคุณเข้ากับคอมมิตที่ต้องการหากคุณย้อนกลับไปในประวัติศาสตร์ ตัวอย่าง: คุณอยู่ที่คอมมิต 100 ในเครื่องคุณต้องการได้ถึง 150 โดยดึงข้อมูลทุกอย่าง (โดย HEAD ระยะไกลอยู่ที่ 100)
ยึด

8
@ ตัวยึดคุณควรอ่านคู่มือgit fetchก่อนที่จะเขียนเรื่องไร้สาระดังกล่าว นอกจากนั้นคุณควรอ่านคำถามเดิมและคำตอบของฉัน ถ้าคุณทำตามคำตอบของฉันแล้วคุณจะไม่เป็น "ย้อนกลับไปในประวัติศาสตร์" git checkout masterเป็นฉันอย่างชัดเจนสั่งให้ผู้ใช้สามารถ โดยรวมแล้วโปรดอย่าโพสต์สิ่งต่างๆหากคุณไม่ชัดเจนอย่างน้อย 50% ในสิ่งที่คุณทำ
developerbmw

1
ในกรณีที่มันไม่ชัดเจนสำหรับคนอื่นgit fetch originอย่างชัดเจนเรียกกำเนิด
Daniel Farrell

2
สิ่งนี้ใช้ได้ผลดีและอธิบายได้ดีกว่าคำตอบที่ยอมรับ
walen

1
คำตอบที่ดีที่สุดทำงานได้อย่างสมบูรณ์แบบ
Asfandyar Khan

13

คุณยังสามารถดึงคอมมิตล่าสุดและเลิกทำจนกว่าจะได้คอมมิตที่คุณต้องการ:

git pull origin master
git reset --hard HEAD~1

แทนที่masterด้วยสาขาที่คุณต้องการ

ใช้บันทึกคอมไพล์เพื่อดูว่าคุณต้องการเปลี่ยนกลับคอมมิตใด:

git log

โดยส่วนตัวแล้วสิ่งนี้ได้ผลสำหรับฉันดีกว่า

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

ข้อดี: ได้ผลตามที่โฆษณา คุณไม่จำเป็นต้องใช้คอมมิตแฮชหรือดึงสาขาที่ไม่จำเป็น

จุดที่ไม่ดี:คุณต้องยกเลิกการคอมมิตทีละรายการ

คำเตือน:ยอมรับ / ซ่อนการเปลี่ยนแปลงในเครื่องทั้งหมดของคุณเพราะ--hardคุณจะสูญเสียการเปลี่ยนแปลงดังกล่าวไปด้วย ใช้ความเสี่ยงของคุณเอง!


3
ฉันไม่รู้ว่าทำไมการโหวตลดลงนี่เป็นวิธีที่สะอาดที่สุดและทันทีที่คุณต้องการทราบข้อมูลล่าสุดการดึงแบบง่ายๆจะทำไม่เหมือนกับคำตอบอื่น ๆ
Mauricio Pasquier Juan

อย่าว่าทำไมไม่โหวตเพิ่มข้อเสียเพียงอย่างเดียวคือคุณต้องไปที่จุดHEADก่อนกลับ - และฉันจะไม่เกิดอะไรขึ้นถ้าคุณต้องแก้ไขความขัดแย้ง แต่วิธีนี้ช่วยให้git pull --rebaseและตรงกันข้ามกับสิ่งที่กล่าวไว้คุณสามารถรีเซ็ตกลับไปที่Ncommits ที่แล้วได้โดยตรงด้วยgit reset --hard HEAD~N(เช่น 3 commits git reset --hard HEAD~3)
Stock Overflaw

2

หากคุณรวมข้อผูกพันเข้ากับสาขาของคุณคุณควรได้รับประวัติทั้งหมดระหว่าง

สังเกต:

$ git init ./
เริ่มต้นที่เก็บ Git ว่างใน /Users/dfarrell/git/demo/.git/
$ echo 'a'> ตัวอักษร
$ git เพิ่มจดหมาย
$ git กระทำ -m 'จดหมายเริ่มต้น'
[master (root-commit) 6e59e76] อักษรย่อ
 เปลี่ยน 1 ไฟล์แทรก 1 (+)
 สร้างโหมด 100644 ตัวอักษร
$ echo 'b' >> จดหมาย
$ git เพิ่มตัวอักษร && คอมมิต -m 'การเพิ่มจดหมาย'
[master 7126e6d] การเพิ่มตัวอักษร
 เปลี่ยน 1 ไฟล์แทรก 1 (+)
$ echo 'c' >> จดหมาย; git เพิ่มตัวอักษร && คอมมิต -m 'การเพิ่มจดหมาย'
[master f2458be] การเพิ่มตัวอักษร
 เปลี่ยน 1 ไฟล์แทรก 1 (+)
$ echo 'd' >> จดหมาย; git เพิ่มตัวอักษร && คอมมิต -m 'การเพิ่มจดหมาย'
[master 7f77979] การเพิ่มตัวอักษร
 เปลี่ยน 1 ไฟล์แทรก 1 (+)
$ echo 'e' >> จดหมาย; git เพิ่มตัวอักษร && คอมมิต -m 'การเพิ่มจดหมาย'
[master 790eade] การเพิ่มตัวอักษร
 เปลี่ยน 1 ไฟล์แทรก 1 (+)
บันทึก $ git
กระทำ 790eade367b0d8ab8146596cd717c25fd895302a
ผู้แต่ง: Dan Farrell 
วันที่: พฤหัสบดี ก.ค. 16 14:21:26 น. 2558 -0500

    การเพิ่มจดหมาย

กระทำ 7f77979efd17f277b4be695c559c1383d2fc2f27
ผู้แต่ง: Dan Farrell 
วันที่: พฤหัสบดี ก.ค. 16 14:21:24 น. 2558 -0500

    การเพิ่มจดหมาย

กระทำ f2458bea7780bf09fe643095dbae95cf97357ccc
ผู้แต่ง: Dan Farrell 
วันที่: พฤหัสบดี ก.ค. 16 14:21:19 น. 2558 -0500

    การเพิ่มจดหมาย

กระทำ 7126e6dcb9c28ac60cb86ae40fb358350d0c5fad
ผู้แต่ง: Dan Farrell 
วันที่: พฤหัสบดี ก.ค. 16 14:20:52 น. 2558 -0500

    การเพิ่มจดหมาย

กระทำ 6e59e7650314112fb80097d7d3803c964b3656f0
ผู้แต่ง: Dan Farrell 
วันที่: พฤหัสบดี ก.ค. 16 14:20:33 น. 2558 -0500

    จดหมายเริ่มต้น
$ git ชำระเงิน 6e59e7650314112fb80097d7d3803c964b3656f
$ git ชำระเงิน 7126e6dcb9c28ac60cb86ae40fb358350d0c5fad
หมายเหตุ: ตรวจสอบ '7126e6dcb9c28ac60cb86ae40fb358350d0c5fad'

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

หากคุณต้องการสร้างสาขาใหม่เพื่อรักษาคอมมิตที่คุณสร้างไว้คุณสามารถทำได้
ทำเช่นนั้น (ตอนนี้หรือใหม่กว่า) โดยใช้ -b กับคำสั่ง checkout อีกครั้ง ตัวอย่าง:

  git checkout -b new_branch_name

HEAD ตอนนี้อยู่ที่ 7126e6d ... กำลังเพิ่มตัวอักษร
$ git ชำระเงิน -b B 7126e6dcb9c28ac60cb86ae40fb358350d0c5fad
เปลี่ยนเป็นสาขาใหม่ 'B'
$ git ดึง 790eade367b0d8ab8146596cd717c25fd895302a
ร้ายแรง: '790eade367b0d8ab8146596cd717c25fd895302a' ดูเหมือนจะไม่ใช่ที่เก็บ git
ร้ายแรง: ไม่สามารถอ่านจากที่เก็บระยะไกล

โปรดตรวจสอบว่าคุณมีสิทธิ์การเข้าถึงที่ถูกต้อง
และมีที่เก็บอยู่
$ git ผสาน 7f77979efd17f277b4be695c559c1383d2fc2f27
กำลังอัปเดต 7126e6d..7f77979
กรอไปข้างหน้า
 จดหมาย | 2 ++
 เปลี่ยน 1 ไฟล์, 2 ส่วนแทรก (+)
จดหมาย $ cat
ก
ข
ค
ง

1

สิ่งนี้ใช้ได้กับฉัน:

git pull origin <sha>

เช่น

[dbn src]$ git fetch
[dbn src]$ git status
On branch current_feature
Your branch and 'origin/master' have diverged,
and have 2 and 7 different commits each, respectively.
...
[dbn src]$ git log -3 --pretty=oneline origin/master
f4d10ad2a5eda447bea53fed0b421106dbecea66 CASE-ID1: some descriptive msg
28eb00a42e682e32bdc92e5753a4a9c315f62b42 CASE-ID2: I'm so good at writing commit titles
ff39e46b18a66b21bc1eed81a0974e5c7de6a3e5 CASE-ID2: woooooo
[dbn src]$ git pull origin 28eb00a42e682e32bdc92e5753a4a9c315f62b42
[dbn src]$ git status
On branch current_feature
Your branch and 'origin/master' have diverged,
and have 2 and 1 different commits each, respectively.
...

สิ่งนี้ดึง 28eb00, ff39e4 และทุกอย่างก่อนหน้านี้ แต่ไม่ดึง f4d10ad อนุญาตให้ใช้ pull --rebase และให้เกียรติการตั้งค่าดึงใน gitconfig ของคุณ สิ่งนี้ได้ผลเนื่องจากคุณถือว่า 28eb00 เป็นสาขา

สำหรับเวอร์ชันของคอมไพล์ที่ฉันใช้วิธีนี้ต้องใช้แฮชคอมมิตแบบเต็ม - ไม่อนุญาตให้ใช้ตัวย่อหรือนามแฝง คุณสามารถทำสิ่งต่างๆเช่น:

[dbn src]$ git pull origin `git rev-parse origin/master^`
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.