Почему слияние git создает коммит в исходной ветке - PullRequest
0 голосов
/ 31 марта 2020

Я пытаюсь объединить изменения из ветки патча в основную. Это сообщение, которое я вижу в github:

kewp wants to merge 36 commits into patch/SEO_prices_pages from development

Когда я нажимаю, чтобы разрешить конфликты, это сообщение, которое я вижу

Resolving conflicts between development and patch/SEO_prices_pages and committing changes development

Почему коммит фиксируется в development? Я пытаюсь обновить ветку патча с изменениями разработки ...

1 Ответ

0 голосов
/ 31 марта 2020

В вопросе есть основной c недостаток:

Почему при объединении git создается коммит в ветви источника

Это не так. Git Концентратор , с другой стороны ...

Здесь важно определить термины и очень четко различать guish между тем, что Git делает, и что GitHub делает. GitHub не Git! GitHub будет хост Git репозиторий для вас, а затем они добавят свои собственные функции, чтобы вы могли использовать их услуги (вместо некоторых конкурентов). Поэтому, когда вы используете надстройки GitHub, они вполне могут делать то, чего не делает сама Git. (Если вам нравятся эти вещи, GitHub преуспевает: помните, их цель - заставить вас использовать их и, в конечном итоге, заставить вас или кого-то еще платить им.)

setup

[GitHub сообщает мне] kewp wants to merge 36 commits into patch/SEO_prices_pages from development [но есть конфликты слияния]

Я предполагаю, что kewp это you и development - это имя, которое вы дали GitHub, когда отправляли некоторые коммиты со своего ноутбука / настольного компьютера / любого компьютера в хранилище на GitHub. Затем вы использовали веб-интерфейс GitHub для генерации GitHub Pull Request (PR), используя ваш development в качестве ветви слияния и patch/SEO_price_pages в качестве ветви слияния, все в одном репозитории на GitHub (так что нет здесь используется дополнительная информация о GitHub).

GitHub PR не является слиянием Git. Однако то, что делает GitHub, когда вы нажимаете кнопки «make PR», включает попытку a git merge в Git хранилище, хранящемся на GitHub. Эта попытка может быть успешной или неудачной. Если это удастся, результирующий коммит слияния можно найти в Git на GitHub; в противном случае такой коммит слияния не будет.

GitHub PR присваивается номер, уникальный для этого репозитория на GitHub. (Это число, которое является глобальным для всех операций в этом репозитории: проблемы и PR совместно используют пространство номеров, поэтому в репозитории, в котором еще нет активности, если вы создадите несколько десятков проблем до создания любых PR, первый PR будет иметь два -di git число.) Этот номер становится Git пространством имен вида refs/pull/<em>number</em>. В этом пространстве имен GitHub создает одно или два имени:

  • refs/pull/<em>number</em>/head относится к tip commit ветви, которую вы просили объединить из ; и
  • refs/pull/<em>number</em>/merge, если он существует, ссылается на коммит слияния , который GitHub успешно сделал.

Этот коммит слияния (пока) не любая ветка. Если он существует, он существует в репозитории Git на GitHub и доступен под именем merge, но фраза commit C находится на ветви B в Git, как правило, интерпретируется означает, что коммит C является достижимым из кончика коммита ветви B .

(Подробнее о достижимости см. Think Like (a ) Git.)

Опять же, если попытка слияния не удалась, здесь нет слияния. Поскольку в вашем случае были конфликты слияния, есть имя refs/pull/<em>number</em>/head, но нет имени refs/pull/<em>number</em>/merge.

Как работает слияние на вашем ноутбуке

Когда вы используете Git на своем ноутбуке, вы можете выполнить слияние следующим образом:

git checkout patch/SEO_prices_pages
git merge development

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

git merge --continue

, чтобы возобновить (и на этот раз sh) объединение. Результатом является новый коммит. Новый коммит включен - и находится на кончике - ветви, которую вы извлекли, то есть patch/SEO_prices_pages. Ветка, которую вы назвали в своей команде git merge, т.е. , development, полностью неизменен: это имя по-прежнему содержит тот же коммит, который х sh он держал до того, как вы начали все это.

Процесс разрешения слияния произошел в индексе Git, но ваше помочь почти наверняка использовать ваши файлы в вашем рабочем дереве: команды, не являющиеся Git вашего компьютера не могут использовать файлы, включенные в индекс Git, так как они находятся в специальном, сжатый, Git -только формат. Чтобы использовать индексный файл, вы должны скопировать его куда-нибудь (обычно с git checkout или git checkout-index), затем поработать с ним там, а затем скопировать обратно поверх старого индексного файла (обычно с git add).

У последнего коммита есть два родителя: его первым родителем является коммит, который был вершиной patch/SEO_prices_pages, на мгновение go, а вторым родителем является коммит, который все еще Это верхушка development.

Как разрешение конфликтов работает на GitHub

Репозитории Git на GitHub не имеют рабочего дерева. (У каждого есть индекс, но он в основном просто рудиментарный.) Это означает, что обычные инструменты просто недоступны.

То, что предлагает GitHub, по крайней мере сегодня, является своего рода уловкой. Они сохраняют некоторую информацию о конфликте где-то - есть только один индекс, и может быть несколько PR «в полете», поэтому не совсем ясно, , где , хотя Git имеет возможность использовать альтернативу index, так что, возможно, для каждого PR есть индекс, хотя я бы и не догадывался - но поскольку нет рабочего дерева, нет места, чтобы просто отредактировать файл и затем git add его снова.

Вместо этого, GitHub делает, когда вы используете их инструмент разрешения конфликтов: делает больше коммитов . Они могут совершать эти коммиты, продвигая refs/pull/<em>number</em>/head ref, и я думаю, что в конечном итоге они делают продвигают его, но согласно своей информационной странице , они добавляют новый коммит, который использует файлы коммитов tip вашей ветки PR в качестве отправной точки, но вносит изменения, которые приведут к конфликту git merge , а не , к вашей ветке .

В данном случае это означает, что они:

  • извлекают файлы из коммита на кончике вашего репозитория on-GitHub-repo development;
  • позволяют вам вносить изменения в каждый из файлов, которые имеют конфликты, так что, если бы это было сделано в качестве нового коммита на вашем development, эти файлы больше не имели бы конфликтов слияния с файлами в коммите tip из patch/SEO_prices_pages ;
  • позволяет вам добавить этот коммит к вашему репозиторию on-GitHub.

Это эквивалентно тому, что вы на своем ноутбуке делаете:

git checkout development

(Примечание: предполагается, что ваш development соответствует вашему GitHub's development!), А затем:

<edit each file that had conflicts>
<git add each such file>
git commit
git push origin development

за исключением того, что, делая это напрямую с репозиторием GitHub, вы не получаете коммит на своем ноутбуке (пока).

Сейчас что ваш репозиторий GitHub development имеет новый коммит, GitHub может попробовать git merge снова. На этот раз слияние будет успешным, и они смогут создавать refs/pull/<em>number</em>/merge.

Дополнительные заметки о странностях GitHub

Когда вам действительно разрешено объединяться на GitHub, вы увидите, что зеленый Кнопка «объединить» имеет выпадающую стрелку. Используя выпадающий список, вы увидите, что есть три варианта:

  • объединить
  • перебазировать и объединить
  • squa sh и объединить

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

Второй копирует каждого будущего коммит с новыми коммитами, которые расширяют целевую ветвь. GitHub делает это, даже если коммиты для слияния уже находятся в правильном положении, графически, для быстрой пересылки. (Я нахожу это противным самому: они должны просто перемотать вперед.)

Последний из них эквивалентен запуску git checkout <target>; git merge --squash .... Вероятно, он использует дерево из существующего слияния, запустив git commit-tree на GitHub, но эффект тот же.

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