如何在不触发自动合并的情况下弹出git stash?

时间:2013-05-08 15:36:39

标签: git

这个问题的简短版本是:如何在不触发自动合并的情况下弹出git藏匿?


现在是更长版本......

考虑以下git stash ... + git pull ... + git pop的替代玩具示例。

首先,git status表明工作目录中的唯一修改是某个跟踪文件foo

# On branch master
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   foo
#
no changes added to commit (use "git add" and/or "git commit -a")

现在,为了将工作目录重置为干净状态,作为运行git pull的先决条件,我暂时重命名已修改的文件foo(以某些未跟踪的名称),并恢复foo中的HEAD版本...

% mv foo foo.$(date +%Y%m%dT%H%M%S)
% git checkout foo
% git status
# On branch master
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#   foo.20130508T110014
nothing added to commit but untracked files present (use "git add" to track)

好的,现在我运行git pull,为了这个例子,我们假设这是一个快进:

% git pull

最后,我恢复暂时重命名的foo

% mv foo.20130508T110014 foo

......我回到了

% git status
# On branch master
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   foo
#

这是git stash save + git pull + git stash pop的“道德等价物”,除了前者,而不是后者,免于“合并冲突”,就像这样:

% git stash save 'WIP'
% git pull
% git stash pop
Auto-merging foo
CONFLICT (content): Merge conflict in foo

如何在不使用触发自动合并的情况下使用rename-checkout-pull-rename复制上述git stash save + ... + git stash pop序列?

顺便说一下,rename-checkout-...-rename例程更接近于我对stash命令的期望。换句话说:现在保存我的工作目录的状态,并在以后替换它。 此图片中没有“合并”。

4 个答案:

答案 0 :(得分:5)

stash合并,这就是它的工作原理。

您可以使用write-tree read-treecheckout-index来实现非合并存储。 Here's a worked example for doing this to achieve a pristine test environment

要强制执行无合并存储应用,您可以例如。

git read-tree stash^{tree}
git checkout-index -af

答案 1 :(得分:5)

我姗姗来迟地意识到git已经为推动这个问题的问题提供了一个非常简单的解决方案(即自动合并可能使存储库处于“未合并状态”)。

所有人需要做的就是使用

git stash branch <branchname> [<stash>]

而不是git stash pop(或git stash apply)。

这会以保证没有冲突的方式弹出存储。 易于peasy-柠檬squeezy

答案 2 :(得分:2)

好的,在遇到这样的事情之后:

% git stash pop
Auto-merging foo
CONFLICT (content): Merge conflict in foo
Auto-merging bar
CONFLICT (content): Merge conflict in bar
Auto-merging baz
CONFLICT (content): Merge conflict in baz
...

# $#@?!?!%$!*@#...

......我设法提出的最佳解决方案就是回应:

% git checkout --theirs $(git diff --name-only --diff-filter=U)
% git reset
% git stash drop

(基于this answer。)

答案 3 :(得分:2)

您看到合并冲突的事实意味着您从服务器中提取的foo文件发生了更改。因此,复制文件并向后移动将完全取消foo文件中repo的所有更改。如果你提交了,那么提交foo的其他人就会讨厌你。

您的问题的答案取决于您要完成的任务。您是否正在尝试查看服务器上的更改与您的代码进行比较?在你完成之前,你是否试图避免处理其他人的代码?

如果您只想查看分支的更改内容,可以使用git fetch代替git pull,并将当前代码与之比较。或者,如果您现在不想合并更改,请考虑在单独的分支中工作,或者在您准备合并之前不要拉动。