Сохранять изменения в определенных файлах

У меня есть большой проект 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 .

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


person ewok    schedule 06.09.2012    source источник
comment
Взгляните на вопрос как я могу git спрятать определенный файл?, но это также звучит так, как будто в вашем случае вы можете git add файлы с изменениями, которые хотите сохранить, а затем git checkout -- ., а затем отключить добавленные файлы в конце, если хотите.   -  person mikej    schedule 06.09.2012
comment
В следующем Git 2.13 (второй квартал 2017 г.) фактическая команда будет git stash push -- file2.cpp file2.h file3.cpp. См. мой ответ ниже   -  person VonC    schedule 23.03.2017


Ответы (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, , как объясняет VonC в своем ответе.

person redhotvengeance    schedule 06.09.2012
comment
почему бы просто не убрать git stash drop вместо clear и просто сдуть ОДИН тайник, который вам не нужен? - person UpAndAdam; 23.03.2018
comment
@UpAndAdam Хорошее предложение. Я обновил ответ. - person redhotvengeance; 21.04.2018

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

Начиная с Git 2.13 (второй квартал 2017 г.), в git stash появится официальная возможность хранить изменения для определенных файлов с помощью

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

См. совершить 9e14090, совершить 1ada502, a> (28 февраля 2017 г.) и совершить 9ca6326, совершить 6f5ccd4, совершить f5727e2 (19 февраля 2017 г.) Томасом Гаммерером (tgummerer).
(объединено Junio ​​C Hamano - gitster - в commit 44c3f09, 10 марта 2017 г.)

Как теперь задокументировано:

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

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

Обратите внимание, как указано medmunds в комментарии, которые git stash будут использовать пути относительно корневой папки репозитория git.


А с помощью Git 2.26 (второй квартал 2020 г.) «git rm» и «git stash» изучают новый параметр «--pathspec-from-file».

Если у вас есть список файлов для хранения filesToStash.txt, этого достаточно:

git stash --pathspec-from-file=filesToStash.txt` is enough.
person VonC    schedule 22.03.2017
comment
Версия 2.13 (для Windows) не выпущена на дату этого комментария. - person ΩmegaMan; 08.05.2017
comment
@OmegaMan да: Git 2.13 (Linux) должен быть выпущен через два дня (10 мая): calendar.google.com/calendar/ (из stackoverflow.com/a/ 14931771/6309). Git для Windows должен быть выпущен в течение следующих 24–48 часов после этого. - person VonC; 08.05.2017
comment
@OmegaMan И ... выпущен! github.com/git-for-windows/ git / Release / tag / v2.13.0.windows.1 - person VonC; 10.05.2017
comment
Спасибо Вам за информацию. Сладкий! - person ΩmegaMan; 10.05.2017
comment
У меня возникла проблема с stash -p pathspec. Проблема Git PathSpec в Git Stash. - person ΩmegaMan; 11.05.2017
comment
Обратите внимание, что пути для git stash указаны относительно вашего git корня проекта - не < / i> текущий рабочий каталог (например, пути, перечисленные в git status). - person medmunds; 15.05.2017
comment
@medmunds Спасибо. Я включил ваш комментарий в ответ для большей наглядности. - person VonC; 15.05.2017
comment
то есть git stash push -- file2.cpp file2.h file3.cpp, чтобы было ясно - person Bernardo Dal Corno; 13.06.2019
comment
@ Z.Khullah, если пути для git stash относятся к корню проекта Git, а не к текущему рабочему каталогу, тогда он должен быть git stash push -- dir/file2.cpp dir/file2.h dir/file3.cp - person VonC; 13.06.2019

Хороший вариант - использовать интерактивный режим тайника.

git stash --patch

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

От man git-stash:

С помощью --patch вы можете интерактивно выбирать блоки из разницы между HEAD и рабочим деревом, которые нужно сохранить. Запись в тайнике построена так, что ее состояние индекса совпадает с состоянием индекса вашего репозитория, а ее рабочее дерево содержит только изменения, которые вы выбрали в интерактивном режиме. Затем выбранные изменения откатываются от вашего рабочего дерева. См. Раздел «Интерактивный режим» в git-add (1), чтобы узнать, как работать в режиме --patch.

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

person Diego V    schedule 14.04.2016

Вы также можете использовать 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
person Kashan    schedule 11.05.2017

Это хорошее применение для git diff и git apply IMO:

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

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

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

person robinst    schedule 06.09.2012