用Git从多个已更改的文件中只存储一个文件。

git git-stash


如何在我的分支上只存放多个更改过的文件中的一个?




Answer 1 bukzor


免责声明:以下答案适用于git 2.13之前的git。对于git 2.13及更高版本,请进一步查找其他答案。


Warning

正如评论中所指出的,这将所有的东西都放入stash中,包括staged和unstaged。而--keep-index只是在stash完成后,不动索引。这可能会在你以后打开 stash 时造成合并冲突。


这将存储您以前未添加的所有内容。只需 git add 要保留的内容,然后运行它。

git stash --keep-index

例如,如果你想把一个旧的提交分成多个变更集,你可以使用这个过程。

  1. git rebase -i <last good commit>
  2. 将一些更改标记为 edit
  3. git reset HEAD^
  4. git add <files you want to keep in this change>
  5. git stash --keep-index
  6. 根据需要进行修复。不要忘了 git add 任何更改。
  7. git commit
  8. git stash pop
  9. 根据需要,从5号开始重复。
  10. git rebase --continue



Answer 2 konrad.kruczynski


您还可以使用 git stash save -p "my commit message" 。这样,您可以选择应将哪些块添加到存储中,也可以选择整个文件。

你会被提示对每个大块进行一些操作。

   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



Answer 3 VonC


Since git is fundamentally about managing a all repository content and index (and not one or several files), git stash deals, not surprisingly, with the all working directory.

Actually, since Git 2.13 (Q2 2017), you can stash individual files, with git stash push:

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

当为' git stash push ' 提供 pathspec 时,新的stash仅记录与pathspec匹配的文件的修改状态。有关更多信息,请参见“将更改存储到特定文件 ”。

简化的例子。

 git stash push path/to/file

此功能的测试案例显示了更多选项:

test_expect_success 'stash with multiple pathspec arguments' '
    >foo &&
    >bar &&
    >extra &&
    git add foo bar extra &&

    git stash push -- foo bar &&   

    test_path_is_missing bar &&
    test_path_is_missing foo &&
    test_path_is_file extra &&

    git stash pop &&
    test_path_is_file foo &&
    test_path_is_file bar &&
    test_path_is_file extra

原答案(如下图,2010年6月)是关于手动选择你想储藏的东西。

Casebash评论:

这个( stash --patch 原始解决方案)很好,但是经常我修改了很多文件,所以使用patch很烦人

bukzor答案(于2011年11月更新)提出了一个更实际的解决方案,该解决方案基于
git add + git stash --keep-index
去看看,给他的答案加个票,应该是官方的答案(而不是我的)。

关于该选项,chhh在注释中指出了另一种工作流程:

您应该在这样的 git reset --soft 之后执行“ git reset --soft ”,以使您清楚地恢复工作:
为了得到原始状态--这是一个清晰的暂存区域,只有一些选定的未暂存的修改,我们可以软性重置索引得到(不需要像你--bukzor--那样犯任何错误)。


(2010年6月的原始答案:手动藏书)

但是, git stash save --patch 可以使您实现部分隐藏:

使用 --patch ,您可以从HEAD与要隐藏的工作树之间的差异中交互选择块。
储藏库条目的构造是,它的索引状态与版本库的索引状态相同,它的工作树只包含你交互式选择的更改。选定的更改会从工作树中回滚。

然而,这将保存完整的索引(这可能不是你想要的,因为它可能包括其他已经编入索引的文件),以及部分工作树(它可能看起来像你想要隐藏的工作树)。

git stash --patch --no-keep-index

可能更适合。


如果 --patch 不起作用,则手动过程可能会:

对于一个或几个文件,一个中间解决方案是:

  • 拷贝到Git repo之外
    (实际上,eleotlecram提出了一个有趣的替代方法
  • git stash
  • copy them back
  • git stash #这次,仅隐藏了您想要的文件
  • git stash pop stash@{1} #重新应用所有文件修改
  • git checkout -- afile #在进行任何本地修改之前将文件重置为HEAD内容

在这个相当繁琐的过程结束后,你将只有一个或几个文件存储。




Answer 4 blueyed


git stash -p (或带有 stash --keep-indexgit add -p )太麻烦时,我发现使用 diffcheckoutapply 更容易:

只 "存储 "某个文件/目录。

git diff path/to/dir > stashed.diff
git checkout path/to/dir

Then afterwards

git apply stashed.diff



Answer 5 sandstrom


使用 git stash push ,如下所示:

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

例如:

git stash push -- my/file.sh

自2017年春季发布的Git 2.13开始可用。