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
ссылка.
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
следующим причинам:
- Это позволяет вам видеть входящие коммиты восходящего потока, прежде чем вы измените свою историю, чтобы включить их.
- Он позволяет вам передать опцию
-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
. Это пытается перемотать вперед к новым коммитам восходящего потока, но если это невозможно, он перебазирует ваши локальные коммиты на новые коммиты восходящего потока. Обычно это нормально, но будьте осторожны:
- Перебазирование - это сложная тема, и вы должны понимать последствия, прежде чем выполнять ребазирование.
git pull --rebase
не дает вам возможности изучить коммиты перед их включением. В зависимости от того, что изменилось вверх по течению, то вполне возможно , что перебазироваться неправильная операция-а rebase --onto
, merge
, reset
или push -f
может быть более подходящим , чем равнины rebase
.
- Невозможно (в настоящее время) перейти
--preserve-merges
к операции rebase, поэтому любое намеренное слияние ветки функции будет линеаризовано, воспроизводя (и, таким образом, дублируя) все коммиты ветки функции.
«Исправление» существующей фиксации слияния, созданной git pull
Если вы еще не отправили коммит слияния, созданный с помощью git pull
, вы можете переустановить коммит слияния. Предполагая, что вы не сделали никаких намеренных слияний (например, слияния уже загруженной функциональной ветки с вашей текущей веткой), следующее должно сделать это:
git rebase @{u}
Вышеупомянутая команда указывает Git выбрать все коммиты без слияния, доступные из HEAD
(текущий коммит), за вычетом всех коммитов, доступных из @{u}
(что является сокращением для «восходящей ветки», то есть, origin/master
если HEAD
есть master
), воспроизведение (вишневый выбор ) их поверх восходящей ветки, а затем переместите ссылку на текущую ветвь так, чтобы она указывала на результат воспроизведения коммитов. Это эффективно перемещает коммиты без слияния на самую последнюю фиксацию восходящего потока, что устраняет слияние, созданное с помощью git pull
.
Если у вас есть намеренная фиксация слияния, вы не хотите запускать, git rebase @{u}
потому что она будет воспроизводить все из другой ветки. Разобраться с этим случаем значительно сложнее, поэтому его хорошо использовать git up
и git pull
вообще избегать . Вероятно, вам придется использовать reset
для отмены слияния, созданного, pull
а затем сделать git rebase -p @{u}
. -p
Аргумент git rebase
надежно не работает для меня, так что вы могли бы в конечном итоге, чтобы использовать , reset
чтобы отменить преднамеренное слияние, обновить локальную ветвь @{u}
, а затем повторить намеренное слияние (который является болью , если там было много волосатого слияние конфликты).