如何在我的分支中只存储多个已更改文件中的一个?


当前回答

万一你真的打算在使用git stash时丢弃更改(而不是真的使用git stash临时存储),那么你可以使用

git checkout -- <file>

[注]

这个git存储只是分支和执行任务的一个快速而简单的替代方案。

其他回答

我也想做同样的事情,但当我再次思考时,我意识到我不想为了保存一个文件而麻烦重重。对我来说,把它复制到其他地方并添加一些注释来提醒我为什么要把它保存在那里会容易得多。

不要误解我的意思:有很多原因可以解释为什么你只想隐藏一个文件,而且总的来说,使用版本控制软件总是最好的做法。但还是要确保你没有浪费时间。在我的情况下,我只想保留一个文件并放弃所有其他更改,然后在切换到新分支后将其弹出。所以cp/mv足够好。

更新(2015年2月14日)-我重写了一点脚本,以更好地处理冲突的情况,现在应该将其显示为未合并的冲突,而不是.rej文件。


我经常发现,与@bukzor的方法相反更直观。也就是说,要进行一些更改,然后只隐藏那些已进行的更改。

不幸的是,git没有提供git存储——只有索引或类似的内容,所以我编写了一个脚本来实现这一点。

#!/bin/sh

# first, go to the root of the git repo
cd `git rev-parse --show-toplevel`

# create a commit with only the stuff in staging
INDEXTREE=`git write-tree`
INDEXCOMMIT=`echo "" | git commit-tree $INDEXTREE -p HEAD`

# create a child commit with the changes in the working tree
git add -A
WORKINGTREE=`git write-tree`
WORKINGCOMMIT=`echo "" | git commit-tree $WORKINGTREE -p $INDEXCOMMIT`

# get back to a clean state with no changes, staged or otherwise
git reset -q --hard

# Cherry-pick the index changes back to the index, and stash.
# This cherry-pick is guaranteed to succeed
git cherry-pick -n $INDEXCOMMIT
git stash

# Now cherry-pick the working tree changes. This cherry-pick may fail
# due to conflicts
git cherry-pick -n $WORKINGCOMMIT

CONFLICTS=`git ls-files -u`
if test -z "$CONFLICTS"; then
    # If there are no conflicts, it's safe to reset, so that
    # any previously unstaged changes remain unstaged
    #
    # However, if there are conflicts, then we don't want to reset the files
    # and lose the merge/conflict info.
    git reset -q
fi

您可以将上面的脚本保存为路径上的某个位置的git stash索引,然后将其作为git stach索引调用

# <hack hack hack>
git add <files that you want to stash>
git stash-index

现在,存储包含一个新条目,该条目仅包含您已暂存的更改,而您的工作树仍然包含任何未暂存的更改。

在某些情况下,工作树的更改可能取决于索引的更改,因此当您隐藏索引更改时,工作树更改会发生冲突。在这种情况下,您将得到通常的未合并冲突,可以使用gitmerge/gitmergetool/等解决。

git add .                           //stage all the files
git reset <pathToFileWillBeStashed> //unstage file which will be stashed
git stash                           //stash the file(s)
git reset .                         // unstage all staged files
git stash pop                       // unstash file(s)

我不知道如何在命令行上执行,只使用SourceTree。假设您已经更改了文件A,并且在文件B中有两个更改块。如果您只想将第二个块存储在文件B,而其他所有内容都保持不变,请执行以下操作:

舞台上的一切对工作副本执行更改,以撤消文件A中的所有更改(例如,启动外部diff工具并使文件匹配)使文件B看起来好像只应用了第二个更改。(例如,启动外部diff工具并撤消第一个更改。)使用“保留暂存更改”创建存储。取消标记所有内容完成!

另一种方法是:

# Save everything
git stash 

# Re-apply everything, but keep the stash
git stash apply

git checkout <"files you don't want in your stash">

# Save only the things you wanted saved
git stash

# Re-apply the original state and drop it from your stash
git stash apply stash@{1}
git stash drop stash@{1}

git checkout <"files you put in your stash">

在我(再次)来到这个页面并不喜欢前两个答案(第一个答案只是不回答问题,我不太喜欢使用-p交互模式)之后,我想到了这个问题。

这一想法与@VonC建议的使用存储库外的文件相同,您可以将所需的更改保存在某个位置,删除存储库中不需要的更改,然后重新应用您移开的更改。然而,我使用了git隐藏作为“某处”(因此,最后还有一个额外的步骤:移除你放在隐藏中的cahnges,因为你也把它们移到了一边)。