Как распаковать только определенные файлы?

Я спрятал свои изменения. Теперь я хочу распаковать только некоторые файлы из тайника. Как я могу это сделать?


person morpheus    schedule 07.03.2013    source источник
comment
Я думаю, вам нужно применить весь тайник, но тогда вы можете выборочно повторно спрятать.   -  person Richard    schedule 07.03.2013
comment
Просто в вашей будущей разработке старайтесь избегать хранения файлов, вместо этого коммитите их, потому что git stash не рекомендуется   -  person Abdou Tahiri    schedule 14.03.2016
comment
@AbdouTahiri Что не так с тайником?   -  person alex    schedule 17.03.2016
comment
@alex С помощью git stash у вас также может быть несколько разных вещей, но они не выстраиваются в очередь друг за другом - это просто случайные независимые патчи, которые вы спрятали, потому что в какой-то момент они были неудобны.   -  person Abdou Tahiri    schedule 17.03.2016
comment
@AbdouTahiri Ухххх .. git stash - это законная функция и чрезвычайно полезная. Использую ежедневно. Допустим, коллеге нужно, чтобы я что-то рассмотрел, но я нахожусь в процессе сложного набора изменений. Я не собираюсь коммитить груду неработающего кода только для того, чтобы переключаться между ветвями. Я собираюсь спрятать, переключить ветки, просмотреть, переключиться обратно, распаковать. Не хотите ли вы подробнее рассказать о том, кто или почему git stash якобы не рекомендуется? Просто потому, что ваша история git stash запутана и ее трудно читать, не означает, что все остальные. Беспорядочный набор git stash - это просто плохой рабочий процесс, а не недостаток Git.   -  person dudewad    schedule 11.05.2016
comment
@alex Ничего. В git stash нет ничего плохого. Продолжайте использовать это.   -  person dudewad    schedule 11.05.2016
comment
Я подумал, что можно исправить уже измененный файл с помощью git show stash@{0} -- <filename> | git apply --check, но он продолжает говорить fatal: unrecognized input   -  person joeytwiddle    schedule 23.05.2016
comment
Возможный дубликат Как мне извлечь один файл (или изменения в файл) из git stash?   -  person Jeff Puckett    schedule 07.09.2016
comment
просто используйте это = git checkout stash@{0} -- <filename>   -  person roottraveller    schedule 25.06.2020


Ответы (8)


Как упомянуто ниже и подробно описано в Как мне извлечь один файл (или изменения в файл) из git stash?, вы можете применить команду use _ 1_ или git show, чтобы восстановить определенный файл.

git checkout stash@{0} -- <filename>

В Git 2.23+ (август 2019 г.) используйте git restore, который заменяет confusing git checkout command:

git restore -s stash@{0} -- <filename>

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

(Как прокомментировано Jaime M., для определенной оболочки, такой как tcsh, где вам нужно экранировать специальные символы, синтаксис будет: git checkout 'stash@{0}' -- <filename>)

или сохранить под другим именем:

git show stash@{0}:<full filename>  >  <newfile>

(обратите внимание, что здесь <full filename> - это полный путь к файлу относительно верхнего каталога проекта (подумайте: относительно stash@{0})).

yucer предлагает в комментариях:

Если вы хотите выбрать вручную, какие изменения вы хотите применить из этого файла:

git difftool stash@{0}..HEAD -- <filename>

Vivek добавляет в комментариях:

Похоже, git checkout stash@{0} -- <filename> восстанавливает версию файла на момент выполнения тайника - он НЕ применяет (только) сохраненные изменения для этого файла.
Чтобы сделать последнее:

git diff stash@{0}^1 stash@{0} -- <filename> | git apply

(как прокомментировал peterflynn, в некоторых случаях вам может понадобиться | git apply -p1, удалив одну (p1) ведущую косую черту из традиционных путей различий)


Как прокомментировано: unstash (git stash pop), затем:

  • добавьте то, что вы хотите сохранить, в индекс (git add)
  • спрятать остальное: git stash --keep-index

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

person VonC    schedule 07.03.2013
comment
Это не сработает, если вы не можете git stash pop из-за конфликтов файлов. Ответ Баламуругана А помог мне в этом случае. - person Andrey; 22.12.2014
comment
Если вы хотите выбрать вручную, какие изменения вы хотите применить из этого файла, вы можете использовать git difftool stash @ {0} .. HEAD - ‹filename› - person yucer; 29.06.2016
comment
@yucer Приятно. Я включил ваш комментарий в ответ для большей наглядности. - person VonC; 29.06.2016
comment
Похоже, что git checkout stash @ {0} - ‹filename› восстанавливает версию файла на момент выполнения тайника - он НЕ применяет (только) сохраненные изменения для этого файла. Для последнего: git diff stash @ {0} ^ 1 stash @ {0} - ‹filename› | git применить - person Vivek; 13.10.2016
comment
Я столкнулся со случаем, когда трюк | git apply (объединить спрятанную копию с локальной копией) завершился неудачно с исправлением ошибки, неприменим. Но при использовании | patch -p1 слияние сработало отлично! - person peterflynn; 04.01.2017
comment
@peterflynn Спасибо. Я включил ваш комментарий в ответ для большей наглядности. - person VonC; 04.01.2017
comment
Обратите внимание, что вам нужно экранировать специальные символы в некоторых оболочках, таких как tcsh, поэтому команда будет git checkout 'stash@{0}' -- <file-name> - person Jaime M.; 04.09.2017
comment
@JaimeM. Спасибо. Я включил ваш комментарий в ответ для большей наглядности. - person VonC; 04.09.2017
comment
Если предположить, что unstash означает pop, что, как мне кажется, вероятно, будет в большинстве случаев, это лишь частично отвечает на вопрос. Как вы затем удалите выборочно примененные части из тайника, чтобы избежать последующих конфликтов и / или путаницы при извлечении оставшихся изменений? - person DylanYoung; 17.10.2017
comment
@DylanYoung Не уверен: вы имеете в виду конкретный случай? В противном случае pop + add + stash --keep-index (упомянутый в конце этого ответа) кажется довольно простым. - person VonC; 17.10.2017
comment
Если у вас есть существующие изменения, которые вы объединяете с выбранными фрагментами из тайника, а затем обновляете, чтобы все они соответствовали друг другу, это может стать беспорядочным. Конечно, временная фиксация, а затем сжатие ее вместе с сохраненными изменениями, будет работать, но для этого нужно очень хорошо знать, что вы делаете. В то время как такие команды, как stash pop --interactive, хотя технически сложны для реализации, они гораздо менее привередливы для пользователя. - person DylanYoung; 17.10.2017
comment
Вы, конечно, правы, что внутренности такой команды почти наверняка будут включать в себя что-то вроде того, что вы обрисовали в общих чертах, подобно тому, как stash -u просто создает некоторую поддержку для работы. Просто любопытно, есть ли поддерживаемое решение (или если оно находится на временной шкале) и указывает на то, что данные решения не являются суперчистыми и требуют много накладных расходов со стороны пользователя, чтобы убедиться, что соответствующие изменения остаются там, где они ' должен и не перепутайся .. - person DylanYoung; 17.10.2017
comment
@DylanYoung ОК. Я не знаю сейчас о таком решении. - person VonC; 17.10.2017
comment
Почему у меня появляется $ git checkout stash@{0} --filename ./myFile.java error: unknown option filename '' - person Janac Meena; 15.01.2019
comment
@JanacMeena, потому что между "--" и именем файла должен быть пробел (как в ответе выше). См. stackoverflow.com/a/1192194/6309 для получения дополнительной информации об обозначении «--». - person VonC; 15.01.2019
comment
@VonC, спасибо! Кроме того, как мне вытащить конкретный файл из моего тайника (а не просто применить его), если этот файл в настоящее время не существует в моем рабочем каталоге - он существует только в тайнике? - person Janac Meena; 15.01.2019
comment
@JanacMeena Команда git show stash@{0}:<full filename> > <newfile> должна иметь возможность создать этот файл в рабочем дереве, даже если он существовал только в тайнике. - person VonC; 15.01.2019
comment
@VonCgit checkout stash @ {0} - ‹filename› заменит изменения тайника. - person Akhil Surapuram; 11.04.2019
comment
@AkhilSurapuram Именно. Это идея. stackoverflow.com/a/50370632/6309 будет объединяться вместо замены. Я отредактирую ответ, чтобы сделать различие более четким. - person VonC; 11.04.2019
comment
@AkhilSurapuram Я отредактировал ответ, чтобы подчеркнуть последствия этой команды git checkout stash@{0} -- <filename>. - person VonC; 11.04.2019

git checkout stash@{N} <File(s)/Folder(s) path> 

Например. Чтобы восстановить только файл ./test.c и папку ./include из последних сохраненных,

git checkout stash@{0} ./test.c ./include
person Balamurugan A    schedule 21.03.2014
comment
Это правильный ответ! Однострочная команда для применения только сохраненных изменений из определенных файлов работает как шарм! - person 4levels; 20.06.2014
comment
Чтобы применить (только) сохраненные изменения к файлу: git diff stash @ {N} ^ 1 stash @ {N} - ‹filename› | git применить - person Vivek; 13.10.2016
comment
У меня это тоже работает. Просто выборочно извлеките файлы из тайника, и все готово. Я застрял в этом, я использовал флаг -a при создании тайника. - person Rajeev Ranjan; 17.10.2017
comment
@ 4levels Я думаю, что применить спрятанные изменения - это не то, что происходит, верно? Я думаю, что происходит перезапись всего, что у вас есть, копией из тайника. - person msouth; 05.11.2019

Я думаю, что ответ VonC - это, вероятно, то, что вы хотите, но вот способ сделать выборочное «git apply»:

git show stash@{0}:MyFile.txt > MyFile.txt
person Mike Monkiewicz    schedule 07.03.2013
comment
В некоторых случаях это может быть то, что вам нужно, но помните, что эта команда перезапишет, а не объединится с любыми изменениями рабочего каталога. - person Rhubbarb; 05.11.2015
comment
Это работает для меня, так как я просто хотел скопировать файл, который существует только в тайнике, и не заботился ни о чем checkout. - person Tom Russell; 26.10.2016
comment
Для Windows PowerShell: git show stash@`{0`}:Path/To/MyFile.txt |sc Path/To/MyFile.txt - обратные кавычки необходимы для PS, чтобы не интерпретировать фигурные скобки специально, а sc необходимо , поскольку оператор PS > по умолчанию UTF-16 (на самом деле UCS-2), который, вероятно, не то, что вам нужно. Ответ @Balamurugan A не страдает от этих проблем. - person Ian Kemp; 09.06.2017

Сначала перечислите все тайники

git stash list

stash@{0}: WIP on Produktkonfigurator: 132c06a5 Cursor bei glyphicon plus und close zu zeigende Hand ändern
stash@{1}: WIP on Produktkonfigurator: 132c06a5 Cursor bei glyphicon plus und close zu zeigende Hand ändern
stash@{2}: WIP on master: 7e450c81 Merge branch 'Offlineseite'

Затем покажите, какие файлы находятся в тайнике (давайте выберем тайник 1):

git stash show 1 --name-only

//Hint: you can also write
//git stash show stash@{1} --name-only

 ajax/product.php
 ajax/productPrice.php
 errors/Company/js/offlineMain.phtml
 errors/Company/mage.php
 errors/Company/page.phtml
 js/konfigurator/konfigurator.js

Затем примените понравившийся файл:

git checkout stash@{1} -- <filename>

или вся папка:

git checkout stash@{1} /errors

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

Также принято распознавать двойной дефис как сигнал о прекращении интерпретации опций и трактовать все последующие аргументы буквально.

person Black    schedule 07.06.2018
comment
Я пробовал много способов, и этот способ был мне нужен. Я столкнулся с проблемой, что git stash pop вызывало ошибку для неотслеживаемых файлов. Спасибо. - person Ramin Firooz; 23.12.2018

Еще один способ:

git diff stash@{N}^! -- path/to/file1 path/to/file2  | git apply -R
person Tomov    schedule 16.05.2018
comment
Это единственно правильный ответ ИМО. Использование checkout или show приведет к слепой перезаписи файла вместо простого применения изменений. Еще один способ - это мягко сказано. - person cambunctious; 08.12.2019
comment
Я не получаю path/to/file2, поскольку вы хотите сравнить тот же файл в вашем рабочем пространстве. У меня нет второго пути. - И я получаю сообщение об ошибке, используя параметр -R (применить патч в обратном порядке, пытаясь исправить спрятанную версию ?!). Так что моя рабочая версия выглядит как git diff stash@{N}^! -- path/to/file | git apply -. - person ThomasH; 15.01.2020
comment
патч не удался? Попробуйте 3-стороннее слияние. ...| git apply -3 - - person John Mee; 24.01.2020
comment
diff stash@{N}^! уже производит прямую разницу, поэтому не указывайте -R - person kxr; 20.08.2020
comment
^! не сработало в моем случае, поэтому я сделал git diff stash@{N} -- path/to/file | git apply -R - person Alwyn Schoeman; 16.04.2021

Если вы git stash pop (без конфликтов), он удалит тайник после его применения. Но если вы git stash apply, он применит патч, не удаляя его из списка тайников. Затем вы можете отменить нежелательные изменения с помощью git checkout -- files...

person Ben Jackson    schedule 07.03.2013
comment
Чтобы прояснить конфликтную часть этого сообщения, если у вас git stash pop и есть конфликты, вам придется исправить их вручную, и тайник НЕ будет удален. - person theflowersoftime; 22.09.2016

Для пользователей Windows: фигурные скобки имеют особое значение в PowerShell. Вы можете заключить в одинарные кавычки или экранировать обратную кавычку. Например:

git checkout 'stash@{0}' YourFile

Без него вы можете получить ошибку:

Unknown switch 'e'

person Janac Meena    schedule 15.01.2019
comment
Полная оценка PowerShell за наименее полезное сообщение пользователя, которое я видел в этом месяце. - person holdenweb; 03.04.2019

Например

git stash show --name-only

результат

ofbiz_src/.project
ofbiz_src/applications/baseaccounting/entitydef/entitymodel_view.xml
ofbiz_src/applications/baselogistics/webapp/baselogistics/delivery/purchaseDeliveryDetail.ftl
ofbiz_src/applications/baselogistics/webapp/baselogistics/transfer/listTransfers.ftl
ofbiz_src/applications/component-load.xml
ofbiz_src/applications/search/config/elasticSearch.properties
ofbiz_src/framework/entity/lib/jdbc/mysql-connector-java-5.1.46.jar
ofbiz_src/framework/entity/lib/jdbc/postgresql-9.3-1101.jdbc4.jar

Затем вставьте тайник в конкретный файл

git checkout stash@{0} -- ofbiz_src/applications/baselogistics/webapp/baselogistics/delivery/purchaseDeliveryDetail.ftl

другие связанные команды

git stash list --stat
get stash show
person Do Nhu Vy    schedule 11.12.2020