赞
踩
如何在我的分支上仅存储多个更改文件中的一个?
huntsbot.com提供全网独家一站式外包任务、远程工作、创意产品分享与订阅服务!
git stash push -p -m "my commit message"
-p 让您选择应该隐藏的大块;也可以选择整个文件。
系统会提示您针对每个大块执行一些操作:
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
我是一个 TortoiseGit 瘾君子。但是 TortoiseGit 不支持 stash -p。我奖励这个答案是因为它仍然是最具交互性/用户友好性的。
您可能要添加:git stash save -p my stash message;因为参数的顺序不是很直观......
在这和 git log -p 之间,我认为 -p 标志必须表示“做我想做但不知道如何表达的酷事”。
这是一个正确的答案,但如果你有太多的大块要解决,它就会变得不可用。
一个较新的问题上发布的快速呼叫回答:stackoverflow.com/a/5506483/2661238 @svick git stash push -m
huntsbot.com提供全网独家一站式外包任务、远程工作、创意产品分享与订阅服务!
免责声明:以下答案适用于 git 2.13 之前的 git。对于 git 2.13 及更高版本,请查看 another answer further down。
警告
正如评论中所指出的,这会将所有内容都放入存储中,包括分阶段和非分阶段。 --keep-index 只是在存储完成后单独保留索引。当您稍后弹出存储时,这可能会导致合并冲突。
这将隐藏您之前未添加的所有内容。只需git add您想要保留的内容,然后运行它。
git stash --keep-index
例如,如果要将旧提交拆分为多个变更集,则可以使用以下过程:
git rebase -i 将一些更改标记为编辑。 git reset HEAD^ git add git stash --keep-index 根据需要进行修复。不要忘记 git 添加任何更改。 git commit git stash pop 根据需要从 #5 开始重复。 git rebase – 继续
我发现这种方法要简单得多:stackoverflow.com/a/5506483/457268
我不知道为什么这会被赞成。每个人的期望都与我不同。原来的帖子是问“我如何只存储一部分未提交的更改?”当我使用 git stash save -k 时,是的,索引(git stat 中的绿色)被保留,但 整个 变更集(绿色和红色)进入存储区。这违反了 OP 的要求,“仅存储一些更改”。我想存储一些红色(以备将来使用)。
如果您对@Pistos 提出的问题的答案更感兴趣(就像我一样),请看这里:stackoverflow.com/questions/5506339/…
@拉曼:太好了! git stash -p 正是我想要的。我想知道这个开关是不是最近才添加的。
警告:git stash --keep-index 已损坏。如果您进行了更多更改,那么稍后再尝试 git stash pop,您会遇到合并冲突,因为存储区包括您保留的已更改文件,而不仅仅是您未保留的文件。例如:我更改了文件A和B,然后stash B,因为我想测试A中的更改;我发现了 A 的问题,然后我修复了;我承诺 A;现在我无法取消存储,因为旧版本的 A 无缘无故地在存储中导致合并冲突。在实践中A和B可能是很多文件,甚至可能是二进制图像什么的,所以我基本上不得不放弃并失去B。
huntsbot.com – 程序员副业首选,一站式外包任务、远程工作、创意产品分享订阅平台。
从 Git 2.13(2017 年第二季度)开始,您可以使用 git stash push 存储单个文件:
git stash push [-m ] [--] [...]
当 pathspec 被赋予 ‘git stash push’ 时,新的 stash 仅记录与 pathspec 匹配的文件的修改状态。有关更多信息,请参阅“将更改存储到特定文件”。
简化示例:
git stash push path/to/file
此功能的 The test case 显示了更多关闭选项:
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 原始解决方案)很好,但我经常修改很多文件,所以使用补丁很烦人
bukzor 的 answer(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
可能更合适。
如果 --patch 不起作用,手动过程可能会:
对于一个或多个文件,中间解决方案是:
将它们复制到 Git 存储库之外(实际上,eleotlecram 提出了一个有趣的替代方案)
混帐藏匿
把它们复制回来
git stash # 这次只存放你想要的文件
git stash pop stash@{1} # 重新应用所有文件修改
git checkout – afile # 在任何本地修改之前将文件重置为 HEAD 内容
在这个相当繁琐的过程结束时,您将只存储一个或多个文件。
这很好,但我经常修改很多文件,所以使用补丁很烦人
@Kal:是的,stackoverflow.com/a/13941132/6309 建议使用 git reset(混合)
git is fundamentally about managing a all repository content and index and not one or several files - 实现掩盖了正在解决的问题;这是一个解释,但不是一个理由。任何源代码控制系统都是关于“管理多个文件”的。看看哪些评论最受好评。
-1 推荐 git stash --keep-index;正如对 bukzor 答案的评论中所指出的那样,它根本不会像您认为的那样做。创建两个文件,foo 和 bar。提交他们。为每个添加一行。 git add foo。 git stash --keep-index。现在想要的结果是您已隐藏对 bar 的更改,并且您对 foo 的更改仍然存在并暂存。现实情况是,您对 foo 的更改已呈现并暂存,但您对 both 文件的更改已隐藏。如果您 git reset 并修改 foo,由于冲突,您现在不能 git stash pop。
这也隐藏了所有暂存文件。因此,请确保您没有进行任何更改
huntsbot.com提供全网独家一站式外包任务、远程工作、创意产品分享与订阅服务!
使用 git stash push,如下所示:
git stash push [--] [...]
例如:
git stash push -- my/file.sh
这是自 2017 年春季发布的 Git 2.13 以来可用的。
但我确实在 5 个月前的 my answer above 中提到了 git stash push。我在这里详细介绍了新的 Git 2.13 命令:stackoverflow.com/a/42963606/6309。
@VonC你是对的,你也提到了正确的答案,但是,在两个答案之间,这个更容易阅读(没有令人困惑的文字,还有一个例子)。也许他们应该编辑您的答案
然后是否使用 git stash apply 来恢复隐藏的更改?
谁能告诉我为什么使用这样一个晦涩的单词“pathspec”来指示文件路径?还是它不像我想的那么晦涩难懂?
@NikhilVandanapu 我认为使用术语 pathspec 是因为它不仅仅是一条简单的路径。它可以包括标准通配符、双星号通配符甚至更深奥的语法。有关详细信息,请转到 https://git-scm.com/docs/gitglossary 并搜索 pathspec。
huntsbot.com洞察每一个产品背后的需求与收益,从而捕获灵感
当 git stash -p(或 git add -p 与 stash --keep-index)过于繁琐时,我发现使用 diff、checkout 和 apply 更容易:
仅“存储”特定文件/目录:
git diff path/to/dir > stashed.diff
git checkout path/to/dir
然后之后
git apply stashed.diff
我在上面自己的答案中提到的 git add -p 的有趣替代方案。 +1。
请注意,如果您有二进制文件(如 PNG),它们将不会输出到 diff 文件。所以这不是一个 100% 的解决方案。
@RobertDailey:这对我来说很有趣,因为 git diff > file.diff 和 git apply 是我常用的部分存储工具。对于更大的变更集,我可能不得不考虑切换到 git stash -p。
@thekingoftruth 这是我用来创建补丁文件的别名,它确实支持二进制文件:patch = log --pretty=email --patch-with-stat --reverse --full-index --binary。但是请注意,这需要您对要提交的补丁所做的更改。
如果要存储的文件类似于 ../../foo/bar.txt,这对我来说不是很干净。补丁生成正常,但我需要移动到存储库根目录才能应用补丁。因此,如果您遇到问题 - 只需确保您是从存储库根目录执行此操作。
huntsbot.com洞察每一个产品背后的需求与收益,从而捕获灵感
假设您有 3 个文件
a.rb
b.rb
c.rb
并且您只想存储 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
你完成了! HTH。
huntsbot.com – 高效赚钱,自由工作
如果您不想在隐藏的更改中指定消息,请在双破折号后传递文件名。
$ git stash -- filename.ext
如果它是一个未跟踪的/新文件,您必须先暂存它。
此方法适用于 git 版本 2.13+
这个答案很冗长,这很简洁。如果它对某人有帮助,我会离开它。这个页面上没有人提到这个语法和结果——他们反而提到了
git stash push。
这是我一直在寻找的答案。谢谢! +1
huntsbot.com精选全球7大洲远程工作机会,涵盖各领域,帮助想要远程工作的数字游民们能更精准、更高效的找到对方。
如果您只想存储部分更改的文件,只需在 Stage 中添加其他文件,然后执行 git stash push --keep-index
它将存储所有未暂存的更改文件
huntsbot.com汇聚了国内外优秀的初创产品创意,可按收入、分类等筛选,希望这些产品与实践经验能给您带来灵感。
另一种方法:
# 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 stash 用作“某处”(因此,最后还有一个额外的步骤:删除您放入 stash 的 cahnges,因为您也将它们移开了)。
我最喜欢这种方法。它只使用 stash 和 revert 命令在 tortoisegit 中提供了一个简单的工作流程。
不建议使用职位参考关于 SO 的答案。排名随着评级的变化而变化。
@BryanAsh好吧,这并不重要。我是在讲一个轶事,而不是真正提到其他答案。信息是我不喜欢社区喜欢的答案,而不是这些答案实际包含的内容。此外,第二个和第三个答案之间的 900 票差距使得这在不久的将来不太可能改变,如果它应该改变,我总是可以编辑它说“当时的答案最高”。真的,我不明白在这种情况下这是怎么回事。
huntsbot.com提供全网独家一站式外包任务、远程工作、创意产品分享与订阅服务!
你可以简单地这样做:
git stash push "filename"
或带有可选消息
git stash push -m "Some message" "filename"
这并没有增加任何新内容。多个答案中已经提到了 Git stash push
git stash push -- 对我有用,并在最近的 GIT 版本 (v2.13>) 中添加为要走的路。你可以得到<文件路径>如果你运行 git status。
huntsbot.com – 程序员副业首选,一站式外包任务、远程工作、创意产品分享订阅平台。
更新(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
您可以将上述脚本另存为 git-stash-index 在路径中的某处,然后可以将其作为 git stash-index 调用
#
git add
git stash-index
现在 stash 包含一个新条目,其中仅包含您已暂存的更改,并且您的工作树仍包含任何未暂存的更改。
在某些情况下,工作树的更改可能依赖于索引的更改,因此当您存储索引更改时,工作树的更改会发生冲突。在这种情况下,您将获得可以使用 git merge/git mergetool/etc 解决的常见未合并冲突。
建议在脚本末尾使用 pushd 而不是 cd 和 popd,这样如果脚本成功,用户将在与运行之前相同的目录中结束。
@Nate:据我所知,如果用户获取脚本,它应该只更改用户的目录。如果您正常运行脚本(~/bin/git-stash-index),或者通过 git(git stash-index),它会在单独的终端会话中运行,并且该会话中的任何工作目录更改都不会影响用户终端会话中的工作目录。当这不正确时,您是否知道常见的使用案例? (除了采购脚本,我不认为这是“常见的”)
huntsbot.com聚合了超过10+全球外包任务平台的外包需求,寻找外包任务与机会变的简单与高效。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。