Git: объединить ветки, но сохранить историю фиксации
В моем рабочем процессе git у нас есть один основной репозиторий и один ветки, мастер. Все тянут от удаленного мастера, и все нажимают на удаленный мастер. Я хочу работать в своей ветке, пока я готовлю эту функцию. Пока что моя история выглядит примерно так:
git pull --rebase
git checkout -b new_feature
<make some commits>
git checkout master
git pull --rebase
Теперь я хочу объединить ветку и вот что мне нужно:
- В моей локальной ветки мастера не происходит слияния.
- Все коммиты, сделанные в моей ветке new_feature, сливаются с мастером, как если бы я сделал их мастером.
- Все объединенные коммиты объединяются где-то поверх моего локального указателя удаленной головки.
Моя самая большая проблема - пункт 3, когда это необходимо, чтобы я мог безопасно подталкивать изменения. Если объединенные коммиты переплетаются с коммитами перед головой, тогда у меня будут проблемы с нажатием, см. Связанную с этим проблему: git: нажатие одиночных коммитов, переупорядочение с помощью rebase, дублирование записей.
Я читал следующее:
И я думаю, что мне нужно сделать:
git checkout master
git pull --rebase
git checkout new_feature
git rebase master
git checkout master
git rebase new_feature
git push
Я понимаю, что
git checkout new_feature
git rebase master
сделает new_feature таким, как если бы он был отделен от новой текущей головы. Это правда? И что
git checkout master
git rebase new_feature
поместит new_feature поверх мастера. Это верно? Если это так, это основной момент моей путаницы. Если "git мастер переадресации" помещает мастер в нижнюю часть new_feature, тогда почему "git rebase new_feature" помещает new_feature в верхнюю часть ведущего, т.е. Почему он не делает обратное?
Ответы
Ответ 1
Ответ
Вот рабочий процесс, который вы можете использовать, который выполняет именно то, что вам нужно.
git checkout master
git pull --rebase (1)
git checkout new_feature
<do a bunch of commits>
git rebase master (2)
git checkout master
git merge new_feature (3)
git branch -D new_feature (4)
Объяснение
(1) git pull --rebase
сначала выберет origin/master
, а затем вернет вам локальный master
. Обратите внимание, что в журнале примера ваши локальные коммиты находятся поверх вашего локального указателя удаленной HEAD.
> git log --oneline --all -10 --decorate
d34d34c (HEAD, master) Local commit message.
d3434r2 Local commit message.
d234d4c Local commit message.
er3ede3 (origin/master, origin/HEAD) Remote commit message.
sfe3fd3 Remote commit message.
Теперь вы можете checkout
и работать с веткой new_feature
на некоторое время. Когда вы закончите...
(2) git rebase master
будет воспроизводиться new_feature
поверх master
. Опять же, ваши локальные коммиты остаются на вершине вашего локального указателя удаленной HEAD.
> git log --oneline --all -10 --decorate
fc5773d (new_feature) Local new_feature commit.
9282838 Local new_feature commit.
d34d34c (HEAD, master) Local commit.
d3434r2 Local commit.
d234d4c Local commit.
er3ede3 (origin/master, origin/HEAD) Remote commit.
sfe3fd3 Remote commit.
Команда rebase
просто поместит new_feature
впереди ведущего, и чтобы выровнять их, вам нужно запустить...
(3) git merge new_feature
, который будет выполнять ускоренное слияние. Теперь HEAD
, new_feature
и master
все указывают на одну и ту же фиксацию.
> git log --oneline --all -10 --decorate
fc5773d (HEAD, new_feature, master) Local new_feature commit.
9282838 Local new_feature commit.
d34d34c Local commit.
d3434r2 Local commit.
d234d4c Local commit.
er3ede3 (origin/master, origin/HEAD) Remote commit.
sfe3fd3 Remote commit.
(4) После этого вы можете безопасно удалить ветвь new_feature
. Ваш последний журнал перед нажатием будет выглядеть так:
> git log --oneline --all -10 --decorate
fc5773d (HEAD, master) Local new_feature commit 2
9282838 Local new_feature commit.
d34d34c Local commit.
d3434r2 Local commit.
d234d4c Local commit.
er3ede3 (origin/master, origin/HEAD) Remote commit.
sfe3fd3 Remote commit.
Ответ 2
Не нужно запускать git rebase new_feature
в главной ветке после запуска git rebase master
в ветке new_feature. После того, как вы запустили git rebase master
в ветке new_feature, вы можете слить new_feature в master - это будет быстрое слияние и не будет вводить фиксацию слияния.
Причина, по которой git rebase new-feature
не воспроизводит все новые функции, совершаемые поверх мастера, состоит в том, что git распознает, что мастер уже находится в основе новой функции - мы выполнили этот шаг с git rebase master
- и это он просто будет перестраивать сам по себе. Поэтому вместо этого он просто быстро переходит к новой функции.
Кроме того, вам не нужно беспокоиться о том, чтобы перетаскивать коммиты, которые находятся ниже вашего удаленного/главного подсказки - пульт отклонит ваш push, если вы попытаетесь (если вы не предоставите опцию -f, а это не так). И если ваш локальный мастер отслеживает ваш удаленный мастер, git status
сообщит, отклонился ли ваш локальный узел от удаленной ветки.