Ответ 1
git pull
, вероятно, создает коммит. Если вы сделаете локальную фиксацию, а затем запустите git pull
, после того как кто-то еще нажат на фиксацию до репозитория, Git загрузит другую команду разработчика, а затем объединит ее в вашу локальную ветвь.
Как избежать этих слияний в будущем
Вы можете использовать git pull --rebase
, чтобы это не происходило в будущем, но перезагрузка имеет свои опасности, а Я рекомендую вообще избегать pull
.
Вместо этого я рекомендую вам следовать этому шаблону использования:
# download the latest commits
git remote update -p
# update the local branch
git merge --ff-only @{u}
# if the above fails with a complaint that the local branch has
# diverged:
git rebase -p @{u}
Объяснение
-
git remote update -p
загружает все коммиты в удаленных репозиториях и обновляет ветки удаленного отслеживания (например,origin/master
). Это НЕ касается вашего рабочего каталога, индекса или локальных ветвей.Аргумент
-p
отключает дочерние ветки. Таким образом, если ветвьfoo
удаляется в репозиторииorigin
,git remote update -p
автоматически удалит вашorigin/foo
ref. -
git merge --ff-only @{u}
сообщает Git объединить ветвь вверх по течению (аргумент@{u}
) в вашу локальную ветвь, но только если ваша локальная ветка может быть "переадресована" в ветвь вверх по течению (другими словами, если он не расходился). -
git rebase -p @{u}
эффективно перемещает сделанные вами коммиты, но еще не нажал поверх верхней ветки, что устраняет необходимость создания глупых слияний, которые вы пытаетесь избежать. Это улучшает линейность истории разработки, что упрощает обзор.Опция
-p
сообщает Git сохранять слияния. Это предотвращает Git от линеаризации переустановленных коммитов. Это важно, если, например, вы объединили ветвь функции вmaster
. Без-p
каждая фиксация в ветки признака будет дублироваться наmaster
как часть линеаризации, сделаннойgit rebase
. Это упростило бы историю разработки, а не проще.Остерегайтесь:
git rebase
может не делать то, что вы ожидаете от него, поэтому просмотрите результаты перед нажатием. Например:git log --graph --oneline --decorate --date-order --color --boundary @{u}..
Я предпочитаю этот подход по git pull --rebase
по следующим причинам:
- Он позволяет видеть, что входящий upstream совершает, прежде чем изменять свою историю, чтобы включить их.
- Это позволяет вам передать параметр
-p
(--preserve-merges
) вgit rebase
, если вам нужно переустановить намеренное слияние (например, слияние уже перенесенной ветки функции вmaster
).
Сокращение: git up
вместо git pull
Чтобы сделать это легко, я рекомендую создать псевдоним up
:
git config --global alias.up '!git remote update -p; git merge --ff-only @{u}'
Теперь все, что вам нужно сделать, чтобы обновить ваш филиал, можно запустить:
git up
вместо git pull
. Если вы получили сообщение об ошибке, потому что ваша локальная ветка отклонилась от ветки вверх по течению, то ваш реквизит для переадресации.
Почему бы не git pull --rebase
?
Запуск git pull --rebase
эквивалентен запуску git fetch
, за которым следует git rebase
. Это пытается ускорить переходы на новые восходящие коммиты, но если это невозможно, это приведет к переустановке ваших локальных коммитов на новые восходящие коммиты. Обычно это нормально, но будьте осторожны:
- Rebase - это расширенная тема, и вы должны понимать последствия перед перезагрузкой.
-
git pull --rebase
не дает вам возможности изучить коммиты до их включения. В зависимости от того, что изменилось вверх по течению, вполне возможно, что rebase является неправильной операцией -rebase --onto
,merge
,reset
илиpush -f
могут быть более подходящими, чем простойrebase
. - В настоящее время невозможно передать
--preserve-merges
операции переадресации, поэтому любое преднамеренное объединение ветки признака будет линеаризовано, воспроизведение (и, таким образом, дублирование) завершает работу всей ветки функции.
"Фиксация" существующего слияния, созданного git pull
Если вы еще не нажали фиксацию слияния, созданную git pull
, вы можете переустановить фиксацию слияния. Предполагая, что вы не сделали каких-либо намеренных слияний (например, слияние уже вложенной ветки функции в вашу текущую ветку), следующее должно сделать это:
git rebase @{u}
Приведенная выше команда сообщает Git, чтобы выбрать все коммиты не-слияния, достижимые из HEAD
(текущая фиксация), за вычетом всех достижимых достижений из @{u}
(что является сокращением для "восходящей ветки", т.е. origin/master
, если HEAD
- master
), повторите (вишневый) их поверх ветки вверх по течению, а затем переместите текущую ссылку на ветку, чтобы указать на результат повторения коммитов. Это эффективно перемещает нечеткие коммиты на самую последнюю команду upstream, которая устраняет слияние, созданное git pull
.
Если у вас есть намеренное объединение слиянием, вы не хотите запускать git rebase @{u}
, потому что он будет воспроизводить все из другой ветки. Работа с этим случаем существенно сложнее, поэтому полезно использовать git up
и вообще избегать git pull
. Вероятно, вам придется использовать reset
, чтобы отменить слияние, созданное с помощью pull
, а затем сделать git rebase -p @{u}
. Аргумент -p
для git rebase
не работал надежно для меня, поэтому вам может понадобиться использовать reset
, чтобы отменить намеренное слияние, обновить локальную ветвь до @{u}
, а затем повторить преднамеренное слияние ( которая является болью, если было много волосатых конфликтов слияния).