Может ли "git pull" автоматически прятать и высовывать ожидающие изменения?
Я знаю, как решить это:
user@host$ git pull
Updating 9386059..6e3ffde
error: Your local changes to the following files would be overwritten by merge:
foo.bar
Please, commit your changes or stash them before you can merge.
Aborting
Но разве нет способа позволить git pull
сделать stash
а также pop
станцуй для меня?
Если эта команда имеет другое имя, это нормально.
Создание псевдонима оболочки для git stash; git pull; git stash pop
это решение, но я ищу лучшее решение.
5 ответов
Для Git 2.6+ (выпущено 28 сентября 2015 г.)
Единственный git config
Установка, которая будет представлять интерес, это:
rebase.autoStash
Если задано значение true, автоматически создавать временное хранилище перед началом операции и применять его после завершения операции.
Это означает, что вы можете запустить rebase на грязном рабочем дереве.Однако используйте с осторожностью: окончательное приложение-хранилище после успешной перезагрузки может привести к нетривиальным конфликтам. По умолчанию false.
объединить это с:
pull.rebase
Если задано значение true, перебазировать ветви поверх выбранной ветви вместо объединения ветви по умолчанию с удаленного по умолчанию при запуске "git pull".
git config pull.rebase true
git config rebase.autoStash true
Этого было бы достаточно для простого git pull
работать даже в грязном дереве.
В этом случае псевдоним не требуется.
Смотрите коммит 53c76dc (04 июля 2015 г.) Кевина Даудта ( Ikke
)
(Объединено Юнио С Хамано - gitster
- в комитете e69b408, 17 августа 2015 г.)
pull
: разрешить грязное дерево, когдаrebase.autostash
включенrebase научился прятать изменения, когда он сталкивается с грязным рабочим деревом, но
git pull --rebase
не.Только проверяйте, грязное ли рабочее дерево, когда
rebase.autostash
не включен
Примечание: если вы хотите вытащить без автозагрузки (хотя rebase.autoStash true
установлено с git 2.9 (июнь 2016 г.):
pull --rebase --no-autostash
См. Коммит 450dd1d, коммит 1662297, коммит 44a59ff, коммит 5c82bcd, коммит 6ddc97c, коммит eff960b, коммит efa195d (02 апреля 2016 г.) и коммит f66398e, коммит c48d73b (21 марта 2016 г.) от Mehul Jain ( mehul2029
)
(Объединено Юнио С Хамано - gitster
- в коммите 7c137bb, 13 апреля 2016 г.)
В частности, в состав f66398e входят:
pull --rebase
: добавлять--[no-]autostash
флагЕсли
rebase.autoStash
переменная конфигурации установлена, нет возможности переопределить ее для "git pull --rebase
"из командной строки.Учат "
git pull --rebase
"--[no-]autostash
флаг командной строки, который переопределяет текущее значениеrebase.autoStash
, если установлено. Как "git rebase
"понимает--[no-]autostash
опция, это просто вопрос передачи опции в базовыйgit rebase
" когда "git pull --rebase
" называется.
Предупреждение: перед Git 2.14 (3 квартал 2017 года) " git pull --rebase --autostash
"не спрятать автоматически, когда местная история переходит к верхнему течению.
Смотрите коммит f15e7cf (01 июня 2017 г.) от Tyler Brazier ( tylerbrazier
)
(Объединено Юнио С Хамано - gitster
- в коммите 35898ea, 05 июня 2017 г.)
pull
: ff--rebase --autostash
работает в грязном репокогда
git pull --rebase --autostash
в грязном репозитории произошел перемотка вперед, автоматическое сохранение ничего не происходило, а извлечение не удалось.
Это произошло из-за ярлыка, чтобы избежать запуска rebase, когда мы можем выполнить ускоренную перемотку вперед, но autostash игнорируется в этом пути кода.
Обновление: Mariusz Pawelski задает в комментариях интересный вопрос:
Так что все пишут о
autostash
когда вы делаете ребаз (илиpull --rebase
).Но никто не занимается автоматическим запоминанием, когда вы выполняете обычное вытягивание со слиянием.
Так что для этого нет автоматического выключателя? Или я что-то упустил? Я предпочитаю делатьgit pull --rebase
но ОП спросил о " стандартном " git pull
Ответ:
Оригинальный поток, обсуждающий эту функцию автозапуска, он был первоначально реализован как для git pull
(объединить) и git pull --rebase
,
Но... Junio C Hamano (сопровождающий Git) отметил, что:
Если
pull-merge
были чем-то, что вызывало бы "раздражение", вызвавшее эту тему, по определению, локальные изменения перекрываются слиянием, и это внутреннее "всплывающее окно" будет касаться путей, которых коснулось слияние, и, скорее всего, не приведет к "Отбросу", но оставить дальнейшие конфликты для разрешения.Я подозреваю что
pull.autostash
конфигурация не является хорошим дополнением, потому что она поощряет плохой, вызывающий боль рабочий процесс.
В простых случаях это может не повредить, но когда локальные изменения являются сложными, они будут более вредными, чем их отсутствие, и конфигурация лишает стимул для выбора.Уравнение несколько отличается для "pull-rebase", так как "rebase" настаивает на том, чтобы вы начинали с чистого рабочего дерева, поэтому раздражение при "загрузке и остановке" ощущается больше. У меня есть подозрение, что ослабление может быть более продуктивным решением настоящей проблемы.
Итак, что касается классического pull-слияния, лучше:
побудить пользователя подумать о природе WIP, которую он имеет в рабочем дереве, перед запуском "
git pull
"
Это слишком сложный зверь, который может помешать тому, что делают другие, или это тривиальное изменение, которое он может спрятать и вернуть обратно?Если первый, ему будет гораздо лучше делать "
checkout -b
msgstr ", продолжайте работать, пока локальное изменение не станет несколько лучше и" зафиксировать ", прежде чем переходить в исходную ветку.Если последнее, ему лучше делать:
- "
git pull
",- после обнаружения конфликтов, запустите
git stash
,git merge FETCH_HEAD
а такжеgit stash pop
Чтобы сэкономить несколько секунд для начинающих исследователей, вот краткая сводка (спасибо @VonC):
git pull --rebase --autostash
Как сказано выше, установка двух значений конфигурации в настоящее время не работает с git pull
, так как конфигурация autostash применяется только к фактическим перебазам. Эти команды git делают то, что вы хотите:
git fetch
git rebase --autostash FETCH_HEAD
Или установите его как псевдоним:
git config alias.pullr '!git fetch; git rebase --autostash FETCH_HEAD'
Затем сделайте:
git pullr
Конечно, этот псевдоним может быть переименован по желанию.
С Git 2.6+ вы можете использовать следующее:
alias gup='git -c rebase.autoStash=true pull --rebase'
это --rebase
делает git-pull использование rebase
вместо merge
так настройки / опции вроде --ff-only
не будет применяться
Я использую псевдоним, чтобы тянуть с --ff-only
по умолчанию (git pull --ff-only
), а затем может использовать gup
(сверху), если слияние в ускоренном режиме невозможно или имеются скрытые изменения.
Как вы уже упоминали, это способ сделать это. Вы можете использовать его в псевдониме, чтобы сохранить ваш набор текста и использовать ярлык, или вы можете использовать его в одной строке (также может быть псевдоним)
git stash && git pull --rebase && git stash pop
Он будет делать то же самое, что и вы, но в одной строке (&&), и если вы установите в качестве псевдонима, он будет даже короче.
В следующих строках будут отображаться входящие / исходящие изменения, прежде чем вы нажмете / нажмете
git log ^master origin/master
git log master ^origin/master