[TOC]
概述
本文以一个实例带你从安装Git慢慢深入,跟着做完这个小Demo,你将学会如何使用git的基本命令,熟悉Git版本管理的流程,理解什么是暂存区,深入理解暂存区和工作区的以及本地仓库的关系。
1 安装Git
参考官方教程
本文基于OSX系统:
先下载MacPorts
|
|
解压
|
|
安装
|
|
打开用户/你的用户名文件夹下的“.bash_profile”文件,看是否有export PATH="/opt/local/bin:/opt/local/sbin:$PATH"
,没有就加上。修改完“.bash_profile”文件后需要在终端输入source .bash_profile
命令,是修改立即生效。
安装git
|
|
如果提示git-core not found
,就输入sudo port -d sync
,如果提示port not found
,就检查环境变量是否设置成功。
2 初始化
|
|
一般够用了,其他的配置参考初次运行 Git 前的配置
3 创建本地仓库
终端进入需要创建Git仓库的目录下,
|
|
|
|
4 工作区和暂存区
接下来,这里我们开始学习工作区和暂存区了,这部分内容很容易混淆。为了让大家更简单地了解这部分知识,我画了一组流程图。首先,我们来看下git版本控制的文件位置构成。
可以看到四个区域:
- 工作区 我们平时开发就在工作区里
- 暂存区 add命令之后,工作区文件会在暂存区留一份快照,我觉得淘宝的购物车和暂存区挺像,在提交订单前可以随意修改购物车,暂存区也是,先这样理解吧。。。。
- 本地仓库 commit命令之后,文件会提交到本地仓库,相当于购物车提交订单
- 远程仓库 push命令之后,文件从本地仓库提交到远程仓库,相当于服务器接收到订单,额,有点勉强的比喻
首先,我们在gitdemo
目录下新建一个文件 test.text,内容为:
|
|
执行
|
|
查看文件状态
|
|
可以看到文件是未跟踪的状态。
现在的目录结构是这样的:
接着,执行
|
|
这个操作会将文件快照添加到暂存区,注意,是快照,不是备份,虽然暂存区这里快照和备份好像看不出什么区别。这个区别主要体现commit操作, commit之后,暂存区快照会存储在本地git仓库中,如果之前版本的文件在此次commit没有发生改动,那么git存的就是之前版本文件的链接。
查看文件状态
|
|
此时的文件结构是:
然后我们修改工作区中的文件内容为
|
|
此时的文件结构是
查看文件状态
|
|
我们看到有两个文件,一个是new file: test.text
,这就是暂存区的文件,一个是modified: test.text
,就是工作区的文件。
现在我们执行
|
|
现在的文件结构是:
暂存区的文件被提交到本地仓库了。
查看文件状态
|
|
可以看到test.text处于已修改的状态,这是工作区中的文件,执行
|
|
可以将工作区中所有已跟踪的文件提交到暂存区,然后再执行
|
|
文件就提交到本地仓库了,此时的文件结构是
现在继续修改文件内容
|
|
此时的文件结构
突然我发现修改错了,我想取消修改,于是执行
|
|
此时的文件结构
然后可以看到工作区的文件内容被暂存区的文件内容覆盖了。
当我不想让git管理test.text
文件了,可以执行
|
|
执行
|
|
可以发现test.text文件回到了未跟踪状态,它已经脱离了git版本控制系统。
现在再来总结下,各个区的含义
- 工作区 我们对文件的创建和修改操作都是在工作区中进行的。
- 暂存区 暂存区是工作区和本地仓库的桥梁,在最后将文件提交到本地仓库之前,可以对文件进行随意修改,将文件从工作区添加到暂存区或者从暂存区恢复文件。
- 本地仓库
commit
命令就是将暂存区的所有文件提交到本地仓库,如果工作区的修改没有添加到暂存区,则修改不会被提交到本地仓库。
5 本地仓库
5.1 HEAD指针
在终端输入git log
可以查看提交到本地仓库的历史记录
|
|
提交次数多的话可以用git log --pretty=oneline
,显示更清晰
|
|
可以看到我们提交了两次。回顾一下刚才的提交
第一次提交: 我刚创建
第二次提交: 我被修改了
这时也许你会问提交记录前面那一大串字符是什么,这个是版本号,也叫commit id
。当我们创建一个git
仓库的时候,git
会自动创建一个master
分支,master
分支当前版本的用指针HEAD
表示,上一个版本用HEAD^
表示,上上个版本用HEAD^^
表示,往前的版本多了,可以用HEAD~数字
表示,比如HEAD~0
表示当前版本,HEAD~1
表示上一个版本,现在的第二次提交就是HEAD,HEAD的值就是版本号。
可以通过git rev-parse HEAD
命令获取最新一次的版本号。也可以通过git rev-parse --short HEAD
获取7位短版本号,这个短版本号完整的版本号是一样使用的。
将当前版本的仓库文件覆盖暂存区文件:
|
|
现在处于我被修改了
这个版本,我想回到上一个版本,有两种方式
第一种:使用git reset --hard HEAD^
|
|
第二种:首先,使用git log
查看提交历史
|
|
找到上一个版本我刚创建
的版本号为65b88a34150e77b3ba6122238fd1e6b4609f0e85
,执行
|
|
现在回到了我刚创建
的版本,好吧,我后悔了,我要回去!怎么办?
这个时候用git log
只能查看历史版本哦,不能查看在我刚创建
后提交的未来版本,这时我们使用git reflog
来查看操作历史,
|
|
找到我被修改了
的版本号为a0c3991
,执行
|
|
哈哈,回去啦。
5.2 分支管理
5.2.1 分支切换
使用git branch
查看当前分支
|
|
*
表示当前分支。
修改下test.text文件内容为
|
|
执行git commit -am "修改master分支文件内容"
。
master分支是开发主线,这时有个功能需要在不影响主线的情况下开发,就需要新建一个分支。比如我们要开发v1版本,就可以使用git branch beta_v1
新建一个分支,现在查看下分支情况:
|
|
虽然新建了一个分支,但是现在还是处于master分支下,我们先使用git checkout beta_v1
切换到beta_v1分支。
|
|
5.2.2 分支合并
编辑test.text
文件,修改内容为我在beta_v1分支被修改了
,git commit -am "修改beta_v1分支文件内容"
提交,然后再使用git checkout master
切换回master
分支。
查看test.text
文件的内容:
|
|
使用git merge beta_v1
把分支beta_v1
的内容合并过来,这时文件被自动合并了,此时的文件内容是:
|
|
再使用git checkout beta_v1
切换到beta_v1
分支,修改文件内容为我在beta_v1分支再次被修改了
,此时merge master的内容git merge master
,
|
|
提示自动合并失败,查看文件内容:
|
|
我们可以手动编辑这个文件解决冲突,修改test.text内容为冲突解决了
,然后git commit -am "解决了冲突"
提交。
现在的Android Studio、Intellij IDEA等IDE都有解决冲突的图形化界面,使用起来非常方便。
如果你没有用IDE,那么可以使用git mergetool --tool=编辑器名
,然后使用git mergetool
命令进行合并操作。使用git mergetool --tool-help
查看所有支持的工具。
|
|
rebase
命令也能合并内容,区别参考Git Community Book 中文版。
6 远程仓库
以github为例,我创建了一个仓库test。