微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

修复 git repo 中的连接并与旧 repo 合并以保留历史记录

如何解决修复 git repo 中的连接并与旧 repo 合并以保留历史记录

问题

我有两个代码库“REPO A”和“REPO B”,它们属于同一个项目。事实上,REPO B 是 REPO A 的延续,因此应该包括 REPO A。我无法从本地存储库 REPO B 推送回原始(裸)存储库 REPO A,因为似乎存在结构错误。在 REPO B 中调用 git log 时,我得到:

error: Could not read 3c4168d
fatal: Failed to traverse parents of commit 3d8c67a

背景

在 2016 年,我开始推送“REPO A”,它位于 RaspBerry Pi Linux 计算机上作为裸存储库。自 2018 年以来,我不再推送到 REPO A,因为我是该项目中唯一的开发人员,并且更喜欢只提交到我的本地克隆“REPO B”。现在,三年后,我想继续推到REPO A,但在尝试时遇到了问题。这是structure of the two REPOs

                                                        +-----  HEAD -> master of REPO B
                                                        |
                                                        |
                                                        v
                                                    +---------+
                                           d784821  |         |  latest commit
                                                    +---------+  20 Mar 2021
                                                         |
                                                    +---------+
                                           bcc1186  |         |  commit
                                                    +---------+  14 Dec 2020
                                                         |

                                                        ...

                                                         |
                                                    +---------+
REPO A                                     86dea25  |         |  commit
                                                    +---------+  8 Nov 2018
HEAD -> master                                           |
origin/master   -----+                              +---------+
origin/HEAD          |                     f5ea2e3  |         |  commit
                     |                              +---------+  7 Apr 2018
                     |                                   |
                     |                              +~~~~~~~~~+
                     |                              |    ?    |  -> error: Could not read 3c4168d
                     |                              +~~~~~~~~~+  -> fatal: Failed to traverse
                     v                                   |                 parents of commit 3d8c67a
                +---------+                         +~~~~~~~~~+
        commit  |         |  3c4168d       =        |         |
   13 Mar 2018  +---------+                         +~~~~~~~~~+
                     |                                   |

                    ...                    =            ...

                     |                                   |
                +---------+                         +~~~~~~~~~+
        commit  |         |  7ad262b       =        |         |
    2 Aug 2016  +---------+                         +~~~~~~~~~+
                     |                                   |
                +---------+                         +~~~~~~~~~+
initial commit  |         |  09b9c4d       =        |         |
    2 Aug 2016  +---------+                         +~~~~~~~~~+

                   REPO A                              REPO B

推理

两个REPO的下半部分应该是相同的,因为REPO B包含了REPO A的延续。3c4168d的HASH值,属于REPO A的最新提交,是相同的HASH值,即在尝试 git log REPO B 时出现错误。因此,在 REPO B 的最旧有效提交 f5ea2e3 之后的向下连接不知何故丢失了。

当尝试使用 SourceTree 打开 REPO B 时,它拒绝设置显示错误消息的项目:

error code 128: refs/remotes/GitPi/master does not point to a valid object!
error: Could not read 3c4168d...
fatal: revision walk setup Failed

但是提交到 REPO B 仍然使用命令行。

问题

我如何“修复” REPO B 以便我找回当前丢失的提交历史记录(它仍然有效地位于 REPO A 中?我如何才能恢复 logpush 从再从 REPO B 到 REPO A?

我明白了,有很多帖子涉及粘合两个存储库和修复提交历史,但经过几个小时的阅读,我无法弄清楚我的具体情况。

感谢您的任何提示

解决方法

经过一整天的阅读和尝试,问题可以解决;-)。这是,它是如何执行的。希望对某人有帮助:

概念

  1. 通过在 REPO A 的尖端创建一个新的“恢复提交”来修复提交链中缺失的链接,然后
  2. 为 REPO B 的每个有效提交创建补丁,然后
  3. 将补丁应用到 REPO A。补丁不查看 blob,而只包含更改的代码片段。从而使“重放”提交变得容易。

修复 REPO A 和 B 之间丢失的链接

找到两个有效提交 f5ea2e3 (Repo B) 和 3c4168d 之间的链接

cd RepoB
git show <sha-of-broken-commit>
  • commit 3d8c67a 已损坏且未找到其父项
  • 但对象可能没问题

上面的命令给出了树对象(参见文件夹)的 sha 以查找更多的 blob 对象(文件)。这样,尝试从损坏的提交 3d8c67a 中恢复所需的尽可能多的信息,以便在 REPO A 之上创建一个有效的提交 3c4168d,它可以顺利地适应由提交 {{1} 强加的更改} 来自回购 B。

f5ea2e3
  • 相应的树对象确实存在并且有效
  • git cat-file -p <sha-of-tree-object> 中更改的文件的相应 blob 对象存在且有效

现在,使用 Python 和 f5ea2e3 包恢复属于损坏提交 3d8c67a 的文件

zlib

从 REPO B 创建补丁

从提交 import zlib fname = r'<path-to-object-within-object-folder-below-git-management-folder>' compressed = open(fname,'rb').read() decompressed=zlib.decompress(compressed) fh = open("./<filename>",'w') fh.write(decompressed.decode('utf-8')) fh.close() 到 repo 结束在 REPO B 中创建补丁。

f5ea2e3

在回购 A 中应用补丁

将所有补丁应用到 REPO A 的尖端(在新的“恢复提交”之上)

cd ../RepoB
git format-patch f5ea2e3 -o _patches/

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。