这篇文章是因为公司内部协作出现问题,主要是因为有些人多git的不熟悉,并且没意思到git管理的重要性,所以我梳理出觉得大家比较盲点的知识点,并且也为了说服别人用之前公司所用的工作流提供很好的帮助。
git知识
git是属于分布式版本控制系统
git快照
Git会先将那些变更的文件复制一份,然后把备份文件转换成Blob对象,并对其进行压缩,再把文件各自的内容通过SHA-1哈希运算出对应Blob的名称(即版本号),如下所示,最后由这些哈希值作为索引组成一个快照
工作区域
- 工作目录
- 暂存区
- 仓库
常用git命令
git init 创建仓库
git remote prune origin 删除本地有但在远程库已经不存在的分支
git remote add origin git@github.com:XXX/demo.git 新增远程仓库
git remote set-url origin git@github.com:XXX/demo.git 修改远程仓库
git remote set-url --add origin git@github.com:XXX/demo.git 添加多个远程仓库
git stash 不提交工作区内容
git stash pop 恢复工作区
git fetch 拉取远程分支
git checkout <file相对路径> 撤销工作目录中的文件变更
git reset --hard <commit ID号> 撤销暂存区中的文件变更
git push -f origin master 推送到远程分支
git diff 查看工作区和暂存区的区别
git diff –cached 查看暂存区和版本库之间的区别
git diff HEAD 查看工作区和版本库之间的区别
git status 查看当前的工作状态
git push --set-upstream origin分支 推远程分支
git push origin --delete 分支 删除远程分支
git branch -d 分支 删除本地分支
git cherry-pick 分支 合并指定版本
git pull 做了两个操作分别是‘获取’和合并。
git pull --rebase 就是以rebase的方式进行合并分支,默认为merge。
恢复策略
git checkout <file相对路径> 撤销工作目录中的文件变更 git reset --hard <commit ID号> 撤销暂存区中的文件变更
如果demo.txt文件修改了多次,并且执行了多次git add .,如果要撤销,需要多次执行上面2条命令
git merge 和 git rebase的区别
1.分析
- git merge
通过git merge将当前分支与xxx分支合并,产生的新的commit对象有两个父节点
如果“指定分支”本身是当前分支的一个直接子节点,则会产生快照合并
举个例子,bugfix分支是从master分支分叉出来的,如下所示:
合并bugfix分支到master分支时,如果master分支的状态没有被更改过,即 bugfix分支的历史记录包含master分支所有的历史记录
所以通过把master分支的位置移动到bugfix的最新分支上,就完成合并
如果master分支的历史记录在创建bugfix分支后又有新的提交,如下情况:
这时候使用git merge的时候,会生成一个新的提交,并且master分支的HEAD会移动到新的分支上,如下:
从上面可以看到,会把两个分支的最新快照以及二者最近的共同祖先进行三方合并,合并的结果是生成一个新的快照
- git rebase
同样,master分支的历史记录在创建bugfix分支后又有新的提交,如下情况:
通过git rebase,会变成如下情况:
在移交过程中,如果发生冲突,需要修改各自的冲突,如下:
rebase之后,master的HEAD位置不变。因此,要合并master分支和bugfix分支
从上面可以看到,rebase会找到不同的分支的最近共同祖先,如上图的B
然后对比当前分支相对于该祖先的历次提交,提取相应的修改并存为临时文件(老的提交X和Y也没有被销毁,只是简单地不能再被访问或者使用)
然后将当前分支指向目标最新位置D, 然后将之前另存为临时文件的修改依序应用
- 区别
- merge:使用
merge命令合并分支,解决完冲突,执行git add .和git commit -m'fix conflict',这个时候会产生一个commit。【只有在冲突的时候,解决完冲突会自动新增一个merge commit记录】
它是一种非破坏性的操作,对现有分支不会以任何方式被更改
- rebase:使用
rebase命令合并分支,解决完冲突,执行git add .和git rebase --continue,不会产生额外的commit。
主要的好处是,‘干净’,历史记录更加清晰,分支上不会有无意义的解决分支的commit;
坏处是如果合并的分支中存在多个commit,需要重复处理多次冲突。
-
如何选择 我觉得看个人习惯,各有各的好处,我习惯用git rebase
-
其他
- 获取远程项目中最新代码时:
git pull --rebase,这个时隐性的合并远程分支的代码不会产生而外的commit(但是如果存在冲突的commit太多,需要处理很多遍冲突)。 - 合并到分支的时候:
git merge --no-ff,自动一个merge commit。
如果想在没有冲突的情况下也自动生成一个commit,记录此次合并就可以用:git merge --no-ff命令
多人协作如何管理Git分支
没有最完整稳定的工作流,结合自己的经验在此分享下我觉得比较稳定使用的工作流。希望对大家有帮助。
其实还可以扩展创建分支规范、commit规范,属于很基础的知识就不在此处写明。