63

我有一个 Git 存储库 (A),其中包含一个项目的开发直到某一点。然后我丢失了这个 repo A 所在的 U 盘。幸运的是,我有最新提交的备份,因此我可以稍后创建一个新存储库 (B),在其中导入最新项目的状态并继续开发。现在我找回了丢失的 U 盘,所以我有两个 Git 存储库。

我想我只需要以某种方式将 repo B 重新定位到 repo A 上,但我不知道该怎么做,也许使用 fetch/pull 和 rebase?

4

4 回答 4

68

如果 A 和 B 不是同一个 repo(你使用最新的工作副本创建了 B),你必须使用移植来假装它们有共同的历史。

假设您已根据VonC 的回答将 A 添加为 B 的遥控器,并且 repo 看起来像这样1

~/B$ git tnylog 
* 6506232 (HEAD, master) Latest work on B
* 799d6ae Imported backup from USB stick
~/B$ git tnylog A/master
* 33b5b16 (A/master) Head of A
* 6092517 Initial commit

创建一个嫁接,告诉 B 的根,它的父级是 A 的头:

echo '799d6aeb41095a8469d0a12167de8b45db02459c 33b5b16dde3af6f5592c2ca6a1a51d2e97357060' \
 >> .git/info/grafts

现在,当您请求 B 的历史记录时,上面的两个历史记录将显示为一个。使移植永久化很简单git filter-branch,没有任何参数。但是,在过滤器分支之后,您不在任何分支上,因此您应该git branch -D master; git checkout -b master.


1 git tnylog =git log --oneline --graph --decorate

于 2010-03-11T20:15:31.843 回答
40

如果 A 和 B 是同一个 repo(第一个 SHA1 是通用的),你可以:

  • 将 A 声明为 B 的遥控器:git remote add A /path/to/A
  • git fetch A更新B 存储库上的所有远程 A 分支
  • git checkout dev(在 B 上,您正在开发的地方)
  • git rebase A/devBranchA/devBranch在(您丢失的开发)之上重放 B(即您开发或从备份中重新开发的内容)。有点像这个SO question

最后一步允许您将您的开发与丢失的开发同步。
但实际上,一旦你从 A 获取,你就完成了:B 现在包含“所有”历史(你丢失的历史和你当前的工作)

于 2010-03-11T19:59:47.760 回答
4

2021 更新

git filter-branch自 Git 2.24(2019 年第四季度)以来已被弃用。相反,对于 A 和 B 不是同一个 repo 的场景,您可以使用git replace --graft <commit> <parent>.

看:

于 2021-04-30T14:33:50.760 回答
2

首先,首先制作 repo A 的工作克隆。

然后简单地从 B 拉入它并合并。您可能更喜欢创建一个新分支,拉入它,然后合并两个分支。您可能还需要一个强制标志;我在 Mercurial 中做过类似的事情(将两个明显不相关的存储库嫁接在一起),它需要“-f”。

于 2010-03-11T20:01:17.573 回答