非常大的 TFS 存储库 — <git tfs 分支>来自子文件夹



我将非常感谢所有关于如何处理手头任务的建议。我已经相当彻底地阅读了关于git-tfs clonegit-tfs quick-clonegit-tfs branch的文档,但仍然无法解决这个问题。

我们的TFS代码库是可怕的大型(之所以如此,是因为它包含大型BLOB等令人讨厌的原因)。然而,它组织得相当好,具有以下结构:

 $/TeamProject/Dev (TERRIBLY LARGE)
  |
  +- $/TeamProject/Dev.EpicX (TERRIBLY LARGE)
  |
  +- $/TeamProject/Dev.EpicY (TERRIBLY LARGE)
  |
  +- $/TeamProject/Dev.EpicZ (TERRIBLY LARGE)

这些分支中的每一个都是"合法的"TFS分支(相对于仅分支的"文件夹")。我们可以将Dev分支视为主要的集成分支。这些分支包含我们的解决方案和项目,以及其他一些资源(如我所提到的,BLOB等)

正如我所说,由于这些分支的规模太大,我们大多数人甚至都不想提取整个分支,而是只提取我们正在开发的相应目录或解决方案。例如,我在$/TeamProject/Dev工作。开发中的EpicY/Foo/Bar/SolutionDirectory。EpicY分支。SolutionDirectory下的源的大小更易于管理(约200MB)。这是我需要创建一个git repo来进行工作的目录,同时享受所有git的好处(本地分支等),而不会影响我将继续使用TFS的同事。

最重要的是:我需要能够通过"合并"来自相应的"父级"$/TeamProject/Dev/Foo/Bar/SolutionDirectory来进行前向集成,该目录正在不断开发中。


我尝试过的

第一次尝试:使用所有分支进行克隆

我对该项目过去的历史不感兴趣,所以我想使用git tfs quick-clone

git tfs quick-clone http://tfs-server/Collection $/TeamProject/Dev.EpicY/Foo/Bar/SolutionDirectory . --branches=all

然后是:

git tfs quick-clone http://tfs-server/Collection $/TeamProject/Dev/Foo/Bar/SolutionDirectory . --branches=all

当我这样做时,我没有得到DevDev之间的父子分支关系。EpicY。例如:

git tfs branch
Git-tfs remote details:
default -> http://tfs-server/Collection $/TeamProject/Dev/Foo/Bar/SolutionDirectory
refs/remotes/tfs/default - 04ddfd8641096a2d02eed4c087423bc0cdeb4ed7 @ 44016

第二次尝试:显式初始化分支

克隆后。现在我甚至得到一个错误:

git tfs branch --init --all
error: The use of the option '--branches=all' to init all the branches is only possible 
when 'git tfs clone' was done from the trunk!!! '$/TeamProject/Dev/Foo/Bar/SolutionDirectory'
is not a TFS branch!

第三次尝试:转到TFS并将子文件夹转换为分支

对于git tfs,TFS中常规文件夹分支之间的区别似乎很大,所以我转到TFS并将SolutionDirectory转换为一个分支及其层次结构:

 $/TeamProject/Dev/Foo/Bar/SolutionDirectory
  |
  +- $/TeamProject/Dev.EpicX/Foo/Bar/SolutionDirectory
  |
  +- $/TeamProject/Dev.EpicY/Foo/Bar/SolutionDirectory
  |
  +- $/TeamProject/Dev.EpicZ/Foo/Bar/SolutionDirectory

现在,当我运行git tfs branch --init --all时,有了一些进展,但它仍然失败了,出现了一个奇怪的错误:

git tfs branch --init --all
Tfs branches found:
- $/TeamProject/Dev.EpicY/Foo/Bar/SolutionDirectory
=> Working on TFS branch : $/TeamProject/Dev.EpicY/Foo/Bar/SolutionDirectory
Branches to Initialize successively :
-$/TeamProject/Dev.EpicY/Foo/Bar/SolutionDirectory (43506)
The name of the local branch will be : Dev.EpicY/Foo/Bar/SolutionDirectory
error: an error occurs when initializing the branch. Branch is ignored and continuing...
=> Working on TFS branch : $/TeamProject/Dev/Foo/Bar/SolutionDirectory
warning: Some Tfs branches could not have been initialized:
- $/TeamProject/Dev.EpicY/Foo/Bar/SolutionDirectory
Please report this case to the git-tfs developers! (report here : https://github.com/git-tfs/git-tfs/issues/461 )
warning: Some Tfs branches could not have been initialized or entirely fetched due to errors:
- $/TeamProject/Dev.EpicY/Foo/Bar/SolutionDirectory
   =>error:error: Couldn't fetch parent branch

文档有些简洁,但我最终成功地实现了创建一个git repo的精确目标,该repo只有必要的历史记录和TFS子目录中的分支代码库。

事实证明,克隆主干的建议并不意味着你必须克隆主干及其分支的整个历史记录,也不意味着你被迫作为分支留在顶级TFS文件夹中。

事实上,为了让git-tfs从TFS中提取分支,它必须是TFS分支(而不仅仅是已分支的文件夹)。但是您可以临时将所需的SolutionDirectory文件夹转换为TFS分支!这是关键。

这是正确的行动顺序:

  1. $/TeamProject/Dev分支到$/TeamProject/Dev.EpicY以开发~/Foo/Bar/SolutionDirectory 时,识别TFS变更集

    • 假设此变更集为:43541
  2. 确保$/TeamProject/Dev/Foo/Bar/SolutionDirectory$/TeamProject/Dev.EpicY/Foo/Bar/SolutionDirectory都是TFS分支

  3. 假设您想在当前目录中初始化git存储库,请运行以下命令:

    PS> git tfs clone --changeset=43541 --branches=all `
        http://tfs-server/Collection $/TeamProject/Dev/Foo/Bar/SolutionDirectory .
    
  4. 显示的输出将显示TFS分支是如何一路拾取的,以及相应的提交是如何获取的

    Initialized empty Git repository in E:/git-tfs/SolutionDirectory/.git/
    Fetching from TFS remote 'default'...
    1 objects created...
    C43541 = 731d29764d88e424b9d6dfb9a34c107aa4cca9c3
    C43608 = aebc94b96079e73e88ea74ed859eec65440c3b03
    C43609 = 64c03137f555345ec7f24fefc992162e6e082a98
    ...
    C44016 = e1b5c55efa528733ecaa3afba31b05cf1a310cb4
    Tfs branches found:
    - $/TeamProject/Dev.EpicY/Foo/Bar/SolutionDirectory
    => Working on TFS branch : $/TeamProject/Dev.EpicY/Foo/Bar/SolutionDirectory
    Branches to Initialize successively :
    -$/TeamProject/Dev.EpicY/Foo/Bar/SolutionDirectory (43506)
    The name of the local branch will be : Dev.EpicY/Foo/Bar/SolutionDirectory
    C43541 = 73589d08398415549fbad191b06c55a272c7ca37
    C43666 = c4bbe9b09138331041cb958cbc8b89f16f7a2902
    C43670 = e7c1e4c787c6c4a745baed46da0eb5d0e3f2fc79
    ...
    C44019 = b2401575dec8347e1debc701073f523aa09e668c
    => Working on TFS branch : $/TeamProject/Dev/Foo/Bar/SolutionDirectory
    
  5. 快乐:)

clone命令创建一个新的git存储库,从TFS源树初始化并获取所有变更集,其中包含--branches=VALUE概要。

quickclone命令创建一个新的git存储库,从TFS源树中的最后一个变更集(或历史中的特定变更集)初始化,忽略不包含--branches=VALUE概要的完整历史。

而且,要使用克隆所有分支的功能,所有与分支对应的源代码文件夹都应该转换为分支。

错误消息指示错误"error:只能使用选项'-branches=all'初始化所有分支当"git-tfs-clone"从主干完成时!!!",在我看来,您只需要使用克隆主干(带有依赖分支),请检查:https://github.com/git-tfs/git-tfs/blob/master/doc/commands/clone.md

最新更新