จะเปลี่ยนสาขาในพื้นที่ด้วยรีโมตสาขาทั้งหมดใน Git ได้อย่างไร


778

ฉันมีสองสาขา:

  1. สาขาท้องถิ่น (สาขาที่ฉันทำงานด้วย)
  2. สาขาระยะไกล (สาธารณะเท่านั้นที่ผ่านการทดสอบอย่างดี)

เมื่อเร็ว ๆ นี้ฉันทำให้สาขาของฉันสับสน

ฉันจะแทนที่สาขาในพื้นที่ทั้งหมดด้วยรีโมตได้อย่างไรฉันจึงสามารถทำงานต่อจากที่สาขารีโมตได้ในขณะนี้

ฉันค้นหาแล้วและเช็คเอาท์ที่สาขาระยะไกลในพื้นที่ไม่มีผลใด ๆ


1
ฉันรู้ว่าคำตอบที่ยอมรับมี 1280 คะแนนขึ้นไป แต่คุณควรพิจารณาเปลี่ยนคำตอบที่ยอมรับเป็น @TTT
Jamie

คำตอบ:


1288
  1. ตรวจสอบให้แน่ใจว่าคุณได้ตรวจสอบสาขาที่คุณกำลังจะเปลี่ยน (จากความคิดเห็นของZoltán )
  2. สมมติว่าต้นแบบนั้นเป็นสาขาในพื้นที่ที่คุณกำลังจะเปลี่ยนและ "Origin / master" เป็นสาขาระยะไกลที่คุณต้องการรีเซ็ตเป็น:

    git reset --hard origin/master
    

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


4
ขอบคุณสำหรับคำแนะนำของคุณฉันแค่กลัวการใช้ - ฮาร์ดและ - บังคับอยู่แล้วดังนั้นฉันจึงเลือกโซลูชันที่ไม่ได้ใช้
YemSalat

13
@ KonstantinLevin: ใช่แล้วการตั้งชื่อตัวเลือกเหล่านั้นค่อนข้างน่ารำคาญ git resetโดยค่าเริ่มต้นจะทำให้สาขาปัจจุบันของคุณและซิงค์ดัชนี --softจะข้ามการอัปเดตดัชนี--hardจะซิงค์พื้นที่ทำงานด้วย ประสบการณ์ของตัวเองของฉันคือการใช้--hardเวลาส่วนใหญ่ของยกเว้นเมื่อฉันต้องการที่จะยกเลิกการกระทำที่ผ่านมา (ซึ่งเป็นเพียงgit reset HEAD^)
araqnid

9
หลังจากมีประสบการณ์มากขึ้นกับคอมไพล์ฉันมั่นใจว่านี่เป็นทางออกที่ดีกว่าขอบคุณ
YemSalat

24
อาจคุณจะต้องดึงข้อมูลมาก่อน:git fetch origin remote_branch
b1r3k

53
คุณควรทราบว่านี้จะเข้ามาแทนที่แล้วแต่จำนวนใดสาขาของคุณปัจจุบันอยู่กับเนื้อหาของต้นแบบ ดังนั้นหากคุณอยู่ในสาขาฟีเจอร์มันจะแทนที่คอมมิชชันทั้งหมดด้วยmasterดังนั้นตรวจสอบให้แน่ใจว่าคุณได้ตรวจสอบสาขาที่คุณกำลังจะเปลี่ยนก่อน
Zoltan

218

นั่นง่ายเหมือนสามขั้นตอน:

  1. ลบสาขาในพื้นที่ของคุณ: git branch -d local_branch
  2. ดึงสาขาระยะไกลล่าสุด: git fetch origin remote_branch
  3. สร้างสาขาในเครื่องโดยยึดตามรีโมต: git checkout -b local_branch origin/remote_branch

7
จริงๆแล้วสิ่งที่ @araqnid พูดนั้นถูกต้องและรัดกุมกว่า ฉันได้ทำการทดสอบแล้วและคุณสามารถลองใช้ได้เช่นกัน
adamsmith

ว้าวการชำระเงินคอมไพล์ -b local_branch กำเนิด / remote_branch ยอดเยี่ยมมาก! ฉันทำสิ่งนี้ในสองคำสั่งแยกกันเสมอ ขอบคุณ!
kendepelchin

11
คุณอาจต้องทำgit branch -D local_branchในขั้นตอนแรกหากสาขาของคุณไม่ถูกผสาน
szeryf

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

2
เราควรตรวจสอบให้แน่ใจว่าสาขาปัจจุบันไม่ใช่สาขาที่จะถูกลบ
a_secenthusiast

43
git branch -D <branch-name>
git fetch <remote> <branch-name>
git checkout -b <branch-name> --track <remote>/<branch-name>

ส่วนของแทร็กทำอะไร
eonist

3
@GitSync, นี่คือสิ่งที่กล่าวเกี่ยวกับgit help branch ฉันแก้ไขคำสั่งนี้ในคำตอบ ขอบคุณสำหรับการยกประเด็น --trackWhen creating a new branch, set up branch.<name>.remote and branch.<name>.merge configuration entries to mark the start-point branch as "upstream" from the new branch. This configuration will tell git to show the relationship between the two branches in git status and git branch -v. Furthermore, it directs git pull without arguments to pull from the upstream when the new branch is checked out.
Sailesh

ดังนั้นในแง่คนธรรมดามันเพิ่ม URL ระยะไกลไปยังสาขาใหม่ ดังนั้นพวกเขาจะซิงค์กันตลอดไป ดังนั้นที่จะพูด
eonist

2
คุณสามารถพูดได้ว่ามันเป็นเพียงเพื่อความสะดวก หากคุณทำเช่นgit statusนั้นจะรายงานว่าสาขาในพื้นที่ของคุณอยู่ข้างหน้าหรือข้างหลังสาขาระยะไกลหากคุณมีสาขาที่เกี่ยวข้อง นอกจากนี้คุณยังสามารถทำgit pull(หรือpush) แทนเต็มรูปแบบถ้าคุณได้กำหนดไว้แล้วสาขาของคุณเพื่อติดตามgit pull <remote> <branch> <remote/branch>
Sailesh

22

แทนที่ทุกสิ่งด้วยสาขาระยะไกล แต่มีเพียงสาขาเดียวที่ผูกพันสาขาในพื้นที่ของคุณเท่านั้น:

git reset --hard origin/some-branch

หรือรับล่าสุดจากสาขาระยะไกลและแทนที่ทุกอย่าง:

git fetch origin some-branch
git reset --hard FETCH_HEAD

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

git clean -fd

git cleanคำสั่งมันสำหรับฉัน git reset hard origin/masterอย่าลบไฟล์ที่ไม่ได้ติดตาม ขอบคุณ!
Mornor

9

วิธีที่ปลอดภัยที่สุดและสมบูรณ์ที่สุดในการเปลี่ยนสาขาท้องถิ่นด้วยรีโมต:

git stash
git merge --abort
git rebase --abort
git branch -M yourBranch replaced_yourBranch
git fetch origin yourBranch:yourBranch
git checkout yourBranch

stashบรรทัดบันทึกการเปลี่ยนแปลงที่คุณไม่ได้มุ่งมั่น branchเส้นย้ายสาขาของคุณกับชื่อที่แตกต่างกันพ้นขึ้นชื่อเดิม fetchสายดึงสำเนาล่าสุดของระยะไกล checkoutบรรทัด recreates สาขาเดิมเป็นสาขาการติดตาม

หรือเป็นฟังก์ชันทุบตี:

replaceWithRemote() {
    yourBranch=${1:-`git rev-parse --abbrev-ref HEAD`}
    git stash
    git merge --abort
    git rebase --abort
    git branch -M ${yourBranch} replaced_${yourBranch}_`git rev-parse --short HEAD`
    git fetch origin ${yourBranch}:${yourBranch}
    git checkout ${yourBranch}
}

ซึ่งเปลี่ยนชื่อสาขาปัจจุบันเป็นสิ่งที่ต้องการ replace_master_98d258f


อาจต้องการรวมgit stash popไว้ในเวิร์กโฟลว์นั้น หากคุณต้องการใช้ไฟล์ที่ถูกซ่อนอีกครั้ง
eonist

คุณทำอะไรกับสาขาที่ซ่อนไว้ ฉันกลัวว่ามันจะปรากฏขึ้นอีกครั้งในอนาคตหลังจากที่ฉันลืมไปแล้วว่ามันมีไว้เพื่ออะไร
Scott Biggs

1
@ScottBiggs หากคุณต้องการลบสาขาที่เก็บไว้ให้ใช้ "git stash clear"
Mark A. Durham

4

ฉันประหลาดใจมากที่ยังไม่มีใครพูดถึงเรื่องนี้ ฉันใช้มันเกือบทุกวัน:

git reset --hard @{u}

โดยทั่วไป@{u}เป็นเพียงชวเลขสำหรับสาขาต้นน้ำที่สาขาปัจจุบันของคุณกำลังติดตาม origin/[my-current-branch-name]ตัวอย่างเช่นนี้มักจะเท่ากับ มันดีเพราะมันเป็นผู้ไม่เชื่อเรื่องพระเจ้าสาขา

ตรวจสอบให้แน่ใจgit fetchก่อนว่าจะได้รับสำเนาล่าสุดของสาขาระยะไกล


1
ดูดีมากฉันเบื่อที่จะคัดลอกและวางชื่อสาขาเพื่อรีเซ็ต!
pedroct92

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

3

มันสามารถทำได้หลายวิธีอย่างต่อเนื่องเพื่อแก้ไขคำตอบนี้เพื่อกระจายมุมมองความรู้ที่ดีขึ้น

1) รีเซ็ตฮาร์ด

หากคุณกำลังทำงานจากสาขาการพัฒนาระยะไกลคุณสามารถรีเซ็ต HEAD เป็นการกระทำล่าสุดในสาขาระยะไกลดังต่อไปนี้:

git reset --hard origin/develop

2) ลบสาขาปัจจุบันและชำระเงินอีกครั้งจากที่เก็บระยะไกล

เมื่อพิจารณาแล้วคุณกำลังทำงานเพื่อพัฒนาสาขาใน repo ท้องถิ่นที่ซิงค์กับสาขาระยะไกล / พัฒนาคุณสามารถทำดังต่อไปนี้:

git branch -D develop
git checkout -b develop origin/develop

3) ยกเลิกการรวม

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

git merge --abort

4) การยกเลิกการยกเลิก

หากคุณอยู่ระหว่างการรีบูตที่ไม่ดีคุณสามารถยกเลิกการร้องขอการรีบู๊ตได้ดังต่อไปนี้:

git rebase --abort

2

คุณสามารถทำตาม @Hugo ของ @Laurent กล่าวหรือคุณสามารถใช้git rebaseเพื่อลบคอมมิทที่คุณต้องการกำจัดหากคุณรู้ว่าอันไหน ฉันมักจะใช้git rebase -i head~N(โดยที่ N เป็นตัวเลขช่วยให้คุณสามารถจัดการ N สุดท้ายที่คอมมิท) สำหรับการดำเนินการประเภทนี้


จริงๆแล้วมันเป็นคำสั่ง 'git rebase' ที่ทำให้ทุกอย่างยุ่งเหยิงจากนั้นมีการรวมการบังคับและการรีเซ็ตอย่างหนัก .. อย่างไรก็ตามสิ่งที่ฉันกำลังมองหาเป็นเพียงวิธีง่ายๆในการดึง repo ทั้งหมดจากเซิร์ฟเวอร์ระยะไกลโดยไม่ต้องรวม
YemSalat

2

คำตอบที่เลือกเป็นอย่างถูกต้องแต่ก็ไม่ได้ทิ้งฉันกับล่าสุดกระทำ / ดัน ...

ดังนั้นสำหรับฉัน:

git reset --hard dev/jobmanager-tools
git pull  ( did not work as git was not sure what branch i wanted)

เนื่องจากฉันรู้ว่าฉันต้องการตั้งค่าสาขาต้นน้ำของฉันชั่วคราวเป็นเวลาสองสามสัปดาห์เป็นสาขาเฉพาะ

ดังนั้นหลังจากรีเซ็ตแล้ว

git branch --set-upstream-to=origin/dev/jobmanager-tools
git pull
git status    ( says--> on branch  dev/jobmanager-tools 

1

หากคุณต้องการอัปเดตสาขาที่ไม่ได้ชำระเงินในขณะนี้คุณสามารถทำได้:

git fetch -f origin rbranch:lbranch

0

ตามที่ระบุไว้ในคำอธิบายที่เลือกการรีเซ็ต gitนั้นดี แต่ทุกวันนี้เรามักใช้ sub-modules: repositories ภายใน repositories ตัวอย่างเช่นคุณถ้าคุณใช้ ZF3 และ jQuery ในโครงการของคุณคุณอาจต้องการให้พวกเขาโคลนจากแหล่งเก็บข้อมูลดั้งเดิมของพวกเขา ในกรณีเช่นนี้การรีเซ็ต gitไม่เพียงพอ เราจำเป็นต้องอัปเดต submodules เป็นเวอร์ชันที่แน่นอนที่กำหนดไว้ในที่เก็บของเรา:

git checkout master
git fetch origin master
git reset --hard origin/master
git pull

git submodule foreach git submodule update

git status

มันเป็นเช่นเดียวกับที่คุณจะมา (cd) ซ้ำกับไดเรกทอรีการทำงานของแต่ละโมดูลย่อยและจะทำงาน:

git submodule update

และมันแตกต่างจาก

git checkout master
git pull

เพราะโมดูลย่อยไม่ได้ชี้ไปที่สาขา แต่ไปที่การกระทำ

ในกรณีนั้นเมื่อคุณเช็คเอาต์สาขาด้วยตนเองสำหรับ 1 หรือมากกว่า submodules คุณสามารถเรียกใช้

git submodule foreach git pull

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

git reset --hardคำตอบที่ได้รับการยอมรับแล้วเสนอ นี่เป็นการเพิ่มมูลค่าเพียงเล็กน้อย
florisla

0
git reset --hard
git clean -fd

สิ่งนี้ใช้ได้กับฉัน - clean แสดงไฟล์ทั้งหมดที่ถูกลบด้วย ถ้ามันบอกคุณว่าคุณจะสูญเสียการเปลี่ยนแปลงคุณต้องซ่อน


-6

วิธีที่น่าเกลียด แต่ง่ายกว่า: ลบโฟลเดอร์ในเครื่องของคุณและโคลนที่เก็บระยะไกลอีกครั้ง


10
หรือเพียงแค่ลบสาขาและตรวจสอบอีกครั้ง
เรน

ใช่ฉันเดาว่าเป็นสิ่งที่ฉันจะทำถ้าฉันไม่พบวิธีที่จะทำในทางที่ 'น่าเกลียด' น้อยกว่า
YemSalat

2
บางครั้งน่าเกลียดมีประโยชน์ที่จะรู้ ฉันหวังว่าผู้คนจะไม่ลดทอนสิ่งต่าง ๆ เพียงเพราะพวกเขาไม่ใช่วิธีปกติ: จะต้องมีเหตุผลที่สมเหตุสมผลมากกว่าสำหรับการ downvoting ... และควรได้รับ Git เป็นสิ่งที่ได้ผลลัพธ์ มันไม่ได้เป็นข้อความศักดิ์สิทธิ์บางชนิด
ไมค์หนู

3
ฉันไม่เข้าใจ downvotes :-( ใช่มันไม่เหมาะสม ฯลฯ แต่มันสามารถทำงานได้ดีที่สุดในบางกรณี ... ขออภัย @Hugo
silverdr

@Hugo เห็นด้วย มีบางสิ่งที่ลึกลับและส่งกลิ่นเกิดขึ้นกับสาขาพัฒนาท้องถิ่นของฉันและทั้งหัวหน้าทีมและผู้จัดการฝ่ายวิศวกรรมแนะนำวิธีแก้ปัญหาที่สง่างามยิ่งขึ้น (ซิปคัดลอกและบันทึกงานคุณลักษณะของฉันแล้ว) ทำหน้าที่ repo และ reclone ในท้องถิ่น
AmitaiB
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.