Каков точный смысл "наших" и "их" в git?

Это может звучать как слишком простой вопрос, но я искал ответы, и теперь я больше смущен, чем раньше.

Что означает "наш" и "их" в git при слиянии моей ветки с моей другой ветвью? Обе ветки "наши".

В конфликте слиянием всегда "наш" отображается верхняя из двух версий?

Всегда ли "наш" относится к ветке, на которую указывал HEAD, когда началось слияние? Если да, то почему бы не использовать ясную притяжательную ссылку, такую ​​как "текущая ветвь", вместо того, чтобы использовать притяжательное местоимение, подобное "нашему", которое на самом деле неоднозначно (поскольку обе ветки технически наши)?

Или просто используйте название ветки (вместо того, чтобы говорить "наши", просто скажите "локальный хозяин" или такой)?

Самая запутанная часть для меня - если я укажу в конкретном файле .gitattributes ветки. Предположим, что в ветке тестирования у меня есть следующий файл .gitattributes:

config.xml merge=ours

Теперь я проверяю и нажимаю HEAD на master, затем сливаюсь в test. Поскольку master является нашим, а test.gitattributes не проверяется, будет ли он даже иметь эффект? Если это имеет эффект, так как master теперь "наш", то что будет?

Ответ 1

Я подозреваю, что вы здесь смущены, потому что это принципиально сбивает с толку. Чтобы все ухудшилось, весь наш/их материал переключает роли (становится обратным), когда вы делаете rebase.

В конечном счете, во время git merge ветка "наш" относится к ветке, в которую вы сливаетесь:

git checkout merge-into-ours

а ветка "их" относится к единственной ветки, которую вы объединяете:

git merge from-theirs

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

При использовании фактического имени ветки может быть довольно круто, оно разваливается в более сложных случаях. Например, вместо вышесказанного вы можете:

git checkout ours
git merge 1234567

где вы объединяетесь с помощью raw commit-ID. Хуже того, вы можете это сделать:

git checkout 7777777    # detach HEAD
git merge 1234567       # do a test merge

в этом случае не задействованы имена ветвей!

Я думаю, что это немного помогает здесь, но на самом деле, в gitrevisions синтаксисе, вы можете ссылаться на отдельный путь в индексе на число во время конфликта слияния

git show :1:README
git show :2:README
git show :3:README

Этап №1 является общим предком файлов, этап №2 - это версия для целевой ветки, а этап № 3 - это версия, из которой вы сходите.


Причина, по которой "наши" и "их" понятия обмениваются вокруг во время rebase, заключается в том, что rebase работает, выполняя серию вишневых кусков, в анонимную ветку (отдельный режим HEAD). Целевая ветка - анонимная ветвь, а ветка слияния - это ваш исходный (pre-rebase) ветвь: так что "--ours" означает, что анонимная rebase строится, а "- theirs" означает "наша ветка переустанавливается",.


Что касается записи gitattributes: это может иметь эффект: "наш" действительно означает "использовать этап №2" внутри. Но, как вы заметили, на самом деле это не на самом деле в то время, поэтому он не должен иметь эффекта здесь... ну, если вы не скопируете его в дерево работы, прежде чем начать.

Кроме того, кстати, это относится ко всем видам использования наших и их, но некоторые из них находятся на уровне всего файла (-s ours для стратегии слияния; git checkout --ours во время конфликта слияния), а некоторые - на части (-X ours или -X theirs в течение слияния -s recursive). Который, вероятно, не помогает с путаницей.

Я никогда не придумал лучшего имени для них. И: см. ответ VonC на другой вопрос, где git mergetool вводит еще больше имен для них, называя их "local" и "remote"!

Ответ 2

" наш" в Git относится к исходной рабочей ветке, которая имеет авторитетную/каноническую часть истории Git.

" их" относится к версии, которая содержит работу, чтобы быть rebased (изменения, которые нужно переименовать в текущую ветку).

Возможно, это может быть заменено на людей, которые не знают, что делать перезагрузку (например, git rebase) на самом деле задерживает вашу работу (которая является их собственностью) для воспроизведения на канонической/основной истории, которая является нашей, потому что мы перестраиваем наши изменения как сторонние работы.

Документация для git-checkout была дополнительно уточнена в Git >= 2.5.1 согласно f303016 commit:

--ours --theirs

При проверке путей из индекса проверьте этап №2       ('ours') или # 3 ('theirs') для несвязанных путей.

Обратите внимание, что во время git rebase и git pull --rebase, 'ours' и 'theirs' могут быть заменены; --ours дает версию из ветки, на которую переупорядочиваются изменения, а --theirs дает версию из ветки, которая содержит вашу работу, которая перестраивается.

Это связано с тем, что rebase используется в рабочем процессе, который рассматривает историю на удаленном компьютере как общую каноническую, и рассматривает работу, выполненную в ветки, которую вы перестраиваете, в качестве сторонней работы, которая должна быть интегрирована, и вы временно берут на себя роль хранителя канонической истории во время перебазирования. Как хранитель канонической истории, вам нужно просмотреть историю с удаленного как ours (т.е. "Наша общая каноническая история" ), а то, что вы делали на своей боковой ветки как theirs (то есть "один вкладчик работает над вверху" ).

Для git-merge это объясняется следующим образом:

наша

Этот параметр заставляет конфликтующие куски быть автоматически разрешенными, пользуясь нашей версией. Изменения от другого дерева, которые не конфликтуют с нашей стороной, отражаются на результате слияния. Для двоичного файла все содержимое берется с нашей стороны.

Это не следует путать с нашей стратегией слияния, которая даже не смотрит на то, что содержит другое дерево. Он отбрасывает все, что делал другое дерево, заявляя, что наша история содержит все, что произошло в нем.

их

Это противоположность нашей.

Далее, здесь объясняется, как их использовать:

Механизм слияния (git merge и git pull) позволяет выбирать стратегии объединения бэкэнда с опцией -s. Некоторые стратегии также могут принимать свои собственные параметры, которые могут быть переданы с помощью аргументов -X<option> для git merge и/или git pull.


Поэтому иногда это может сбивать с толку, например:

  • git pull origin master где -Xours является нашей локальной, -Xtheirs является их (удаленной) веткой
  • git pull origin master -r где -Xours является их (удаленным), -Xtheirs является нашим

Итак, второй пример противоположный первому, потому что мы переставляем нашу ветку поверх удаленного, поэтому наша стартовая точка - удаленная, и наши изменения рассматриваются как внешние.

Аналогично для стратегий git merge (-X ours и -X theirs).