Может ли "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
Другие вопросы по тегам