git stash выходит из 0, но тайник не создан

Мне посоветовали избегать git pull --autostash и вместо этого использовать:

git alias.pull-autostash '!git stash push && git pull --rebase && git stash pop'

Когда в индексе или рабочем дереве нет изменений, делаем:

$ git stash push

дает:

No local changes to save

Дополнительная проблема заключается в том, что статус выхода — 0.

Любой stash pop затем pop что-то, что не было нажато.

Как заставить создать пустой тайник, например git commit --allow-empty?


person Tom Hale    schedule 29.09.2018    source источник


Ответы (2)


Для сценариев используйте git stash create (который выдает хэш-идентификатор созданного тайника в стандартном выводе или ничего в стандартном выводе, если тайник не был создан). Затем вы можете использовать git stash store, чтобы вставить созданный тайник как stash@{0}, если и только если он действительно был создан.

Если ваш Git слишком стар для git stash create, вы можете запустить две команды git rev-parse в refs/stash до и после запуска git stash save.1 Это может:

  • Оба терпят неудачу: тайника не было до и нет тайника после.
  • Первый не удается, второй удается: раньше не было тайника, а теперь есть, значит, он был создан.
  • Оба успешны, с двумя выходными строками, совпадающими (тайник не создан) или различающимися (тайник создан).

Таким образом, если вы используете --quiet --verify и фиксируете фактический вывод каждого из них, вы можете сказать, был ли создан тайник. То есть фрагмент программирования, который применим здесь, таков:

old=$(git rev-parse --quiet --verify refs/stash)
git stash save || die ...
new=$(git rev-parse --quiet --verify refs/stash)
if [ "$old" != "$new" ]; then
    made_stash=true
else
    made_stash=false
fi
... do things ...
if $made_stash; then ... do things with the stash you made ...

(Я рекомендую избегать как git stash , так и git pull, за исключением очень ограниченных, особых обстоятельств. У меня было слишком много неудачного опыта с ними.)


1Если в вашем Git отсутствует git stash create, возможно, он также предшествует git stash push, поэтому вместо него вам нужен git stash save.

person torek    schedule 29.09.2018

Этот ответ не отвечает, как вы прячете пустое изменение, но он должен решить вашу проблему.

Сначала проверьте, есть ли ожидающие изменения (см. https://stackoverflow.com/a/3879077/3526980)

$ git alias.pull-autostash '(git diff-index --quiet HEAD -- && git pull --rebase) || (git stash push && git pull --rebase && git stash pop)'
person Richard    schedule 29.09.2018
comment
Вам также нужен git diff-files: diff-index сравнивает индекс, но не смотрит на рабочее дерево, а git stash создает тайник (два коммита, один для индекса и один для рабочего дерева), если либо индекс или рабочее дерево грязное. - person torek; 29.09.2018
comment
@Торек, почему бы и нет [ -z "$(git status -uno --porcelain)" ] && echo clean? - person Tom Hale; 29.09.2018
comment
@TomHale: Этого, вероятно, будет достаточно, поскольку вам все равно, что грязно (индекс, рабочее дерево или и то, и другое), просто есть ли хотя бы одно. - person torek; 29.09.2018