kon*_*ski 2949
你也可以使用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
Run Code Online (Sandbox Code Playgroud)
buk*_*zor 1322
警告
正如评论中所指出的,这会将所有内容都放入存储中,无论是分阶段还是非分阶段.在保存完成后,--keep-index只保留索引.以后弹出存储时,这可能会导致合并冲突.
这将隐藏您之前未添加的所有内容.只是git add你要保留的东西,然后运行它.
git stash --keep-index
Run Code Online (Sandbox Code Playgroud)
例如,如果要将旧提交拆分为多个更改集,可以使用以下过程:
git rebase -i <last good commit>edit.git reset HEAD^git add <files you want to keep in this change>git stash --keep-indexgit add任何改变.git commitgit stash popgit rebase --continueVon*_*onC 411
由于git基本上是关于管理所有存储库内容和索引(而不是一个或多个文件),因此git stash交易毫不奇怪,与所有工作目录.
实际上,自Git 2.13(2017年第2季度)以来,您可以使用以下方式存储单个文件git stash push:
git stash push [--] [<pathspec>...]
Run Code Online (Sandbox Code Playgroud)
当
pathspec赋予'git stash push'时,新的存储仅记录与pathspec匹配的文件的修改状态
有关更多信息,请参阅"存储对特定文件的更改 ".
测试用例不言自明:
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
Run Code Online (Sandbox Code Playgroud)
最初的答案(下面,2010年6月)是关于手动选择您想藏匿的内容.
Casebash评论:
这(
stash --patch原始解决方案)很好,但我经常修改了很多文件,因此使用补丁很烦人
bukzor的回答(upvoted,2011年11月)提出了一个更实用的解决方案,基于
git add+git stash --keep-index.
去看看并提出他的回答,这应该是正式的(而不是我的).
关于该选项,chhh在评论中指出了另一种工作流程:
git reset --soft在这样的存储之后你应该" "以获得明确的暂存:
为了进入原始状态 - 这是一个明确的暂存区域并且只有一些选择的非分阶段修改,可以轻轻地重置索引以获得(没有承诺像你一样 - bukzor - 做了).
(原始答案2010年6月:手动藏匿)
然而,git stash save --patch可以让你实现你所追求的部分存储:
使用
--patch,您可以交互式地从HEAD和工作树之间的差异中选择难以存储.
构建存储条目,使其索引状态与存储库的索引状态相同,并且其工作树仅包含您以交互方式选择的更改.然后,从您的工作树中回滚所选更改.
但是,这将保存完整索引(可能不是您想要的,因为它可能包括已编入索引的其他文件),以及部分工作树(可能看起来像您要隐藏的那个).
git stash --patch --no-keep-index
Run Code Online (Sandbox Code Playgroud)
可能更适合.
如果--patch不起作用,手动过程可能:
对于一个或多个文件,中间解决方案是:
git stashgit stash #这次,只有你想要的文件被藏起来了git stash pop stash@{1} #重新应用所有文件修改git checkout -- afile #在任何本地修改之前,将文件重置为HEAD内容在相当繁琐的过程结束时,您将只有一个或几个文件被藏起来.
blu*_*yed 83
当git stash -p(或git add -p有stash --keep-index)将是太麻烦了,我发现它更容易使用diff,checkout并apply:
仅"隐藏"特定文件/目录:
git diff path/to/dir > stashed.diff
git checkout path/to/dir
Run Code Online (Sandbox Code Playgroud)
然后是
git apply stashed.diff
Run Code Online (Sandbox Code Playgroud)
san*_*rom 77
使用git stash push,像这样:
git stash push [--] [<pathspec>...]
Run Code Online (Sandbox Code Playgroud)
例如:
git stash push -- my/file.sh
Run Code Online (Sandbox Code Playgroud)
这是自2017年春季发布的Git 2.13开始提供的.
ven*_*ddy 46
假设你有3个文件
a.rb
b.rb
c.rb
Run Code Online (Sandbox Code Playgroud)
并且你想只存储b.rb和c.rb而不是a.rb
你可以做这样的事情
# 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
Run Code Online (Sandbox Code Playgroud)
你完成了!HTH.
Jas*_*per 28
另一种方法:
# 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">
Run Code Online (Sandbox Code Playgroud)
在我(再一次)来到这个页面并且不喜欢前两个答案之后我想出了这个(第一个答案就是没有回答问题,我不喜欢使用-p交互模式).
这个想法与@VonC建议使用存储库外部文件的想法相同,您可以保存您想要的更改,删除存储中不需要的更改,然后重新应用您移动的更改.但是,我使用git stash作为"某处"(结果,最后还有一个额外的步骤:删除你存放在存储中的cahnges,因为你也将它们移开了).
Jes*_*eke 23
更新(2015年2月14日) - 我稍微重写了脚本,以便更好地处理冲突的情况,现在应该将其显示为未合并的冲突而不是.rej文件.
我经常发现做@ bukzor方法的倒数更直观.也就是说,要进行一些更改,然后只存储那些分阶段的更改.
不幸的是,git不提供git stash --only-index或类似的东西,所以我掀起了一个脚本来做到这一点.
#!/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
Run Code Online (Sandbox Code Playgroud)
您可以将上述脚本保存在git-stash-index路径上的某个位置,然后可以将其作为git stash-index调用
# <hack hack hack>
git add <files that you want to stash>
git stash-index
Run Code Online (Sandbox Code Playgroud)
现在,存储包含一个新条目,该条目仅包含您已暂存的更改,并且您的工作树仍包含任何未暂存的更改.
在某些情况下,工作树更改可能取决于索引更改,因此当您隐藏索引更改时,工作树更改会发生冲突.在这种情况下,您将获得通常使用git merge/git mergetool/etc解决的未合并冲突.
sha*_*iao 18
由于在Git中创建分支是微不足道的,因此您可以创建一个临时分支并将单个文件检入其中.
sea*_*cal 13
如果不想使用隐藏的更改指定消息,请在双破折号后传递文件名。
$ git stash -- filename.ext
Run Code Online (Sandbox Code Playgroud)
如果是未跟踪/新文件,则必须先上载它。
此方法在git版本2.13+中有效
小智 12
万一你实际上意味着在你使用时丢弃更改git stash(并且实际上不使用git stash暂时存储它),在这种情况下你可以使用
git checkout -- <file>
Run Code Online (Sandbox Code Playgroud)
[ 注意 ]
这git stash只是分支和做事的一种快速而简单的替代方案.
apr*_*cot 11
将以下代码保存到文件中,例如,命名stash.用法是stash <filename_regex>.参数是文件完整路径的正则表达式.例如,要存储a/b/c.txt,stash a/b/c.txt或stash .*/c.txt等.
$ chmod +x stash
$ stash .*.xml
$ stash xyz.xml
Run Code Online (Sandbox Code Playgroud)
要复制到文件中的代码:
#! /usr/bin/expect --
log_user 0
set filename_regexp [lindex $argv 0]
spawn git stash -p
for {} 1 {} {
expect {
-re "diff --git a/($filename_regexp) " {
set filename $expect_out(1,string)
}
"diff --git a/" {
set filename ""
}
"Stash this hunk " {
if {$filename == ""} {
send "n\n"
} else {
send "a\n"
send_user "$filename\n"
}
}
"Stash deletion " {
send "n\n"
}
eof {
exit
}
}
}
Run Code Online (Sandbox Code Playgroud)
vin*_*uja 10
您可以简单地做到这一点:
git stash push "filename"
Run Code Online (Sandbox Code Playgroud)
或带有可选消息
git stash push -m "Some message" "filename"
Run Code Online (Sandbox Code Playgroud)
VonC将文件复制到Git仓库之外的"中间"解决方案的问题在于,您丢失了路径信息,这使得稍后复制一堆文件会有些麻烦.
找到更容易使用tar(类似的工具可能会做)而不是复制:
在我提交之前,有时候我在我的分支上做了一个无关的更改,我想将它移动到另一个分支并单独提交(就像master).我这样做:
git stash
git checkout master
git stash pop
git add <files that you want to commit>
git commit -m 'Minor feature'
git stash
git checkout topic1
git stash pop
...<resume work>...
Run Code Online (Sandbox Code Playgroud)
注意第一个stash&stash pop可以被淘汰,您可以master在结账时将所有更改都带到分支,但前提是没有冲突.此外,如果您要为部分更改创建新分支,则需要存储.
假设没有冲突且没有新分支,您可以简化它:
git checkout master
git add <files that you want to commit>
git commit -m 'Minor feature'
git checkout topic1
...<resume work>...
Run Code Online (Sandbox Code Playgroud)
藏匿甚至不需要......
使用SourceTree可以在3个步骤中轻松完成.
这可以在SourceTree中在几秒钟内完成,您可以在其中单击要添加的文件(甚至是单独的行).添加后,只需将它们提交给临时提交.接下来,单击复选框以添加所有更改,然后单击存储以存储所有内容.通过隐藏的更改,浏览提交列表并在临时提交之前记下提交的哈希,然后运行'git reset hash_b4_temp_commit',这基本上就像通过将分支重置为"弹出"提交在它之前提交.现在,你只剩下你不想藏匿的东西.
我会用git stash save --patch.我没有发现交互性令人讨厌,因为在它期间有选项将所需操作应用于整个文件.
这里的每个答案都是如此复杂......
这个"藏匿"怎么样:
git diff /dir/to/file/file_to_stash > /tmp/stash.patch
git checkout -- /dir/to/file/file_to_stash
Run Code Online (Sandbox Code Playgroud)
这将弹出文件更改回来:
git apply /tmp/stash.patch
Run Code Online (Sandbox Code Playgroud)
与存储一个文件并将其弹回的完全相同的行为.
我已经查看了此主题以及许多类似主题的答案和评论。请注意,以下命令都不正确,无法存储任何特定的跟踪/未跟踪文件:
git stash -p (--patch):手动选择帅哥,排除未跟踪的文件git stash -k (--keep-index):隐藏所有跟踪/未跟踪的文件并将它们保存在工作目录中git stash -u (--include-untracked):隐藏所有跟踪/未跟踪的文件git stash -p (--patch) -u (--include-untracked): 无效命令目前,能够存储任何特定跟踪/未跟踪文件的最合理方法是:
我在回答另一个问题时为此过程编写了一个简单的脚本,这里有在 SourceTree 中执行该过程的步骤。