Git是分布式的,但多数时候仍然要使用中央仓库作为所有开发者的交互中心,和svn一样,开发人员仍要在本地写代码并提交到中央服务器。Git相较于svn最大的优势就在于其强大的分支系统,而git的工作流程配合其强大的分支系统,可以说几乎完美的契合了敏捷开发的要求。任何事情都一样,有一个明确的管理规范,做事情才能有条理,git使用这个事情,Vincent Driessen同学提出了这么一套理论:http://nvie.com/posts/a-successful-git-branching-model,文章的翻译版本:http://www.cnblogs.com/yaks/p/5666400.html。

  几个常用分支约定:

  •  Master分支:主干分支,一般用作生产分支
  •  Develop分支:开发分支,开发人员日常交互所用分支
  •  Release分支:发布分支,一般是打包给测试人员的分支
  •  Feature分支:功能分支,开发人员在本地为某个功能而建立的分支
  •  Hotfix分支:热修复分支,生产出现问题,临时修复bug所用的分支

  各个分支如何协同工作:

  Master是线上版本,所有的提交都应该打tag,并记录修改内容;Release、develop跟feature分支:

  

  Develop分支是从master分支检出的,开发人员自己本地具体的feature分支是开发人员在自己本地建立的(过程2跟3),命名一般是自己名字或者功能名字之类,如果该功能跟其它开发人员无关,一般不建议推送服务器(开发人员多的时候,看上去太乱)。开发人员完成功能(也可能没完成功能,每天下班提交代码),提交到develop分支(过程4),有功能开发完毕,需要打包给测试人员,我们需要从develop分支检出一个分支release(过程5),其它功能仍然正常提交develop分支(过程6,开发分支仍然正常往下走),release分支进行测试,有bug直接在release进行修改,测试通过后,将改动合并到develop分支(过程8),如果该功能需要上线,则合并到master分支,上线。

  疑问1、为什么要在本地建一个feature分支?

  因为在开发一个新功能时,我们肯定不想把原来的代码给搞乱了,所以我们搞一个新的分支,开发完成后合并到开发分支。如果你觉得就喜欢在develop分支进行开发,保证不会因为搞乱代码之类的造成一些困扰,没问题,可以不要feature分支。

  疑问2、为啥打包的时候要独立出一个release分支,在原来的develop分支上打包进行测试不行么?

  不是说不行,是不好,比如说第一次打包develop0.1给测试人员,第二天经过测试后发现了几个bug,然后开发人员进行修复后提交到develop,重新打包develop0.2给测试人员,注意,这里提交代码的时候,可能其它的开发人员也提交了代码到develop分支,这些代码有可能对develop0.1测试的几个问题有影响!因此为了避免这种情况,单独打一个release分支出来,维持不变,develop继续提交。因此:一旦打了Release分支之后不要从Develop分支上合并新的改动到Release分支。

  热修复分支用于线上发布版本的快速bug修复。它直接从master分支检出,修复测试完成后合并到master跟develop分支(过程9跟10)。为了bug修复使用专门分支,让团队可以处理掉问题而不用打断其它工作或者是等待下一个发布循环。

  具体使用(以eclipse的egit为例):

  1、上传项目到git

  Eclipsegit插件egit为例,项目右键---->share project---->勾选use or create repository in parent folder of project---->点击project下的复选框,然后点击create repository---->finish,然后项目右键---->team---->commit---->填写提交信息---->commit and push,url一栏填写资源库的url,插件会自动补齐host跟repository path,下方填写账号密码用于验证,然后finish就可以了。

  2、添加忽略文件

  跟svn一样,有一些配置文件之类的是我们不想提交到中央服务器的,因为每个人的配置都会不一样。添加忽略文件为:文件右键---->team---->ignore,会在本地生成一个名称为.ignore的文件,也可以手动修改该文件,把要忽略的文件路径添加进来。

  

  3、分支的新建、切换、删除

  在项目上右键---->team---->switch to可以进行新建分支或者切换分支,点击new branch进行新建分支,点击列表中的分支名称进行切换分支,切换后会看到项目名后的分支名称变化(图中蓝色框部分),删除分支在项目右键---->team---->advanced---->delete branch(只能删除非当前分支,需要切换到其它分支删除本分支)。

  

  4、本地的功能开发开发,分支合并,冲突解决以及提交

  两个用户同时检出dev分支,并以此为基础分别在本地新建分支feature1_branch,feature2_branch,项目有两个java文件,内容分别为:

package test.gittest;
public class A {
public static void main(String[] args){
System.out.println("aaaaaaaaaaaaa");
System.out.println("aaaaaaaaaaaaa");
System.out.println("aaaaaaaaaaaaa");
System.out.println("aaaaaaaaaaaaa");
}
} 
package test.gittest;
public class App {
public static void main( String[] args ){
System.out.println( "Hello World!" );
}
}

  假设feature1_branch只改动了A.java,改动后内容如下(修改,新增各一行): 

package test.gittest;
public class A {
public static void main(String[] args){
System.out.println("aaaaaaaaaaaaa");
System.out.println("aaaaaaaaaaaaa");
System.out.println("aaaaaaaaaaaaa");
System.out.println("aaaaaaaaaaaaa_feature1_branch修改");
System.out.println("feature1_branch新增");
}
}

  feature1_branch在本分支本地提交,然后切换到dev分支,然后项目右键---->team---->merge,选择feature1_branch,可直接将代码merge到dev分支。然后项目右键team---->synchronize workspace进行本地跟中央库代码同步,双击,可以看到本地文件跟中央库文件的差别:

  

  没有冲突,点击上方的push图标,可以将本地修改push到远程仓库,或者项目右键---->team---->commit,选择commit and push推送远程。

  Feature2_branch改动A.java跟App.java如下:

package test.gittest;
public class A {
public static void main(String[] args){
System.out.println("aaaaaaaaaaaaa");
System.out.println("aaaaaaaaaaaaa");
System.out.println("aaaaaaaaaaaaa");
System.out.println("aaaaaaaaaaaaa_feature2_branch修改");
System.out.println("feature2_branch新增");
}
}
package test.gittest;
public class App {
public static void main( String[] args ){
System.out.println( "Hello World!" );
System.out.println("feature2_branch新增2");
}
}

  同feature1_branch,右键跟中央库进行同步对比,结果如下:

  问题出现了,有冲突!

  1、错误做法,错误做法,错误做法:先merge后synchronize

  类似于svn的做法,直接在本页面进行合并,并提交。找到feature1_branch的开发人员,沟通后合并代码,假设沟通后决定此例中第7行代码应该为System.out.println("aaaaaaaaaaaaa_feature1_branch修改_feature2_branch修改");第8行两者均需保留,则可以直接在此页面的左侧完成此修改,并直接右键commit and push或者直接点上方的push按钮推送到中央服务器。这种做法极不推荐,可以认为这种操作时不对的。这会覆盖掉服务器的上次提交,虽然本地代码提交了,服务器的代码也是正常的,但会导致他人更新时的一些冲突:feature1_branch的用户pull时报错:

  

  2、 正确做法:先synchronize后merge

  本地feature2_branch开发完成并本地commit后,切换到dev分支,先不要merge新的feature2_branch的内容到dev分支,先将dev跟远程synchronize一下看是否有差别,若有,进行pull,然后再把feature2_branch的改动merge进去。(同样,feature1_branchmerge前同样应该先synchronize)

  注意:在merge页面,merge options选择第三个,否则无法填写提交的备注信息。

  

  由于feature1_branch的内容先提交到dev分支,因此要先pull一下,再merge本地的feature2_branch,merge后会有冲突,提示如下:

  

  这时候右键---->team---->merge tools由灰色变成了亮色,点击merge tools进行合并:

  

  merge tools 提供的图形界面,可以比较方便的进行对比并修改代码,这是egit比git bash等命令行为数不多的优点之一。

  合并完后,右键文件---->add index---->项目右键---->team---->commit。不点add to index,不会纳入git管理,提交的时候列表中看不到这个文件。

  这种方式的提交,他人在更新代码的时候不会有冲突,会直接pull到正常的代码,无需本地合并。

  这个地方,跟svn的使用习惯略有不同(个人感觉是这样,不知大家怎么用svn),svn是synchronize,然后可以直接在synchronize这个视图进行代码合并,合并完成后把有冲突的标记为合并,然后就可以commit了,egit的话,经过尝试,这么搞不可以,它的synchronize视图功能比较弱,我们只是用来看一下是否有更新,有的话pull下来,然后本地merge即可,剩下的跟synchronize视图无关了。

  注意:1、提交后如果所建的分支feature1_branch,feature2_branch无用,最好删掉分支,保持服务分支的整洁。

       2、git提供了丰富的操作命令,我们也可以通过在命令行完成以上操作,且更加便捷(只有merge冲突的时候不够直观),但相对命令较多,不利于新手使用。建议可以采用gui跟命令相结合的方式来学习使用git;intellij idea也自带了git插件,并同时支持命令行操作(eclipse只能自己打开文件夹然后使用命令行操作),想要尝试的可以试一下。

git如何使用的更多相关文章

  1. Git 子模块 - submodule

    有种情况我们经常会遇到:某个工作中的项目需要包含并使用另一个项目. 也许是第三方库,或者你 独立开发的,用于多个父项目的库. 现在问题来了:你想要把它们当做两个独立的项目,同时又想在 一个项目中使用另 ...

  2. Git 在团队中的最佳实践--如何正确使用Git Flow

    我们已经从SVN 切换到Git很多年了,现在几乎所有的项目都在使用Github管理, 本篇文章讲一下为什么使用Git, 以及如何在团队中正确使用. Git的优点 Git的优点很多,但是这里只列出我认为 ...

  3. Git与Repo入门

    版本控制 版本控制是什么已不用在说了,就是记录我们对文件.目录或工程等的修改历史,方便查看更改历史,备份以便恢复以前的版本,多人协作... 一.原始版本控制 最原始的版本控制是纯手工的版本控制:修改文 ...

  4. Git Bash的一些命令和配置

    查看git版本号: git --version 如果是第一次使用Git,你需要设置署名和邮箱: $ git config --global user.name "用户名" $ gi ...

  5. 在Ubuntu 16.10 安装 git 并上传代码至 git.oschina.net

    1. 注册一个账号和创建项目 先在git.oschina.net上注册一个账号和新建一个project ,如project name 是"myTest". 2.安装git sudo ...

  6. 史上最详细git教程

    题外话 虽然这个标题很惊悚,不过还是把你骗进来了,哈哈-各位看官不要着急,耐心往下看 Git是什么 Git是目前世界上最先进的分布式版本控制系统. SVN与Git的最主要的区别 SVN是集中式版本控制 ...

  7. [版本控制之道] Git 常用的命令总结(欢迎收藏备用)

    坚持每天学习,坚持每天复习,技术永远学不完,自己永远要前进 总结日常开发生产中常用的Git版本控制命令 ------------------------------main-------------- ...

  8. 【解决方案】Myeclipse 10 安装 GIT 插件 集成 步骤 图解

    工程开发中,往往要使用到集成GIT ,那么下面说说插件安装步骤 PS:以Myeclipse 10 为例,讲解集成安装步骤. ----------------------main------------ ...

  9. git 命令

    切换仓库地址: git remote set-url origin xxx.git切换分支:git checkout name撤销修改:git checkout -- file删除文件:git rm  ...

  10. git亲测命令

    一.Git新建本地分支与远程分支关联问题 git checkout -b branch_name origin/branch_name 或者 git branch --set-upstream bra ...

随机推荐

  1. Android将程序崩溃信息保存本地文件

    大家都知道,现在安装Android系统的手机版本和设备千差万别,在模拟器上运行良好的程序安装到某款手机上说不定就出现崩溃的现象,开发者个人不可能购买所有设备逐个调试,所以在程序发布出去之后,如果出现了 ...

  2. JQuery UI - selectable

    ·概述 Selectable插件允许用户对指定的元素进行选中的动作.此外还支持按住Ctrl键单击或拖拽选择多个元素. 官方示例地址:http://jqueryui.com/demos/selectab ...

  3. 树莓派(Raspberry Pi 3) centos7使用yum命令报错File "/usr/bin/yum", line 30 except KeyboardInterrupt, e:

    使用yum命令报错 File "/usr/bin/yum", line 30 except KeyboardInterrupt, e: ^SyntaxError: invalid ...

  4. Memcached Cache

    using System; using System.Collections.Generic; using System.Linq; using System.Web; using Memcached ...

  5. ASP.NET MVC Razor语法及实例

    1.混合HTML与Razor脚本 知识点:(1).cshtml怎样引用访问数据, (2).if  for 与html嵌套 @using System.Data @using CIIC.TCP.Enti ...

  6. 一道面试题关于js中添加动态属性

    js中数据类型包含基本数据类型和引用类型,基本类型包括:string.null.undefined.number.boolean.引用类型即是对象比如:array  .function以及自定义对象等 ...

  7. 【转】32位plsql连接64位oracle

    源地址:http://www.cnblogs.com/ymj126/p/3712727.html

  8. 正交表生成工具 PICT 成对组合覆盖 收藏

    收藏:https://www.cnblogs.com/wmjperson/p/4557246.html

  9. 处理Json接收日期格式问题

    //处理Json接收日期格式问题function getNormalDate(dateNormal) { var receiveDate = new Date(parseInt(dateNormal. ...

  10. HDU6315 Naive Operations(多校第二场1007)(线段树)

    Naive Operations Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 502768/502768 K (Java/Other ...