在《为什么选择Git?》文章里,我们探讨了如何使用Git来帮助我们团队开发更敏捷,一旦你决定做转变到使用Git,你下一步就是找出如何将你现在工作流迁移到Git上的方法。
这篇文章将会介绍在你从SVN迁到Git上会遇到的一些最大的变化。在迁移过程中你需要记住一件很重要的事情就是Git和SVN是不同的。意识到Git的巨大潜力,努力脑洞大开去从一些的新的角度去考虑版本控制。
从管理员的角度
根据团队的规模的不同,使用Git需要使用几天到几个月不等的时间。这个章节我们来阐述在培训工程师使用Git和迁移仓库到Git时,工程管理者主要关心的问题。
Git基本命令
Git被大家认为门槛其实挺高的。不过Git的维护者已经逐步地发布了一些改进版本,比如实用的默认配置以及上下文帮助信息,这些措施让我们的学习过程更加轻松愉快。
Atlassian提供了综合的自我学习系列课程Git教程,也提供了论坛和在线培训课堂。这些可以让我们的团队学习Git提供了选择。下面列出一些常见的Git基础命令来帮助你开始熟悉Git:
Git 任务 | 注意 | Git命令 |
---|---|---|
配置姓名 | 配置开发者的姓名和邮箱地址。注意Git会过滤一些姓名里的字符(比如句号) | git config –global user.name “Sam Smith”git config –global user.email sam@example.com |
创建一个本地仓库 | git init | |
检出(checkout)分支 | 创建本地仓库的工作区副本 | git clone /path/to/repository |
对于远程仓库来说, 可以使用: | git clone username@host:/path/to/repository | |
添加文件 | 将一个或者多个文件添加到暂存区 | git add |
提交 | 提交代码到头部(还没有保存到远程仓库) | git commit -m “Commit message” |
提交你使用git add命令添加的文件,也提交其他你之后修改了的文件 | git commit -a | |
推送 | 将修改提交打远程仓库的master分支 | git push origin master |
状态 | 列出已经修改、需要添加到暂存区的或者需要提交的文件 | git status |
连接远程仓库 | 如果你本地的仓库还没有连接远程服务器,添加连接到服务器,这样你就可以推送了 | git remote add origin |
列出所有你配置了的远程仓库 | git remote -v | |
分支 | 创建一个新的分支并切换过去 | git checkout -b |
切换分支 | git checkout |
|
列出仓库所有分支,而且让你知道你当前在哪个分支 | git branch | |
删除功能分支 | git branch -d |
|
推送分支到远程仓库,这样其他人可以查看到 | git push origin |
|
推送所有分支到远程仓库 | git push –all origin | |
删除你的远程分支 | git push origin : |
|
从远程仓库更新本地仓库 | 获取以及合并远程服务器代码到工作区 | git pull |
合并其他分支到当前分支 | git merge |
|
查看所有的合并冲突;查看冲突;在合并前预览修改 | git diffgit diff –base |
|
在你手动解决冲突后,你标记修改的文件 | git add |
|
标签 | 你可以使用标签对重要的修改做标记,比如一个发布版本 | git tag 1.0.0 |
提交Id是标记这次修改的ID,必须是唯一的,查看ID使用: | git log | |
推送所有的标签到远程仓库 | git push –tags origin | |
放弃本地修改 | 如果你修改不正确,你想放弃这些修改,并回到最后一次提交的前状态,不过已经添加到索引的文件,以及新文件会被保留 | git checkout – |
如果你想放弃本地所有的修改,你可以从服务器端获取所有的提交,并奖本地的master分支指向它 | git fetch origin git reset –hard origin/master | |
搜索 | 在工作区域搜索包含foo()的内容 | git grep “foo()” |
Git迁移工具
有很多工具可以帮助我们迁移SVN代码到Git。但在我们选择工具前,我们先确认你想如何迁移你的代码,你的选择有如下四个:
迁移你的整个代码库到Git并且一起放弃使用SVN。
不迁移已经存在的项目到Git,但是所有新项目使用Git.
迁移部分项目到Git,然而其他项目使用SVN。
在同一项目同时使用SVN和Git.
完全的迁移到Git会降低你开发工作流的复杂度,因此这是一个更好的选择。但是,在成百上千的大型团队里,包含几百项目这通常不太可能。在这种情况下,混合策略是一个更安全的做法。
迁移工具的选择很大程度取决于你选择哪个策略。下文我们介绍一些常见的SVN到Git的迁移工具。
Atlassian公司的迁移脚本
如果你对快速迁移Git感兴趣,Atlassian公司的迁移脚本是一个好的选择。这些脚本提供所有你需要的工具,它们可以妥妥的将你的SVN仓库迁移到Git仓库。在迁移之后你将不需要处理SVN-to-Git的互相影响的问题。
我们提供了一个完整的《技术演练教程》,介绍如何使用这些脚本来将你整个代码库转变为一个Git仓库集。这个演练教程解释了所有关于提取SVN信息到重构不标准的SVN仓库结构的知识。
SVN Mirror for Stash (now Bitbucket Server) plugin
SVN Mirror for Stash 是Bitbucket Server 插件,让你可以很容易的维护一个同时使用SVN和Git的混合代码库。和Atlassian公司的迁移脚本不同,SVN Mirror for Stash可以让你一直在同一仓库同时使用SVN和Git.
对于大型公司这个拖鞋方案是一个最好的选择。通过让不同团队在他们的方便的时候再做迁移,它能够采用增量Git。
Git提交到SVN服务器
Git的git svn工具可以作为本地Git仓库和远程SVN仓库的接口,它让开发者可以在本地写代码然后使用Git创建本地提交,然后使用svn提交方式来推送代码到中央SVN仓库。
如果你还没有确定要切换到Git并且希望有工程师可以研究一下Git命令,这时候git svn是一个好的选择。它也是很适合培训阶段,而不是突然转变的过程,你的团队可以可以很轻松地在本地使用Git命令,而不必担心团队合作工作流。
git svn仅仅应该作为你迁移过程中的临时阶段。因为它仍然使用SVN作为后端,因此不能充分发挥Git功能的强大,比如分支或者高级合作开发流。
部署策略
迁移代码只是采用Git的一个方面。你也需要考虑培训写代码的人。在迁移你的团队到Git上,采用外部专家培训、内部培养Git高手、先锋队是三个主要的策略。
外部Git专家
Git专家能够用合适的价格为你处理这个迁移过程。这个优势也很明显,你不用去花费时间去调研适合你团队的工作流,就可以建立适合你团队的最佳工作流。而且让你的团队可以得到学习Git的资源。Atlassian Experts是一个很好的资源,当你从SVN迁移到Git时这个非常有用。
并且,由你自己去设计和实施Git工作流,可以让你的团队理解新的工作流的内部工作原理。这避免了专家离开的后的空白所带来的风险。
内部Git高手
Git高手是你公司对Git很有热情的开发者,对于有工程师文化和强烈学习意愿的开发者发挥Git高手的价值更有用。这可以让你的一个工程师可以成为Git专家,因此他们可以设计一个Git工作流服务于公司,当团队其他人需要迁移到Git的时候这个人可以作为专家顾问的角色提供帮助。
相比外部专家,这可以让你的团队有一个Git高手,然而,它可能需要更多的时间去培训那个Git高手。而且可能会选错工作流或者实施不到位的风险。
先锋队
迁移到Git第三个选择就是可以在先锋队中试验。如果有个小团队在一个相对独立的项目中工作使用这个方法最佳。结合外部顾问专家和内部先锋队的Git高手在一起这样能取得更好的效果。
相比外部购买的的方案这有优势也有可能选错工作流的风险,因为它是由整个团队来设计开发过程。不过,相比让顾问专家或者专家完全自己来设计新的开发工作流,它确保团队不错过任何细节。
而且,使用先锋队的方式因为更多的基础培训和建立时间:由于不是一个开发者去发现新的开发工作流,而是整个团队潜在可能降低效率,因为团队可能习惯新的工作流需要时间。然后,短时间的付出相比长期的回报来说还是值得的。
安全和权限
在你需要重新考虑如何在Git中管理代码的时候访问权限控制是一个方面。
在SVN中,我们通常将所有代码保存在一个单一的中央仓库,然后通过文件夹给不同团队或者个人限制访问权限。在Git中,这不可能:开发者必须取出整个仓库来从事开发,通常不能只活去仓库的一部分代码,而在SVN中是可的。权限授权是针对整个Git仓库进行的。
这意味着你必须拆分你巨大的SVN仓库为几个不同的Git仓库。当我们将JIRA开发团队迁移到Git时,我们事实上在Atlassian经历过一次这样的情况。我们所有的JIRA插件都是存储在一个单一的SVN仓库,但是在迁移之后,我们为每个插件建立了一个仓库。
Git当初设计的时候是为了保证安全的合并成千上万的Linux开发者的代码,这点我们要时刻记住。因此它当然有一些方法来设置任何你团队需要的访问权限。当然,这需要对构建周期有一个全新的视角。
如果你关心保持你新仓库集的依赖,你可能发现在Git上面的一个依赖管理层非常有用。在仓库不断增大,依赖管理层将通过构建次数来提供帮助,为了加快构建时间,你需要“缓存”。这篇文章:“Git and project dependencies”,列举了为每个技术栈推荐的依赖管理层工具。
从开发者的角度
所有开发者的一个仓库
作为开发,你需要适应和理解Git分布式的特性,相比一个单一的中央仓库,每一个开发者本地有整个仓库的备份,这极大的改变了你和同事们的合作方式。
我们使用svn checkout命令来检出一个SVN仓库的代码,然后在Git中你通过git clone来克隆整个Git仓库到电脑上。
合作开发经常会使用git push ,git pull或者git fetch命令在git仓库之间切换分支。在Git中经常使用在分支层面共享代码,当然也可以像SVN一样通过提交来实现。但在是在Git中,一个提交代表整个项目的状态而不是一个文件的修改。一旦你在Git和SVN中能够使用分支,他们最大的区别就是你可以使用Git提交到本地,而不用把代码提交到服务端。这可以让你更自由的实验,离线状态下更有效率的工作,几乎所有的命令操作起来更快。
但是,要清楚的知道远程仓库不实直接和你的仓库关联的,它仅仅是一个书签,可以避免在你需要和远程仓库交互的时候你必须频繁输入完整的URL链接。直到你明确的拉取或者推送分支到远程仓库,你一直在自己独立的环境下工作。
对于SVN使用者来说另一个很大转变就是意识到本地和远程仓库的概念。本地仓库存在于你自己的电脑上,其他的仓库都是远程仓库。远程仓库存在的主要目的就是让你的代码可以共享给其他成员。因此在远程仓库并不会有进行中的开发。你电脑上的本地仓库则你所有软件开发的场所。
无惧分支和合并
SVN中,我们在工作区编辑文件然后提交,然后执行svn commit来推送代码到中央仓库。每个人可以通过svn update拉取这些修改到他们的工作区。SVN分支在大型,长时间维护的项目中不怎么使用,因为合并非常的危险,可能会破坏项目。
Git的基本开发工作流则不同,分支和合并非常的容易,而不是只能一条线的开发(比如trunk/)。
当你想在Git中开始工作,你可以使用git checkout -b
常见的开发工作流
在选择开发工作流的时候最好考虑团队的需要。一个简单的工作流可以加快开发速度和提高灵活性,然而一个复杂的工作流可以确保更好的一致性和对开发工作的掌控。你可以结合下面介绍的常见的方法来适应你的需要以及团队的不同角色的需要,比如,一个核心的开发者可以使用功能分支而一个外包人员可以在分叉(fork)上开发。
集中式开发工作流提供类似SVN的工作流程,因此对于开始使用Git来说非常合适。
为开发一个功能需求,使用分支开发工作流 再合适不过了,它绕过开发者的工作保持独立,而且重要的是保护公共分支。功能分支也构成了让我们能够使合并申请来管理修改的基础。
Git流开发工作流 是一个更加正式而且是对功能分支的结构性的扩展,是大团队的一个很好的选择,因为它明确定义了产品发布的周期。
最后,如果你需要最大限度的保持仓库隔离,控制代码修改,或者有许多的开发者在为仓库贡献代码,这时候你可以考虑使用分叉(forking)开发工作流 。
作为一个专业团队。如果你真的想发挥Git的最大价值,你应当考虑使用分支开发工作流,它是真正的分布式开发工作流,保证了高度的安全性,极大的可扩展性,非常必要的灵活性。
总结
让你的团队过渡到Git不是一件容易的事情,不过也没多难。这篇文章介绍了迁移你的代码库的常见选项,向开发团队推荐Git,处理安全和权限问题。这篇文章也介绍了在迁移过程中开发者们寻药准备好接受的一些挑战。
最后希望你已经掌握强有力的知识基础,来将Git分布式开发工作流介绍到你们公司,而且不管团队的大小或者当前你们是什么开发流,都可以迁移。