存储对特定文件的更改

时间:2012-09-06 17:10:54

标签: git git-stash

我有一个大型的git项目,我愚蠢地导入了eclipse并运行了一个autoformat。现在,项目中的每个文件都显示为已修改。而不是提交我的格式化文件,我宁愿还原我只格式化的所有文件,而不是其他更改。例如:

$ 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 .

如果有一种明显的方法可以做到这一点而不涉及藏匿,请告诉我。无论如何完成工作。

4 个答案:

答案 0 :(得分:40)

  

我知道file2.cppfile2.hfile3.cpp已被内容修改(即,不仅仅是格式化)。
  我想隐藏对这三个文件的更改,然后签出一个旧版本,以便我可以在之后重新应用这些文件的更改。

使用Git 2.13(2017年第二季度),git stash将正式使用

隐藏特定文件的更改
git stash push [--] [<pathspec>...]

请参阅commit 9e14090commit 1ada502commit df6bba0(2017年2月28日)和commit 9ca6326commit 6f5ccd4commit f5727e2(2017年2月19日) Thomas Gummerer (tgummerer) Junio C Hamano -- gitster --于2017年3月10日commit 44c3f09合并)

作为now documented

  

为了快速制作快照,您可以省略&#34; push&#34;。
  在此模式下,不允许使用非选项参数来防止拼写错误   子命令来自不需要的藏匿。
  对此的两个例外是stash -p,它充当stash push -p和pathspecs的别名,在双连字符--之后允许消除歧义。

     

当pathpec被赋予&#39; git stash push&#39;时,新的藏匿记录了   修改状态仅适用于与pathspec匹配的文件   然后索引条目和工作树文件回滚到状态   HEAD仅针对这些文件,留下与文件不匹配的文件   pathspec完整。

请注意,正如medmundsthe comments所指出的,git stash会使用路径relative to the root folder of the git repo

答案 1 :(得分:33)

您可以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 pushas VonC explains in his answer存储特定文件的更直接方法。

答案 2 :(得分:11)

一个不错的选择是使用交互式存储模式。

git stash --patch

它的工作方式大多类似于交互式添加模式:您将看到一系列差异,显示您在工作树中的更改,您必须选择哪些文件(或仅文件的某些部分!)您想要藏匿,剩下的将保持不变。

来自man git-stash

  

使用--patch,您可以交互式地从HEAD和工作树之间的差异中选择要存储的数据。构建存储条目,使其索引状态与存储库的索引状态相同,并且其工作树仅包含您以交互方式选择的更改。然后,从您的工作树中回滚所选更改。请参阅"Interactive Mode" section of git-add(1)以了解如何操作--patch模式。

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

答案 3 :(得分:3)

这对git diffgit apply IMO很有用:

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

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

请注意,如果补丁不能完全应用,您可能需要使用--reject选项。另请参阅man page for apply