git-stash против git-branch

92

В предыдущем вопросе Git Дэниел Бенами говорил о рабочем процессе в Git:

Я работал над мастером и передал кое-какие вещи, а затем решил, что хочу отложить эту работу. Я сделал резервную копию нескольких коммитов, а затем разветвился, прежде чем начал свою дерьмовую работу.

Он хотел восстановить свое рабочее состояние до предыдущего момента времени без потери текущих изменений. Все ответы по-разному вращались вокруг чего-то вроде

git branch -m master crap_work
git branch -m previous_master master

Как это по сравнению с git stash? Я немного сбит с толку, пытаясь понять, какой здесь другой вариант использования, когда кажется, что все, git stashчто происходит, уже обрабатывается ветвлением ...


@ Jordi Bunster : Спасибо, это проясняет ситуацию. Я полагаю, что я бы рассмотрел «заначку» как легкую безымянную ветку. Таким образом, stash может делать все, что и ветвь, но с большим количеством слов. Ницца!

Уилл Робертсон
источник

Ответы:

109

'stash' берет незафиксированные, « грязные » вещи из вашей рабочей копии и прячет их, оставляя вам чистую рабочую копию.

На самом деле это вообще не ветвь. Затем вы можете применить тайник поверх любой другой ветки. Или, начиная с Git 1.6, вы можете:

git stash branch <branchname> [<stash>]

чтобы применить тайник поверх новой ветки, все в одной команде.

Итак, stash отлично работает, если вы еще не выбрали « неправильную » ветку.

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

Хорди Бунстер
источник
1
одна вещь, которая укусила меня ... можешь написать, как на самом деле выглядит [<stash>]! Они использовали это обозначение в документации, но неясно, должно ли это быть 1 или @ {1} или что-то еще.
Gregg Lind
1
Если вы хотите указать конкретный тайник «N», используйте тайник @ {N}
Джорди Бунстер,
9
Смотрите git stash listназвания ваших тайников.
idbrii 06
6
Грегг, да, вы можете: git stash save (название вашего тайника). Делает его более полезным, если вы используете его часто, чтобы вы знали, что делает каждый тайник. Вы можете использовать git stash show -p (name), чтобы показать вам патч тайника.
Thomas Vander Stichele 02
7
также, git stash show -uчтобы показать разницу между тайником и рабочей копией.
Кен
49

Когда вы восстанавливаете свой тайник, ваши изменения применяются повторно, и вы продолжаете работать над своим кодом.

Чтобы сохранить ваши текущие изменения

$ git stash save 
Saved "WIP on master: e71813e..."

Вы также можете иметь более одного тайника. Тайник работает как стек. Каждый раз, когда вы сохраняете новый тайник, он кладется поверх стека.

$ git stash list
stash@{0}: WIP on master: e71813e..."

Обратите внимание на stash@{0}часть? Это ваш идентификатор тайника. Он понадобится вам для восстановления позже. Сделаем это прямо сейчас. ID тайника меняется с каждым созданным вами тайником. stash @ {0} относится к последнему сделанному вами тайнику.

Чтобы применить тайник

$ git stash apply stash@{0}

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

$ git stash drop stash@{0}

Или, поскольку тайник действует как стек, вы можете извлечь последний сохраненный тайник:

$ git stash pop

Если вы хотите стереть все свои тайники, выполните команду 'clear':

$ git stash clear

Вполне возможно, что вы не так часто используете тайники. Если вы просто хотите быстро сохранить изменения, чтобы восстановить их позже, вы можете не указывать идентификатор тайника.

$ git stash
...
$ git stash pop

Не стесняйтесь экспериментировать с тайником, прежде чем использовать его для действительно важной работы.

У меня также есть более подробная версия этого размещена в моем блоге .

Ариеджан
источник
гораздо более полезный ресурс, чем предполагаемый «лучший» ответ ... (хотя лучший ответ прояснил это, были некоторые недоразумения, связанные с полным использованием)
kumarharsh
9

Я всегда опасаюсь git stash. Если вы отложите несколько раз, все станет беспорядочно. git stash list отобразит нумерованный список созданных вами тайников с сообщениями, если вы их предоставили ... Но проблема заключается в том, что вы не можете очистить тайники, кроме как с помощью жесткой очистки git stash clear (которая удаляет их все) . Так что, если вы не всегда анально рассуждаете о своих тайниках (что-то вроде противоречит философии тайников), вы получите непонятную кучу тайников.

Единственный известный мне способ выяснить, какой из них - использовать gitk --all и определить тайники. По крайней мере, это позволяет вам увидеть, для какой фиксации был создан тайник, а также разницу всего, что включено в этот тайник.

Обратите внимание, что я использую git 1.5.4.3, и я думаю, что 1.6 добавляет git stash pop, который, я думаю, применит выбранный тайник и удалит его из списка. Что кажется намного чище.

На данный момент я всегда пытаюсь перейти на ветку, если не уверен, что вернусь к этому тайнику в тот же день, даже в течение часа.

веб-коврик
источник
3
Вы делаете ветки, не давая им полезных имен? Если нет, то я не понимаю, почему вы не делаете то же самое с тайником. Если вы действительно хотите знать, что они содержат, вы просто используете git-stash show, чтобы показать, какие файлы были изменены, или git-stash apply и git-diff, чтобы увидеть фактические различия. Урезать тайники - это то же самое, что держать свои ветки под контролем.
Xiong Chiamiov
18
фактически, вы можете удалить один тайник с помощьюgit stash drop [<stash>]
kumarharsh
1
Правда, у git есть git stash drop уже давно. Сейчас использовать PITA гораздо меньше. Я использую его каждый день и даже в течение длительного времени.
webmat 07
3

Если вы ищете рабочий процесс, который может быть более подходящим, чем git stash, вы можете посмотреть git-bottle . Это утилита, предназначенная для сохранения и восстановления различных рабочих состояний git при обычных фиксациях git, эффективно создавая моментальные снимки текущего и подходящего состояния вашего рабочего дерева и всех различных состояний файлов, отображаемых в разделе git status.

Ключевые отличия от git stash:

  • git stashсохраняет грязное состояние git узко (измененные файлы и добавленные файлы в индекс), тогда git-bottleкак предназначен для сохранения всего, что отличается от HEAD, и различает сохраняющим образом измененные, измененные и не добавленные, не добавленные, неслитые пути, и полные состояния перебазирования / слияния ( .gitignoreне сохраняются только пути ниже ).
  • git stashсохраняет, чтобы спрятать объекты, которые нужно отслеживать отдельно. Если бы я что-то спрятал 2 недели назад, я мог бы этого не вспомнить, тогда как git-bottleсохраняет как предварительные коммиты в текущую ветку . Обратное действие git-unbottleэквивалентно git stashпопу. Эти коммиты можно отправлять и публиковать в репозиториях. Это может быть полезно для удаленных сборок, когда у вас есть другой репозиторий на удаленном сервере только для сборки или для совместной работы с другими людьми по разрешению конфликтов.
Дэн Алони
источник