一、Git的简介
Git 是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目。
Git 工作区、暂存区和版本库、本地仓库的概念:
- 工作区: 电脑里能看见(非隐藏)的工作目录。
- 暂存区: 英文叫
stage
或index
,暂存区域是一个文件,保存了下次将提交的文件列表信息。一般存放在.git
目录下的index
文件(.git/index)中,所以我们把暂存区有时也叫作索引(index)。 - 版本库: 工作区有一个隐藏目录
.git
,这个不算工作区,保存项目的元数据和对象数据库,用来跟踪管理仓库。 - 本地仓库: 本地仓库保存了对象被提交过的各个版本。
git commit
后同步index的目录树到本地仓库,方便从下一步通过git push
同步本地仓库与远程仓库。说明如下:- 只有把修改提交到本地仓库,该修改才能在仓库中留下痕迹
- 可以在任何地方新建本地仓库,只需要在目标目录下执行
git init
指令,就会将此目录自动初始化为本地仓库,同时它会新建.git
目录
工作区、版本库中的暂存区和版本库之间的关系:
- “HEAD” 实际是指向 master 分支的一个"游标"。
- objects 标识的区域为 Git 的对象库,实际位于 “.git/objects” 目录下,其包含了创建的各种对象及内容。
- 当对工作区修改(或新增)的文件执行 git add 命令时,暂存区的目录树被更新,同时工作区修改(或新增)的文件内容被写入到对象库中的一个新的对象中,而该对象的ID被记录在暂存区的文件索引中。
- 当执行提交操作(git commit)时,暂存区的目录树写到版本库(对象库)中,master 分支会做相应的更新。即 master 指向的目录树就是提交时暂存区的目录树。 实现master和暂存区的联系
- 当执行 git reset HEAD 命令时,暂存区的目录树会被重写,被 master 分支指向的目录树所替换,但是工作区不受影响。
- 当执行 git rm --cached
命令时,会直接从暂存区删除文件,工作区则不做出改变。 - 当执行 git checkout . 或者 git checkout –
命令时,会用暂存区全部或指定的文件替换工作区的文件。这个操作很危险,会清除工作区中未添加到暂存区中的改动。 - 当执行 git checkout HEAD . 或者 git checkout HEAD
命令时,会用 HEAD 指向的 master 分支中的全部或者部分文件替换暂存区和以及工作区中的文件。这个命令也是极具危险性的,因为不但会清除工作区中未提交的改动,也会清除暂存区中未提交的改动。
二、Git的配置
1 | # git的配置列表 |
1 | # Github配置:ssh方式 |
三、创建仓库
1 | # 使用当前目录作为 Git 仓库,该命令执行完后会在当前目录生成一个 .git 目录。 |
四、基本操作
1 | git clone *** |
.git文件夹
- 本地分支的refs保存在
./.git/refs/heads/
文件夹下 - 远端分支的refs存储在
./.git/refs/remotes/
文件夹下(git branch -r
查看远端分支 + git checkout) - objects 标识的区域为 Git 的对象库,实际位于 “.git/objects” 目录下,其包含了创建的各种对象及内容。
五、分支管理
几乎每一种版本控制系统都以某种形式支持分支,一个分支代表一条独立的开发线。
使用分支意味着你可以从开发主线上分离开来,然后在不影响主线的同时继续工作。
Git 分支实际上是指向更改快照的指针。
1 | # 列出本地分支,-r 列出远程分支 |
查看提交历史
Git 提交历史一般常用两个命令:
- git log - 查看历史提交记录。
- git blame
- 以列表形式查看指定文件的历史修改记录。
1 | # 使用 git log 命令列出历史提交记录 |
为什么会发生合并冲突?
提示:以两个分支为例
- git找到两个分支的ancestor commit,在当前情况下,ancestor commit为两个分支的分叉口。
- 记录两分支在ancestor commit之后的修改记录(文本文件记录起始行号和修改范围)。
- 最后生成合并结果,有三种情况:
- 只有一条分支进行了修改,此时判断没有发生冲突;
- 两条分支都进行了修改,但是修改记录没有发生重叠,则没有发生冲突;
- 两条分支都进行了修改,并且修改记录发生了重叠,则发生了冲突。
理解git diff命令
git diff 用来比较文件之间的不同,其基本用法如下。
-
git diff:显示工作目录(working tree)与索引区(即暂存区快照,index,就是git add过的)之间的文件变更,即显示未被add的文件变更。
-
git diff --cached 或 git diff --staged:显示索引区和最后一次commit(HEAD)之间的文件更改,即显示已add但还未commit的文件变更。也即用"git commit"(不带-a)将被提交的文件变更。
-
git diff HEAD:显示工作目录与最后一次commit之间的文件变更,即显示所有未commit(包括未add和add两类)的文件变更。也即用"git commit -a”将被提交的文件变更。
-
git diff <分支名1> <分支名2> :比较两个分支上最后 commit 的内容的差别。以分支1为基础进行比较的。