git 存储对特定文件的更改
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12305093/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Stash changes to specific files
提问by ewok
I have a large git project that I, stupidly, imported to eclipse and ran an autoformat on. Now, every file in the project is showing as modified. Rather than commit my formatted files, I would rather revert all the files that I have only been formatted and not had other changes. For instance:
我有一个大型 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
I know that file2.cpp
, file2.h
, and file3.cpp
have been modified with content (i.e., not just formatted). I want to stash the changes to these three files and then checkout an old revision, so that I can reapply the changes to these files after. I would rather avoid something like:
我知道file2.cpp
, file2.h
, 并且file3.cpp
已经修改了内容(即,不仅仅是格式化)。我想存储对这三个文件的更改,然后检出旧版本,以便我可以在之后重新应用对这些文件的更改。我宁愿避免类似的事情:
$ cp file2.cpp ~/tmp
$ git checkout blahblahblah
$ cp ~/tmp/file2.cpp .
If there's an obvious way to do this that doesnt involve stashing, let me know. whatever gets the job done.
如果有一种不涉及藏匿的明显方法可以做到这一点,请告诉我。无论什么都能完成工作。
采纳答案by redhotvengeance
You can add
the files with changes you want to keep, then stash
the rest of the files and clear the stash:
您可以add
保留要保留的更改的文件,然后stash
是其余文件并清除存储:
git add file2.cpp file2.h file3.cpp
git stash --keep-index
At this point, you've stashed your unwanted changes. If you'd like to permanently get rid of them, run:
此时,您已经隐藏了不需要的更改。如果您想永久摆脱它们,请运行:
git stash drop
Now you have file2.cpp
, file2.h
, and file3.cpp
staged for commit. If you then want to stash these files (and not commit them):
现在,您已经file2.cpp
、file2.h
和file3.cpp
准备提交。如果您想隐藏这些文件(而不是提交它们):
git reset
git stash
Now you'll be at your previous commit, with only those three files stashed.
现在您将处于之前的提交状态,只有这三个文件被隐藏。
Update:
更新:
Git 2.13 and later includes a more direct way to stash specific files with git stash push
, as VonC explains in his answer.
正如 VonC 在他的回答中所解释的那样git stash push
,Git 2.13 及更高版本包含一种更直接的方式来存储特定文件。
回答by VonC
I know that
file2.cpp
,file2.h
, andfile3.cpp
have been modified with content (i.e., not just formatted).
I want to stash the changes to these three files and then checkout an old revision, so that I can reapply the changes to these files after.
我知道
file2.cpp
,file2.h
, 并且file3.cpp
已经修改了内容(即,不仅仅是格式化)。
我想存储对这三个文件的更改,然后检出旧版本,以便我可以在之后重新应用对这些文件的更改。
With Git 2.13 (Q2 2017), git stash will have officially a way to stash changes for specific files with
在 Git 2.13(2017 年第二季度)中,git stash 将正式提供一种方法来存储特定文件的更改
git stash push [--] [<pathspec>...]
See commit 9e14090, commit 1ada502, commit df6bba0(28 Feb 2017), and commit 9ca6326, commit 6f5ccd4, commit f5727e2(19 Feb 2017) by Thomas Gummerer (tgummerer
).
(Merged by Junio C Hamano -- gitster
--in commit 44c3f09, 10 Mar 2017)
请参阅Thomas Gummerer ( ) 的commit 9e14090、commit 1ada502、commit df6bba0(2017 年 2 月 28 日)和commit 9ca6326、commit 6f5ccd4、commit f5727e2(2017 年 2 月 19 日)。(由Junio C Hamano合并-- --在commit 44c3f09,2017 年 3 月 10 日)tgummerer
gitster
As now documented:
正如现在记录的那样:
For quickly making a snapshot, you can omit "push".
In this mode, non-option arguments are not allowed to prevent a misspelled subcommand from making an unwanted stash.
The two exceptions to this arestash -p
which acts as alias forstash push -p
and pathspecs, which are allowed after a double hyphen--
for disambiguation.When pathspec is given to '
git stash push
', the new stash records the modified states only for the files that match the pathspec.
The index entries and working tree files are then rolled back to the state inHEAD
only for these files, too, leaving files that do not match the pathspec intact.
为了快速制作快照,您可以省略“推送”。
在这种模式下,不允许使用非选项参数来防止拼写错误的子命令进行不需要的存储。
对此的两个例外是stash -p
作为别名stash push -p
和路径规范,允许在双连字符后--
消除歧义。当 pathspec 被赋予 '
git stash push
' 时,新的存储仅记录与 pathspec 匹配的文件的修改状态。
然后,索引条目和工作树文件也将回滚到HEAD
仅针对这些文件的状态 ,从而使与路径规范不匹配的文件保持完整。
Note, as pointed out by medmundsin the comments, that git stash
would use paths relative to the root folder of the git repo.
请注意,正如medmunds在评论中指出的那样,这git stash
将使用相对于 git repo 根文件夹的路径。
And with Git 2.26 (Q2 2020), "git rm
" and "git stash
" learns the new "--pathspec-from-file
" option.
在Git 2.26(2020 年第二季度)中,“ git rm
”和“ git stash
”学习了新的“ --pathspec-from-file
”选项。
If you have a list of files to stash in filesToStash.txt
, then this is enough:
如果您有一个要存放的文件列表filesToStash.txt
,那么这就足够了:
git stash --pathspec-from-file=filesToStash.txt` is enough.
回答by Diego V
A nice option is using the interactive stash mode.
一个不错的选择是使用交互式存储模式。
git stash --patch
It works mostly like the interactive add mode: you are going to be presented with a series of diffs showing the changes you have in your working tree and you have to choose which files (or only certain parts of a file!) you want to stash, the rest will be left intact.
它的工作方式主要类似于交互式添加模式:您将看到一系列差异,显示您在工作树中所做的更改,您必须选择要隐藏的文件(或仅文件的某些部分!) ,其余的将保持不变。
From man git-stash
:
来自man git-stash
:
With --patch, you can interactively select hunks from the diff between HEAD and the working tree to be stashed. The stash entry is constructed such that its index state is the same as the index state of your repository, and its worktree contains only the changes you selected interactively. The selected changes are then rolled back from your worktree. See the "Interactive Mode" section of git-add(1)to learn how to operate the --patch mode.
使用 --patch,您可以交互地从 HEAD 和要隐藏的工作树之间的差异中选择大块头。存储条目的构造使其索引状态与存储库的索引状态相同,并且其工作树仅包含您交互选择的更改。然后,所选更改将从您的工作树中回滚。请参阅git-add(1)的“交互模式”部分以了解如何操作 --patch 模式。
In your case, you will be able to see formatting-only hunks and stash them individually, without loosing your meaningful changes.
在您的情况下,您将能够看到仅格式化的大块并将它们单独存储,而不会丢失有意义的更改。
回答by Kashan
You can also use git stash -p. This way you can select which hunks should be added to stash, whole files can be selected as well.
您也可以使用 git stash -p。通过这种方式,您可以选择应将哪些大块添加到存储中,也可以选择整个文件。
You'll be prompted with a few actions for each hunk:
系统会提示您对每个大块执行一些操作:
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
回答by robinst
That's a good use for git diff
and git apply
IMO:
这是一个很好用的git diff
和git apply
IMO:
git diff file2.cpp file2.h file3.cpp > ../my-changes.patch
git checkout ...
git apply ../my-changes.patch
After diff
, you can inspect the patch file to make sure that all your changes are there.
之后diff
,您可以检查补丁文件以确保所有更改都在那里。
Note that you may need to use the --reject
option to apply, in case the patch does not apply cleanly. Also see the man page for apply.