Изменения Stash в определенных файлах

у меня есть большой проект git, который я, глупо, импортировал в eclipse и запустил автоформат. Теперь каждый файл в проекте отображается как измененный. Вместо того, чтобы фиксировать мои отформатированные файлы, я бы предпочел вернуть все файлы, которые я только отформатировал и не имел других изменений. Например:

$ git status
# On branch master
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#   (commit or discard the untracked or modified content in submodules)

#     modified: dir/file1.cpp
#     modified: dir/file1.h
#     modified: dir/file2.cpp
#     modified: dir/file2.h
#     modified: dir/file3.cpp
#     modified: dir/file3.h
#     modified: dir/file4.cpp
#     modified: dir/file4.h

Я знаю, что file2.cpp, file2.h и file3.cpp были изменены с содержанием (т. е. не только отформатированы). Я хочу занести изменения в эти три файла и затем проверьте старую ревизию, чтобы я мог повторно применить изменения к этим файлам после. Я бы предпочел избежать чего-то вроде:

$ cp file2.cpp ~/tmp
$ git checkout blahblahblah
$ cp ~/tmp/file2.cpp .

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

5 ответов


вы можете add файлы с изменениями, которые вы хотите сохранить, затем stash остальные файлы и очистить тайник:

git add file2.cpp file2.h file3.cpp
git stash --keep-index

на данный момент вы спрятали свои нежелательные изменения. Если вы хотите навсегда избавиться от них, запустите:

git stash drop

теперь у вас есть file2.cpp, file2.h и file3.cpp устроили для фиксации. Если вы хотите сохранить эти файлы (и не зафиксировать их):

git reset
git stash

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

обновление:

Git 2.13 и более поздняя версия включает в себя более прямой способ хранения определенных файлов с git stash push, как объясняет Вонк в своем ответе.


Я знаю, что file2.cpp, file2.h и file3.cpp были изменены с содержанием (т. е. не только отформатированы).
Я хочу занести изменения в эти три файла, а затем проверить старую редакцию, чтобы я мог повторно применить изменения к этим файлам после.

С Git 2.13 (Q2 2017), git stash будет официально иметь способ заначки изменений для конкретных файлов с

git stash push [--] [<pathspec>...]

посмотреть совершить 9e14090, совершить 1ada502, совершить df6bba0 (28 февраля 2017), и совершить 9ca6326, совершить 6f5ccd4, совершить f5727e2 (19 Feb 2017) by Томас Gummerer (tgummerer).
(слитый Junio C Hamano -- gitster -- на совершить 44c3f09, 10 марта 2017)

As теперь документально:

для быстро делать снимок, вы можете опустить "толчок".
В этом режиме аргументы non-option не разрешены для предотвращения ошибки от создания нежелательной заначки.
Два исключения из этого являются stash -p который действует как псевдоним для stash push -p и pathspecs, которые разрешены после двойного дефиса -- для уточнения.

когда pathspec дается 'git stash push', новый тайник записывает измененные состояния только для файлов, соответствующих pathspec.
Индекс записи и рабочие файлы дерева затем откатываются в состояние in HEAD только для этих файлов тоже, оставляя файлы, которые не соответствуют pathspec нетронутыми.

Примечание, как указано medmunds на комментарии, что git stash использовать пути относительно корневой папки репозитория git.


хорошим вариантом является использование интерактивного режима тайника.

git stash --patch

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

С man git-stash:

With --patch, вы можете интерактивно выбирать куски из разницы между головой и рабочее дерево, которое нужно спрятать. Запись stash построена таким образом, что ее состояние индекса совпадает с состоянием индекса репозитория, а ее рабочее дерево содержит только изменения, выбранные вами в интерактивном режиме. Выбранные изменения затем откатываются из рабочего дерева. Вижу раздел "интерактивный режим" git-add (1) научиться работать режиме --патч.

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


это хорошее использование для git diff и git apply ИМО:

git diff file2.cpp file2.h file3.cpp > ../my-changes.patch
git checkout ...
git apply ../my-changes.patch

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

обратите внимание, что вам может понадобиться, чтобы использовать применить, в случае если патч не применяется, чисто. Также см. man-страница для apply.


вы также можете использовать git stash-p. Таким образом, вы можете выбрать, какие куски должны быть добавлены в тайник, целые файлы также могут быть выбраны.

вам будет предложено несколько действий для каждого куска:

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