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

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

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

8 ответов


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

тайник представляется как фиксация, дерево которой записывает состояние рабочий каталог и его первый родитель-это commit at HEAD, когда тайник был создан.

таким образом, вы можете лечить заначку (например,stash@{0} первая / высшая заначку) как фиксацию, и использовать:

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

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

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

также должно работать (см. git rev-parse manpage для объяснения 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 show stash@{0}:<filename>

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


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


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

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

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


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

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

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


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

Примечания:

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

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

    git stash list
    

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


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