Как мне извлечь один файл (или изменения в файл) из git stash?

Я хотел бы знать, возможно ли извлечь один файл или diff из файла git stash, не отключая набор изменений stash.

Может ли кто-нибудь быть в состоянии предоставить некоторые предложения / идеи по этому поводу?

10 ответов

Решение

На странице руководства git stash вы можете прочитать это (в разделе "Обсуждение", сразу после описания "Опции"):

Тайник представляется в виде коммита, в дереве которого записывается состояние рабочего каталога, а его первым родителем является коммит в HEAD при создании тайника.

Таким образом, вы можете лечить тайник (например, stash@{0} это первый / самый верхний тайник) как коммит слияния, и используйте:

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

Объяснение: stash@{0}^1 ярлык означает первого родителя данного тайника, который, как указано в объяснении выше, является коммитом, при котором изменения были спрятаны. Мы используем эту форму "git diff" (с двумя коммитами), потому что stash@{0} / refs/stash это коммит слияния, и мы должны сказать git, против какого родителя мы хотим использовать diff. Более загадочный:

$ git diff stash@{0}^! -- <filename>

также должен работать (см. страницу руководства git rev-parse для объяснения rev^! синтаксис, в разделе "Задание диапазонов").

Аналогично, вы можете использовать git checkout для проверки одного файла из тайника:

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

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

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

или же

$ git show stash@{0}:./<relative filename> > <newfile>

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


Возможно, вам нужно защитить stash@{0} от расширения оболочки, т.е. использовать "stash@{0}" или же 'stash@{0}',

Если вы используете git stash apply скорее, чем git stash pop, он применит тайник к вашему рабочему дереву, но все равно сохранит тайник.

Сделав это, вы можете add/commit файл, который вы хотите, а затем сбросьте оставшиеся изменения.

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

Заметки:

  1. Убедитесь, что вы поставили пробел после "-" и параметра имени файла

  2. Замените ноль (0) вашим конкретным номером тайника. Чтобы получить список тайников, используйте:

    git stash list
    

На основании ответа Якуба Наренбского - более короткая версия

Существует простой способ получить изменения из любой ветки, включая тайники:

$ git checkout --patch stash@{0} path/to/file

Вы можете опустить спецификацию файла, если вы хотите патчить во многих частях. Или пропустите патч (но не путь), чтобы получить все изменения в одном файле. замещать 0 с номером тайника из git stash listЕсли у вас есть более одного. Обратите внимание, что это как diffи предлагает применить все различия между филиалами. Чтобы получить изменения только от одного коммита / тайника, взгляните на git cherry-pick --no-commit,

Короткий ответ

Чтобы увидеть весь файл: git show stash@{0}:<filename>

Чтобы увидеть разницу: git diff stash@{0}^1 stash@{0} -- <filename>

Используйте следующее, чтобы применить изменения к файлу в тайнике вашего рабочего дерева.

git diff stash^! -- <filename> | git apply

Обычно это лучше, чем использовать git checkout потому что вы не потеряете никаких изменений, внесенных в файл с момента создания тайника.

Вы можете получить различие для тайника с "git show stash@{0}"(или независимо от того, какой номер хранилища; см." список хранилищ git"). Легко извлечь раздел diff для одного файла.

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

Если вы делаете git stash спрятать их всех, git stash apply чтобы вернуть их снова, а затем git checkout f.c на файл, чтобы эффективно сбросить его.

Когда вы хотите распаковать этот файл, запустите git reset --hard а потом беги git stash apply опять же, используя тот факт, что git stash apply не очищает diff из стека

Для пользователей VS Code есть один метод. Убедитесь, что установлено расширение GitLens .

  1. ПродолжатьSOURCE CONTROLвкладка
  2. Нажмите наSTASHES.
  3. Вы сможете увидеть доступные тайники.
  4. Нажмите на нужный тайник.
  5. Щелкните правой кнопкой мыши нужный файл, который вы хотите удалить.
  6. Вы получите 2 варианта, и . Вы можете выбрать любой из вариантов, и вы получите свой файл подChangesесли вы выберетеApply ChangesилиStaged Changesесли вы выберетеRestore (Checkout).

Если спрятанные файлы необходимо объединить с текущей версией, используйте предыдущие способы, используя diff. В противном случае вы можете использовать git pop за то, что расправил их, git add fileWantToKeep для постановки вашего файла, и сделать git stash save --keep-index, для того, чтобы спрятать все, кроме того, что на сцене. Помните, что отличие этого способа от предыдущих заключается в том, что он "выталкивает" файл из stash. Предыдущие ответы сохраняют это git checkout stash@{0} -- <filename> так что идет в соответствии с вашими потребностями.

Другие вопросы по тегам