Зміна бази філій


145

У мене таке дерево:

(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, щоб перетворити і залишити демо недоторканим. Зрештою, і демо, і PRO будуть висіти від майстра.


можливий дублікат пункту "
Відміняти"

Відповіді:


282

Використовуйте --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
@Fla в такому випадку це було бgit rebase --onto first-branch master second-branch
nVitius

9
Я читав цей посібник далі --onto, і те, як вони писали, допомогло меніgit rebase --onto newBase oldBase feature/branch
Габе

@PhilipRego Це неправильно. origin/newBase- це назва гілки, як newBaseу моєму прикладі. Це буде просто залежати, якщо ви переходите на гілку, яка існує у вашому локальному сховищі ( newBase), або ту, яка існує на віддаленому ( origin/newBase).
loganfsmyth

@PhilipRego Це не самостійні речі. newBase- це назва місцевої гілки, і origin/newBaseце назва віддаленої гілки. Кому ви хочете, залежить від того, на що ви отримуєте відмову. Справа не в тому, що один працює, а ні - це те, що вони переходять на різні речі. Оригінальне запитання ніколи не згадує про віддалені, тому використання пульта в моєму прикладі не відповідало б заданому питанню.
loganfsmyth

22

Я постараюся бути такою ж родовою, наскільки я можу бути. По-перше, переконайтеся, що ви перебуваєте на потрібній гілці:

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 тепер перезавантажить вашу current-branchповерх temp-commit-hash. Можуть виникнути подальші конфлікти, і вам знову доведеться їх вирішувати вручну. Закінчивши, ви продовжуєте знову git add .і git rebase --continueпісля цього ви успішно переобладнали свій current-branchверх new-base-branch.


Примітка. Якщо ви почнете замішати, то можете зробити це в git rebase --abortбудь-який час під час перезавантаження і повернутися до початкової точки.


Опублікована rebaseкоманда просто дає мені "фатальний: недійсний вгору" поточна база-гілка "". Крім того, чому навіть потрібно сказати GIT, що таке поточна материнська гілка поточної гілки - не повинна вона цього знати вже?
Метт Арнольд

21

Оформити замовлення на PROгілку, скопіюйте найстаріший ( commit4 ) та останній ( commit5 ) хеші цієї гілки та вставте десь ще:

$ 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

1

У мене був дещо інший підхід із застосуванням скидання та аналізу даних, що дозволяє уникнути видалення та повторного створення гілок, а також усунення необхідності перемикання гілок:

$ 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-му рядку?
Алексіс Вілке
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.