我们正试图远离TFS。使用git-tfs工具,我们能够迁移现有仓库的一部分,但在某些麻烦的签入时崩溃了。我们已经能够制作一套拼凑的Git repos,它涵盖了大多数原始TFS提交。
目前有:
所需:
我们有什么方法可以将它们拼接成一个Git仓库吗?我们并不关心保留SHA(他们反正全新),但我们无法打破文件历史记录。
答案 0 :(得分:3)
Git没有拥有文件历史记录。
Git存储提交,提交是历史记录。它们是唯一的历史。 (我说它不是文件历史记录,因为它的提交历史记录。)每个提交都有一个父提交,或者如果提交是一个合并,两个父母(或者可能超过如果是章鱼合并,则为两个。
除了拥有父级之外,每次提交都是该提交中所有文件的独立快照。这里没有历史:它只是一个快照。如果您想查看上一次提交和当前提交之间发生的情况,您可以让Git解压缩先前的提交(旧的快照 O )和当前提交(快照 N for new)并运行diff ON 。发生了什么变化: O 和 N 之间有什么不同。
你可以要求Git合成一个文件历史记录,但它是通过一个可怕的黑客来实现的:它在每个提交中查找一个特定的已更改文件,因为它会通过提交历史记录返回。它打印提交的提交,与该提交的父级相比,该提交会更改文件。如果文件 name 更改 - 如果提交重命名了文件 - 并且您已使用--follow
,则Git会更改哪个(单个)文件名称它寻找,所以现在它以先前的名字寻找。
如果您的历史记录包含一系列提交:
(history starts here, at a root commit)
|
v
o--o--<branches and merges...>--o <-- end
和第二个历史:
o--o--<branches and merges...>--o <-- end
o--o--...--o <-- end2
^
|
(we want to replace this one)
在单个存储库中,您可以编写&#34;替换&#34;提交对象(使用git replace
),就像我们想要要替换的第二个根提交一样,除了一件事:它作为其父提交,具有{{{ 1}}点。
这个替换提交有效地将两个历史拼接在一起。
根据需要对您要添加的多个拼接重复此操作,因为您可以在单个存储库中使用多个单独的提交链。然后,您可以在此存储库上运行end
,该存储库会复制每个提交,但会遵循替换。这具有将移植物固定在适当位置的效果。例如,请参阅What does git filter-branch with no arguments do?或Rebase entire git branch onto orphan branch while keeping commit tree intact。
答案 1 :(得分:1)
使用git的'graft'功能有一种简单的方法可以做到这一点。它是与@torek提到的git replace
目标相同的功能,但在您的情况下更容易使用。
首先,导入同一存储库中的所有历史记录。在最新的存储库中,为另外两个存储库执行操作:
git remote add c:/path/toward/other/repository
git fetch
然后在帮助后创建git移植文件.git/info/grafts
:
https://git.wiki.kernel.org/index.php/GraftPoint
(你的文件中应该有2行)
如果你使用git log
或任何Git GUI,你现在应该看到你想要的历史。
如果您满意,请重写历史记录以使其明确:
git filter-branch
您现在可以将历史记录推送到中央存储库或共享它。
Ps:关于这个主题的另一个文档但融化移植并替换git功能:https://legacy-developer.atlassian.com/blog/2015/08/grafting-earlier-history-with-git/
答案 2 :(得分:0)
- 创建一个新的空存储库New。
- 进行初始提交,因为我们在合并之前需要一个提交。
- 将遥控器添加到旧存储库OldA。
- 将OldA / master合并为New / master。
- 创建一个子目录OldA。
- 将所有文件移至子目录OldA。
- 提交所有文件移动。
- 为OldB重复3-6。
醇>