Может ли" 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 83

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 работать даже в грязном дереве.
В этом случае псевдоним не нужен.


посмотреть commit 53c76dc (04 июля 2015) by Кевин Daudt (Ikke).
(слитый Junio C Hamano--gitster-- на commit e69b408, 17 авг 2015)

pull: разрешить грязное дерево, когда rebase.autostash включено

rebase научился прятать изменения, когда он сталкивается с деревом грязной работы, но git pull --rebase нет.

только проверьте, если рабочее дерево грязно, когда rebase.autostash не включен.


Примечание: Если вы хотите тянуть без автосташ (хоть и rebase.autoStash true установлен), у вас есть с git 2.9 (июнь 2016):

 pull --rebase --no-autostash

посмотреть commit 450dd1d,совершить 1662297,совершить 44a59ff,commit 5c82bcd,commit 6ddc97c, commit eff960b,commit efa195d (02 апр 2016), и commit f66398e,commit c48d73b (21 марта 2016) by Мехул Кумар Джайн (mehul2029).
(слитый Junio C Hamano--gitster-- на commit 7c137bb, 13 апр 2016)

Commit f66398e в частности, включает в себя:

pull --rebase добавить --[no-]autostash флаг

если rebase.autoStash переменная конфигурации установлена, нет никакого способа переопределить его для "git pull --rebase" из командной строки.

учить "git pull --rebase " the --[no-]autostash флаг командной строки, которая переопределяет текущее значение rebase.autoStash, если установлено. Как"git rebase" понимает --[no-]autostash вариант, это просто вопрос прохождения опция для базового "git rebase" для "git pull --rebase" называется.


предупреждение: перед Git 2.14 (Q3 2017),"git pull --rebase --autostash " не было автоматического тайника, когда местная история быстро переходит к восходящему потоку.

посмотреть commit f15e7cf (01 июня 2017) by Тайлер Жаровни (tylerbrazier).
(слитый Junio C Hamano--gitster-- на совершить 35898ea, 05 июня 2017)

pull: ff --rebase --autostash работает в грязном РЕПО

, когда git pull --rebase --autostash в грязном хранилище в результате быстрая перемотка вперед, ничего не было автосташировано, и тяга не удалась.
Это было связано с ярлыком, чтобы избежать запуск rebase, когда мы можем перемотать вперед, но автосташ игнорируется на этом пути кода.


обновление: Мариуш Павельски просит в комментариях интересный вопрос:

так все пишут о autostash когда вы делаете rebase (или pull --rebase).

но никто не берет об автостешировании, когда вы делаете нормальную тягу с слияние.
Так что нет автоматического переключиться на это? Или я что-то упускаю? Я предпочитаю делать git pull --rebase но ОП спросил о"стандартный " git pull

ответ:

The исходный поток обсуждая эту функцию автосташа, она была реализована первоначально как для git pull (слияния) и git pull --rebase.

но... Junio C Hamano (git maintainer) отметил, что:

если pull-merge были что-то, что бы побудить раздражение" это вызвало эту тему, по определению, локальные изменения перекрываются с слиянием, и этот внутренний "тайник поп" будет касаться путей слияние коснулось, и это, вероятно, не приведет к "падению", но оставит конфликты должны быть решены.

я подозреваю, что pull.autostash конфигурация не является хорошим дополнением, потому что она поощряет плохой, вызывающий боль рабочий процесс.
В простых случаях это может не навредить, но когда локальные изменения сложны, это будет активно обиднее, чем не иметь его, а конфигурация лишает стимула выбирать.

уравнение несколько отличается для "pull-rebase", как " rebase" настаивает на том, чтобы вы начали с чистого рабочего дерева, поэтому " скачать и тогда прекратите " раздражение чувствует себя больше. У меня есть подозрение, что ослабление, которое может быть более продуктивным решением реальной проблемы.

Итак, что касается классического pull-merge, то лучше:

поощрять пользователь должен подумать о характере НЗП, который он имеет в рабочем дереве перед запуском"git pull".
Это слишком сложный зверь, который может мешать тому, что делают другие, или это тривиальное изменение, которое он может спрятать и вернуть обратно?

если первое, то ему будет гораздо лучше делать"checkout -b", сохранить работа до тех пор пока местное изменение не получит в несколько лучшую форму и "commit", прежде чем потянуть в исходную ветку.

если последнее ему лучше делать:

  • "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 (сверху) в случае, если быстрое слияние невозможно или есть скрытые изменения.

Как вы уже упоминали, это способ сделать это. Вы можете использовать его в alias, чтобы сохранить ввод и использовать ярлык, или вы можете использовать его в одной строке (может быть также псевдоним)

git stash && git pull --rebase && git stash pop

Он будет делать то же самое, что и вы, но в одной строке ( & & ), и вы устанавливаете в качестве псевдонима, он будет даже короче.

в следующих строках будут отображаться входящие / исходящие изменения, прежде чем вы потянете/нажмете

git log ^master origin/master
git log master ^origin/master