您也可以使用 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
# commit the files temporarily you don't want to stash
git add a.rb
git commit -m "temp"
# then stash the other files
git stash save "stash message"
# then undo the previous temp commit
git reset --soft HEAD^
git reset
你完成了! HTH .
6
另一种方法:
# 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">
#!/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
# revert to previous state, keeping the files changed
git reset HEAD~
#make sure it's ok
git diff
git status
#revert the file we don't want to be within the commit
git checkout specs/nagios/nagios.spec
#make sure it's ok
git status
git diff
#now go ahead with commit
git commit -a -m "same|new message"
#eventually push tu remote
git push
这将提示: Stash this hunk [y,n,q,a,d,j,J,g,/,e,?]? ? . 只需输入 a (将此大块以及所有后来的文件藏在文件中)就可以了 .
2
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)
17
一个复杂的方法是首先提交一切:
git add -u
git commit // creates commit with sha-1 A
重置回原始提交,但从新提交中检出the_one_file:
git reset --hard HEAD^
git checkout A path/to/the_one_file
现在你可以存储the_one_file:
git stash
通过在重置回原始提交时将已提交内容保存在文件系统中进行清理:
git reset --hard A
git reset --soft HEAD^
是的,有点尴尬......
7
我发现没有答案是我需要的,这很简单:
git add -A
git reset HEAD fileThatYouWantToStash
git commit -m "committing all but one file"
git stash
27 回答
这里的每个答案都是如此复杂......
这个“藏匿”怎么样:
这将弹出文件更改回:
与存储一个文件并将其弹回的完全相同的行为 .
我会用
git stash save --patch
. 我没有发现交互性令人讨厌,因为在它期间有选项将所需操作应用于整个文件 .当
git stash -p
(或git add -p
与stash --keep-index
)太麻烦时,我发现使用diff
,checkout
和apply
更容易:仅“隐藏”特定文件/目录:
然后是
您也可以使用
git stash save -p "my commit message"
. 通过这种方式,您可以选择将哪些帅哥添加到藏匿处,也可以选择整个文件 .每个块都会提示您一些操作:
由于git基本上是关于管理所有存储库内容和索引(而不是一个或多个文件),所以
git stash
毫不奇怪地与所有工作目录进行交易 .实际上,自Git 2.13(2017年第2季度)以来,您可以使用git stash push存储单个文件:
有关更多信息,请参阅“Stash changes to specific files” .
The test case不言自明:
原始答案(下面,2010年6月)是关于手动选择您想藏匿的内容 .
Casebash评论:
bukzor的answer(upvoted,2011年11月)提出了一个更实际的解决方案,基于
git add + git stash --keep-index .
去看看并提出他的答案,这应该是官方的(而不是我的) .
关于该选项,chhh在评论中指出了另一种工作流程:
(原始答案2010年6月:手动藏匿)
然而,
git stash save --patch
可以让你实现你所追求的部分存款:但是,这将保存完整索引(可能不是您想要的,因为它可能包括已编入索引的其他文件),以及部分工作树(可能看起来像您要隐藏的那个) .
可能更适合 .
如果
--patch
不起作用,则手动过程可能:对于一个或多个文件,中间解决方案是:
将它们复制到Git仓库之外
(实际上,eleotlecram提出interesting alternative)
git stash
将它们复制回来
git stash
#这次,只有你想要的文件被隐藏起来git stash pop stash@{1}
#重新应用所有文件修改git checkout -- afile
#在任何本地修改之前将文件重置为HEAD内容在相当繁琐的过程结束时,您将只有一个或几个文件被藏起来 .
使用
git stash push
,如下所示:例如:
自2017年 Spring 季发布的Git 2.13开始提供此功能 .
Warning
正如评论中所指出的,这会将所有内容都放入存储中,无论是分阶段还是非分阶段 . -step-index只在保存完成后保留索引 . 以后弹出存储时,这可能会导致合并冲突 .
这将隐藏您之前未添加的所有内容 . 只需
git add
你要保留的东西,然后运行它 .例如,如果要将旧提交拆分为多个变更集,则可以使用此过程:
git rebase -i <last good commit>
将某些更改标记为
edit
.git reset HEAD^
git add <files you want to keep in this change>
git stash --keep-index
根据需要进行修复 . 不要忘记
git add
任何变化 .git commit
git stash pop
根据需要从#5开始重复 .
git rebase --continue
假设你有3个文件
并且你想只存储b.rb和c.rb而不是a.rb
你可以做这样的事情
你完成了! HTH .
另一种方法:
在我(再一次)来到这个页面并且没有回答这个问题之后我想出了这个问题,我不太喜欢使用
-p
交互模式 .这个想法与@VonC建议使用存储库外部文件的想法相同,您可以保存您想要的更改,删除存储中不需要的更改,然后重新应用您移动的更改 . 但是,我使用git stash作为“某处”(结果,最后还有一个额外的步骤:删除你放在藏匿处的cahnges,因为你也将它们移开了) .
更新(2015年2月14日) - 我已经重写了一下脚本,以便更好地处理冲突的情况,现在应该是表示为未合并的冲突而不是.rej文件 .
我经常发现做@ bukzor方法的倒数更直观 . 也就是说,要进行一些更改,然后只存储那些分阶段的更改 .
不幸的是,git没有提供git stash --only-index或类似的东西,所以我掀起了一个脚本来做到这一点 .
您可以将上述脚本保存为路径上的
git-stash-index
,然后可以将其作为git stash-index调用现在,存储包含一个新条目,该条目仅包含您已暂存的更改,并且您的工作树仍包含任何未分级的更改 .
在某些情况下,工作树更改可能取决于索引更改,因此当您隐藏索引更改时,工作树更改会发生冲突 . 在这种情况下,您将获得通常使用git merge / git mergetool / etc解决的未合并冲突 .
由于在Git中创建分支是微不足道的,因此您可以创建一个临时分支并将单个文件检入其中 .
万一你使用
git stash
实际意味着 discard changes (并且真的不使用git stash暂时存放它),在这种情况下你可以使用[ NOTE ]
那个
git stash
只是分支和做事的一种快速而简单的替代方案 .将以下代码保存到文件中,例如,名为
stash
. 用法是stash <filename_regex>
. 参数是文件完整路径的正则表达式 . 例如,要存储a / b / c.txt,stash a/b/c.txt
或stash .*/c.txt
等 .要复制到文件中的代码:
VonC将文件复制到Git仓库之外的“中间”解决方案的问题在于您丢失了路径信息,这使得稍后复制一堆文件会有些麻烦 .
找到更容易使用tar(类似的工具可能会做)而不是复制:
tar cvf /tmp/stash.tar path / to / some / file path / to / some / other / file(... etc.)
git checkout path / to / some / file path / to / some / other / file
git stash
tar xvf /tmp/stash.tar
等(见VonC 's `intermediate'建议)
使用SourceTree可以在3个步骤中轻松完成 .
暂时提交您不想要藏匿的所有内容 .
Git添加其他所有内容,然后将其存储起来 .
通过运行git reset来弹出临时提交,在临时提交之前定位提交 .
这可以在SourceTree中在几秒钟内完成,您可以在其中单击要添加的文件(甚至单独的行) . 添加后,只需将它们提交给临时提交 . 接下来,单击复选框以添加所有更改,然后单击存储以存储所有内容 . 通过隐藏的更改,浏览提交列表并在临时提交之前记下提交的哈希,然后运行'git reset hash_b4_temp_commit',这基本上就像通过将分支重置为“弹出”提交在它之前提交 . 现在,你只剩下你不想藏匿的东西 .
有时候,在我提交之前,我已经在我的分支上做了一个无关的更改,我想将它移动到另一个分支并单独提交(如master) . 我这样做:
请注意,第一个
stash
&stash pop
可以被删除,您可以在结账时将所有更改带到master
分支,但前提是没有冲突 . 此外,如果要为部分更改创建新分支,则需要存储 .假设没有冲突且没有新分支,您可以简化它:
藏匿甚至不需要......
我已经回顾了这个和许多类似线程的答案和评论 . 请注意,以下任何命令都不能用于存储 any specific tracked/untracked files :
git stash -p (--patch)
:手动选择帅哥,不包括未跟踪的文件git stash -k (--keep-index)
:存储所有已跟踪/未跟踪的文件并将其保留在工作目录中git stash -u (--include-untracked)
:存储所有已跟踪/未跟踪的文件git stash -p (--patch) -u (--include-untracked)
:命令无效目前,能够存储任何特定跟踪/未跟踪文件的最合理方法是:
暂时提交您不想存储的文件
添加并藏匿
弹出临时提交
I wrote a simple script for this procedure in an answer to another question,还有steps for performing the procedure in SourceTree here .
解决方案
地方变化:
file_A(已修改)未上演
file_B(已修改)未上演
file_C(已修改)未上演
仅使用 file_C 上的更改创建存储"my_stash":
完成 .
解释
将file_C添加到暂存区域
创建一个名为"temp_stash"的临时存储,并保留对file_C的更改
创建想要存储("my_stash"),只需要对file_C进行更改
将"temp_stash"(file_A和file_B)中的更改应用于您的本地代码并删除存储
您可以在步骤之间使用git status来查看正在进行的操作 .
在这种情况下我
git add -p
(交互式),git commit -m blah
然后在必要时存储剩下的内容 .类似的情况 . 提交并意识到它不行 .
根据答案,这对我有所帮助 .
我不知道如何在命令行上执行此操作,仅使用SourceTree . 假设您已经更改了文件A,并且在文件B中有两个更改块 . 如果您只想隐藏文件B中的第二个块并保持其他所有内容不变,请执行以下操作:
舞台一切
对工作副本执行更改,撤消文件A中的所有更改 . (例如,启动外部差异工具并使文件匹配 . )
使文件B看起来好像只对其应用了第二次更改 . (例如,启动外部差异工具并撤消第一次更改 . )
使用"Keep staged changes"创建存储 .
取消所有内容
完成!
当您尝试在两个分支之间切换时,会出现这种情况 .
尝试使用“
git add filepath
”添加文件 .稍后执行此行
要存储单个文件,请使用
git stash --patch [file]
.这将提示:
Stash this hunk [y,n,q,a,d,j,J,g,/,e,?]? ?
. 只需输入a
(将此大块以及所有后来的文件藏在文件中)就可以了 .一个复杂的方法是首先提交一切:
重置回原始提交,但从新提交中检出the_one_file:
现在你可以存储the_one_file:
通过在重置回原始提交时将已提交内容保存在文件系统中进行清理:
是的,有点尴尬......
我发现没有答案是我需要的,这很简单:
这只存储了一个文件 .
快速回答
要在git中还原特定的已更改文件,您可以执行以下操作:
这是一个实际的例子: