Git 推送分离远程和本地分支

Git push diverges the remote and local branch

我有一个名为 source_report_overview_Approach3 的本地分支,在 github 上有一个名为 origin/source_report_overview_Approach3 的远程分支。

  1. 在一个点,两者都指向同一个提交,如下图所示。

  2. 现在我使用消息 "test commit" 向我的本地分支再次提交 (git commit)。这将我的本地分支向前移动,同时将远程保持在同一位置,如下所示:

  3. 现在我将此提交推送到远程 (git push origin source_report_details_Approach3)。据我所知,git 应该将 remotes/origin/source_report_details_Approach3 移动到以后的提交,即 test commit 并且我的本地和远程分支应该再次同步并且应该指向相同的 test commit,但不知何故它做了如下所示的事情:

  4. 现在,如果我这样做 git status,它会给我以下消息: 我相信这不应该发生。 remotes/origin/source_report_details_Approach3 不应该更新为自动指向 source_report_details_Approach3 吗?

  5. 我通过在同一个文件中的同一个地方进行了另一个提交(git commit),就像我在提交 test commit 中所做的消息 test commit 2 .它使历史如下:

  6. 现在我尝试推送此提交 (test commit 2),然后出现以下错误:

  7. 我该如何解决这个问题。根据我对 git 的了解,发生这种情况很奇怪。

  8. 如果我尝试使用 git pull origin source_report_details_Approach3 拉出分支,则会出现合并冲突。这是因为 test commit and test commit 2 都在同一文件的同一位置进行了更改。 Git 尝试将 test commit 从远程合并到我的本地分支。由于我的本地文件有 test commit 2 ,它会产生冲突。

  9. 而且我是唯一一个在分支机构工作的人。还是因为问题,几乎每次push什么都要解决合并冲突

尝试 git show-ref source_report_details_Approach3 并检查可用的引用以及相关的提交 ID。我怀疑您可能遇到与所提到的问题类似的问题 in this question

看来问题出在服务器端。如果这些更改了提交,那么远程提交和本地提交之间当然会有差异。您可以像这样检查本地和远程提交之间的区别:

git diff origin/source_report_details_Approach3

注意 :这只会显示更改的文件中的差异;提交消息之间没有差异。我不知道有什么简单的方法可以看出提交消息中的差异,但您可以自己使用以下方法查看它们:

git show --stat source_report_details_Approach3 > local
git show --stat origin/source_report_details_Approach3 > remote
diff local remote
rm local remote

一些解释:

  • git show : 显示带有消息的完整提交
  • --stat :仅显示文件中更改的行数的选项;使输出方式更短
  • 我创建了两个临时文件。这是一个解决方法,但我还没有找到更好的方法来执行此操作

因此,在一些帮助下,我能够找出问题的根本原因。

我写了一个 pre-push 钩子,它做了如下事情:

  1. 从历史记录中查找最后一条提交消息。
  2. 如果该消息中包含特定文本,则 git commit --amend -m "new message" 然后推送提交。

  3. 从逻辑上讲,#2 应该将修改后的提交推送到远程。但是这里违反了逻辑。

  4. 发生的事情是,push 命令实际上在调用挂钩之前找出要推送的内容。所以在我的例子中,远程提交的是未修改的提交,而我的本地提交是最新的修改提交。这显然将我的本地与远程分开,因此我发生了这件奇怪的事情。

Link 值得一读,帮助我发现 push 在调用挂钩之前确定要推送的内容:don't commit in pre push hook

另外 gitk HEAD @{u} 证明真的很有帮助。