ฉันจะรีเซ็ตสาขาหลัก git เป็นสาขาต้นน้ำในที่เก็บแบบแยกได้อย่างไร


117

ฉันทำสาขาหลักของที่เก็บคอมไพล์ที่แยกออกจากกันอย่างสมบูรณ์

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

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

ดังนั้นฉันจะรีเซ็ตสาขาหลักที่ผลักดันด้วยต้นแบบต้นน้ำได้อย่างไร


git clone https://myrepo.git
cd myrepo
git remote add upstream https://upstream.git
git fetch upstream

ฉันจะไปที่ใดจากที่นี่เพื่อรีเซ็ตสาขาหลักในพื้นที่และระยะไกลกับต้นแบบต้นน้ำ

คำตอบ:


217

คุณสามารถรีเซ็ตสาขาหลักในเครื่องของคุณเป็นเวอร์ชันอัปสตรีมและส่งไปยังที่เก็บของคุณ

สมมติว่า "ต้นน้ำ" เป็นที่เก็บดั้งเดิมและ "ต้นทาง" คือส้อมของคุณ:

# ensures current branch is master
git checkout master

# pulls all new commits made to upstream/master
git pull upstream master

# this will delete all your local changes to master
git reset --hard upstream/master

# take care, this will delete all your changes on your forked master
git push origin master --force

(คุณสามารถกำหนด repo เดิมเป็น "ต้นน้ำ" ได้ด้วยgit remote add upstream /url/to/original/repo)


1
อาจเป็นการgit reset --hard upstream/masterรีเซ็ตไดเร็กทอรีการทำงานด้วย แต่คำตอบของคุณถูกต้องอย่างไรก็ตาม
j6t

1
สิ่งนี้มีประโยชน์มาก
Aleem S

4
ต้องโทรgit fetch upstreamก่อน
Henry E

4
ดังที่ @HenryE บันทึกความล้มเหลวในการดึงข้อมูลการเปลี่ยนแปลงต้นน้ำก่อนgit fetch upstreamโดยมักจะให้ข้อผิดพลาดที่ไม่สามารถอ่านได้โดยมนุษย์ดังต่อไปนี้"fatal: ambiguous argument 'upstream/master': unknown revision or path not in the working tree."
Cecil Curry

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

6

การดำเนินการนี้จะรีเซ็ตสาขาหลักของคุณด้วยต้นแบบต้นน้ำและหากสาขาได้รับการอัปเดตตั้งแต่การแยกของคุณก็จะดึงการเปลี่ยนแปลงเหล่านั้นออกไปเช่นกัน

git checkout master 
git reset upstream/master
git pull --rebase upstream master
git push origin master --force

PS: สมมติว่า Upstream เป็น repo ดั้งเดิมในขณะที่ต้นทางเป็นสำเนาของคุณ


ดูเหมือนว่าคุณจะสร้างสาขาของคุณจากคอมมิตอื่น เหตุผลหลักในการเปลี่ยนใหม่คือการรักษาประวัติโครงการเชิงเส้น ที่กล่าวว่าคุณไม่ควรตั้งค่าคอมมิชชันใหม่อีกครั้งเมื่อเผยแพร่ไปยังที่เก็บสาธารณะเพราะสิ่งนี้จะแทนที่การกระทำแบบเก่าด้วยการกระทำใหม่ สำหรับรายละเอียดโปรดดูatlassian.com/git/tutorials/rewriting-history/git-rebase
user8128167

0

ฉันได้ลองใช้วิธีนี้แล้ว:

$REPO=<repo>
$ORIGIN=<user>/$REPO
$UPSTREAM=<upstream>/$REPO

$ git clone git@github.com:$ORIGIN.git
$ cd $REPO
$ git checkout master
$ git remote add upstream git@github.com:$UPSTREAM.git
$ git reset --hard upstream/master
$ git pull --rebase upstream master
$ git push origin master --force

ผลลัพธ์จะแสดงคำเตือน:

fatal: ambiguous argument 'upstream/master': 
unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'

ดังนั้นจึงใส่วิธีที่ถูกต้องไว้git pullก่อนgit reset:

$ git clone git@github.com:$ORIGIN.git
$ cd $REPO
$ git checkout master
$ git remote add upstream git@github.com:$UPSTREAM.git
$ git pull --rebase upstream master
$ git reset --hard upstream/master
$ git push origin master --force

จากนั้นผลลัพธ์จะเป็นดังนี้:

From github.com:<upstream>/<repo>
 * branch                master     -> FETCH_HEAD
 * [new branch]          master     -> upstream/master
HEAD is now at 7a94b1790 Merge pull request #4237 from <upstream>/...
Current branch master is up to date.
Everything up-to-date.

0
git reset --hard @{upstream}

หรือสั้นกว่า:

git reset --hard @{u}

หรือคุณสามารถก้าวไปอีกขั้นหนึ่งและตั้งค่านามแฝงที่จะช่วยให้คุณพิมพ์git scrub:

git config --global alias.scrub 'reset --hard @{upstream}'

(สิ่งนี้จะถือว่าสาขาของคุณได้รับการกำหนดค่าให้ติดตามสาขาระยะไกลที่เกี่ยวข้องซึ่งโดยปกติจะเป็นเว้นแต่คุณจะทำสิ่งพิเศษดูgit-branch(1)รายละเอียดเพิ่มเติมเกี่ยวกับการติดตามและgit-rev-parse(1)รายละเอียดเกี่ยวกับไวยากรณ์ข้อกำหนดสาขา)

จากนั้นคุณก็แค่git push --forceส้อมของคุณตามที่อธิบายไว้ในคำตอบอื่น ๆ

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