git代码管理实践

Posted by jabin on October 20, 2018

本文分两部分,【快速上手】和【深入学习】 【快速上手】部分,旨在让未接触过git的同学,能迅速掌握基本git使用 【深入学习】部分,整合自己学习的总结心得, 最后罗列了个人觉得学习git比较好的资料、文章


一、快速上手

1.1. git介绍

git是分布式的代码版本控制软件。

1.1.1. 特点

本地提交、分支创建和切换简便、多人并行开发等(详见后续【为什么要用git】)

1.1.2. 与svn的原理对比

svn 只有没有本地仓库的概念,如下图:

图片描述

git有本地仓库,提交远程仓库时,多一步push(同步), 如下图:

图片描述

1.2. 安装和使用

git和svn一样有完善的GUI, windows下推荐TortoiseGit, 使用过程和TortoiseSvn类似,学习成本不大。 界面如下图: 图片描述

  1. 下载并安装git:Downloading Git
  2. 下载并安装TortoiseGit:Download
  3. 右键克隆远程仓库 图片描述

    图片描述

  4. 修改代码
  5. 提交到本地仓库 图片描述

    图片描述

  6. 推送(同步)到远程仓库

    图片描述

    图片描述

  7. 完成在远程仓库可查看提交

    图片描述

1.3. 远程仓库的搭建和使用

1.3.1. gitlab 和 github

  1. gitlab可以理解为开源版的github, 允许开发者创建自己的私有远程仓库(github私有仓库收费)
  2. 公司内部也有git.tencent.com这个完全基于gitlab的代码仓库,经了解,会全面切换到自研的git代码仓库(工蜂)
  3. 由于工蜂已经相对成熟,和gitlab在使用上基本无差异, 并且有许多大项目(包括微信的前端代码等)接入,所以这里建议直接使用工蜂系统。 对gitlab有兴趣的同学可以参考基于 CentOS 7 搭建 GitLab搭建gitlab实践。

1.4. svn项目迁移git

可保留svn的提交记录,代码的迁移成本不大,详见【svn项目迁移到git】


二、深入学习

2.1 为什么要用git

引用腾讯工蜂系统介绍为什么使用工蜂的一句话:“目前为止的BATJ,除腾讯之外, 均已经在2017年完成了到Git的完全替换。Git已经成为业界的主流方案,在不久的将来,工蜂Git也将接替SVN的历史使命。”

2.1.1 工作中可能会遇到以下场景

  1. 希望写一半的代码,能随时提交,做版本管理, 而不是现在需要开发完成才能提交svn
  2. A和B再同时改撮合代码的时候,A要拉svn最新的代码发布了, B拦住说,我svn有一部分代码还不能发布
  3. A改了B的seed server的代码, A希望的不是马上合入svn, 再去让B先review, 因为A担心在提交后,就有人拉了svn最新的去发布了
  4. A的开发的接口, 希望有重大版本迭代的里程碑tag, 这样A就知道这个接口都经历什么重要更新,也方便回退, 然而搜了下svn打tag的方式,比较繁琐

2.1.2 使用svn的痛点

  1. 希望未可发布的代码,也能随时随地提交,做版本管理, 而不会影响到并行开发的同学
  2. 希望在跨部门,跨公司合作时,代码共享能优雅点,而不是通过代码拷贝,邮件备忘
  3. 希望在重要模块的代码修改后,能发起code review,通过后再合入外网主干版本,而不是像目前这样先提交svn或者文件拷贝
  4. 希望有个代码库,是和外网一致, 并且重大版本发布有tag可回溯
  5. 希望有个更合理、更高效、更便捷的代码开发流程
  6. 希望能顺应时代潮流, 目前很多大项目(linux 内核、jquery等)和大公司都用git, 社区异常活跃

2.1.3. git优势

  1. 分布式,支持离线本地代码版本管理
  2. 合并到外网主干分支时, 支持code review, 降低代码的bug率
  3. 代码合并时,冲突解决机制更强大, 需要手动解决冲突情形大大减少
  4. 速度更快;空间更少

最后想说的是svn和git没有谁是绝对好,只能说不一样。 比如svn也具备更加简单易学等特点。 只是在使用svn过程中,遇到了上述几个较难满足的点, 所以研究学习了下git的开发流程,发现确实有她的优势。

2.2. git与svn的使用对比

2.2.1. 基本区别

对比项 git svn
管理方式 分布式 集中式
存储方式 快照 增量存储
分支 同个目录 目录拷贝
版本号 无全局版本号 有全局唯一版本号
版本库与工作区 同个目录 分离
代码克隆(检出) 全部 支持指定目录
远程仓库更新本地 fetch+merge/pull update
远程仓库提交 commit(提交本地仓库)+push(推送到远程仓库) commit

2.2.2. 命令对比

https://backlog.com/git-tutorial/cn/reference/git-svn.html# 最主要的一个区别是提交命令, 在svn中commit即提交远程版本仓库,而在git中, 因为有本地仓库和远程仓库的概念,所以commit只是提交到本地仓库,要提交(同步)到远程仓库,还需要执行push命令

2.2.3. gui工具对比

os git svn
windows TortoiseGit/Sourcetree TortoiseSvn
mac Sourcetree Cornerstone

2.3. 远程仓库的选择-腾讯工蜂介绍

2.3.1. gitlab和github

github是当前最火爆的开源代码库及版本控制系统, 同时提供公共仓库和私有仓库,但是私有仓库是收费的。 gitlab解决了github私有仓库收费的问题, 允许开发团队创建免费的自己的私有仓库,给了开发者更多的控制权

2.3.2. 工蜂

腾讯工蜂,曾用名(TGit),是一套 java 实现的现代化 VCS 系统,和 git 交互的最底层是 jGit,源码由腾讯团队实现。

2.4. svn项目迁移到git

可保留svn的代码提交记录! 具体步骤如下:

  1. 停止更新svn
  2. git-svn 安装
  3. 初始化本地git目录 & svn提交记录同步到git
  4. 工蜂git代码托管平台创建远程代码仓库
  5. 关联本地和远程仓库 & 推送本地仓库到远程

2.5. git开发模式、流程规范

2.5.1. 主流开发模式

  1. 总的介绍: Git 工作流程
  2. 详细介绍:gitlab flow , github flow, git flow

2.5.2. 针对qqgame的开发流程

个人比较推崇每个开发阶段有对应的一个版本库,并遵循“上游优先”原则, 即gitlab flow模式。

  1. github flow开发流程 官方介绍:https://guides.github.com/introduction/flow/index.html 一句话描述: 一个主分支(master), 新特性从这个主分支创建新的功能分支,开发测试, 准备发外网前,发起PR 通过则发外网, 打个tag, 并合入主分支 如下图: 图片描述
  2. 开发规范 1). 流程规范
    • 每个修改,都需要从主干分支, fork一个功能分支, 或者bugfix分支
    • PR为发布外网前的强制流程, 除非类似深夜外网突发, PR找不到人
    • 若打tag 需要指定服务名, 此举方便回滚版本

2). 分支/tag命名规范

  • 功能/特性分支: feature-xxxx, 如 feature-addSomething
  • bugfix分支: bugfix-xxxx, 如 bugfix-bug1
  • tag: [appVersion]-[服务名], 如 3.0-tserver, appVersion即为写在代码的版本号

2.6. 常用命令

git pull   //从远程仓库更新代码到本地仓库, 相当于 fetch + merge	

git checkout -b [分支名] master  //创建并切换到指定分支	

git add .  //把改动的文件添加到暂存区
git commit -m "提交信息"   //把改动的文件提交到本地仓库
git commit --amend   //追加到上一次提交的版本, 并修改上一次的提交信息
git commit --amend --no-edit   不想修改上一次的提交信息	

git checkout  master   //切换到master分支
git merge --no-ff [要合并的分支名]  //master指定的分支合并, 保留节点信息
git branch -d [分支名]    //删除分支
git branch -m old new  //本地分支重命名

git push   //将当前分支的本地仓库修改, 推送到远程对应分支
git push origin teacher:teacher  //将本地分支推送到远端,远端没有则创建
git push origin :teacher   //删除远端分支


git tag -a course_v1.0 -m "初始化tag" //新建tag
git tag -d [tagname]   //删除tag
git push origin course_v1.0  //推送tag到远程仓库
git tag //列出所有的tag
git tag -l "course*"  //列出匹配通配符的tag

//强制回退到某次commit, 并提交远程
git reset --hard commitID && git push -f origin xx:xx
//回退某次提交
git revert commitID && push
//详细参考[git回滚](https://juejin.im/post/5b0e5adc6fb9a009d82e4f20)

// 添加本地的目录,到远程仓库,没有则新建仓库
git init
git remote add origin [email protected]:sdk/appauth-rpc.git
git push --set-upstream origin master

2.7. 参考资料

  1. git官方权威文档 https://git-scm.com/book/zh/v2

  2. git与svn对比 差异对比:http://zyjustin9.iteye.com/category/300256

  3. 5分钟掌握git

  4. git开发模式 git flow: https://nvie.com/posts/a-successful-git-branching-model/ github flow: https://guides.github.com/introduction/flow/index.html gitlab flow: https://docs.gitlab.com/ee/workflow/gitlab_flow.html

  5. 公司内git使用实践 工蜂git代码仓库: https://code.tencent.com/help/productionDoc/permission/