เปลี่ยนฐานสาขา


157

ฉันมีต้นไม้แบบนี้:

(commit 1) - master
                \-- (commit 2) - (commit 3) - demo
                                                \-- (commit 4) - (commit 5) - PRO

และฉันต้องย้ายสาขา PRO ไปเชี่ยวชาญ

(commit 1) - master
                |-- (commit 2) - (commit 3) - demo
                \-- (commit 4) - (commit 5) - PRO

ฉันได้ลองใช้git rebase masterสาขา PRO แล้ว แต่ไม่มีอะไรเกิดขึ้น

เพื่อชี้แจง : ฉันทำงานในระดับปริญญาโทจากนั้นฉันต้องทำการสาธิตผลิตภัณฑ์ ( git checkout -b demoและการกระทำบางอย่าง) จากนั้นโดยไม่ได้ตั้งใจฉันสร้างสาขาอื่นจากการสาธิต ( git checkout -b PROและบางส่วน) และตอนนี้ฉันต้องย้ายสาขา PRO ไปเชี่ยวชาญและปล่อยให้การสาธิตเหมือนเดิม ในตอนท้ายทั้งเดโมและโปรจะหยุดทำงานจากมาสเตอร์


อาจซ้ำกันของจุดเปลี่ยนสาขา
Wladimir Palant

คำตอบ:


319

ใช้--ontoสำหรับสิ่งนั้น:

git rebase --onto newBase oldBase feature/branch

ระบุกรณีของคุณ:

git checkout PRO # Just to be clear which branch to be on.
git rebase --onto master demo PRO

โดยพื้นฐานแล้วคุณจะรับการกระทำทั้งหมดจากภายหลังdemoถึงPROและกำหนดฐานข้อมูลใหม่เข้าสู่การmasterกระทำ


นั่นเป็นวิธีที่จะไปหากสถานการณ์ตรงกันข้ามหรือไม่? == ฉันชำระเงิน -b จากมาสเตอร์สาขาที่สอง แต่ฉันต้องการทำจากสาขาแรก ฉันได้git rebase --onto first-branch second-branch second-branchแต่ไม่ได้รับไวยากรณ์
Fla

1
ในกรณีนั้นจะเป็นgit rebase --onto first-branch master second-branch
nVitius

11
ผมอ่านคู่มือใน--ontoและวิธีการที่พวกเขาเขียนช่วยให้ฉันgit rebase --onto newBase oldBase feature/branch
เกบ

@PhilipRego นั่นไม่ถูกต้อง origin/newBaseเป็นชื่อของสาขาเช่นเดียวกับnewBaseในตัวอย่างของฉัน มันจะขึ้นอยู่กับว่าคุณกำลังเปลี่ยนสาขาที่มีอยู่ในที่เก็บในเครื่องของคุณ ( newBase) หรือสาขาที่มีอยู่บนรีโมต ( origin/newBase)
loganfsmyth

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

25

ชำระเงินไปที่PROสาขาคัดลอกแฮชคอมมิตที่เก่าที่สุด ( คอมมิต 4 ) และล่าสุด ( คอมมิต 5 ) ของสาขานี้แล้ววางที่อื่น

$ git checkout PRO
$ git log            # see the commit history
# copy the oldest & latest commit-hash 

ลบPROสาขา (เก็บข้อมูลสำรองเพื่อความปลอดภัย) สร้างและชำระเงินไปยังPROสาขาใหม่จากmaster:

$ git branch PRO.bac    # create a new branch PRO.bac = PRO as backup

$ git checkout master
$ git branch -D PRO     # delete the local PRO branch
$ git checkout -b PRO   # create and checkout to a new 'PRO' branch from 'master'

ใช้ ( เลือกเชอร์รี่ ) ช่วงของการยอมรับPROสาขาก่อนหน้าไปยังPROสาขาใหม่:

$ git cherry-pick commit4^..commit5   # cherry-pick range of commits
# note the '^' after commit4

ตอนนี้ถ้าทุกอย่างเรียบร้อยให้บังคับ (-f) ผลักไปที่remote PROสาขาและลบPRO.bacสาขาในพื้นที่:

$ git log                  # check the commit history

$ git push -f origin HEAD  # replace the remote PRO by local PRO branch history
# git branch -D PRO.bac    # delete local PRO.bac branch

23

ฉันจะพยายามทำตัวให้ธรรมดาที่สุดเท่าที่จะทำได้ ขั้นแรกตรวจสอบให้แน่ใจว่าคุณอยู่ในสาขาที่ต้องการ:

git checkout current-branch

จากนั้นใช้คำสั่งต่อไปนี้ ( new-base-branchสาขาที่คุณต้องการให้เป็นฐานใหม่อยู่ที่ไหนและcurrent-base-branchคือสาขาซึ่งเป็นฐานปัจจุบันของคุณ)

git rebase --onto new-base-branch current-base-branch

หากคุณไม่มีความขัดแย้งก็ยิ่งดี - คุณทำเสร็จแล้ว หากคุณทำ (ในกรณีส่วนใหญ่) โปรดอ่านต่อ

ความขัดแย้งอาจเกิดขึ้นและคุณจะต้องแก้ไขด้วยตนเอง Git ตอนนี้พยายามที่จะทำ "3 วิธีผสาน" ระหว่างคุณcurrent-branch, และcurrent-base-branch new-base-branchโดยประมาณนี่คือวิธีที่ git จะทำงานภายใน:

  1. Git จะสร้างฐานข้อมูลใหม่current-base-branchที่ด้านบนของไฟล์new-base-branch. อาจมีความขัดแย้ง ซึ่งคุณจะต้องแก้ไขด้วยตนเอง หลังจากนั้นจะทำคุณมักจะทำและgit add . git rebase --continueมันจะสร้างการคอมมิตชั่วคราวใหม่temp-commit-hashสำหรับสิ่งนี้

  2. หลังจากนี้ Git ตอนนี้จะ rebase ของคุณบนของcurrent-branch temp-commit-hashอาจมีความขัดแย้งเกิดขึ้นอีกและคุณจะต้องแก้ไขด้วยตนเองอีกครั้ง เมื่อเสร็จแล้วคุณดำเนินการต่ออีกครั้งโดยgit add .และgit rebase --continueหลังจากนั้นคุณได้เปลี่ยนฐานข้อมูลใหม่current-branchที่ด้านบนของไฟล์new-base-branch.


หมายเหตุ:หากคุณเริ่มสับสนคุณสามารถทำได้git rebase --abortทุกเมื่อในระหว่างกระบวนการ rebase และกลับไปที่จุดเริ่มต้น


rebaseคำสั่งโพสต์เป็นเพียงแค่ให้ฉัน "ร้ายแรง: ต้นน้ำที่ไม่ถูกต้องในปัจจุบันฐานสาขา" นอกจากนี้เหตุใดจึงจำเป็นต้องบอก GIT ว่าสาขาแม่ของสาขาปัจจุบันคืออะไร - ไม่ควรรู้เรื่องนี้แล้ว
Matt Arnold

2

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

$ git checkout PRO
$ git reset commit4 # This will set PROs HEAD to be at commit 4, and leave the modified commit 5 files in ur working index
$ git stash save -m "Commit message"
$ git reset commit 3
$ git stash save -m "Commit message"
$ git reset master --hard
$ git stash pop
$ git stash pop
$ git push --force # force if its already been push remotely

โดยการรีเซ็ตสาขาตามการคอมมิตโดยพื้นฐานของคุณเพียงแค่กรอกลับที่แยกสาขาประวัติศาสตร์การกระทำในแต่ละครั้ง


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