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

Posted

技术标签:

【中文标题】git stash -> 将隐藏的更改与当前更改合并【英文标题】:git stash -> merge stashed change with current changes 【发布时间】:2012-07-25 10:13:17 【问题描述】:

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

有没有办法做到这一点?

为了方便起见,我最终放弃并首先提交了我当前的更改,然后是我隐藏的更改,但我更愿意一举将它们纳入。

【问题讨论】:

可能与***.com/q/1360712/72178重复 【参考方案1】:

运行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 压缩这两个提交,但这可能会带来更多麻烦。

【讨论】:

我确实收到了这条消息 - 更改不冲突但共享相同的文件,是否使用 stashes/apply 的? 对不起,这就是我所说的“合并冲突”,但这是一个糟糕的词选择。我认为该错误消息是最终的:如果在工作副本中更改的文件也在存储中更改,则无法应用存储。我已经用可能的解决方法更新了我的答案。 我不会在所有情况下都认为这是一个答案。您可能只在特定文件中隐藏了一组更改的一部分,因为您想在开发时测试一些东西。您可能不想在此时提交文件的当前内容(或根本不想提交),因为它是 WIP。 git 的一个真正问题是隐藏的更改无法合并到您当前的分支中 Joshua Warner 的答案应该是正确的。要合并存储,暂存更改,应用存储,处理任何冲突,然后(如果需要)取消暂存更改。 "如果您真的不想要两次提交,您可以提交更改、应用存储、再次提交,然后使用 git rebase 压缩这两个提交,但这可能会带来更多麻烦,但值得。 "您可以这样做:提交更改,应用存储,然后git commit --amend【参考方案2】:

tl;博士

首先运行git add


我刚刚发现,如果将您未提交的更改添加到索引中(即“分阶段”,使用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"

...这可能是您正在寻找的。​​p>

【讨论】:

这样的黑客,但是,嘿,它有效,似乎是唯一的方法。我希望有git stash apply --force 之类的。 实际上,这不是 hack - 它是对您想要的改进,因为您可以轻松地恢复到索引中的更改。 哇,这种行为真的是 git 想要的吗? 我不认为 git 有任何“意图”。我的直觉是,git 所做的任何事情都是偶然的。 这是完美的解决方案。我刚刚做了git add .git stash apply,然后git reset 将存储应用到我的工作更改并合并而无需提交。【参考方案3】:

正如@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^

【讨论】:

【参考方案4】:

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

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

【讨论】:

它将应用一个diff的问题变成了应用两个diff的问题。此外,公认的解决方案不涉及提交,只是一个阶段,而且它只是一个命令(git add)。 (我不是反对者。) 对我来说至少感觉更简单,更少的巫术魔法......干杯!【参考方案5】:

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

这是另一种选择:

git stash show -p|git apply
git stash drop

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

【讨论】:

谢谢你——我不知道为什么git stash pop 不只是在合并完全适用的情况下这样做...... 扩展版:git stash show -p --no-color | git apply --3way--3way = 如果补丁失败,则退回到 3 路合并)。 但是git stash show -p 创建了一个差异between the stashed contents and the commit back when the stash entry was first created。因此,这将覆盖 OP 所做的工作文件更改。 为什么要覆盖?使用git stash show -p 产生的差异将由git apply 合并,如果可以做到没有冲突的话。【参考方案6】:

我这样做的方法是先git add,然后再git stash apply <stash code>。这是最简单的方法。

【讨论】:

这不是接受答案的 tl;dr 的精确副本吗?【参考方案7】:

也许,从……是的……一个分支合并(通过 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

【讨论】:

【参考方案8】:

你可以轻松

    提交您当前的更改 取消隐藏并解决冲突 从存储提交更改 软重置以提交您来自(最后一次正确的提交)

【讨论】:

以上是关于git stash -> 将隐藏的更改与当前更改合并的主要内容,如果未能解决你的问题,请参考以下文章

Git diff 与 stash

git切换分支不合并当前分支的修改--git stash

git stash操作

git命令之git stash 暂存临时代码

git常用命令

git stash 保存当前工作状态