git rebase, отслеживание "локальных" и "удаленных"
при выполнении git rebase, я часто испытываю трудности с разработкой того, что происходит с "локальным" и "удаленным" при разрешении конфликтов. У меня иногда складывается впечатление, что они меняют стороны от одного коммита к другому.
Это наверное (наверняка), потому что я до сих пор не правильно поняли.
при перебазировании, кто является "локальным", а кто "удаленным"?
(Я использую P4Merge для разрешения конфликтов)
3 ответа:
TL; DR;
обобщить (как Benubirdкомментарии), когда:
git checkout A git rebase B # rebase A on top of B
local
иB
(rebase на),remote
иA
и:
git checkout A git merge B # merge B into A
local
иA
(слияния на),remote
иB
переключатели перебазирования
ours
(текущие ответвление перед началом перебазирования) иtheirs
(ветка, поверх которой вы хотите перебазировать).
kutschkem указывает, что в контексте GUI mergetool:
- локальные ссылки частично перебазируется совершает: "
ours
" (ветка вверх по течению)- remote относится к входящим изменениям: "
theirs
" - текущая ветвь перед перебазировать.см. иллюстрации в последней части этого ответа.
инверсия при перебазировании
путаница может быть связана с инверсия
ours
иtheirs
во время перебазирования.
(соответствующие выдержки)обратите внимание, что слияние rebase работает путем воспроизведения каждого коммита из рабочей ветви поверх
<upstream>
отделение.из-за этого, когда происходит конфликт слияния:
- сторона сообщила как'
ours
' - это пока что перебазированная серия, начиная с<upstream>
,- и
theirs
- это рабочая ветка. Другими словами, стороны меняются местами.
инверсия иллюстрированное
на слияние
x--x--x--x--x(*) <- current branch B ('*'=HEAD) \ \ \--y--y--y <- other branch to merge
, мы не меняем текущую ветвь 'B', так что у нас есть все еще то, что мы работали дальше (а мы сливаемся из другой ветки)
x--x--x--x--x---------o(*) MERGE, still on branch B \ ^ / \ ours / \ / --y--y--y--/ ^ their
на перебазирование:
но на перебазирование, мы переключаемся на другую сторону, потому что первое, что делает rebase, - это проверка восходящей ветви! (чтобы воспроизвести текущие коммиты поверх него)
x--x--x--x--x(*) <- current branch B \ \ \--y--y--y <- upstream branch
A
git rebase upstream
сначала изменитьHEAD
из B в восходящую ветвьHEAD
(следовательно, переключатель "наш" и " их "по сравнению с предыдущим" текущим" рабочая ветка.)x--x--x--x--x <- former "current" branch, new "theirs" \ \ \--y--y--y(*) <- upstream branch with B reset on it, new "ours", to replay x's on it
, а затем ребаз будет воспроизводить "свои" коммиты на новой "нашей" ветке B:
x--x..x..x..x <- old "theirs" commits, now "ghosts", available through reflogs \ \ \--y--y--y--x'--x'--x'(*) <- branch B with HEAD updated ("ours") ^ | upstream branch
Примечание:понятие"вверх по течению" - это ссылочный набор данных (все РЕПО или, как здесь, ветвь, которая может быть local ветвь), из которой считываются данные или в которую добавляются/создаются новые данные.
'
local
' и 'remote
' и 'mine
' и -theirs
'Pandawood добавляет в комментарии:
для меня все еще остается вопрос, который является "локальным", а кто "удаленным" (поскольку термины "наш" и "их" не используются при перезагрузке в git, ссылаясь на них, похоже, делает ответ более запутанным).
GUI git mergetool
kutschkem добавляет, и это правильно:
когда разрешая конфликты, git скажет что-то вроде:
local: modified file and remote: modified file.
я совершенно уверен, что вопрос направлен на определение местного и удаленного на данный момент. В этот момент мне кажется из моего опыта, что:
- локальные ссылки частично перебазируется совершает: "
ours
" (ветка вверх по течению)- remote относится к входящим изменениям: "
theirs
" - в текущей ветке до перебазирования.
git mergetool
действительно упоминает "локальный" и "удаленный":Merging: f.txt Normal merge conflict for 'f.txt': {local}: modified file {remote}: modified file Hit return to start merge resolution tool (kdiff3):
например, KDiff3 б отображение разрешения слияния так:
и meld б отображать его тоже:
то же самое для VimDiff,что отображает:
вызовите Vimdiff как mergetool с Git mergetool-t gvimdiff. Последние версии Git вызывают Vimdiff со следующим макетом окна:
+--------------------------------+ | LOCAL | BASE | REMOTE | +--------------------------------+ | MERGED | +--------------------------------+
LOCAL
:
Временный файл, содержащий содержимое файла в текущей ветке.BASE
:
Временный файл, содержащий общую базу для слияния.REMOTE
:
Временный файл, содержащий содержимое объединяемого файла.MERGED
:
Файл, содержащий маркеры конфликтов.Git выполнил как можно больше автоматического разрешения конфликтов, и состояние этого файла представляет собой комбинацию обоих
LOCAL
иREMOTE
с маркерами конфликтов, окружающими все, что Git не мог решить сам.
Этотmergetool
следует записать результат разрешения в этот файл.
в нижней строке
git rebase
- местная = базовая ты перебазирования на
- REMOTE = коммиты, которые вы перемещаете наверх
git merge
- LOCAL = исходная ветвь, в которую вы сливаетесь
- REMOTE = другая ветвь, коммиты которой вы объединяете в
другими словами, LOCAL всегда оригинал, и REMOTE всегда есть парень, чьи коммиты не были там раньше, потому что они объединяются или перебазируются сверху
докажи!
конечно. Не верьте мне на слово! Вот простой эксперимент, который вы можете сделать, чтобы увидеть для себя.
во-первых, убедитесь, что у вас есть git mergetool настроен правильно. (Если бы вы этого не сделали, вы, вероятно, не читали бы этот вопрос в любом случае.) Затем найдите каталог для работы.
настройка репозитория:
md LocalRemoteTest cd LocalRemoteTest
создать начальную фиксацию (с пустым файлом):
git init notepad file.txt (use the text editor of your choice) (save the file as an empty file) git add -A git commit -m "Initial commit."
создать фиксацию на ветке, которая не является master:
git checkout -b notmaster notepad file.txt (add the text: notmaster) (save and exit) git commit -a -m "Add notmaster text."
создать фиксацию на главной ветви:
git checkout master notepad file.txt (add the text: master) (save and exit) git commit -a -m "Add master text." gitk --all
на данный момент ваш репозиторий должен выглядеть так:
теперь для теста rebase:
git checkout notmaster git rebase master (you'll get a conflict message) git mergetool LOCAL: master REMOTE: notmaster
теперь тест слияния. Закрыть mergetool без сохранения каких-либо изменений, а затем отменить перебазирование:
git rebase --abort
затем:
git checkout master git merge notmaster git mergetool LOCAL: master REMOTE: notmaster git reset --hard (cancels the merge)
ваши результаты должны быть такими же, как показано наверху.
Я не понял вашу проблему точно, но я думаю, что следующая диаграмма решает вашу проблему. (Rebase: Remote Repository - - - > Workspace)
источник: Мой Рабочий Процесс Git