Я не думаю, что принятый ответ @ bukzor является правильным ответом на вопрос, который был задан. git stash --keep-indexсохраняет индекс, но он хранит все - и в индексе, и вне его.
Раман
@Antonio Мне кажется, что ваша награда на самом деле должна быть отдельным вопросом, поскольку оригинальный вопрос не имеет ничего общего с TortoiseGit.
JesusFreke
1
@JesusFreke Да, учитывая результат, который я мог бы сэкономить 50 повторений :) Это просто вопрос, на который вы будете перенаправлены, если попытаетесь найти «частичную черепаху». Черепаха не кажется популярной темой здесь stackoverflow.com/questions/tagged/tortoisegit
Антонио
7
>>>>>>>>> git diff -- *filename* > ~/patchтогда git checkout -- *filename*и позже можно повторно применить патч с помощьюgit apply ~/patch
neaumusic
36
Большинство существующих ответов ниже устарели. Начиная с Git 2.13 (Q2 2017), он поддерживается с git stash push [--] [<pathspec>...].
Охад Шнайдер
Ответы:
1372
Отказ от ответственности : следующий ответ для git перед git 2.13. Для git 2.13 и выше, проверьте другой ответ ниже .
Предупреждение
Как отмечено в комментариях, это помещает все в тайник, как поэтапный, так и не постановочный. --Keep-index просто оставляет индекс в покое после того, как тайник сделан. Это может вызвать конфликты слияния при последующем открытии тайника.
Это сохранит все, что вы еще не добавили. Просто git addвещи, которые вы хотите сохранить, а затем запустить его.
git stash --keep-index
Например, если вы хотите разделить старый коммит на более чем один набор изменений, вы можете использовать эту процедуру:
git rebase -i <last good commit>
Отметить некоторые изменения как edit.
git reset HEAD^
git add <files you want to keep in this change>
git stash --keep-index
Исправьте вещи по мере необходимости. Не забывайте о git addлюбых изменениях.
Я не уверен, почему за это проголосовали. У всех должно быть другое ожидание чем я. Оригинальный пост спрашивает "как спрятать только часть незафиксированных изменений?" Когда я использую git stash save -k, да индекс (зеленый в git stat) сохраняется, но весь набор изменений (зеленый и красный) идет в тайник. Это нарушает запрос ОП, «спрятать только некоторые изменения». Я хочу спрятать только некоторые из красных (для будущего использования).
@ Раман: Отлично! git stash -pэто именно то, что я искал. Интересно, этот переключатель был добавлен только недавно.
Pistos
14
ВНИМАНИЕ: git stash --keep-indexсломан. Если вы сделаете больше изменений, попробуйте git stash popпозже получить конфликты слияния, потому что тайник включает в себя измененные файлы, которые вы сохранили, а не только те, которые вы не сохранили. Например: я изменяю файлы A и B, затем коплю B, потому что я хочу проверить изменения в A; Я нахожу проблему с А, которую затем исправляю; Я совершаю A; Теперь я не могу распаковать, потому что старая версия A находится в тайнике без веской причины, вызывающей конфликт слияния. На практике у A и B может быть много файлов, возможно, даже двоичные изображения или что-то в этом роде, поэтому я в основном должен сдаться и потерять B.
rjmunro
3015
Вы также можете использовать git stash save -p "my commit message". Таким образом, вы можете выбрать, какие блоки должны быть добавлены в тайник, а также целые файлы.
Вам будет предложено несколько действий для каждого блока:
y - stash this hunk
n - do not stash this hunk
q - quit; do not stash this hunk or any of the remaining ones
a - stash this hunk and all later hunks in the file
d - do not stash this hunk or any of the later hunks in the file
g - select a hunk to go to
/ - search for a hunk matching the given regex
j - leave this hunk undecided, see next undecided hunk
J - leave this hunk undecided, see next hunk
k - leave this hunk undecided, see previous undecided hunk
K - leave this hunk undecided, see previous hunk
s - split the current hunk into smaller hunks
e - manually edit the current hunk
? - print help
Не было. Он был заимствован у Дарка примерно через 7 лет после свершившегося факта.
номен
6
Я наркоман TortoiseGit. Однако TortoiseGit не поддерживает stash -p. Я награждаю этот ответ, потому что он остается наиболее интерактивным / удобным для пользователя.
Антонио
27
Вы можете добавить git stash save -p my stash message:; поскольку порядок аргументации не очень интуитивен ...
Крис Мэйс
15
Между этим и git log -p, я думаю, -pфлаг должен означать «делай классную вещь, которую я хочу, но не знаю, как выразить».
Кайл Стрэнд
2
с какой стати этот великий ответ находится на 12-й позиции ?? после всех этих 0, +1, +2 ответов ??????
DenisFLASH
550
Поскольку git в основном занимается управлением всем содержимым и индексом репозитория (а не одним или несколькими файлами) git stash, неудивительно, чтосо всем рабочим каталогом,
На самом деле, начиная с Git 2.13 (Q2 2017), вы можете хранить отдельные файлы с помощью git stash push:
git stash push [--] [<pathspec>...]
Когда pathspecзадано ' git stash push', новый тайник записывает измененные состояния только для файлов, которые соответствуют спецификациям пути. Дополнительные сведения см. В разделе « Изменения в тайнике для определенных файлов ».
Упрощенный пример:
git stash push path/to/file
Тестовый пример для этой функции показывает еще несколько опций:
test_expect_success 'stash with multiple pathspec arguments' '
>foo &&
>bar &&
>extra &&
git add foo bar extra &&
git stash push -- foo bar &&
test_path_is_missing bar &&
test_path_is_missing foo &&
test_path_is_file extra &&
git stash pop &&
test_path_is_file foo &&
test_path_is_file bar &&
test_path_is_file extra
Исходный ответ (ниже, июнь 2010 г.) был о ручном выборе того, что вы хотите спрятать.
Это ( stash --patchоригинальное решение) хорошо, но часто я модифицировал много файлов, поэтому использование патча раздражает
bukzor «s ответ (upvoted, ноябрь 2011) предлагает более практичное решение, основанное на git add+git stash --keep-index .
Иди посмотри и провозгласи его ответ, который должен быть официальным (вместо моего).
Об этой опции chhh указывает альтернативный рабочий процесс в комментариях:
Вы должны " git reset --soft" после такого тайника вернуть себе чистую промежуточную стадию:
чтобы вернуться в исходное состояние, которое является чистой промежуточной областью и только с некоторыми выбранными нематериальными модификациями, можно мягко сбросить индекс, чтобы получить (без совершать что угодно, как ты - букзор - делал).
(Оригинальный ответ, июнь 2010 г .: тайник)
Тем git stash save --patchне менее, может позволяет вам получить частичное копирование вы после:
С помощью --patchвы можете в интерактивном режиме выбирать фрагменты в разнице между HEAD и рабочим деревом, которое нужно спрятать.
Запись stash составлена таким образом, что ее индексное состояние совпадает с индексным состоянием вашего репозитория, а его рабочее дерево содержит только изменения, выбранные вами в интерактивном режиме. Выбранные изменения затем откатываются с вашего рабочего дерева.
Однако это сохранит полный индекс (который может быть не тем, что вы хотите, поскольку он может включать другие уже проиндексированные файлы), а также частичное рабочее дерево (которое может выглядеть как тот, который вы хотите сохранить).
git stash --patch --no-keep-index
может быть лучше.
Если --patchне работает, ручной процесс может:
Для одного или нескольких файлов промежуточным решением будет:
Это хорошо, но часто я модифицировал много файлов, поэтому использование патча раздражает
Casebash
6
@VonC: Это хороший стиль - иметь только один ответ на каждый ответ. Кроме того, копировать чужие ответы в свои собственные дурные манеры.
Букзор
3
@bukzor: Мне жаль, если мой отредактированный ответ показался неправильным. Мое единственное намерение состояло в том, чтобы сделать ваш ответ более заметным. Я снова отредактировал свой пост, чтобы прояснить это намерение.
git is fundamentally about managing a all repository content and index and not one or several files- эта реализация затмевает решаемую проблему; это объяснение, но не оправдание. Любая система контроля версий - это «управление несколькими файлами». Просто посмотрите, какие комментарии получили наибольшее количество голосов.
Виктор Сергиенко
90
Когда git stash -p(или git add -pс stash --keep-index) было бы слишком громоздким, я нашел, что проще в использовании diff, checkoutи apply:
Чтобы «спрятать» определенный файл / каталог только:
Интересная альтернатива git add -pя упоминал в своем ответе выше. +1.
VonC
11
Обратите внимание, что если у вас есть двоичные файлы (например, PNG), они не будут выводиться в файл diff. Так что это не 100% решение.
void.pointer
1
@RobertDailey: Это интересный момент для меня, как git diff > file.diffи git applyмои обычные инструменты частичного тайника. Возможно, мне придется рассмотреть возможность перехода git stash -pна более крупные наборы изменений.
thekingoftruth
1
@thekingoftruth Вот псевдоним я использую для создания файлов исправлений, и это делает поддержку бинарные файлы: patch = log --pretty=email --patch-with-stat --reverse --full-index --binary. Обратите внимание, однако, что это требует внесения изменений для исправления.
void.pointer
2
Это не сработало для меня, если файл для сохранения был что-то вроде ../../foo/bar.txt. Патч генерирует ОК, но затем мне нужно перейти в корень репозитория, чтобы применить патч. Так что если у вас возникли проблемы с этим - просто убедитесь, что вы делаете это из корневого каталога репозитория.
Майкл Андерсон
86
Используйте git stash push, как это:
git stash push [--] [<pathspec>...]
Например:
git stash push -- my/file.sh
Это доступно с Git 2.13, выпущенного весной 2017 года.
Я рад, что Git продвигается так быстро, долгое время это было невозможно, а затем была выпущена версия 2.13, и внезапно стало доступно простое решение!
Sandstrom
1
@VonC вы правы, вы также упоминаете правильный ответ, однако, между двумя ответами, этот легче читать (нет запутанного текста, и есть также пример). Возможно, они должны были отредактировать твой ответ вместо этого
Утопик
@Utopik У меня был "ты прав" ... но да, я отредактировал свой ответ, чтобы включить пример.
VonC
Используется ли затем git stash applyдля восстановления скрытых изменений?
Чад
49
Допустим, у вас есть 3 файла
a.rb
b.rb
c.rb
и вы хотите спрятать только b.rb и c.rb, но не a.rb
вы можете сделать что-то вроде этого
# commit the files temporarily you don't want to stash
git add a.rb
git commit -m "temp"
# then stash the other files
git stash save "stash message"
# then undo the previous temp commit
git reset --soft HEAD^
git reset
# Save everything
git stash
# Re-apply everything, but keep the stash
git stash apply
git checkout <"files you don't want in your stash"># Save only the things you wanted saved
git stash
# Re-apply the original state and drop it from your stash
git stash apply stash@{1}
git stash drop stash@{1}
git checkout <"files you put in your stash">
Я придумал это после того, как я (еще раз) зашел на эту страницу, и мне не понравились первые два ответа (первый ответ просто не отвечает на вопрос, и мне не очень понравилась работа с -pинтерактивным режимом).
Идея та же, что и в @VonC, предлагая использовать файлы вне репозитория: вы сохраняете где-то нужные изменения, удаляете ненужные изменения в своем хранилище, а затем повторно применяете изменения, которые вы удалили. Тем не менее, я использовал git stash как «где-то» (и в результате есть один дополнительный шаг в конце: удаление канавок, которые вы поместили в stash, потому что вы также убрали их с пути).
я предпочитаю такой подход больше всего. Это обеспечивает легкий рабочий процесс в tortoisegit, используя только команды stash и revert.
Марк Ч
Ссылка на ответы по SO с использованием позиций не рекомендуется. Позиции меняются по мере изменения рейтинга.
Брайан Эш
2
@BryanAsh Ну, здесь это не так важно. Я даю анекдот, а не ссылаюсь на другие ответы. Суть в том, что мне не понравились ответы сообщества, а не то, что на самом деле содержат эти ответы. Кроме того, разрыв в 900 голосов между вторым и третьим ответом делает это вряд ли изменится в ближайшем будущем, и, если он когда-либо изменится, я всегда могу отредактировать его так, чтобы он говорил «сверху ответов». На самом деле, я не понимаю, как это может быть проблемой в этой ситуации.
Джаспер
23
Обновление (14.02.2015) - Я немного переписал скрипт, чтобы лучше справляться со случаями конфликтов, которые теперь должны быть представлены в виде неконтролируемых конфликтов, а не файлов .rej.
Я часто нахожу более интуитивным делать обратный подход @ bukzor. То есть, чтобы внести некоторые изменения, а затем спрятать только те поэтапные изменения.
К сожалению, git не предлагает git stash --only-index или аналогичный, поэтому я создал сценарий для этого.
#!/bin/sh
# first, go to the root of the git repo
cd `git rev-parse --show-toplevel`
# create a commit with only the stuff in staging
INDEXTREE=`git write-tree`
INDEXCOMMIT=`echo "" | git commit-tree $INDEXTREE -p HEAD`
# create a child commit with the changes in the working tree
git add -A
WORKINGTREE=`git write-tree`
WORKINGCOMMIT=`echo "" | git commit-tree $WORKINGTREE -p $INDEXCOMMIT`
# get back to a clean state with no changes, staged or otherwise
git reset -q --hard
# Cherry-pick the index changes back to the index, and stash.
# This cherry-pick is guaranteed to succeed
git cherry-pick -n $INDEXCOMMIT
git stash
# Now cherry-pick the working tree changes. This cherry-pick may fail
# due to conflicts
git cherry-pick -n $WORKINGCOMMIT
CONFLICTS=`git ls-files -u`
if test -z "$CONFLICTS"; then
# If there are no conflicts, it's safe to reset, so that
# any previously unstaged changes remain unstaged
#
# However, if there are conflicts, then we don't want to reset the files
# and lose the merge/conflict info.
git reset -q
fi
Вы можете сохранить вышеприведенный скрипт как git-stash-indexгде-то на вашем пути, а затем вызвать его как git stash-index
# <hack hack hack>
git add <files that you want to stash>
git stash-index
Теперь тайник содержит новую запись, которая содержит только те изменения, которые вы поставили, а ваше рабочее дерево по-прежнему содержит любые неустановленные изменения.
В некоторых случаях изменения рабочего дерева могут зависеть от изменений индекса, поэтому при сохранении изменений индекса возникает конфликт рабочего дерева. В этом случае вы получите обычные неразрешенные конфликты, которые вы можете разрешить с помощью git merge / git mergetool / etc.
Рекомендовать pushdвместо cdи popdв конце сценария, чтобы в случае успешного выполнения сценария пользователь оказался в том же каталоге, что и до его запуска.
Nate
1
@Nate: насколько я знаю, он должен изменять каталог для пользователя только в том случае, если он использует сценарий. Если вы запускаете скрипт нормально (~ / bin / git-stash-index) или через git (git stash-index), он запускается в отдельном сеансе терминала, и любые изменения рабочего каталога в этом сеансе не влияют на рабочий каталог в терминальной сессии пользователя. Знаете ли вы о частом случае использования, когда это не так? (кроме поиска сценария, который я бы не
назвал
20
Если вы не хотите указывать сообщение с вашими скрытыми изменениями, передайте имя файла после двойной тире.
$ git stash -- filename.ext
Если это неотслеживаемый / новый файл, вам придется сначала его поместить.
Этот ответ многословен, это сжато. Если это кому-то поможет, я оставлю это. Никто на этой странице не упоминает этот синтаксис и результат - вместо этого они упоминают `git stash push`.
Морской
Это ответ, который я искал. Спасибо! +1
Никодп
19
Поскольку создание веток в Git тривиально, вы можете просто создать временную ветку и проверить в ней отдельные файлы.
Вы не можете создать ветку с неустановленными изменениями. Вы можете легко переместить все изменения в новую ветвь (stash / stash pop), но затем вы вернетесь к исходной точке: как вы тестируете свою ветку только с некоторыми из этих правок, не теряя другие?
Букзор
7
Вы не можете переключать филиалы, если у вас есть локальные изменения. Однако вы можете создать новую ветку и выборочно добавить / зафиксировать файлы, а затем создать другую ветку и сделать то же самое рекурсивно ... затем извлечь исходную ветку и выборочно объединить обратно. Я только что сделал это. На самом деле это кажется естественным способом сделать что-то, поскольку вы по сути создаете функциональные ветви.
Иэн
3
@iain вы можете переключать ветки, если у вас есть локальные изменения, если они не требуют слияния. Смотрите пример Gist . Это верно как минимум для Git v2.7.0.
Это ничего нового не добавляет. Git Stash Push уже упоминается в нескольких ответах
JesusFreke
12
Сохраните следующий код в файл, например, с именем stash. Использование есть stash <filename_regex>. Аргумент - это регулярное выражение для полного пути к файлу. Например, чтобы спрятать a / b / c.txt, stash a/b/c.txtили stash .*/c.txtи т. Д.
Отличный метод. Я бы выбрал это в качестве ответа. Совет для будущих читателей: вы должны соответствовать на полном пути. например, stash subdir / foo.c
er0
12
На тот случай, если вы на самом деле имеете в виду отмену изменений при каждом использовании git stash(и на самом деле не используете git stash для временного хранения), в этом случае вы можете использовать
git checkout -- <file>
[ ПРИМЕЧАНИЕ ]
Это git stashпросто более быстрая и простая альтернатива ветвлению и тому подобному.
Проблема с «промежуточным» решением VonC по копированию файлов за пределы репозитория Git заключается в том, что вы теряете информацию о пути, что делает копирование нескольких файлов позже в некоторой стычке.
Обнаружить, что проще использовать tar (вероятно, схожие инструменты) вместо copy:
tar cvf /tmp/stash.tar path / to / some / путь к файлу / to / some / other / file (... и т. д.)
git checkout path / to / some / путь к файлу / to / some / other / file
checkout -fне нужно, checkout(без -f) достаточно, я обновил ответ.
eleotlecram
8
Иногда я вносил несвязанные изменения в свою ветку, прежде чем зафиксировать ее, и я хочу переместить ее в другую ветку и зафиксировать ее отдельно (например, master). Я делаю это:
git stash
git checkout master
git stash pop
git add <files that you want to commit>
git commit -m 'Minor feature'
git stash
git checkout topic1
git stash pop
...<resume work>...
Обратите внимание, что первое stash& stash popможет быть исключено, вы можете перенести все свои изменения в masterфилиал при оформлении заказа, но только при отсутствии конфликтов. Также, если вы создаете новую ветку для частичных изменений, вам понадобится тайник.
Вы можете упростить его, не допуская конфликтов и новых веток:
git checkout master
git add <files that you want to commit>
git commit -m 'Minor feature'
git checkout topic1
...<resume work>...
Все это можно сделать за несколько секунд в SourceTree, где вы можете просто щелкнуть файлы (или даже отдельные строки), которые вы хотите добавить. После добавления просто передайте их во временную фиксацию. Далее, установите флажок, чтобы добавить все изменения, затем нажмите stash, чтобы спрятать все. С сохраненными изменениями в пути, взгляните на ваш список коммитов и запишите хеш для коммита перед вашим временным коммитом, затем запустите 'git reset hash_b4_temp_commit', который в основном похож на "выталкивание" коммита путем сброса вашей ветви в совершить прямо перед этим. Теперь у вас есть только то, что вы не хотели спрятать.
Я бы использовал git stash save --patch. Я не считаю, что интерактивность раздражает, потому что во время нее есть опции для применения желаемой операции ко всем файлам.
Я попробовал, но ничего не происходит. Когда у git applyменя нет ошибок, но изменения не возвращаются ни
ClementWalter
Файл патча, созданный вами в / tmp, вероятно, был удален. Возможно, вы перезагрузились между diff и apply. Попробуйте другое более постоянное местоположение. Это работает. Также проверьте содержимое файла патча.
Кристоф Фондачи
4
Я просмотрел ответы и комментарии для этой и ряда похожих тем. Имейте в виду, что ни одна из следующих команд не подходит для того, чтобы иметь возможность хранить любые определенные отслеживаемые / неотслеживаемые файлы :
git stash -p (--patch): выберите фрагменты вручную, за исключением неотслеживаемых файлов
git stash -k (--keep-index): хранить все отслеживаемые / неотслеживаемые файлы и хранить их в рабочем каталоге
git stash -u (--include-untracked): хранить все отслеживаемые / неотслеживаемые файлы
git stash -p (--patch) -u (--include-untracked): неверная команда
В настоящее время наиболее разумным способом сохранения любых определенных отслеживаемых / неотслеживаемых файлов является:
Временно зафиксируйте файлы, которые вы не хотите хранить
Для хранения одного файла используйте git stash --patch [file].
Это будет подсказка: Stash this hunk [y,n,q,a,d,j,J,g,/,e,?]? ?. Просто введите a(спрятать этот кусок и все последующие фрагменты в файле), и все в порядке.
@FilipeEsperandio pushработает только в более свежих версиях Git save. В любом случае pushили saveподразумевается путем вызова stash: «Вызов git stash без каких-либо аргументов эквивалентен git stash push», docs
patrick
2
Похожая ситуация. Совершил и понял, что это не хорошо.
git commit -a -m "message"
git log -p
На основании ответов это помогло мне.
# revert to previous state, keeping the files changed
git reset HEAD~
#make sure it's ok
git diff
git status
#revert the file we don't want to be within the commit
git checkout specs/nagios/nagios.spec
#make sure it's ok
git status
git diff
#now go ahead with commit
git commit -a -m "same|new message"
#eventually push tu remote
git push
Я не знаю, как это сделать в командной строке, только используя SourceTree. Допустим, вы изменили файл A и имеете два блока изменений в файле B. Если вы хотите сохранить только второй блок в файле B и оставить все остальное без изменений, сделайте следующее:
Сцена все
Внесите изменения в вашу рабочую копию, чтобы отменить все изменения в файле A. (например, запустите внешний инструмент сравнения и сопоставьте файлы).
Сделайте так, чтобы файл B выглядел так, как будто к нему применено только второе изменение. (например, запустите внешний инструмент сравнения и отмените первое изменение.)
Создайте тайник с помощью «Сохранить поэтапные изменения».
git add . //stage all the files
git reset <pathToFileWillBeStashed> //unstage file which will be stashed
git stash //stash the file(s)
git reset . // unstage all staged files
git stash pop // unstash file(s)
Ну, ты не должен этого делать. Ответ должен обеспечить решение вопроса. Вы можете просто задать свой вопрос.
L_J
Это решение является одним из самых простых ответов на этот вопрос. Прочитайте вопрос, сравните все ответы и мои, тогда, если у вас есть какие-либо сомнения, что этот ответ не является ни применимым решением, ни недостаточной информацией по этому вопросу, тогда мы можем поговорить снова.
Celikz
Это не сработает, потому что третья команда, "git stash", не учитывает промежуточные файлы. Как промежуточные, так и нестандартные файлы попадут в тайник. В частности, на вопрос, как спрятать только один файл
CyberProdigy
0
Одним сложным способом было бы сначала зафиксировать все:
git add -u
git commit // creates commit with sha-1 A
Вернитесь к исходному коммиту, но извлеките the_one_file из нового коммита:
git reset --hard HEAD^
git checkout A path/to/the_one_file
Теперь вы можете спрятать the_one_file:
git stash
Очистите, сохранив зафиксированный контент в вашей файловой системе и вернув исходный коммит:
git stash --keep-index
сохраняет индекс, но он хранит все - и в индексе, и вне его.git diff -- *filename* > ~/patch
тогдаgit checkout -- *filename*
и позже можно повторно применить патч с помощьюgit apply ~/patch
git stash push [--] [<pathspec>...]
.Ответы:
Отказ от ответственности : следующий ответ для git перед git 2.13. Для git 2.13 и выше, проверьте другой ответ ниже .
Предупреждение
Как отмечено в комментариях, это помещает все в тайник, как поэтапный, так и не постановочный. --Keep-index просто оставляет индекс в покое после того, как тайник сделан. Это может вызвать конфликты слияния при последующем открытии тайника.
Это сохранит все, что вы еще не добавили. Просто
git add
вещи, которые вы хотите сохранить, а затем запустить его.Например, если вы хотите разделить старый коммит на более чем один набор изменений, вы можете использовать эту процедуру:
git rebase -i <last good commit>
edit
.git reset HEAD^
git add <files you want to keep in this change>
git stash --keep-index
git add
любых изменениях.git commit
git stash pop
git rebase --continue
источник
git stash save -k
, да индекс (зеленый вgit stat
) сохраняется, но весь набор изменений (зеленый и красный) идет в тайник. Это нарушает запрос ОП, «спрятать только некоторые изменения». Я хочу спрятать только некоторые из красных (для будущего использования).git stash -p
это именно то, что я искал. Интересно, этот переключатель был добавлен только недавно.git stash --keep-index
сломан. Если вы сделаете больше изменений, попробуйтеgit stash pop
позже получить конфликты слияния, потому что тайник включает в себя измененные файлы, которые вы сохранили, а не только те, которые вы не сохранили. Например: я изменяю файлы A и B, затем коплю B, потому что я хочу проверить изменения в A; Я нахожу проблему с А, которую затем исправляю; Я совершаю A; Теперь я не могу распаковать, потому что старая версия A находится в тайнике без веской причины, вызывающей конфликт слияния. На практике у A и B может быть много файлов, возможно, даже двоичные изображения или что-то в этом роде, поэтому я в основном должен сдаться и потерять B.Вы также можете использовать
git stash save -p "my commit message"
. Таким образом, вы можете выбрать, какие блоки должны быть добавлены в тайник, а также целые файлы.Вам будет предложено несколько действий для каждого блока:
источник
stash -p
. Я награждаю этот ответ, потому что он остается наиболее интерактивным / удобным для пользователя.git stash save -p my stash message
:; поскольку порядок аргументации не очень интуитивен ...git log -p
, я думаю,-p
флаг должен означать «делай классную вещь, которую я хочу, но не знаю, как выразить».Поскольку git в основном занимается управлением всем содержимым и индексом репозитория (а не одним или несколькими файлами)
git stash
, неудивительно, чтосо всем рабочим каталогом,На самом деле, начиная с Git 2.13 (Q2 2017), вы можете хранить отдельные файлы с помощью
git stash push
:Упрощенный пример:
Тестовый пример для этой функции показывает еще несколько опций:
Исходный ответ (ниже, июнь 2010 г.) был о ручном выборе того, что вы хотите спрятать.
Casebash комментарии:
bukzor «s ответ (upvoted, ноябрь 2011) предлагает более практичное решение, основанное на
git add
+git stash --keep-index
.Иди посмотри и провозгласи его ответ, который должен быть официальным (вместо моего).
Об этой опции chhh указывает альтернативный рабочий процесс в комментариях:
(Оригинальный ответ, июнь 2010 г .: тайник)
Тем
git stash save --patch
не менее, может позволяет вам получить частичное копирование вы после:Однако это сохранит полный индекс (который может быть не тем, что вы хотите, поскольку он может включать другие уже проиндексированные файлы), а также частичное рабочее дерево (которое может выглядеть как тот, который вы хотите сохранить).
может быть лучше.
Если
--patch
не работает, ручной процесс может:Для одного или нескольких файлов промежуточным решением будет:
(на самом деле, eleotlecram предлагает интересную альтернативу )
git stash
git stash
# на этот раз спрятаны только те файлы, которые вы хотитеgit stash pop stash@{1}
# повторно применить все ваши модификации файловgit checkout -- afile
# сбросить файл до содержимого HEAD перед любыми локальными изменениямиВ конце этого довольно громоздкого процесса у вас будет спрятан только один или несколько файлов.
источник
git reset
(смешанный)git is fundamentally about managing a all repository content and index and not one or several files
- эта реализация затмевает решаемую проблему; это объяснение, но не оправдание. Любая система контроля версий - это «управление несколькими файлами». Просто посмотрите, какие комментарии получили наибольшее количество голосов.Когда
git stash -p
(илиgit add -p
сstash --keep-index
) было бы слишком громоздким, я нашел, что проще в использованииdiff
,checkout
иapply
:Чтобы «спрятать» определенный файл / каталог только:
Потом потом
источник
git add -p
я упоминал в своем ответе выше. +1.git diff > file.diff
иgit apply
мои обычные инструменты частичного тайника. Возможно, мне придется рассмотреть возможность переходаgit stash -p
на более крупные наборы изменений.patch = log --pretty=email --patch-with-stat --reverse --full-index --binary
. Обратите внимание, однако, что это требует внесения изменений для исправления.../../foo/bar.txt
. Патч генерирует ОК, но затем мне нужно перейти в корень репозитория, чтобы применить патч. Так что если у вас возникли проблемы с этим - просто убедитесь, что вы делаете это из корневого каталога репозитория.Используйте
git stash push
, как это:Например:
Это доступно с Git 2.13, выпущенного весной 2017 года.
источник
git stash push
уже упоминал в своем ответе выше в марте прошлого года, 5 месяцев назад. И я подробно описал эту новую команду Git 2.13 здесь: stackoverflow.com/a/42963606/6309 .git stash apply
для восстановления скрытых изменений?Допустим, у вас есть 3 файла
и вы хотите спрятать только b.rb и c.rb, но не a.rb
вы можете сделать что-то вроде этого
И вы сделали! НТН.
источник
Еще один способ сделать это:
Я придумал это после того, как я (еще раз) зашел на эту страницу, и мне не понравились первые два ответа (первый ответ просто не отвечает на вопрос, и мне не очень понравилась работа с
-p
интерактивным режимом).Идея та же, что и в @VonC, предлагая использовать файлы вне репозитория: вы сохраняете где-то нужные изменения, удаляете ненужные изменения в своем хранилище, а затем повторно применяете изменения, которые вы удалили. Тем не менее, я использовал git stash как «где-то» (и в результате есть один дополнительный шаг в конце: удаление канавок, которые вы поместили в stash, потому что вы также убрали их с пути).
источник
Обновление (14.02.2015) - Я немного переписал скрипт, чтобы лучше справляться со случаями конфликтов, которые теперь должны быть представлены в виде неконтролируемых конфликтов, а не файлов .rej.
Я часто нахожу более интуитивным делать обратный подход @ bukzor. То есть, чтобы внести некоторые изменения, а затем спрятать только те поэтапные изменения.
К сожалению, git не предлагает git stash --only-index или аналогичный, поэтому я создал сценарий для этого.
Вы можете сохранить вышеприведенный скрипт как
git-stash-index
где-то на вашем пути, а затем вызвать его как git stash-indexТеперь тайник содержит новую запись, которая содержит только те изменения, которые вы поставили, а ваше рабочее дерево по-прежнему содержит любые неустановленные изменения.
В некоторых случаях изменения рабочего дерева могут зависеть от изменений индекса, поэтому при сохранении изменений индекса возникает конфликт рабочего дерева. В этом случае вы получите обычные неразрешенные конфликты, которые вы можете разрешить с помощью git merge / git mergetool / etc.
источник
pushd
вместоcd
иpopd
в конце сценария, чтобы в случае успешного выполнения сценария пользователь оказался в том же каталоге, что и до его запуска.Если вы не хотите указывать сообщение с вашими скрытыми изменениями, передайте имя файла после двойной тире.
Если это неотслеживаемый / новый файл, вам придется сначала его поместить.
Этот метод работает в git версии 2.13+
источник
Поскольку создание веток в Git тривиально, вы можете просто создать временную ветку и проверить в ней отдельные файлы.
источник
Вы можете просто сделать это:
или с дополнительным сообщением
источник
Сохраните следующий код в файл, например, с именем
stash
. Использование естьstash <filename_regex>
. Аргумент - это регулярное выражение для полного пути к файлу. Например, чтобы спрятать a / b / c.txt,stash a/b/c.txt
илиstash .*/c.txt
и т. Д.Код для копирования в файл:
источник
На тот случай, если вы на самом деле имеете в виду отмену изменений при каждом использовании
git stash
(и на самом деле не используете git stash для временного хранения), в этом случае вы можете использовать[ ПРИМЕЧАНИЕ ]
Это
git stash
просто более быстрая и простая альтернатива ветвлению и тому подобному.источник
Проблема с «промежуточным» решением VonC по копированию файлов за пределы репозитория Git заключается в том, что вы теряете информацию о пути, что делает копирование нескольких файлов позже в некоторой стычке.
Обнаружить, что проще использовать tar (вероятно, схожие инструменты) вместо copy:
источник
checkout -f
не нужно,checkout
(без-f
) достаточно, я обновил ответ.Иногда я вносил несвязанные изменения в свою ветку, прежде чем зафиксировать ее, и я хочу переместить ее в другую ветку и зафиксировать ее отдельно (например, master). Я делаю это:
Обратите внимание, что первое
stash
&stash pop
может быть исключено, вы можете перенести все свои изменения вmaster
филиал при оформлении заказа, но только при отсутствии конфликтов. Также, если вы создаете новую ветку для частичных изменений, вам понадобится тайник.Вы можете упростить его, не допуская конфликтов и новых веток:
Копить даже не нужно ...
источник
Это можно легко сделать за 3 шага, используя SourceTree.
Все это можно сделать за несколько секунд в SourceTree, где вы можете просто щелкнуть файлы (или даже отдельные строки), которые вы хотите добавить. После добавления просто передайте их во временную фиксацию. Далее, установите флажок, чтобы добавить все изменения, затем нажмите stash, чтобы спрятать все. С сохраненными изменениями в пути, взгляните на ваш список коммитов и запишите хеш для коммита перед вашим временным коммитом, затем запустите 'git reset hash_b4_temp_commit', который в основном похож на "выталкивание" коммита путем сброса вашей ветви в совершить прямо перед этим. Теперь у вас есть только то, что вы не хотели спрятать.
источник
Я бы использовал
git stash save --patch
. Я не считаю, что интерактивность раздражает, потому что во время нее есть опции для применения желаемой операции ко всем файлам.источник
git stash -p
позволяет быстро спрятать весь файл и выйти из него.Каждый ответ здесь такой сложный ...
Что по этому поводу "прятать":
Это чтобы вернуть файл обратно:
Точно такое же поведение, как при сохранении одного файла и его возврате.
источник
git apply
меня нет ошибок, но изменения не возвращаются ниЯ просмотрел ответы и комментарии для этой и ряда похожих тем. Имейте в виду, что ни одна из следующих команд не подходит для того, чтобы иметь возможность хранить любые определенные отслеживаемые / неотслеживаемые файлы :
git stash -p (--patch)
: выберите фрагменты вручную, за исключением неотслеживаемых файловgit stash -k (--keep-index)
: хранить все отслеживаемые / неотслеживаемые файлы и хранить их в рабочем каталогеgit stash -u (--include-untracked)
: хранить все отслеживаемые / неотслеживаемые файлыgit stash -p (--patch) -u (--include-untracked)
: неверная командаВ настоящее время наиболее разумным способом сохранения любых определенных отслеживаемых / неотслеживаемых файлов является:
Я написал простой скрипт для этой процедуры в ответ на другой вопрос , и здесь есть шаги для выполнения процедуры в SourceTree .
источник
Решение
Локальные изменения:
Чтобы создать тайник "my_stash" только с изменениями в file_C :
Выполнено.
объяснение
Вы можете использовать git status между шагами, чтобы увидеть, что происходит.
источник
При попытке переключения между двумя ветками возникает такая ситуация.
Попробуйте добавить файлы, используя "
git add filepath
".Позже выполните эту строку
источник
Для хранения одного файла используйте
git stash --patch [file]
.Это будет подсказка:
Stash this hunk [y,n,q,a,d,j,J,g,/,e,?]? ?
. Просто введитеa
(спрятать этот кусок и все последующие фрагменты в файле), и все в порядке.источник
push
как вgit stash push --patch [file]
push
работает только в более свежих версиях Gitsave
. В любом случаеpush
илиsave
подразумевается путем вызоваstash
: «Вызов git stash без каких-либо аргументов эквивалентен git stash push», docsПохожая ситуация. Совершил и понял, что это не хорошо.
На основании ответов это помогло мне.
источник
В этой ситуации я
git add -p
(интерактивно),git commit -m blah
а затем прячу то, что осталось, если это необходимо.источник
Я не знаю, как это сделать в командной строке, только используя SourceTree. Допустим, вы изменили файл A и имеете два блока изменений в файле B. Если вы хотите сохранить только второй блок в файле B и оставить все остальное без изменений, сделайте следующее:
источник
источник
Одним сложным способом было бы сначала зафиксировать все:
Вернитесь к исходному коммиту, но извлеките the_one_file из нового коммита:
Теперь вы можете спрятать the_one_file:
Очистите, сохранив зафиксированный контент в вашей файловой системе и вернув исходный коммит:
Да, немного неловко ...
источник
Я не нашел ответа на вопрос, что мне нужно, и это так просто, как:
Это прячет ровно один файл.
источник
Быстрый ответ
Чтобы вернуть определенный измененный файл в git, вы можете сделать следующую строку:
Вот фактический пример:
источник
Если вы хотите сохранить некоторые измененные файлы, просто
Это сохранит все неустановленные измененные файлы
источник