Как мне извлечь один файл (или изменения в файле) из тайника git?
Вопрос
Я хотел бы знать, можно ли извлечь один файл или разницу файла из тайника git, не отключая набор изменений тайника.
Может ли кто-нибудь дать некоторые предложения/идеи по этому поводу?
Решение
На git тайник man-страницу вы можете прочитать (в разделе «Обсуждение», сразу после описания «Параметры»), что:
Кстань представлен в качестве коммита, чье дерево записывает состояние рабочего каталога, а его первым родителем является коммит в голове, когда был создан тайник.
Таким образом, вы можете лечить тайник (например, 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 man-страница для объяснения rev^!
синтаксис в разделе «Указание диапазонов»).
Аналогично, вы можете использовать git проверка чтобы проверить один файл из тайника:
$ 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 checkout --patch stash@{0} path/to/file
Вы можете опустить спецификацию файла, если хотите внести исправления во многие части.Или опустите patch (но не путь), чтобы сохранить все изменения в одном файле.Заменять 0
с номером тайника от git stash list
, если у вас их несколько.Обратите внимание, что это похоже на diff
, и предлагает подать заявку все различия между ветвями.Чтобы получить изменения только из одного коммита/тайника, взгляните на git cherry-pick --no-commit
.
$ git checkout stash@{0} -- <filename>
Примечания:
Убедись, что ты поставьте пробел после "--" и параметр имени файла
Замените ноль (0) на ваш конкретный номер тайника.Чтобы получить список тайников, используйте:
git stash list
На основе Ответ Якуба Нарембского -- Более короткая версия
Вы можете получить разницу для тайника с помощью "git show stash@{0}
" (или любой другой номер тайника;см. «список git stash»).Извлечь раздел различий для одного файла легко.
Самая простая для понимания концепция, хотя, возможно, и не самая лучшая, заключается в том, что у вас изменено три файла, и вы хотите спрятать один файл.
Если ты это сделаешь git stash
чтобы спрятать их все, git stash apply
чтобы вернуть их снова, а затем git checkout f.c
в рассматриваемом файле, чтобы эффективно сбросить его.
Если вы хотите удалить этот файл, выполните git reset --hard
а затем запустить git stash apply
опять же, воспользовавшись тем, что git stash apply
не очищает разницу из стека тайника.
Если спрятанные файлы необходимо объединить с текущей версией, используйте предыдущие способы, используя diff.В противном случае вы можете использовать git pop
за их разоблачение, git add fileWantToKeep
для размещения вашего файла и выполните git stash save --keep-index
, за то, что спрятал всё, кроме того, что находится на сцене.Помните, что отличие этого способа от предыдущих в том, что он «вытаскивает» файл из тайника.Предыдущие ответы сохраняют это git checkout stash@{0} -- <filename>
так что это соответствует вашим потребностям.