git stash->将隐藏的更改与当前更改合并


186

我对分支机构进行了一些更改,但意识到我忘记了对所述分支进行其他必要的更改。我想要的是一种将隐藏的更改与当前更改合并的方法。

有没有办法做到这一点?

为了方便起见,我最终放弃了并承诺首先进行了当前的更改,然后隐瞒了我所做的更改,但是我宁愿一口气将它们加入。



约书亚的答案应该是被接受的答案。此stackoverflow帖子是此问题的第一个Google链接,为互联网提供正确的答案!
–Jérôme,

Answers:


271

我刚刚发现,如果将您未提交的更改添加到索引中(即使用进行了“暂存” git add ...),则git stash apply(并且大概是git stash pop)实际上将进行正确的合并。如果没有冲突,那您就是金。如果不是,请使用正常解决问题git mergetool,或使用编辑器手动解决。

明确地说,这是我正在谈论的过程:

mkdir test-repo && cd test-repo && git init
echo test > test.txt
git add test.txt && git commit -m "Initial version"

# here's the interesting part:

# make a local change and stash it:
echo test2 > test.txt
git stash

# make a different local change:
echo test3 > test.txt

# try to apply the previous changes:
git stash apply
# git complains "Cannot apply to a dirty working tree, please stage your changes"

# add "test3" changes to the index, then re-try the stash:
git add test.txt
git stash apply
# git says: "Auto-merging test.txt"
# git says: "CONFLICT (content): Merge conflict in test.txt"

...这可能就是您要寻找的。


tl; dr

git add第一。


8
这样的hack,但是,嘿,它可行,并且似乎是实现此目的的唯一方法。我希望有git stash apply --force什么。
马特·坎托

12
实际上,这不是黑客,而是对所需内容的改进,因为您可以轻松地恢复索引的更改。
hoffmanc 2014年

2
哇,这个行为真的是git想要的吗?
edi9999 '16

9
我认为git从来没有“打算”做任何事情。我的直觉是,现在git所做的任何事情都是偶然的。
Profpatsch,2016年

5
这是完美的解决方案。我只是做了git add .git stash apply然后git reset将隐藏应用于我的工作更改并合并而不必进行提交。
史蒂芬·史密斯

70

运行git stash popgit stash apply本质上是合并。除非隐藏文件中更改的文件在工作副本中也被更改,否则您不需要提交当前更改,在这种情况下,您将看到以下错误消息:

error: Your local changes to the following files would be overwritten by merge:
       file.txt
Please, commit your changes or stash them before you can merge.
Aborting

在这种情况下,您不能一步一步将存储空间应用于当前更改。git rebase如果您确实不希望进行两次提交,则可以提交更改,应用存储,再次提交并压缩这两个提交,但这可能更麻烦,值得这样做。


1
我确实收到了该消息-更改没有冲突,但是共享相同的文件,是否使用存储/应用程序?
Bemis

1
抱歉,这就是我所说的“合并冲突”,但这是糟糕的单词选择。我认为该错误消息是最后的消息:如果工作副本中更改的文件在存储中也更改了,则无法应用该存储。我已经用可能的解决方法更新了答案。
布兰登

3
我不会在所有情况下都认为这是答案。您可能只在特定文件中保存了一部分更改,因为您想在开发时进行测试。而且,由于它是WIP,因此您可能不希望在该时间点(或根本不希望)提交文件的当前内容。git的一个真正问题是无法将隐藏的更改合并到您当前的分支中
Thomas Watson

21
约书亚·华纳的答案应该是正确的答案。要合并存储,请暂存更改,应用存储,处理所有冲突,然后(如果需要)取消暂存更改。
Vroo

4
“如果您确实不希望进行两次提交,则可以提交更改,应用存储,再次提交,并使用git rebase压缩这两次提交,但这值得付出更多的麻烦。” 替代此方法,您可以执行以下操作:提交更改,应用存储,然后单击git commit --amend
gabe 2015年

27

我想要的是一种将隐藏的更改与当前更改合并的方法

这是另一种选择:

git stash show -p|git apply
git stash drop

git stash show -p将显示最后保存的隐藏补丁。git apply将应用它。合并完成后,可以使用删除合并的存储git stash drop


1
谢谢您-我不知道为什么git stash pop在合并完全适用的情况下不这样做……
Iguananaut

扩展版本:git stash show -p --no-color | git apply --3way--3way=如果补丁失败,则退回到三路合并)。
DmitrySandalov,

但是,在首次创建存储项时,会在存储的内容和提交之间git stash show -p产生差异。因此,这将覆盖OP所做的工作文件更改。
Paul F. Wood

为什么要覆盖?与产生的差异git stash show -p将通过合并git apply,如果可能的话不会发生冲突。
ks1322

1

我这样做的方法是git add先做到这一点git stash apply <stash code>。这是最简单的方法。


3
这是不是已接受答案的tl; dr的精确副本?
RomainValeri

0

正如@Brandan所建议的那样,这是我需要解决的问题

error: Your local changes to the following files would be overwritten by merge:
       file.txt
Please, commit your changes or stash them before you can merge.
Aborting

请遵循以下过程:

git status  # local changes to `file`
git stash list  # further changes to `file` we want to merge
git commit -m "WIP" file
git stash pop
git commit -m "WIP2" file
git rebase -i HEAD^^  # I always use interactive rebase -- I'm sure you could do this in a single command with the simplicity of this process -- basically squash HEAD into HEAD^
# mark the second commit to squash into the first using your EDITOR
git reset HEAD^

您将剩下对的完全合并的本地更改file,准备进行进一步的工作/清理或进行单个良好的提交。或者,如果您知道的合并内容file正确,则可以编写适当的消息并跳过git reset HEAD^


0

可能是,(通过difftool)从...是...分支合并不是一个最坏的主意!

> current_branch=$(git status | head -n1 | cut -d' ' -f3)
> stash_branch="$current_branch-stash-$(date +%yy%mm%dd-%Hh%M)"
> git stash branch $stash_branch
> git checkout $current_branch
> git difftool $stash_branch

0

你可以轻松地

  1. 提交您当前的更改
  2. 释放藏匿处并解决冲突
  3. 提交隐藏的更改
  4. 软重置以提交您来自的提交(最后一次正确提交)

-1

另一种选择是对本地未提交的更改执行另一个“ git stash”,然后合并两个git stash。不幸的是,git似乎没有办法轻松地合并两个存储。因此,一种选择是创建两个.diff文件并同时应用它们-至少这不是额外的提交,并且不涉及十个步骤:

如何:https : //stackoverflow.com/a/9658688/32453


这将应用一个差异的问题变成了应用两个差异的问题。此外,公认的解决方案不涉及提交,而仅涉及一个阶段,并且仅是一个命令(git add)。(我不是拒绝投票的人。)
Eike

至少对我来说,这感觉更简单,更少的伏都教徒……欢呼!
rogerdpack
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.