Как уже говорили другие, невозможно перебазировать ветку, не касаясь рабочего каталога (даже предлагаемые альтернативы, такие как создание нового клона или рабочего дерева, не могут изменить этот факт; эти альтернативы действительно не затрагивают ваш текущий рабочий каталог,но только путем создания нового рабочего дерева).
Для особого случая, когда ветвь, которую вы хотите обновить, должна быть перебазирована в текущем рабочем дереве (или его родительском элементе), можно «перебазировать»другая ветвь без ненужного прикосновения к файлам.
Этот особый случай часто случается, если у вас есть рабочий процесс git, где вы работаете со многими ветвями, которые все разветвляются от основной ветки «master» (которая регулярно обновляется до удаленного мастера)ветвь).
Для иллюстрации предположим, что Git-репозиторий имеет следующую структуру:
repo
- commitA
- commitB
- commitC <-- master <-- OtherBranch based on master
- commitD <-- First commit in otherBranch
- commitE <-- Second commit in OtherBranch
- commitD <-- Unrelated commit in current working tree
. Для примера предположим, что «OtherBranch» разветвляется от «master»,и что ваше текущее рабочее дерево также основано на "мачтеэр».Ваш рабочий процесс обычно начинается с обновления локальной ветки master с удаленной версией ...
# Fetch commits from remote "origin" and update the master branch:
# If your current branch is identical to master
git pull origin master
# If your current branch has extra commits on top of master
git pull --rebase origin master
# If you don't want to touch your current branch
git fetch origin master:master
... и затем вы переключаетесь с текущей веткой и выполняете некоторые трудоемкие компиляции.В конце концов, вы решаете, что хотите работать на OtherBranch
.Этот OtherBranch
должен быть перебазирован на master
(желательно с минимальными операциями файловой системы).В следующем разделе будет показано, как.
Перебазирование другой ветви (справочный пример - НЕ делайте этого)
Следующее решение - это git способ сделать это:
git checkout OtherBranch
git rebase master # or git rebase origin/master
Недостатком является то, что первая команда изменяет даты текущего рабочего дерева, даже если файлы будут восстановлены второй командой.
Перебазирование другой ветви с минимальными изменениями
Чтобы свести к минимуму количество файлов, к которым вы обращались, необходимо перейти к новой базовой ветви, а затем применить все дополнительные коммиты в OtherBranch
поверх базовой ветви, используя git cherry-pick
.
* 1031.* Прежде чем что-либо делать, вам нужно определить коммиты в
OtherBranch
.
git log OtherBranch
показывает коммиты на OtherBranch (в основном полезно, если вы еще не изменили OtherBranch
) git reflog
показывает изменения веток в вашем локальном репозитории (полезно, если вы уже обновили ветки и допустили ошибку).
В текущем примере вы обнаружите, что lasOtherBranch
- это commitE
.Вы можете увидеть список коммитов до этого с помощью git log commitE
(или, если вы хотите более короткий список, git log --oneline commitE
).Если вы посмотрите список, вы увидите, что базовый коммит равен commitC
.
Теперь вы знаете, что базовый коммит - commitC
, а последний коммит - commitE
, вы можете перебазировать OtherBranch (от предыдущего «мастера» к новому «мастеру») следующим образом:
# Replace the old OtherBranch with "master" and switch to it.
git checkout -B OtherBranch master
# Cherry-pick commits starting from commitC and ending at commitE.
cherry-pick commitC^..commitE
В качестве альтернативы (если вы хотите успешно завершить «ребазирование» перед заменой OtherBranch
):
# Create new branch NewOtherBranch based off "master" and switch to it.
git checkout -b NewOtherBranch master
# Cherry-pick commits starting from commitC and ending at commitE.
cherry-pick commitC^..commitE
# Replace the old branch with the current branch (-M = --move --force)
git branch -M OtherBranch
Почему это работает?
Перебазирование веток в git требует переключения текущей ветки на ветку, которую вы хотите обновить (OtherBranch
).
С git rebase
В рабочем процессе происходит следующее:
- Переключение на
OtherBranch
(возможно, разветвленная очень старая базовая ветвь). - Перебазировка (внутренний шаг 1): сохранение коммитов, которые не находятся ввосходящая ветвь.
- Rebase (внутренний шаг 2): сброс текущей ветви к (новой) базовой ветке.
- Rebase (внутренний шаг 3): восстановление фиксаций с шага 2.
Шаг 1 и шаг 3 касаются многих файлов, но в конечном итоге многие изфайлы hed фактически не изменились.
Мой метод объединяет шаги 1 и 3 в шаг 3, и в результате количество файлов, к которым обращаются, минимально.К этим файлам обращаются только следующие файлы:
- Файлы, которые были изменены между базовой веткой и текущим коммитом в текущем рабочем дереве.
- Файлы, которые были изменены коммитами в
OtherBranch
.