Хранить изменения, сохраняя изменения в рабочем каталоге в Git

156

Есть ли git stashкоманда, которая хранит ваши изменения, но также сохраняет их в рабочем каталоге? Итак, в основном, за git stash; git stash applyодин шаг?

Майкл Дорст
источник
Тот же вопрос: stackoverflow.com/q/6315459/350384
Мариуш Павельский
Отвечает ли это на ваш вопрос? Команда Git для сохранения тайника без изменения рабочего дерева?
Мариуш Павельский,
1
@MariuszPawelski Нет, не совсем. Этот вопрос более конкретный, чем мой. Ответ на мой вопрос был просто «нет». Однако спасибо за ссылку, она может быть полезна некоторым людям или даже мне позже.
Майкл Дорст,
Для ясности, у меня другой вопрос, потому что я не требую, чтобы файлы оставались нетронутыми. Я просто искал альтернативы git stash && git stash apply. Вы заметите, что ответы на этот вопрос сильно отличаются от моих.
Майкл Дорст,
ах, да, ваш вопрос немного менее конкретен. Но я задаю этот вопрос, потому что его ответы также соответствуют вашему требованию. Таким образом, этот вопрос будет отображаться как «Связанный» на боковой панели, поэтому он может быть кому-то полезен.
Мариуш Павельский,

Ответы:

167

Как бы то ни было, другой способ сделать это - подготовить изменения, которые вы хотите сохранить, а затем спрятать все, используя --keep-index:

$ git add modified-file.txt
$ git stash push --keep-index

Приведенные выше команды сохранят все, но файлы останутся в вашем рабочем каталоге.

Из официальной документации Git ядра Linux дляgit stash или от git-scm :

Если этот --keep-indexпараметр используется, все изменения, уже добавленные в индекс, остаются без изменений.

Cirelli94
источник
5
это, безусловно, самое простое объяснение --keep-index, которое я когда-либо видел. Я не совсем понял смысл того, как это было сформулировано в документации.
40detectives
54

git stashа затем git stash apply( git stash && git stash apply) сохранит файлы и сразу после них применит тайник. Итак, в конце концов, у вас будут изменения в тайнике и в рабочем каталоге.

Вы можете создать псевдоним, если хотите, чтобы он был целым. Просто введите что-то вроде этого ~/.gitconfig:

[alias]
    sta = "!git stash && git stash apply"

Недостатком этого подхода является то, что все файлы сохраняются и создаются заново. Это означает, что метки времени в рассматриваемых файлах будут изменены. (Заставляет Emacs жаловаться, когда я пытаюсь сохранить файл, если он открыл его до того, как это сделал я git sta, и может вызвать ненужные перестроения, если вы используете makeили друзья.)

сумасшедший
источник
1
также, в чем разница между git stash; git stash applyи git stash && git stash apply?
Michael Dorst
2
@anthropomorphic git config --global alias.sta "!git stash && git stash apply"должен это сделать.
Как я могу изменить этот псевдоним для использования git stash saveс аргументом, а затем сделать git stash apply?
spinningarrow
1
@JaySidri, bang означает, что на самом деле это внешняя команда, а не сам аргумент git. Согласно документации : «Как вы понимаете, Git просто заменяет новую команду тем, для чего вы ее называете. Однако, возможно, вы захотите запустить внешнюю команду, а не подкоманду Git. В этом случае вы начинаете команду с ! персонаж."
madhead
11

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

$ git add modified-file.txt  
(OR $ git add .    ---- for all modified file)
$ git stash save --keep-index "Your Comment"
Премчандра Сингх
источник
ПРИМЕЧАНИЕ: не работает без "git add" (например, для измененных, но не добавленных в файлы фиксации)
alex_1948511
4

Вам может помочь трюк, но не тайник, а FWIW:

git add -A
git commit -m "this is what's called stashing"       (create new stash commit)
git tag stash                               (mark the commit with 'stash' tag)
git reset HEAD~        (Now go back to where you've left with your working dir intact)

Итак, теперь в вашем распоряжении есть хранилище с тегами фиксации, сделать это в git stash popлюбом случае невозможно, но вы можете делать такие вещи, как создание патча или сброс файлов и т. Д. Оттуда, ваши рабочие файлы dir также остаются нетронутыми, BTW.

KenIchi
источник
3

Вы можете использовать git stash createдля создания фиксации тайника, а затем сохранить его в тайнике, используя git stash store:

git stash store $(git stash create) -m "Stash commit message"

Это можно сохранить в псевдониме git, чтобы было удобнее:

git config --global alias.stash-keep '!git stash store $(git stash create)'

git stash-keep -m "Stash commit message"

Обратите внимание, что это не все, что git stash pushделает. Например, он не добавляет имя ветки к фиксации, например " stash@{0}: On myBranch: Stash commit message".

М. Джастин
источник
1
Нравится вот этот!! Одно исправление: man git-stashговорит, что -m <message>должен быть перед хешем фиксации. Кроме того, что-то изменилось в новейшем git.
tanius