Почему git допускает только быстрое слияние при нажатии? - PullRequest
0 голосов
/ 26 апреля 2020

Итак, я знаю, что когда вы делаете git push, git пытается интегрировать изменения из вашей локальной ветки в соответствующую удаленную ветку. Однако, если ветви разошлись, git не позволит вам набрать sh, сказав

подсказка: обновления были отклонены, поскольку на удаленном компьютере есть работа, которой у вас нет локально.

Когда пользователь успешно нажимает, он ожидает, что удаленная ветвь, которую он только что нажал, отражает его собственную. Если мы допустим трехстороннее слияние при нажатии (только если нет конфликтов), тогда удаленная ветвь явно не будет соответствовать его собственной, поскольку она фиксирует нашу локальную копию, о которой не знает, а также коммит слияния. Однако разве git не может просто сделать пул после пу sh, если для этого требуется слияние в 3 направления? Каковы недостатки в разрешении трехстороннего слияния при толчке таким образом, и почему создатели Git решили разрешить только быстрые коммиты?

Вот диаграмма, иллюстрирующая ситуацию: https://imgur.com/a/800v5Eq

Ответы [ 3 ]

1 голос
/ 26 апреля 2020

Причина в том, что перезапись пульта без принудительной операции pu sh приведет к потере данных, а другие действия, такие как автоматическое выполнение слияния, будут удивительными и трудно рассуждать.

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

Кроме того, для случая, когда Пользователь действительно хочет текущее поведение, тогда для него все равно должна быть опция, а также опция перезаписи текущей ветви, поскольку последняя полезна при перебазировании. Таким образом, вместо двух опций (обычного и принудительного толчков) их должно быть три.

Наконец, в некоторых рабочих процессах нельзя иметь sh для фиксации слияния и выполнения слияние создаст нежелательную нелинейную историю. Точно так же, даже если кто-то использует рабочий процесс на основе слияний, часто требуются дополнительные коммиты слияния (например, слияния от master), и пользователи будут недовольны, обнаружив, что они неожиданно испортили свою историю.

1 голос
/ 26 апреля 2020

Потому что по определению на удаленной (онлайн) копии git, которую вы нажимаете, «никого нет дома». Поэтому, если есть проблема (конфликт), кто и как ее решит?

Если вы используете GitHub или аналогичный, однако, есть способ обойти это: сделать запрос на извлечение. Таким образом, существует интерфейс для решения проблем на сервере , и поэтому запрос на извлечение может выполнить любое объединение.

0 голосов
/ 26 апреля 2020

Как вы заметили, факт в том, что git push никогда не объединяется. (Другой способ выразить это - я думаю, возможно, лучший - это то, что «быстрое слияние» Git вовсе не является слиянием.)

Как заметил Мэтт когда вы используете функцию запроса на извлечение в GitHub, 1 GitHub делает доступным для человека, работающего с целевым репозиторием, метод с одним нажатием кнопки, чтобы действительно выполнить слияние с помощью коммитов, которые вы git push - Ed, при условии, что это слияние может быть сделано автоматически. Но git push никогда даже не проверяет, возможно ли слияние: он просто говорит, что слияние или какое-то другое действие потребуется , чтобы добавить новые коммиты в целевой репозиторий без потери некоторого коммита. (s) из целевой ветви.

Определение fast-forward : 2

  • Let C старый будет коммитом ha sh ID, идентифицируемый в настоящее время по имени N .
  • Let C new будет коммитом га sh ID, который вы предлагаете N должен идентифицировать.
  • Операция ускорена, если и только если C old C новый .

Этот забавный символ ≼ (Юникод ПРЕДВАРИТЕЛЬНЫЙ ИЛИ РАВНЫЙ, U + 227 c ), который выглядит как соблазнительный знак меньше или равный - это то, что тестирует Git команда git merge-base --is-ancestor, т. е. что ha sh ID старого коммита является предшественником или таким же коммитом, как, новый коммит. Иными словами, старый коммит все равно будет достижимым от нового коммита: см. Думайте как (а) Git.

Коммиты слияния имеют специфическое свойство иметь более одного родительского коммита ha sh ID, что делает доступным более одного подграфа общего коммита DAG . Следовательно, простой способ сохранить доступность некоторого старого подграфа при добавлении нового фрагмента графа - добавить коммит слияния. Команда git merge может добавить такой коммит, но в процессе она делает что-то полезное с тремя коммитами снимков , которые являются входными данными для слияния.

As bk2204 отмеченные , git push могут обнаружить сбой pu sh и автоматически вызвать git fetch и git merge на вашем конце. Вы можете написать сценарий самостоятельно, чтобы сделать то же самое. Но это не всегда правильно, поэтому потребуется еще больше ручек настройки. Я сам придерживаюсь мнения, что git pull, который запускает выборку и затем слияние для вас, уже делает слишком много, и что такая ручка управления для git push будет далеко слишком много.

В любом случае, вы могли бы написать это сами. (Возможно, это помогло бы, если бы git push зарезервировал определенный статус выхода для «отклонено из-за отсутствия ускоренной перемотки вперед», но здесь есть еще одна проблема: вы можете git push несколько имен в одном go, и могут иметь некоторые успехи, а другие - неудачи, каждая по разным причинам.) Не стесняйтесь написать это самостоятельно - в конце концов, Git - это большой набор инструментов, а не одно конкретное c решение, но помните, что некоторые слияния заканчиваются конфликтами слияния. Ваша команда должна ограничить внутренний шаг pu sh только pu sh только текущей веткой .


1 Это действительно GitHub функция, не является частью базы Git. Другие веб-хостинги предоставляют функцию с тем же именем и очень похожей операцией. Очевидно, есть сильное желание этого. Но у Git его по-прежнему нет, по крайней мере по техническим причинам. В частности, кто должен быть автором и инициатором коммита слияния? GitHub ответит: подождите, пока кто-то не нажмет кнопку, затем используйте информацию этого человека . Этим человеком обычно является , а не человек, который первым сделал запрос на получение ответа, но часто также не один конкретный человек: может быть, целой группе людей разрешено утверждать PR. В любом случае, всегда есть человек в 1125 *.

2 Ну, это определение a . Есть и другие эквивалентные, которые вы могли бы сформулировать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...