git checkout --merge - 没有按预期工作

问题描述 投票:2回答:2

当我尝试通过检查其路径将我的工作树更改合并到tree-ish中的文件时,前一个更改将被后一个更改覆盖。

我没想到这种行为。相反,我希望Git用默认,合并或diff3样式中显示的冲突标记替换文件内容,具体取决于是否将--merge--conflict=merge--conflict=diff3选项赋予git checkout

鉴于以下用例:

git init
echo foo > foobar
git add foobar
git commit --message=blabla foobar
echo bar > foobar
git checkout --conflict=diff3 HEAD -- foobar

我失去了用echo bar > foobar做出的局部变化。

另外为什么手册页git-checkout(1)在简介-m中提到--conflict=<style>git checkout [-f|--ours|--theirs|-m|--conflict=<style>] [<tree-ish>] [--] <paths>…选项?这两个选项的目的是什么?

我在Microsoft Windows 7上使用git版本1.9.4.msysgit.2。

git git-merge git-checkout
2个回答
0
投票

我明白为什么你期望这种行为 - 文档在描述你得到的行为时“在从索引中检出路径时”,这看起来像是一个doc bug。请注意,在描述您想要的行为时,它会显示“切换分支时”。我完全按照你的方式阅读那对,并以同样的方式感到惊讶。

我认为,为了准确地描述它现在正在做什么,文档应该只是说“当检查路径”并失去“从索引”部分,但我也会争论你想要什么,“当你从一个提交或树[无论是否指定路径]“对于合并行为将是一个更好的选择,并且它应该被改变为以这种方式工作 - 一个更容易证明理由的课程,因为atm文档没有实际上说这是怎么做的


0
投票

这应该随Git 2.22(2019年第二季度)而改变。

git checkout -m <other>”是关于在检查另一个分支时向前传递HEAD和工作树文件之间的差异,并忽略了HEAD和索引之间的差异。

当索引和HEAD不同时,已经教导该命令中止。

参见commit 6eff409commit 3e41485commit b165faccommit 191e9d2Nguyễn Thái Ngọc Duy (pclouds)(2019年3月22日)。 (由Junio C Hamano -- gitster --合并于commit 4a3ed2b,2019年4月25日)

checkout:防止与--merge失去上演的变化

当指定了--merge时,我们可能需要进行真正的合并(而不是三向树解包),这些步骤最好在git-checkout.sh版本中被删除之前删除:

    # Match the index to the working tree, and do a three-way.
    git diff-files --name-only | git update-index --remove --stdin &&
    work=`git write-tree` &&
    git read-tree $v --reset -u $new || exit

    git merge-recursive $old -- $new $work

    # Do not register the cleanly merged paths in the index yet.
    # this is not a real merge before committing, but just carrying
    # the working tree changes along.
    unmerged=`git ls-files -u`
    git read-tree $v --reset $new
    case "$unmerged" in
    '')     ;;
    *)
            (
                    z40=0000000000000000000000000000000000000000
                    echo "$unmerged" |
                    sed -e 's/^[0-7]* [0-9a-f]* /'"0 $z40 /"
                    echo "$unmerged"
            ) | git update-index --index-info
            ;;
    esac

注意最后一个'read-tree --reset'步骤。 在worktree被merge-recursive弄乱之后,我们将worktree恢复到'new'树。 如果在执行整个命令序列之前存在分阶段更改,则它们将丢失,因为它们不太可能是要恢复的“新”树的一部分。

没有简单的方法来解决这个问题。 Elijah may have something up his sleeves,但在那之前,检查是否有分阶段的变化,并拒绝运行并失去它们。在这种情况下,用户需要执行“git reset”才能继续。

© www.soinside.com 2019 - 2024. All rights reserved.