如何在我的分支中只存储多个已更改文件中的一个?
当前回答
免责声明:以下答案适用于2.13之前的git。对于2.13及以上的数字,请查看下面的另一个答案。
警告
正如评论中所指出的那样,这将所有的东西都放进了储藏室,无论是暂存的还是未暂存的。--keep索引只是在存储完成后保留索引。这可能会在以后弹出存储时导致合并冲突。
这将隐藏您以前未添加的所有内容。只需git添加要保留的内容,然后运行它。
git stash --keep-index
例如,如果要将旧提交拆分为多个变更集,可以使用以下过程:
gitrebase-i<最后一次提交>将某些更改标记为编辑。git重置HEAD^git add<您要在此更改中保留的文件>git stash—保留索引必要时修理一下。不要忘记git添加任何更改。git提交吉特藏弹根据需要,从第5步开始重复。git rebase—继续
其他回答
万一你真的打算在使用git stash时丢弃更改(而不是真的使用git stash临时存储),那么你可以使用
git checkout -- <file>
[注]
这个git存储只是分支和执行任务的一个快速而简单的替代方案。
类似的情况。做了承诺,意识到这不好。
git commit -a -m "message"
git log -p
根据这些回答,这对我有帮助。
# 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
自Git 2.13(2017年第二季度)以来,您可以使用Git stash推送来存储单个文件:
git stash push [-m <message>] [--] [<pathspec>...]
当路径规范被赋予“git stash push”时,新的stash只记录与路径规范匹配的文件的修改状态有关详细信息,请参阅“Stash changes to specific files”。
简化示例:
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注释:
这(隐藏的补丁原始解决方案)很好,但我经常修改很多文件,所以使用补丁很烦人
bukzor的回答(2011年11月投票通过)提出了一个更实际的解决方案,基于git add+git stash--保留索引。去看看并投票给他的答案,这应该是官方的答案(而不是我的答案)。
关于该选项,chhh在评论中指出了另一种工作流:
你应该在这样一个隐藏之后“git-reset-soft”,以获得清晰的分段:为了达到原始状态-这是一个清晰的暂存区,只有一些选择的未暂存修改,可以轻轻地重置索引以获取(而不需要像bukzor那样提交任何操作)。
(原答案2010年6月:手动储存)
然而,git-stash-save补丁可以让你实现你想要的部分存储:
使用--patch,您可以从HEAD和要隐藏的工作树之间的差异中交互选择大块。存储项的构造使其索引状态与存储库的索引状态相同,并且其工作树仅包含您以交互方式选择的更改。然后,所选更改将从工作树回滚。
然而,这将保存完整的索引(这可能不是您想要的,因为它可能包含其他已索引的文件)和部分工作树(看起来可能像您想要隐藏的文件)。
git stash --patch --no-keep-index
可能更合适。
如果--patch不起作用,手动过程可能会:
对于一个或多个文件,中间解决方案是:
将它们复制到Git存储库之外(实际上,eleotlecram提出了一个有趣的替代方案)暂存把它们复制回来git stash#这次,只存储您想要的文件git stash pop stash@{1}#重新应用所有文件修改gitcheckout--afile#在任何本地修改之前将文件重置为HEAD内容
在这个相当繁琐的过程结束时,您将只存储一个或多个文件。
更新(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/等解决。
使用SourceTree,这可以通过3个步骤轻松完成。
暂时提交所有你不想隐藏的东西。Git添加所有其他内容,然后将其隐藏。通过运行git reset来弹出临时提交,在临时提交之前进行提交。
这一切都可以在SourceTree中在几秒钟内完成,您只需单击要添加的文件(甚至单个行)。添加后,只需将它们提交到临时提交。接下来,单击复选框以添加所有更改,然后单击“隐藏”以隐藏所有更改。在隐藏的更改不碍事的情况下,浏览一下提交列表,并在临时提交之前记录提交的哈希值,然后运行“git reset hash_b4_temp_commit”,这基本上就像通过将分支重置为提交之前的提交来“弹出”提交。现在,只剩下不想隐藏的内容。
推荐文章
- 强制LF eol在git的回购和工作副本
- Git:在裸库中更改活动分支的正确方法?
- 删除git中的分支是否会将其从历史记录中删除?
- 防止在GitHub上推送到master ?
- 根据Git,谁是“我们”,谁是“他们”?
- git如何合并后樱桃采摘工作?
- Git搜索单个文件历史记录中的字符串
- Git命令显示所有(轻量级)标签创建日期
- Gitignore并没有忽视文件夹
- 什么时候用。git/info/exclude代替。gitignore来排除文件?
- 如何告诉git忽略个别行,即gitignore为特定行代码
- “git diff——耐心”是什么意思?
- 我如何在GitHub中为其他人的代码做出贡献?
- 签出旧的提交并使其成为新的提交
- gitignore是什么?