序言:目前,Git是最流行的版本控制系统。相比于SVN,我更偏爱Git! 本文将详细介绍Git的使用。
什么是Git?
Git是一种分布式版本控制系统(DVCS),也称为分散式。每个开发人员都拥有存储库的完整副本,该存储库位于云中(远程仓库)。
安装Git
本人使用的是Mac,终端自带Git工具
Mac:通过Homebrew安装
1
2
3
4安装homebrew
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
安装Git
brew install gitLinux
1
2sudo apt-get update
sudo apt-get install git
使用Git
创建本地存储库
1 | git init |
- 执行完git init后本地仓库已初始化完成。ls -a可以查看到.git的隐藏文件
更新仓库内容
创建文件并修改内容
1 | 创建一个README文件 |
查看仓库状态
1 | git status |
将变更的文件纳入版本管理
1 | git add . |
将纳入版本管理的文件提交到本地仓库
1 | git commit -m 'first commit' |
查看日志
1 | git log # 命令是查看全部提交日志 |
日志的样式略微难看,这里给大家推荐一个配置
1 | 给git log起一个别名:git lg |
分支
创建分支
1 | git branch dev1 |
Git创建分支时,它只是创建一个带有该分支名称的指针,该指针指向已创建分支的commit
切换到dev1分支进行开发
1 | git checkout dev1 |
接下来的所有操作都在dev1分支上,我们仍然来更新仓库的文件内容
1 | touch dev1.txt |
合并分支
假设,这条分支的任务已完成,我们切换到主线master上去
1 | git checkout master |
此时,我们再查看日志,并没有刚刚提交的’create a dev1 text file’。原因是:之前所有的操作都在dev1分支上执行,现在切回到master分支自然没有刚刚的日志记录。在实际项目开发中写了不就没有意义了吗? 所有我们要将dev1分支与master合并!
1 | git merge dev1 |
合并问题
合并之后再次查看日志,你会发现并没有存在dev1分支的存在,与我们相像的并不一致,这是为何?
原因:这是因为Git使用快进模式(fast-forward)合并了分支。这里需要注意git给我们打印的输出信息,如上图所示:master和dev1是共同的祖先!
在我们合并分支时,不推荐使用fast-forward模式!可以通过–no-ff(无快进模式)命令来处理
1 | 新建分支dev2重复dev1的操作,再次合并 |
通过这种方式来合并分支,可以完美的显示分支的生命迹象!
删除分支
假设分支合并完成,此分支已没有作用,我们应该移除此分支,以后可再次创建命名为dev1分支
1 | git branch -d dev1 |
合并冲突
下面模拟一下合并冲突问题!
- 在master分支上更新仓库并提交
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27master分支更新仓库并提交
echo 'this is a test log' >> README.md
git status -s
git add .
git commit -m 'readme file change content'
master分支更新仓库并提交
echo 'this is two' >> README.md
git status -s
git add .
git commit -m 'readme file change content two'
切换到dev2分支,更新仓库并提交
git checkout dev2
echo 'this is dev2 change' >> README.md
git status -s
git add .
git commit -m 'readme file change content dev2 change'
再次切换到master分支,更新仓库并提交
git checkout master
echo 'this is three' >> README.md
git status -s
git add .
git commit -m 'readme file change content three'
做完上述工作,接下来合并
合并
1 | git merge dev2 |
很显然,合并失败!此时,两个分支的版本存在冲突,Git已经不知道怎么做了。 在master更新仓库并提交之后版本已经改变,master已不是上次上传的版本,而dev2分支还是从上一次合并的HEAD开始;所以这时是无法合并的。而Git所做的事情是:指出存在这些内容不兼容的部分。
- 接着,我们看一下仓库状态:git status
进入README文件(vi README.md)查看更新的内容,会发现多出了<<<<<<<HEAD、========、>>>>>>>>dev2,这里有两个部分:
- 第一部分:在<<<<<<< HEAD和=======之间,是master分支更新的内容;
- 第二部分:在=======和>>>>>>> dev2之间,是dev2分支更新的内容;
解决办法
- 使用HEAD-master版本
- 使用dev2版本
- 两个版本的组合
- 使用HEAD-master版本
1
2
3
4
5
6
7
8
9将master分支提交的信息保留,去掉dev2分支的内容,并且去掉<<<<<<<HEAD、========、>>>>>>>>dev2
保存如下:
this is a test log
this is two
this is three
esc退出编辑模式,快捷键shift + : 再输入wq,回车即可,保存并退出
查看状态
git status -s
在一开始合并时,查看仓库状态README文件还是Unmerge 状态,在git status -s下是红色的:UU README.md;而现在是AA README.md
1 | git add . |
使用dev2版本
1
与第一种解决办法同理
两个版本的组合
1
2
3
4两个版本组合就是两者都保留,所以只需要去掉<<<<<<<HEAD、========、>>>>>>>>dev2即可
esc退出编辑模式,快捷键shift + : 再输入wq,回车即可,保存并退出
git add .
git commit
版本合并完之后如下:
版本回退(删除)
- 命令
1
2
3
4
5git reset --hard <版本号> # 回退到对应的版本号,这里的版本号就是日志前面的7个字符
git reset --hard -HEAD^ # 删除最后一次提交的版本,也就是回退到最后倒数第二次版本
git reset --hard -HEAD~ # 删除最后一次提交的版本,也就是回退到最后倒数第二次版本
git reset --hard -HEAD^^ # 删除最后两次次提交的版本,也就是回退到最后倒数第三次版本
.... 其他的依次类推
clone命令
在码云或者Github上要克隆别人的代码,需要用到clone命令
1 | git clone <仓库地址:url/ssh> # 如下图所示 |