git rebase, отслеживание "локальных" и "удаленных"


при выполнении git rebase, я часто испытываю трудности с разработкой того, что происходит с "локальным" и "удаленным" при разрешении конфликтов. У меня иногда складывается впечатление, что они меняют стороны от одного коммита к другому.

Это наверное (наверняка), потому что я до сих пор не правильно поняли.

при перебазировании, кто является "локальным", а кто "удаленным"?

(Я использую P4Merge для разрешения конфликтов)

3 139

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 во время перебазирования.
(соответствующие выдержки)

git rebase на странице:

обратите внимание, что слияние 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 б отображение разрешения слияния так:

kdiff3

и meld б отображать его тоже:

Meld diff

то же самое для 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

на данный момент ваш репозиторий должен выглядеть так:

Repository with a base commit and two one-commit branches

теперь для теста 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)

http://assets.osteele.com/images/2008/git-transport.png

источник: Мой Рабочий Процесс Git