Другой разработчик отправил свои изменения в удаленный репозиторий, и когда я хочу их отправить, я получаю следующую ошибку:
error: failed to push some refs to 'xxx@yyy'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
Как я могу загрузить свои изменения?
Резюме (при условии, что вы находитесь в
master
):Если вы не против создать коммит слияния, то этого достаточно:
Если вы предпочитаете избегать фиксации слияния:
Объяснение
В git коммит — это состояние всего репозитория в данный момент времени. Также у каждого разработчика есть копия всего и (если они используют что-то вроде github ) есть центральный репозиторий. В этом сценарии все разработчики
git pull
обращаютсяgit push
к центральному репозиторию, и это единственный удаленный репозиторий. Итак, давайте представим, что изначально состояние вашего удаленного репозитория:и это вы сделали
git pull
без проблем. Ваш локальный репозиторий имеет точно такой же контент, как и удаленный репозиторий.Вы работаете счастливо, но Мартин (еще один разработчик в команде) работает
git push
... поэтому статус удаленного репозитория становится таким:вы заканчиваете работу над ошибкой, которую вы исправляете, и делаете
git commit
... в этот момент в вашем локальном репозитории у вас есть следующее:пока все идеально... но когда вы это сделаете
git push
, произойдет сбой с сообщением об ошибке вопроса. Это происходит потому, что git не знает, что делать с коммитом 4... он должен быть после коммита 2, но в удаленном репозитории это 3 после 2.общая версия
Один из вариантов сделать:
Что это делает, так это переносит изменения из удаленного репозитория на ваш компьютер и пытается выполнить слияние. Если конфликтов нет, окончательный статус в вашей команде выглядит следующим образом:
следующий шаг — загрузить ваши изменения на пульт, выполнив:
и если надоедливый Мартин не загрузил другое изменение, то все будет нормально. Если это не удается по той же причине, просто повторите процедуру.
Версия отряда против слияния
Некоторым из нас не нравится иметь много коммитов слияния. Почему? потому что они не добавляют информацию. К счастью, для таких сумасшедших, как я, есть способ сделать почти то же самое, но более аккуратно.
Сначала мы запускаем:
git fetch
извлекать изменения с удаленного компьютера, но не касаясь веток ... как только вы это сделаетеgit fetch
, в вашем репозитории останется вот что:это означает, что:
master
(ветвь, над которой вы обычно работаете) по-прежнему указывает на ваш коммитorigin/master
) указывает на фиксацию 3Итак... волшебный шаг:
когда вы пишете это, git останавливается на
origin/master
(коммит 3) и повторяет изменения, сделанные в коммите 4. Если конфликтов нет , вывод будет следующим:важно отметить, что больше нет фиксации 4... у нас есть фиксация 5, которая "почти почти" похожа на 4, но отличается (поскольку она указывает на фиксацию 3, у нее есть другой родитель... и этого достаточно чтобы он был другим).
если есть конфликты, вам придется их исправить (консоль сообщит вам, какие файлы следует исправить), добавить их (используя
git add
) и, наконец, продолжить перебазирование (используяgit rebase --continue
).Наконец, необходимо загрузить изменения на пульт (это то, что вы хотели сделать с первого момента, верно?). Для этого:
И готово!
Конфликты существуют и будут существовать всегда (независимо от того, делаете ли вы коммит слияния или нет). Лично я предпочитаю избегать коммитов слияния любой ценой.
И я оставлю вас с одним последним изображением, чтобы вы могли понять, почему было бы неплохо избегать коммитов слияния... без коммитов слияния структура ветвей становится намного яснее:
Графика была сделана с помощью draw.io и доступна здесь .