公司经过多次兼并、收购之后,开发团队使用的工具自然会出现鱼龙混杂的现象。就拿源代码管理工具来说,我们同时在使用的就有Perforce、Team Foundation、Subversion等。为了节省成本,也为了统一工程实践(以提高工作效率),我们决定让所有团队迁移到Git。

                 

      集中式(Centralized)的源代码管理                               分布式的(Distributed)源代码管理

之所以选择Git,是因为:

  1. 它是主流的;
  2. 它是免费、开源的;
  3. 它支持分布式开发——这一点特别适合跨国团队;
  4. 它支持离线环境下的开发(因为每台开发机本地都有一个代码仓库depository);
  5. 它是跨平台的(支持Windows、MAC、Linux)。

Git工具可以到http://git-scm.com/上去下载。为了方便操作,也可以使用一些带图形界面的Git工具。关于Git的介绍,网上可以找到很多资料。(顺便推荐一下中文版的《Pro Git》:http://git-scm.com/book/zh。)我想在这里分享的是,我们是怎么把一大堆老项目(主要在Perforce上)迁移到Git的。(Perforce用了将近9年,终于要说“bye-bye”啦……)

在Perforce上,我们为每个产品建立了一个顶级目录。然后,在它下面分别有Main、Work、ThirdParty、Release等子目录。Main里存放一个产品的主要代码,大部分人直接在这上面工作;Work里存放一些试验性质的代码,或者自己开发的小工具;ThirdParty里存放来自第三方的SDK;而Release里存放从Main派生出来的各个版本,典型情况下是为各个客户做的定制和发布,我们一般把它们命名为RelCustomerXV1、RelCustomerXV2、RelCustomerYV1、RelCustomerZV3……整个代码结构看起来是这样的:

在往Git迁移的过程中,Perforce上每个Changelist的历史记录是移不过去的(或许只是我们不知道……)。我们的办法是:在公司里仍然保留一台Perforce服务器,并开放有限的几个账号,必要时可以提供查询功能;将Perforce上最新的一份代码放到Git上去,并且以后所有的开发都在Git上进行。

我们的迁移是这么做的:首先,由管理员在Git服务器上为每个产品建立一个空的代码仓库,比如ios.git、android.git、pcmac.git等;然后,由各个产品的开发主管负责代码的上传与分支的建立。这里的焦点问题是:如何处置那些RelCustomerXXX分支?因为Perforce的分支概念与Git的有较大的区别:Perforce做的是实实在在的代码拷贝,而Git在创建分支时保存的只是指针或引用。要在Git里为每一个RelCustomerXXX创建分支吗?这样的话,服务器上的分支看起来会比较多(通过git
branch -a命令查看),容易造成日后的混淆。经过团队讨论,我们最终决定把这些RelCustomerXXX都建在master上(不另外创建分支),由此带来的问题是:master的体量比较大,在开发人员第一次做git clone的时候会比较耗时。忍了!

往Git上传代码的过程是在Git Bash(Windows | All Programs | Git)里通过执行一系列git命令来完成的。具体步骤如下(以iOS产品为例):

假设你的工作目录(Working Directory)在D:\GitWorkspace。在运行Git Bash之后,你需要执行cd D:\GitWorkspace进入该目录。然后执行git clone命令将空的代码仓库克隆到本地:

git clone <server URL>:ios.git

克隆完成之后,执行cd命令进入本地仓库(你可以看到默认指向了master)。然后,在文件浏览器里,将Perforce上拿到的最新的产品代码拷贝到D:\GitWorkspace\ios\main中,并且在D:\GitWorkspace\ios\customer_releases\下面建立子目录、拷入各个RelCustomerXXX分支的代码,还有其他一些文件(比如work、thirdparty)都拷入D:\GitWorkspace\ios\……当所有文件都准备好之后,在Git Bash里依次执行下面的命令:

git add -A

git commit -m "the initial porting from Perforce"

git remote add origin <server URL>:ios.git

git push origin master

如果上传的代码比较多,上述过程会比较耗时。至于日后在Git上的产品开发,我们决定采用“Gitflow工作流程”。因此,在完成上述的代码上传之后,每个产品的开发主管须立即创建一个develop分支:

git branch develop

git push -u origin develop

最后,别忘了让另一个开发人员在他的机器上拉一下代码(执行git clone或git pull命令),然后试着编译一下,看看是否有部分文件遗漏了。(完)

从Perforce到Git的迁移的更多相关文章

  1. git仓库迁移和更新远程仓库地址

    一.git仓库迁移 1,从原仓库clone或pull到本地仓库 git clone project_name ​[old_remote_repository_address] 2,​在新的git创建一 ...

  2. GIT工程迁移方法总结

    Git工程迁移方法总结 Git最近准备迁移一下位置,这里采用命令行的方式,做如下操作. 1.git init  初始化git仓库,这个时候发现本地文件夹多了个.git的文件夹. 2.git remot ...

  3. Git工程迁移方法总结(命令行)

    Git工程迁移方法总结 Git工程迁移方法总结 Git最近准备迁移一下位置,这里采用命令行的方式,做如下操作. 1.git init  初始化git仓库,这个时候发现本地文件夹多了个.git的文件夹. ...

  4. git 仓库迁移,git remote 更改源

    git仓库迁移 我们有时候需要迁移git仓库,但又想保留每次commit的记录,所以我们只需要更改git remote [源]的问题即可 首先查看你的remote的地址 git remote -vv ...

  5. Git工程迁移方法总结(命令行) .(转载)

    原文地址:http://blog.csdn.net/hongshan50/article/details/236630433 Git工程迁移方法总结 Git工程迁移方法总结 Git最近准备迁移一下位置 ...

  6. git仓库迁移的两种解决方案

    Git仓库迁移而不丢失log的方法 要求能保留原先的commit记录,应该如何迁移呢? 同时,本地已经clone了原仓库,要配置成新的仓库地址,该如何修改呢? 注意:如果使用了代码审核工具Gerrit ...

  7. git仓库迁移的解决方案

    一.问题 在github中遇到感兴趣的项目,直接克隆下来,随着兴趣越来越浓,在本地做了些修改,后来干脆想fork到自己的github仓库,又要把本地的修改提交到fork后的自己的github仓库中.这 ...

  8. git文件迁移到新架构

    环境: ubuntu16.04 代码托管地址:git.oschina.net 迁移原因: git上某工程是一堆静态页面html,因为在ubuntu下缺乏git图形客户端,想使用eclipse集成的gi ...

  9. git仓库迁移

    最近,装了git的本地服务器坏掉了, 没办法只能临时进行仓库的迁移  保证项目正常进行 在项目的根目录执行右键执行 查询当前仓库的远程地址 git remote -v 查看现有远程仓库的地址url 修 ...

随机推荐

  1. Python小代码_11_生成小于 n 的裴波那契数列

    def fib(n): a, b = 1, 1 while a < n: print(a, end=' ') a, b = b, a + b fib(100000) #输出结果 #1 1 2 3 ...

  2. Luogu P3740 [HAOI2014]贴海报_线段树

    线段树版的海报 实际上这个与普通的线段树相差不大,只是貌似数据太水,暴力都可以过啊 本来以为要离散的,结果没打就A了 #include<iostream> #include<cstd ...

  3. leetcode刷题笔记231 2的幂

    题目描述: 给定一个整数,写一个函数来判断它是否是2的幂. 题目分析: 判断一个整数是不是2的幂,可根据二进制来分析.2的幂如2,4,8,等有一个特点: 二进制数首位为1,其他位为0,如2为10,4为 ...

  4. JavaScript If…Else 语句

    条件语句用于基于不同的条件来执行不同的动作. 条件语句 通常在写代码时,您总是需要为不同的决定来执行不同的动作.您可以在代码中使用条件语句来完成该任务. 在 JavaScript 中,我们可使用以下条 ...

  5. 设计模式一日一练:中介者模式(Mediator)

    Mediator模式,用一个中介对象来封装一系列的对象交互.中介者使各对象不需要显式的相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互. 比较典型的例子是联合国.QQ群等.比如,如果中国有 ...

  6. MySQL系列教程(三)

    mySQL集群(cluster) 这一章,我根本不打算写,因为mySQL 的 官方Cluster方案基本上都是bullshit,尤其是它的官方集群方案,竟然都无人维护了,而且mySQL集群完全可以用眼 ...

  7. 让你的代码量减少3倍!使用kotlin开发Android(二) --秘笈!扩展函数

    本文承接上一篇文章:让你的代码量减少3倍!使用kotlin开发Android(一) 创建Kotlin工程 本文同步自博主的私人博客wing的地方酒馆 上一节说到,kotlin可以省去getter,se ...

  8. 基于AOP的iOS用户操作引导框架设计

    背景 有一种现象,App设计者觉得理所当然的操作方式,却常常被用户所忽视,为了防止这种现象发生,就要为App设计一个帮助,一种低成本的方案是将帮助文档写成HTML然后展示给用户,这样的方式常常不能带来 ...

  9. SpringMVC+BUI实现文件上传(附详解,源码下载)

    中午有限时间写这博文,前言就不必多说了,直奔主题吧. BUI是一个前端框架,关于BUI的介绍请看博主的文章那些年用过的一些前端框架. 下面我们开始实例的讲解! 一.效果演示: 上传成功后,会发现本地相 ...

  10. 自制Linux重命名命令

    相比于Windows上的ren命名,Linux还真的是没有一个特定的重命名的命令.(虽然可以间接的使用mv来实现).下面我就来自己写一个简单的重命名命令. 准备工作 操作系统: Linux内核的系统都 ...