将更改隐藏到特定文件中

我有一个很大的 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.cppfile2.hfile3.cpp已经用内容进行了修改(即,不仅仅是格式化)。我希望将更改隐藏到这三个文件中,然后签出一个旧的修订版,以便之后可以将更改重新应用到这些文件中。我宁愿避免这样的事情:

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

如果有一个显而易见的方法,不涉及藏匿,让我知道。只要能完成任务就行。

70028 次浏览

你可以对你想保留的文件进行 add修改,然后对其余的文件进行 stash修改,清除隐藏的文件:

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

此时,您已经存储了不需要的更改。如果您希望永久地删除它们,请运行:

git stash drop

现在已经为提交准备了 file2.cppfile2.hfile3.cpp。如果你想隐藏这些文件(而不是提交它们) :

git reset
git stash

现在您将处于之前的提交中,只保存了这三个文件。

更新:

Git 2.13以及更高版本包含了一种更直接的方法,用 git stash pushVonC 在他的回答中解释道来存储特定的文件。

对于 git diffgit apply来说,这是一个很好的应用:

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

diff之后,您可以检查补丁文件,以确保所有的更改都在那里。

注意,您可能需要使用 --reject选项来应用,以防补丁不能完全应用。也请参阅 申请手册

一个不错的选择是使用交互式隐藏模式。

git stash --patch

它的工作方式与交互式添加模式非常类似: 您将看到一系列差异,显示您在工作树中所做的更改,您必须选择哪些文件(或者只是文件的某些部分!)如果你想藏起来,其他的都会完好无损。

来自 man git-stash:

使用—— patch,您可以交互式地从 HEAD 和要隐藏的工作树之间的差异中选择大块。隐藏条目的构造使其索引状态与存储库的索引状态相同,并且其工作树仅包含交互式选择的更改。然后从工作树中回滚选定的更改。请参阅 Git-add (1)的“交互模式”部分了解如何操作—— patch 模式。

在您的情况下,您将能够看到只有格式化的块,并将它们单独存储起来,而不会丢失有意义的更改。

我知道 file2.cppfile2.hfile3.cpp已经用内容进行了修改(即,不仅仅是格式化)。
我希望将更改隐藏到这三个文件中,然后签出一个旧的修订版,以便之后可以将更改重新应用到这些文件中。

使用 Git 2.13(2017年第二季度) ,git stash将有一种正式的方法来隐藏特定文件(路径规范)的更改

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


# Example
git stash push -m "named-stash" -- file2.cpp file2.h
# you can then easily reapply that stash with:
git stash apply stash^{/named-stash}

参见 第九季,第14090集提交1ada502提交 df6bba0(2017年2月28日)和 提交9ca6326提交6f5ccd4提交 f5727e2(2017年2月19日)。
(由 朱尼奥 · C · 哈马诺 gitster于2017年3月10日在 犯罪,第三季,第9集合并)

作为 现在有记录了:

为了快速制作快照,您可以省略“推”。
在此模式下,不允许使用非选项参数来防止拼写错误 避免不必要的藏匿。
这方面的两个例外是 stash -p,它充当 stash push -p和 pathspecs 的别名,在双连字符 --之后允许它们消除歧义。

当 pathspec 被赋予“ git stash push”时,新的存储记录 仅修改匹配 Pathspec . < br/> 的文件的状态 索引条目和工作树文件然后回滚到 HEAD也只适用于这些文件,留下的文件与 路径规范完好无损。

注意,正如 评论中的 Medmunds所指出的,git stash将使用路径 相对于 git 回购的根文件夹


还有 Git 2.26(Q22020) ,“ ABC0”和“ ABC1”学习新的“ --pathspec-from-file”选项

如果你有一个文件列表要藏在 filesToStash.txt,那么这就足够了:

git stash --pathspec-from-file=filesToStash.txt

您还可以使用 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