为什么git rev-parse HEAD显示的提交与git log不同?

时间:2018-07-06 16:25:54

标签: git

我正在跟踪上游分支,并且已对本地git pull -s recursive -X theirs release master分支执行了upstream

当我做git log release/master时,会得到922371ba的阴影,但是当我做git rev-parse HEAD时,会得到不同的阴影,03bebbf13。两者有什么区别?

我基本上只是想确保我的本地提交与release/master上的最新提交匹配。

1 个答案:

答案 0 :(得分:3)

已更新-已更新问题,以澄清发出的命令不是最初声明的命令,并说明OP试图完成的操作。某些原始答案仍然适用,因此我将其保留在下面,但这是当前编写的问题的答案:

git pull可以配置为做很多事情,但这始终意味着“将(从我命名的ref)到当前提交行的更改合并起来”。尽管-X theirs会解决所有冲突,以支持您要进行的更改,但这仍将保留当前分支中所有无冲突的更改。

简而言之,pull不是您想要的。

选项1 :如果您只想拔掉upstream并丢弃其历史记录,那相对容易。

git reset --hard release/master

这样做是对upstream的历史重写,因此有两件事:

首先,如果先前已推过upstream,则现在必须强制推入(git push --force-with-lease)。

第二,如果其他人拥有upstream的副本,则强制推送将使它们处于损坏状态。如果他们尝试以直观的方式解决问题,则可能会撤消您的操作。为防止您必须与他们协调并让他们知道您在做什么。请参阅“从上游基础恢复中”下的git rebase文档。

选项2 :如果您希望upstream保留其当前历史记录,但是您希望upstream上的下一次提交与release/master具有相同的内容,有几种方法可以做到这一点。您应该首先检出upstream并创建干净的工作树和索引。然后确保您拥有最新的release/master

git fetch release

从那里开始,一个简单的过程(尽管它使用的命令较少):

git reset --hard $(git commit-tree -p upstream -m "sync with release/master" release/master^{tree})

或者您可以坚持使用更多基本命令

git rm -r *
git checkout release/master -- .
git add .
git commit -m "sync with release/master"

在这一点上,将来和release/master之间的合并肯定会发生冲突,因为git不会保留有关分支当前状态之间关系的任何知识。

选项2B :如果您想保留upstream的历史记录和/或无法彻底协调历史记录的重写,并且仍然不想离开{{ 1}}处于很难与upstream进行交互的状态,那么您将需要在两者之间创建合并提交。这意味着release/master的提交SHA(将是合并提交)仍将与upstream的提交SHA有所不同-但可以使内容匹配,就像您可以使用{{1 }}。为此:

按照上面选项2的步骤进行操作。这样可以确保release/mastergit diff之间的默认合并会发生冲突。这很重要,因为我们下一步要做的就是创建有时称为“邪恶合并”的内容,如果父母可以使用默认合并干净地合并,那么邪恶合并会带来最大的麻烦设置。

因此,既然您在origin/master上拥有正确的内容,我们就需要让git确信分支是相关的。

upstream

请注意,upstreamgit merge -s ours origin/master 不同。在这里,我们使用的是“我们的合并策略”,它只是将内容完全保留为我们已有的内容。 -s ours是一种选择(通常是递归策略);在这种情况下,仍然会发生真正的内容合并,只有解决冲突的情况才有利于我们现有的内容。

----

原始答案

我们没有足够的信息做更多的事情,只是希望能向您指出正确的大致方向...所以这就是我可以说的:

您说-x ours的意思是“获取-X将其合并到我当前的分支中git pull release/master)[1]。

这可能导致以下两种情况之一:如果release/master可以到达upstream头的前一次提交(通过父指针),则默认情况下git将移动{{1} }与upstream的提交相同。

如果您的配置或选项禁止“快进”,或者{{1}中 无法通过父指针到达release/master头的先前提交},然后创建一个新的“合并提交”。此合并提交有两个父级-位于upstream开头的提交和来自release/master的提交。它融合了两者的所有变化。

您似乎看到了后者的行为。不同之处取决于upstream中没有对release/master中的手进行过哪些更改(如果有)。您可以通过upstream来确定这些内容(如果有)。


[1]好吧,这就是默认的含义。您的配置可以对此进行更改,例如,通过告诉分支将分支重新基于release/master提交,而不是合并。我怀疑这是发生了什么,但是从记录来看,这还会导致upstreamorigin/master具有不同的提交哈希,并且您还会看到git diff upstream origin/master有什么不同。