我该如何在TFS库中使用git-tfs和惯用的git分支?

49

我如何习惯使用 git-tfs?

  • git 习惯是将分支 检出到仓库的根目录。检出分支时,会用该分支的内容替换目录中的内容。

  • TFS 习惯是将每个分支检出到仓库根目录下的不同目录(甚至是主分支或 trunk 分支)。检出分支时,会将其放置在当前目录旁边的新目录中。

使用git-tfs,我可以将 TFS 仓库或分支克隆到一个 git 仓库中。我希望以与 git 分支习惯一致的方式处理 TFS 仓库中的多个分支。但我不确定技术上是否可行或是否推荐 :)


克隆整个 TFS 仓库

如果我从 TFS 克隆整个仓库

> git tfs clone http://<tfsurl>:8080 $/main

这将为我提供一个包含所有TFS分支目录的git master

[master]> dir
  trunk
  feature-logon
  feature-search
  release-0.0.1

添加远程 TFS 分支

我不知道是否可以(或如何)将 git 远程分别映射到每个 TFS 分支。

> git init .
[master]> git tfs clone http://<url> $/main/trunk .

然后

[master]> git checkout -b feature-logon
[feature-logon]> git tfs clone http://<url> $/main/feature-logon .
我知道这其实是不正确的,但是我没有更好的方法,如果不进行尝试的话(我的唯一一个TFS存储库非常大,进行实验需要很长时间)。

1
看起来Ivan Danilov正在解决这个问题! - Anthony Mastrean
3个回答

32

现在可以使用git-tfs进行克隆,使得TFS分支变成正确的Git分支。这个功能已经在稳定版本中发布!您需要先克隆trunk而不是整个存储库:

git tfs clone http://<tfsurl>:8080 $/main/trunk

然后运行branch --init,它会在Git仓库中创建一个新的分支。

git tfs branch --init $/MyProject/MyTFSBranch

在您的情况下:

git tfs branch --init $/main/feature-logon

或者在一个新克隆的存储库上使用--all标志来创建TFS服务器上存在的所有分支。

git tfs branch --init --all

您还可以使用标志--with-branches直接克隆所有分支:

git tfs clone http://<tfsurl>:8080 $/main/trunk --with-branches

这个新命令的文档在这里。欢迎提供反馈以改进它...


太好了,这是令人兴奋的消息!我想我应该更密切地关注 git-tfs-dev。我甚至没有意识到这是即将发生的事情。 - skiphoppy

3
这里有一种方法可以实现这一点,并仍然保持主分支和分支之间的某些关系。你可能想要编写脚本。如果我的示例中使用的是bash语句而不是Windows命令行,请原谅我。
首先像你的第一个示例那样克隆整个存储库,将分支作为目录。
这将把主干移动到根目录。(希望你的分支文件夹没有冲突)
mv trunk/*.* .

提交你的新主分支。
git commit -a -m "refactoring master"

创建新分支。
git checkout -b feature-login

将分支文件复制到根目录文件上

mv feature-login/*.* .

这里不再需要这些内容

rm -rf [all_branch_directories]

提交分支
git commit -a -m "refactoring feature-login"

返回主界面

git checkout master

再做一遍

git checkout -b next_branch

最后在结尾处。等等。
git checkout master
rm -rf [all_branch_directories]
git commit -a -m "refactoring master"

这种方法并不完美,但你最终会得到所有分支从主分支克隆出来,并且差异更或多或少地适当。据我所知,如果你用另一个文件覆盖一个文件但内容没有改变,git应该可以正常工作,这使得所有操作都能顺利进行。

缺点之一是,你不会清除从主干中删除的分支中的任何文件。这可能对你有影响,也可能没有...


说起来,你或许可以在将分支文件复制下来之前,删除每个新分支的所有内容。 - Joshua
1
当您再次尝试提交到TFS时,这不会破坏链接吗? - bdukes
2
哦,是的。我的假设是OP想永久将他的TFS迁移到Git。 - Joshua
2
不建议同时使用两个不同的源代码控制系统。 - Joshua
我想继续使用TFS作为“黄金”存储库。我想在侧面或小团队中使用git。 - Anthony Mastrean

3
多个远程tfs仓库,每个分支1个? 我有以下结构:
$/Root/Main/someproject (the trunk)
$/Root/Releases/Branch1/someproject
$/Root/Releases/Branch2/someproject

what i did

git tfs quick-clone http://tfs:8080/tfs/defaultcollection $/Root/Trunk GitRepo
git tfs quick-clone http://tfs:8080/tfs/defaultcollection $/Root/Releases/Branch1 GitRepo -i 
    branch1
git tfs quick-clone http://tfs:8080/tfs/defaultcollection $/Root/Releases/Branch2 GitRepo -i branch2

然后你可以为每个远程分支创建一个本地分支:git checkout -b localbranch1 tfs/Branch1,并将其提交到tfs分支:git tfs ct -i branch1

为了能够轻松地合并这两条线路,请创建一个嫁接点:

echo branch-commit-id trunk-parent-id > .git/infos/grafts

其中ids是第一个分支提交的哈希值(来自Releases repo)和父提交id的哈希值(手动查找)。

PS:我遇到了错误:指定的git仓库目录不为空(以前不知道它是如何工作的),所以我手动在.git/config中添加了第二个url,并执行了git tfs fetch -i Branch1命令。


1
当您尝试多次克隆相同的GitRepo时,是否会出现“error:指定的git存储库目录不为空”的错误? - Boggin
1
@Boggin 目前还没有进行广泛的测试,但是以下步骤似乎可以正常工作:1)使用 git tfs clone 克隆第一个分支。2)手动复制/粘贴/调整 .git\config 中的 tfs-remote 部分。3)运行 git tfs fetch -i {tfs-remote 部分中的引号名称}。 - steamer25
@steamer25,我遵循了你的建议,结合了Boklucius答案中的检出策略,似乎能够得到良好的隔离本地分支以匹配远程tfs分支。此外,如果有人感兴趣,Dr. Random/Casey在这篇博客文章中也谈到了类似的策略。 - user456814

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接