git系统学习
title: git系统学习
date: 2018-12-21 23:00:00
tags:
- git
categories:
- git
git的特性
- 版本控制
最终版,最终版1,最终版2 - 分布式
分布式和集中式都需要中央服务器,不同的是分布式在工作电脑上保存了服务器的完整工程,即使服务器挂掉了,也不会影响工作电脑上的开发。
集中式就不可以了。中央服务器挂掉,其他人就都不可以开发了。
git的安装和基本使用
安装
sudo apt-get install git
基本使用
//目录初始化
git init
// 创建版本
vim code.txt
git add code.txt
git commit -m "create file code.txt"
// 查看版本记录
git log
// 版本回退
git reset --hard HEAD^ // HEAD表示当前的最新版本,也可以用版本编号(commit hash)
// HEAD^也是这样表示HEAD~1,回退四个版本git reset --hard HEAD~4
使用git reset 回退到低版本后,高版本并没有删掉。(但是git log看不到了)如果我们现在又想回到高版本该如何做?
git log看不到高版本的版本编号了,我们可以用git reflog
查看历史操作。就会看到我们高版本的commit hash(版本编号)
git reset --hard 版本编号
工作区和版本库
工作区就是本地工作的目录
版本库就是我们工作区下面的.git文件。
git版本库里有很多东西,其中最重要的就是本称为stage(或者叫index)的暂存区。
已经git add 到暂存区的文件,如何恢复?
git reset HEAD <file>
就相当于git add 命令的倒退,从暂存区清理code.txt,但是工作区的修改依然在。此时用git status,应该又提示文件修改,需要你git add
git只会用暂存区的修改来创建版本,工作区的修改如果没有添加到暂存区。git commit创建的版本中是不会包括工作区修改的内容的。
vim code.txt -> 添加第一行
git add code.txt
vim code.txt -> 添加第二行
// 没有git add 直接git commit
git commit -m "update code.txt" // 这个版本中是没有第二行内容的
撤销修改
编辑完工作区后,想撤销对工作区的修改
git checkout -- <file>
编辑完文件,git add 提交到暂存区,突然又不想到暂存区的此文件的改动了
git reset HEAD <file> // 这就是取消暂存
想要继续丢弃工作区的改动
git checkout -- <file>
总结撤销修改的三种情况
1.只在工作区修改,还没有提交到暂存区
git checkout -- <file>
2.工作区修改后,git add 提交到了暂存区
git reset head <file>
git checkout -- <file>
3 git add 并且已经git commit
git reset --hard HEAD^
git对比文件
工作区和版本库中的对比
git diff HEAD -- <file>
将工作区和版本库HEAD进行比较
如何看比较的内容?
---和+++ ,分队对应diff后面的第一个和第二个
--- a/<file> 代表HEAD版本中的
+++ b/<file> 代表工作区的
前面没有出现+或者-的,就是两个文件共有的
两个版本库中的对比
git diff HEAD HEAD^
删除文件
rm <file>
// 将删除的改动提交到暂存区
git add <file>
// 将删除的改动提交到版本库
git commit - "delete"
rm <file> 和 git add <file>,两个命令可以合为一个,git rm <file>
恢复删除
删除文件也是对工作区的改动,和上面修改文件的恢复是一样的。
在工作区删除后,发现删错了。想要恢复怎么办?
git checkout -- <file>
特别注意:
创建文件touch filename.txt后,如果没有git add添加到暂存区,git是不会开始管理这个文件的。
这个时候,如果你直接rm filename.txt,就真的删掉了。因为git本来就没有跟踪这个文件。
git基本操作小结
image.png分支管理
工厂里面的流水线
平行宇宙
创建分支与合并分支
主分支,默认分支 master
刚才我们说HEAD指向最新的commit,严格的说:HEAD是指向master,master才是指向最新的commit
合并完分支之后,我们可以删除dev分支。删除dev分支就是把dev指针给删除掉。删掉后,我们就剩下一个master分支。
实验
git branch //查看当前仓库又多少分支
* master // *代表当前在那个分支里面
// 创建并切换到新的分支dev
git checkout -b dev
vim code.txt -> add online
git add code.txt // 在dev分支中进行开发
git commit -m "dev 分支提交" // 此时master分支并没有改变
// 切换到master分支
git checkout master
// 查看master分支上有没有dev分支的操作记录
git log --pretty=online //发现并没有dev分支的操作记录
// 合并分支
git merge dev
执行完命令后,我们发现出现又这样的提示,fast-forward,这属于快速合并。快速合并就是直接挪动master指针就可以。
// 删除分支
git branch -d dev
分支-解决冲突
合并分支往往不是一帆风顺的。当我们在两个分支上都对一个文件进行修改了。那执行git merge命令的时候,就会提示自动合并失败。并给出冲突失败文件。当然我们执行git status 也会看到合并有冲突的文件。
这时候我们该怎么做?
需要手动融合,打开冲突文件进行手动融合。
融合之后,需要做一次新的提交。gti add *,git commit - “”
。HEAD指向master,master向前移动了,但是dev分支是不动的。
重点
有时候我们需要看分支图例
git log --graph --pretty=online
分支管理策略
没有快速合并,但是也没有冲突
我们在dev分支和master分支都做了修改,但是修改的不是同一个文件。我们合并时,不能使用fast-forward模式了,但是并没有冲突。
当我们在master分支上git merge dev时,命令行中会出现一次弹窗,让我们输入一个commit信息。
这种合并方式时recursive合并。这时候,git默认会给我们做一次新的提交。
强制禁止快速合并
是在什么样的情景呢?
git checkout -b dev后,在dev分支做了修改,提交了好几个commit。git checkout master,然后git merge dev。此时没有冲突,快速合并成功。
但是:我们在dev分支中的commit记录都没有了!!!
解决办法,禁用fast-forward
git merge --no-ff -m '禁用fast-farword合并' dev
这样就会重新做一次新的提交。
--no-ff指的是强行关闭fast-forward方式。
fast-forward方式就是当条件允许的时候,git直接把HEAD指针指向合并分支的头,完成合并。属于“快进方式”,不过这种情况如果删除分支,则会丢失分支信息。因为在这个过程中没有创建commit
git merge --squash 是用来把一些不必要commit进行压缩,比如说,你的feature在开发的时候写的commit很乱,那么我们合并的时候不希望把这些历史commit带过来,于是使用--squash进行合并,此时文件已经同合并后一样了,但不移动HEAD,不提交。需要进行一次额外的commit来“总结”一下,然后完成最终的合并。
总结:
--no-ff:不使用fast-forward方式合并,保留分支的commit历史
--squash:使用squash方式合并,把多次分支commit历史压缩为一次
bug分支
使用场景
我们正在dev分支上开发,突然接到任务说时让我们赶紧修复一个bug。可是我们当前的工作还没有做完,还不能提交。怎么办?
我们可以把工作暂时保存起来。
git stash
就把我们的工作现场给保护起来了。git status一看,工作区都是干净的。
比如bug时在master分支下面,先git checkout master,然后创建bug分支
git checkout -b bug001
vim main.go
git add mian.go
git commit -m "修复bug001"
git checkout master
git merge --no-ff -m '修复bug001合并' bug001
git branch -d bug001
// 修复完成后,继续回到dev分支干活
git status //工作区干净
git stash list //列出保存的工作现场
// 恢复现场
git stash pop
git status //已经回来了
修改bug时,先回到出现bug的分支上面。