0

我注意到 git merge 在进行合并时似乎没有进行稳定的排序。或者它可能是完全不同的东西。我真的不知道出了什么问题。

如果你尝试这个小测试用例 10-20 次,直到它显示“FLAKY”:

mkdir a; cd a; output=$(git init .; touch 0; git add 0 ; git commit -m0; git checkout -b b1; touch 1; git add 1; git commit -m1; git branch b2 master; git checkout b2; touch 2; git add 2; git commit -m2; git checkout master; git merge b1; git merge b2 -m"merge";) test=$(git log --format=%s|xargs echo); if [[ "merge 2 1 0" == "$test" ]]; then echo "FLAKY " $test; else cd ..; rm -rf a; fi; 2> /dev/null

(它是一个单行器,你可以在 bash 提示符下运行它)

通常,您最后回显的日志将如下所示:

merge 1 2 0

但过了一会儿,你可能会得到 1 和 2 交换位置:

merge 2 1 0

这令人难以置信的愤怒。我总是可以让这两个第一次提交在测试中可以互换,但我宁愿不这样做。我宁愿去除片状。有谁知道是什么原因造成的?

4

1 回答 1

0

TLDR:这是一个很容易触发的竞争条件,因为 git log 以 1 秒的分辨率按时间排序。一个可能的解决方法是使用:

git log --topo-order

所以在调查了这个之后。Git 根据日期/时间对提交进行排序。这是显而易见的。存储的日期以纪元以来的秒数为单位,unix 时间戳,所以分辨率很糟糕。当所有提交具有相同的时间戳(通常情况下)时,它将选择以某种(稳定!)顺序“合并 1 2 0”对它们进行排序。

但是,有时,最后 2 恰好时间更改时发生,因此它将具有高一的时间戳,因此始终位于 1 之上。

所以这是常见的情况:

Merge: a217d34 1f853fc
Date:   1381855683 +0200
    merge

commit a217d34c3b7694e4a5f963ead624b4d3e4a87adf
Date:   1381855683 +0200
    1

commit 1f853fc9acf669929ccab71d341784a525a5360e
Date:   1381855683 +0200
    2

commit 490507918504597c90300889aaf3cb5cbb5dd82c
Date:   1381855683 +0200
    0

这是特殊的(片状)案例。至少在这个测试中,我想在我的真实测试中可能会有所不同,只有当它们突然有相同的时间时才会剥落。

Merge: a2f0bba f3b9f1e
Date:   1381855747 +0200
    merge

commit f3b9f1eeeef0c8c77aa8505224198951dc6d6904
Date:   1381855747 +0200
    2

commit a2f0bba815bb2a1e8e611f755397350c732b5e6b
Date:   1381855746 +0200
    1

commit ab28f3063df4d51c79ee0fbdec0ae77f870e8e3b
Date:   1381855746 +0200
    0

我还没有设计出我将遵循什么计划来解决这个问题,但它似乎git log --topo-order可以做到。至少对于这个小测试,它的行为是相同的。

于 2013-10-15T17:06:56.450 回答