Github сообщает одному пользователю, что существуют конфликты, но не другой пользователь - PullRequest
1 голос
/ 09 мая 2019

У нас есть хранилище на Github.Один пользователь создал ветку, зарегистрировал ее на Github и создал запрос на получение.Когда он входит в Github и смотрит на пиар, внизу появляется сообщение о том, что конфликтов нет, и этот пиар можно объединить.Для этого есть зеленая кнопка.

Когда я захожу в Github и смотрю на тот же PR, я вижу другое сообщение: «Эта ветка не может быть перебазирована из-за конфликтов. Перебазирование коммитов этой ветки наВершина базовой ветви не может быть выполнена автоматически из-за конфликтов, возникающих при повторном применении отдельных коммитов из головной ветви. "

Почему мы не видим одно и то же?

Есть ли что-то другое?о наших логинах, какой-нибудь вариант конфигурации?

У него могут быть разные опции в его IDE, но это не должно иметь значения.На Github есть только одна версия репо.Он работает на Windows, а я на Mac, но это тоже не должно иметь никакого значения.

Есть ли у меня способ увидеть, какие именно конфликты, прежде чем я попытаюсь выполнить локальную перебазировку?

Ответы [ 2 ]

3 голосов
/ 09 мая 2019

Могут быть конфликты перебазирования и конфликт слияния, если одна ревизия добавляет код, который является генератором конфликтов, а затем другая ревизия возвращает его. Если вы объединитесь, у этой ветви не будет конфликтующего кода ... но если вы переходите от редакции к редакции (как при перебазировке), вам придется иметь дело с конфликтом дважды.

1 голос
/ 09 мая 2019

Как отмечено в комментариях под вопросом, это потому, что GitHub предлагает объединить коммитов для парня, который не видит проблем, но для вас GitHub предлагает rebase коммиты. Иногда слияния являются легкими, а перебазировки - нет.

Вот тривиальный пример серии коммитов, которую можно легко объединить, но не перебазировать. Сначала нарисуем фактический график коммитов:

...--G--H------L   <-- master
         \
          I--J--K   <-- branch

В коммите H файл makeconfict выглядит следующим образом:

This is line 1
This is line 2
This is line 3

В коммите L мы изменили строку 2 на This is line two. Поэтому H -vs- L изменяет строку 2 файла makeconflict (и не вносит никаких других изменений).

Между тем, в коммите I мы удаляем строку 2 файла makeconflict. В коммите J мы вносим полезное изменение в некоторый полезный файл, не касаясь файла makeconflict. В коммите K мы помещаем строку 2 файла makeconflict обратно.

Если мы попытаемся merge зафиксировать K (конец ветви branch) в master, Git сравнит H с L и увидит, что makeconflict изменила строку 2. Он сравнивает H с K: здесь говорится, что с H мы должны изменить строку 2 файла makeconflict, чтобы сохранить изменения, сделанные в master. Затем он сравнивает H с K, чтобы увидеть, что мы сделали. Поскольку мы помещаем строку 2 обратно в K, единственное изменение Git, которое необходимо объединить с изменением makeconflict, - это изменение в важном файле. Таким образом, слияние проходит гладко, изменяя важный файл, и мы получаем:

...--G--H------L--M   <-- master (HEAD)
         \       /
          I--J--K   <-- branch

Если мы попытаемся сделать rebase , Git необходимо скопировать коммит I в новый коммит I', следующий за L:

                 I' [in progress, not actually committed yet]
                /
...--G--H------L   <-- master
         \
          I--J--K   <-- branch

Попытка скопировать I в I' - разница от H до I - говорит, что мы должны удалить строку 2 файла makeconflict, тогда как разница между H и L - это то, что мы должны изменить строку 2 файла makeconflict. Эти два разных изменения конфликтуют друг с другом. Мы должны выбрать, какое изменение сделать: заменить 2 на two или полностью удалить строку?

Если мы полностью удалим строку - что требует ручного вмешательства, а GitHub не сделает этого через веб-интерфейс - мы можем продолжить копирование J в J' и K в K':

                 I'-J'-K'   <-- branch (HEAD)
                /
...--G--H------L   <-- master
         \
          I--J--K   [abandoned]

В этом процессе мы вернули строку 2 файла makeconflict обратно в исходное состояние и все еще в оставленном сейчас коммите K. Таким образом, мы получаем один конфликт слияния (копирование I поверх L для создания I'), и, в сущности, в итоге мы отменяем изменения, сделанные в L. Но как только мы закончим, у нас есть серия коммитов, которые просто добавляются непосредственно к master, так что мы можем продвинуть имя master для коммита K', используя git checkout master; git merge --ff-only branch:

...--G--H------L--I'-J'-K'   <-- branch, master (HEAD)
         \
          I--J--K   [abandoned]

Или, конечно, при обработке конфликта слияния на I' мы можем вместо этого отказаться от наших изменений с I и сохранить изменения L. В конце мы просто пропускаем копирование I полностью. Когда мы копируем commit K для создания K', мы обычно получаем другой конфликт слияния, хотя иногда Git понимает, что коммит K также не требуется. Если мы правильно обработаем конфликт, мы также сбросим K:

                 J'  <-- branch (HEAD)
                /
...--G--H------L   <-- master
         \
          I--J--K   [abandoned]

и снова мы можем теперь перемотать вперед master, чтобы указать, чтобы скопировать J'.

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

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