GIT 最佳实践 转载 https://www.cnblogs.com/jeff-liu/p/13850674.html
Git使用最佳实践
git概述
git是一款分布式的版本控制系统。这与SVN这种集中式的版本控制系统最大的区别就是开发者可以commit修改到本地的git仓库。解决多人同步开发代码的问题。
最基本git开发过程图示:
Git本地有四个工作区域:
- 工作目录(working directory),
- 暂存区(stage/index),
- 版本库(Repository或git directory),
- 如果再加上远程的git仓库(remote directory)就可以分为四个工作区域。
文件的四种状态:
- Untracked:未跟踪,此文件在文件夹中,但并没有加入到git库,不参与版本控制。通过git add状态变为Staged
- Unmodified:文件已经入库,未修改,即版本库中的文件快照内容与文件夹中的完全一致。这种类型的文件有两种去处,如果他被修改,就变为Modified;如果使用git rm移出版本库,则变为Untracked。
- Modified:文件已修改,但仅仅是修改,没进行其它的操作。这个文件也有两种去处,通过git add可以进入暂存staged状态;使用git checkout则丢弃修改,返回到Unmodified状态。这个git checkout即从库中取出文件,覆盖当前修改!
- Staged: 暂存状态,执行git commit则将修改同步到库中。这时库中的文件与本地文件一致,又变为了Unmodified状态。执行git reset HEAD 取消暂存,文件状态变为Modified。
比较有趣的一点:一个文件可以又在“暂存区”(先git add),又在“工作目录”的修改状态(再进一步修改)。
git的分支
为什么要用多分支
只有一个分支会遇到下面的问题,例如:
- 比如已经上线了一个版本,并且开始新版本的开发,已经提交了一些修改。但在版本使用了一段时间后发现bug要修改,这时就会很尴尬。修改代码只能在包含了一部分新功能的代码上进行改bug。
- 还有一种情况,两人开发两个不同功能,一个功能先上线,那另外那个人的代码就一直不能提交。这个人的电脑的安全性就变得很重要,唯恐丢失开发的代码,另外也不利于公司跟踪进度。如果第二个功能是多人开发,功能代码无法同步,就更无法实现了。
推荐的分支管理方法
首先,分支管理没有silver bullet,暂时采用下面的分支管理方法:
- master分支(主分支) - 生产环境下的正式版本。
- develop分支 - 平时开发环境的分支。
- release分支 - 来自于develop分支,最后必须合并回develop和master分支。完成所有预期的开发任务时,就可以从 develop 分支创建出 release 分支. 新创建的realse分上可以进行bug fix, 但是禁止在release分支上进行重大特性的更新。release分支属于临时性质,用完可以删除。
- hotfix分支 - 生产环境下发现问题,需要立即修复。修复后需要merge到master分支、develop分支。hotfix分支也属于临时性质,用完可以删除。
- feature分支 - 用来开发新特性的分支,来自于develop分支。完成开发时,合并回develop分支。feature分支也属于临时性质,用完可以删除。
git日常操作
git-创建一个提交版本
#对当前head版本做出修改
git add . #文件修改进入“暂存区”
git commit -m "一定要加注释" #暂存区修改进入版本库,创建版本记录,head指向最新的版本
git log #可以查看版本信息(在IDEA中出现高亮时,可以按ctrl+Enter会打开相应的IDE界面)
图示
git-放弃对一个文件的修改
# 如果文件还没有放入暂存区
git checkout -- <文件名> #放弃对某一个文件已经做出的修改,回到head版本的该文件
# 如果文件已经放入暂存区
git reset HEAD <文件名> #取消暂存,取消暂存后会进入modified状态,再如上操作。
git checkout -- <文件名> #放弃对某一个文件已经做出的修改,回到head版本的该文件
git-回退到上一个版本
git reset --hard head~1 #回到上一个版本
git reset --hard head~100 #回到前面第100个版本
git reset --hard head #回到本版本,用来放弃更改
git reset --hard <commitid> #回到commit id指定的版本
图示
注意:
-
这里被回退掉的版本其实没有丢失,还可以通过commit id找回来。
-
这里的参数--hard的作用:**
-
如果有--hard,则完全回退到上一版本,丢弃所有其它修改,清空暂存区,同步工作目录到指定版本。
例如已经commit了版本2,reset --hard到版本1,则版本1和2之间的变化部分会被彻底丢弃。 -
没有--hard,则该版本之后的变化会变为Modified状态保留在工作目录,只清空暂存区。
例如已经commit了版本2,reset到head版本1,则版本1和2之间的变化部分会保存到工作目录,处于modified状态。
-
git-比较一个文件在两个版本之间的不同
git diff head~1 head -- <文件名> #比较上一个版本和这一个版本某个文件的不同
git diff head~1 -- <文件名> #比较上一个版本和目前正在修改的文件的不同
git diff #只能比较出处于modified状态的修改,如果所有变更都放到暂存区了,则无返回
git-创建一个分支并跳转到这个新建分支,再推送到远端仓库
注意:如果这个新建的分支只是在本地短期使用,可以不必push到远程仓库中。
#建分支和切换分两步完成
git branch <new branch name> #创建分支
git checkout <new branch name> #跳转到新分支
# 或者 建分支和切换用一个命令完成
git checkout -b <new branch name> #创建并跳转到新分支
#------------远程相关----------------------
git push --set-upstream origin <new branch name> #推新分支到远程仓库并在本地分支和远程分支之间建立关联
# 也可以分两步完成,但推荐上面的方式
git push origin <new branch name> #推新分支到远程仓库
git branch --set-upstream-to=origin/<new branch name> <new branch name> #关联本地分支到远程分支,如果不是这个关联,每一次pull或push的时候都需要明确指定本地和远端分支。
git branch -v #查看本地分支有哪些
git branch -r -v #查看本地分支有哪些
git-打标签
tag 是 Git 版本库的一个快照,指向某个 commit 的指针。tag其实也是一种分支,只是这种分支无法再继续被push新内容进去。
git tag -a "release_a.b.c" -m "this is a.b.c version" #打标签, -a是标签名 -m注释
git push origin "release_a.b.c" #将这个新标签推送到远程仓库
git tag #查看标签信息
git show release_a.b.c #显示被打标签的commit的详细信息
git-在hotfix1分支完成开发后,合并到master分支
同理也可以从自己的临时开发分支合并到feature_abc分支
git checkout -b hotfix1 release_a.b.c #从release_a.b.c这个标签的版本上开一个新的修复分支
git push origin hotfix1 #将hotfix1分支推送到远程仓库
git branch --set-upstream-to=origin/hotfix1 hotfix1 #关联本地分支到远程分支
#做一些修改
git add .
git commit -m "改了什么东西"
git push
#经过测试没问题,合并回master
git fetch
git checkout master
git pull #确保是远程仓库的最新代码
git merge hotfix1
git push #把merge后的结果推到远程仓库的master分支
#接下来应该打新标签并发布到生产系统
git tag ...
# 如果此时还有开发分支也要merge到开发分支
git-从develop分支发布正式版本的流程
git checkout -b release-2.1.0 develop #从develop分支上开一个新的发布分支
# 修改版本号,移除包名中的snapshot等
git add .
git commit -m "release version 2.1.0"
#全部bug修复,经过测试没问题,合并回master
git checkout master
git merge release-2.1.0
git push #把merge后的结果推到远程仓库的master分支
#接下来应该打新标签并发布到生产系统
git tag -a "release-2.1.0" -m "release version 2.1.0"
# 如果此时还有开发分支也要改bug的修改合并到开发分支
git fetch
git checkout develop
git merge release-2.1.0
git push
# 最后将release分支删除
git branch -d release-2.1.0
git-如何切换到一个远程分支
例如接手另一个同事的任务时,要从他的远程分支继续开发。
git fetch #刷新远程仓库信息获得远程分支的信息(如果远程分支是新建的话)
git branch -r #查看是否可以看到远程分支了,例子中会是origin/feature2
git checkout -b feature2 origin/feature2 #从远程分支基础上,直接建立本地分支并切换到该分支