У меня есть коллега, который утверждает, что git pull
это вредно, и расстраивается, когда кто-то его использует.
Команда git pull
кажется каноническим способом обновить ваш локальный репозиторий. Использование git pull
создает проблемы? Какие проблемы это создает? Есть ли лучший способ обновить репозиторий git?
git pull --rebase
установить эту стратегию по умолчанию для новых ветокgit config branch.autosetuprebase
--rebase
флаг, чтобыgit pull
синхронизировать локальный с удаленным, а затем воспроизвести ваши локальные изменения поверх обновленного локального. Затем, когда вы нажимаете, все, что вы делаете, это добавление новых коммитов в конец удаленного. Довольно простоОтветы:
Резюме
По умолчанию
git pull
создает коммиты слияния, которые добавляют шум и сложность в историю кода. Кроме того,pull
позволяет легко не думать о том, как на ваши изменения могут повлиять входящие изменения.Эта
git pull
команда безопасна, если она выполняет только быстрое слияние. Еслиgit pull
сконфигурировано только для ускоренного слияния, а ускоренное слияние невозможно, то Git завершит работу с ошибкой. Это даст вам возможность изучить входящие коммиты, подумать о том, как они могут повлиять на ваши локальные коммиты, и выбрать оптимальный порядок действий (слияние, перебазирование, сброс и т. Д.).С Git 2.0 и новее вы можете запустить:
изменить поведение по умолчанию только на ускоренную перемотку вперед. В версиях Git между 1.6.6 и 1.9.x вам придётся набирать привычку:
Однако во всех версиях Git я рекомендую настроить
git up
псевдоним так:и используя
git up
вместоgit pull
. Я предпочитаю этот псевдоним,git pull --ff-only
потому что:origin/*
ветви, которые больше не существуют вверх по течению.Проблемы с
git pull
git pull
Неплохо, если его правильно использовать. Несколько недавних изменений в Git упростилиgit pull
правильное использование , но, к сожалению, поведение равнины по умолчаниюgit pull
имеет несколько проблем:git pull
Эти проблемы более подробно описаны ниже.
Нелинейная история
По умолчанию
git pull
команда эквивалентна выполнению сgit fetch
последующимgit merge @{u}
. Если в локальном репозитории есть невыдвинутые коммиты, часть слиянияgit pull
создает коммит слияния.В коммитах слияния нет ничего плохого по своей сути, но они могут быть опасными и должны рассматриваться с уважением:
Конечно, есть время и место для слияний, но понимание того, когда слияния следует и не следует использовать, может повысить полезность вашего хранилища.
Обратите внимание, что цель Git состоит в том, чтобы упростить совместное использование и использование эволюции кодовой базы, а не точно записывать историю точно в том виде, в каком она была развернута. (Если вы не согласны, рассмотрите
rebase
команду и то, почему она была создана.) Созданные коммиты слиянияgit pull
не передают полезную семантику другим - они просто говорят, что кто-то случайно отправил репозиторий до того, как вы сделали свои изменения. Зачем эти коммиты слияния, если они не имеют смысла для других и могут быть опасны?Можно настроить
git pull
перебазирование вместо слияния, но это также имеет проблемы (обсуждается позже). Вместо этого,git pull
должен быть настроен только для быстрого слияния.Реинтродукция перебазированных комитетов
Предположим, кто-то перебрасывает ветку и силой ее толкает. Как правило, этого не должно происходить, но иногда это необходимо (например, удалить файл журнала размером 50 ГБ, который был случайно обработан и отправлен). Сделанное слияние
git pull
объединит новую версию восходящей ветви со старой версией, которая все еще существует в вашем локальном хранилище. Если вы нажмете результат, вилы и факелы начнут появляться на вашем пути.Некоторые могут утверждать, что настоящая проблема заключается в принудительном обновлении. Да, обычно желательно избегать толчков, когда это возможно, но иногда они неизбежны. Разработчики должны быть готовы справиться с принудительными обновлениями, потому что они иногда случаются. Это означает, что нельзя слепо объединять старые коммиты с помощью обычных
git pull
.Изменения в рабочем каталоге Surprise
Нет способа предсказать, как будет выглядеть рабочий каталог или индекс, пока не
git pull
будет сделано. Могут возникнуть конфликты слияния, которые вам нужно разрешить, прежде чем вы сможете что-либо сделать, это может привести к появлению файла журнала 50 ГБ в вашем рабочем каталоге, потому что кто-то случайно его нажал, он может переименовать каталог, в котором вы работаете, и т. Д.git remote update -p
(илиgit fetch --all -p
) позволяет вам просматривать коммиты других людей, прежде чем вы решите объединить или изменить их, что позволит вам сформировать план перед принятием мер.Трудность рассмотрения других людей
Предположим, вы находитесь в процессе внесения некоторых изменений, и кто-то еще хочет, чтобы вы просмотрели некоторые коммиты, которые они только что выдвинули.
git pull
Операция слияния (или перебазирования) изменяет рабочий каталог и индекс, что означает, что ваш рабочий каталог и индекс должны быть чистыми.Вы можете использовать
git stash
и тогдаgit pull
, но что вы будете делать, когда закончите рецензирование? Чтобы вернуться туда, где вы были, вы должны отменить созданное слияниеgit pull
и применить тайник.git remote update -p
(илиgit fetch --all -p
) не изменяет рабочий каталог или индекс, поэтому его можно безопасно запускать в любое время, даже если вы вносили и / или не ставили изменения. Вы можете приостановить то, что вы делаете, и просмотреть коммит другого, не беспокоясь о сохранении или завершении коммита, над которым вы работаете.git pull
не дает вам такой гибкости.Перебазирование на удаленную ветку
Распространенный шаблон использования Git - сделать,
git pull
чтобы внести последние изменения, после чегоgit rebase @{u}
следует исключитьgit pull
введенный коммит слияния . Это общепринятая достаточно того, что Git имеет некоторые параметры конфигурации , чтобы уменьшить эти два шага за один шаг, рассказавgit pull
выполнить перебазирования вместо слияния (смbranch.<branch>.rebase
,branch.autosetuprebase
иpull.rebase
варианты).К сожалению, если у вас есть невыгруженный коммит слияния, который вы хотите сохранить (например, коммит, сливающий ветку выдвинутого объекта в
master
), ни rebase-pull (git pull
сbranch.<branch>.rebase
установленным значениемtrue
), ни merge-pull (git pull
поведение по умолчанию ), за которым следует ребаз будет работать. Это потому, чтоgit rebase
исключает слияния (линеаризует DAG) без--preserve-merges
опции. Операция rebase-pull не может быть сконфигурирована для сохранения слияний, и pull-merge, сопровождаемыйgit rebase -p @{u}
not, не устранит слияние, вызванное merge-pull. Обновление: добавлен Git v1.8.5git pull --rebase=preserve
иgit config pull.rebase preserve
. Этоgit pull
нужно делатьgit rebase --preserve-merges
после получения вышестоящих коммитов. (Спасибо фанкастеру за хедз-ап!)Очистка удаленных веток
git pull
не удаляет удаленные ветви отслеживания, соответствующие ветвям, которые были удалены из удаленного репозитория. Например, если кто-то удалит веткуfoo
из удаленного репо, вы все равно увидитеorigin/foo
.Это приводит к тому, что пользователи случайно воскрешают убитые ветки, потому что считают, что они все еще активны.
Лучшая альтернатива: используйте
git up
вместоgit pull
Вместо этого
git pull
я рекомендую создать и использовать следующийgit up
псевдоним:Этот псевдоним загружает все последние коммиты из всех вышестоящих ветвей (обрезка мертвых веток) и пытается перемотать локальную ветвь до последней фиксации в вышестоящей ветке. В случае успеха локальных коммитов не было, поэтому не было риска конфликта слияния. Перемотка вперед завершится неудачей, если будут локальные (не выдвинутые) коммиты, что даст вам возможность просмотреть восходящие коммиты перед выполнением действия.
Это все еще изменяет ваш рабочий каталог непредсказуемым образом, но только если у вас нет локальных изменений. В отличие от этого
git pull
,git up
вы никогда не будете получать подсказки, ожидающие, что вы исправите конфликт слияния.Другой вариант:
git pull --ff-only --all -p
Следующее является альтернативой вышеуказанному
git up
псевдониму:Эта версия
git up
имеет то же поведение, что и предыдущийgit up
псевдоним, за исключением:-p
аргумент, который передаетсяfetch
), которая может измениться в будущих версиях GitЕсли вы используете Git 2.0 или новее
С Git 2.0 и новее вы можете настроить
git pull
по умолчанию только ускоренное слияние:Это приводит к тому ,
git pull
чтобы действовать какgit pull --ff-only
, но он все еще не извлечь все добывающие фиксации или очистить старыеorigin/*
ветви , так что я до сих пор предпочитаюgit up
.источник
git remote update -p
эквивалентноgit fetch --all -p
. Я имею привычку печатать,git remote update -p
потому что когда-тоfetch
не было-p
возможности. По поводу ведущих!
смотрите описаниеalias.*
вgit help config
. В нем говорится: «Если расширение псевдонима начинается с восклицательного знака, оно будет рассматриваться как команда оболочки».pull.ff
конфигурацию, которая, кажется, достигает того же самого, без псевдонимов.git up
звучит как интересная альтернатива.git pull
.Мой ответ, извлеченный из обсуждения, которое возникло на HackerNews:
Я чувствую соблазн просто ответить на вопрос, используя Закон Заголовков Betteridge: Почему это
git pull
считается вредным? Это не так.источник
git pull
. Тем не менее, это может противоречить некоторым вредным практикам, таким как желание переписать историю больше, чем это строго необходимо. Но git гибок, поэтому, если вы хотите использовать его по-другому, сделайте это любым способом. Но это потому, что вы (ну, @Richard Hansen) хотите сделать что-то необычное в git, а не потому, чтоgit pull
это вредно.git rebase
и считаютgit pull
вредным? В самом деле?git pull
без--rebase
опции - это направление слияния, которое оно создает. Когда вы смотрите на различия, все изменения в этом слиянии теперь принадлежат человеку, который потянул, а не тому, кто внес изменения. Мне нравится рабочий процесс, в котором объединение зарезервировано для двух отдельных ветвей (A -> B), поэтому коммит слияния понятен, что было введено, а перебазирование зарезервировано для получения обновлений в одной и той же ветви (удаленный A -> локальный A). )Это не считается вредным, если вы используете Git правильно. Я вижу, как это негативно влияет на вас, учитывая ваш вариант использования, но вы можете избежать проблем, просто не изменяя общую историю.
источник
git pull
это не проблема. Ветвление в git это дешево.Принятые ответы на претензии
но с Git 1.8.5 , который датирует этот ответ, вы можете сделать
или
или
В документах говорят
Это предыдущее обсуждение содержит более подробную информацию и диаграммы: git pull --rebase --preserve-merges . Это также объясняет, почему
git pull --rebase=preserve
это не то же самоеgit pull --rebase --preserve-merges
, что неправильно.Это другое предыдущее обсуждение объясняет, что на самом деле делает вариант rebase с сохранением-слиянием, и как оно намного сложнее, чем обычное rebase: что именно делает git «rebase --preserve-merges» (и почему?)
источник
Если вы зайдете в старый репозиторий git, вы увидите, что псевдоним, который они предлагают, отличается. https://github.com/aanand/git-up
git config --global alias.up 'pull --rebase --autostash'
Это прекрасно работает для меня.
источник