一级目录
名称 | 描述 |
---|---|
src | 源代码 |
release | 发布结果 |
test | 单元测试用例 |
doc | 文档 |
example | 示例 |
简介
起步
三种状态
Git有三种状态:==已提交(committed)、已修改(modified)和已暂存(staged)==。
状态 | 描述 |
---|---|
committed | 数据已经安全的保存在本地数据库中 |
modified | 修改了文件,但还没保存到数据库中 |
staged | 对一个已修改文件的当前版本做了标记,使之包含在下次提交的快照中 |
Git项目的三个工作区域
==Git仓库、工作目录以及暂存区域==。
工作区域 | 描述 |
---|---|
Git仓库目录 | Git中最重要的部分。用来保存项目的元数据库 |
工作目录 | 对项目某个版本独立出来的内容 |
暂存区域 | 保存了下次将提交的文件列表信息,一般在Git仓库目录中 |
基本的Git工作流程:
- 在工作目录中修改文件。
- 暂存文件,将文件的快照放入暂存区域
- 提交更新,找到暂存区域的文件,将快照永久性存储到Git仓库目录
工作目录下Git文件两种状态
==已跟踪和未跟踪==。
已跟踪文件:
- 被纳入了版本控制的文件
- 在上一次快照中有记录
- 状态可能处于未修改、已修改或已放入暂存区
为跟踪文件:
- 除已跟踪文件外的所有文件
使用Git时文件的生命周期:
Git基础
获取Git仓库
有两种获取Git仓库的方法:
在现有项目或目录下导入所有文件到Git中
1 | git init |
该命令创建一个名为.git的子目录,包含初始化的Git仓库中所有的必须文件,这些文件是Git仓库的主干。
.git文件夹
文件(夹) | 描述 |
---|---|
hooks/ | 存放一些shell脚本 |
info/ | 存放仓库信息 |
logs/ | 保存所有更新的引用记录 |
logs/HEAD | 内容:上一次提交哈希值 本次提交哈希值 Linux时间、东八区 提交信息 |
objects/ | 存放所有的git对象 |
refs/heads/ | 保存当前最新的一次提交的哈希值 |
COMMIT_CDITMSG | 保存当前最新的一次提交的哈希值 |
config | git仓库的配置文件 |
description | 仓库的描述信息,主要给gitweb等git托管系统使用 |
FETCH_HEAD | 一个版本链接,指向着目前已经从远程仓库取下来的分支的末端 |
HEAD | 映射到ref引用,能够找到下一次commit的前一次哈希值(logs内) |
index | 暂存区(stage),二进制文件 |
ORIG_HEAD | HEAD指针的前一个状态 |
packed-refs |
当更新一个引用时,git不会packed-refs,而是会在refs/heads下写入一个新文件。当查找一个引用时,git首先在refs目录下查找,如果未找到则到packed-refs文件中去查找
从一个服务器克隆一个现有的Git仓库
1 | git clone [url] |
==Git克隆的是该Git仓库服务器上的几乎所有数据==1
git clone ../../test
上命令会在当前目录下创建一个名为test的目录,并在这个目录下初始化一个.git文件夹,然后从中读取最新版本的文件的拷贝。
1 | //本地文件夹名为 name |
记录更新到仓库
工作目录下的每个文件都不外乎两种状态:已跟踪和未跟踪。
已跟踪文件:
- 被纳入了版本控制的文件
- 在上一次快照中有记录
- 状态可能处于未修改、已修改或已放入暂存区
为跟踪文件:
- 除已跟踪文件外的所有文件
使用Git时文件的生命周期:
检查当前文件状态
1 | git status |
状态 | 描述 |
---|---|
?? | 未跟踪 |
A | 新添加到暂存区的文件 |
M | 修改过的文件 |
MM | 文件修改且已放入暂存区(左M),文件修改后未放入暂存区(右M) |
跟踪新文件
1 | git add [file] |
此时再运行git status查看文件状态。
忽略文件
无需纳入Git管理,也不希望出现在未跟踪文件列表的文件。
创建.gitignore文件,列出要忽略的文件模式
提交更新
1 | git commit |
提价更新前要确认是否所有需更新文件都有git add。
每次准备提交前,先用git status查看文件是否已暂存,然后再提交。
1 | git commit -m "提交信息" |
==提交时记录的是放在暂存区域的快照==。
跳过使用暂存区域:1
git commit -a
提交后,Git终端会显示的信息:
- 提交的分支
- 提交的完整SHA-1校验和
- 修改过的文件和行信息
移除文件
1 | git rm [file_name] |
强制删除1
git rm -f [file_name]
把文件从Git仓库中删除(亦即从暂存区域移除),但仍保留在当前工作目录中。即让文件保留在磁盘,但是并不让Git继续跟踪。1
git rm --cached [file_name]
查看提交历史
1 | git log |
撤销对文件的修改
命令行输入git status有提示。1
git checkout -- [file]
推送到远程仓库
将master分支推送到origin服务器:1
git push origin master
Git分支
分支简介
Git保存的不是文件的变化,而是一系列不同时刻的文件快照。
在进行提交操作时,Git会保存一个提交对象,该提交对象会包含一个指向暂时内容快照的指针(该提交对象还包含了作者的姓名、邮箱、提交时输入的信息以及指向它的父对象的指针)。首次提交的对象没有父对象,普通提交操作产生的提交对象有一个父对象,而由多个分支合并产生的提交对象有多个父对象。
Git的分支,本质上是指向提交对象的==可变指针==。
创建分支
Git创建新分支只是创建了一个可以移动的新指针。
1 | //创建名为testing的分支 |
这会在当前所在的提交对象上创建一个指针。
==Git中有一个名为HEAD的特殊指针,指向当前所在的本地分支==。git branch命令仅仅创建一个分支,并不会自动切换到新分支中去。
1 | //查看各个分支当前所指的对象 |
分支切换
1 | //切换到testing分支 |
切换分支会使HEAD指向分支(testing),并且将工作目录恢复成分支(testing)所指向的快照内容。
在切换分支时,工作目录里的文件会被改变。如果是切换到一个较旧的分支,工作目录会恢复到该分支最后一次提交时的样子。如果Git不能干净利落地完成这个任务,它将禁止切换分支。
分叉历史
输出提交历史、各个分支的指向以及项目分支分叉情况:1
git log --oneline --decorate --graph --all
Git分支实质上仅是包含所指对象校验和的文件。
分支的新建与合并
新建分支
1 | //新建issue分支,并切换到该分支 |
删除分支
1 | //删除issue分支 |
分支的合并
若合并分支issue到master1
2git checkout master
git merge issue
分支管理
查看分支列表:1
git branch
查看每一分支最后一次提交:1
git branch -v
查看已合并分支:1
git branch --merged
查看未合并分支:1
git branch --no-merged
新建和合并分支的时候,所有操作只发生在本地的Git版本库中,没有与服务器发生交互。
远程分支
远程引用是对远程仓库的引用(指针),包括分支、标签等。
拉取
当git fetch命令从服务器上抓取本地没有的数据时,它并不会修改工作目录中的内容。
如果有设置好的跟踪分支,git pull会查找当前分支所跟踪的服务器与分支,从服务器上抓取数据然后尝试合并入那个远程分支。
删除远程分支
从服务器上删除serverfix分支:1
git push origin --delete serverfix
变基
在Git中整合来自不同分支的修改方法:==merge和rebase==。
Git钩子
Git能在特定的重要动作发生时触发自定义脚本,有两组这样的钩子:客户端和服务端。
- 客户端钩子由提交和合并等操作调用
- 服务端钩子作用于诸如接受被推送的提交的联网操作
Git内部原理
底层命令和高层命令
.git目录初始默认结构:
文件(夹) | 描述 |
---|---|
HEAD | 指示目前被检出的分支 |
config | 包含项目特有的配置选项 |
info/ | 包含一个全局性排除文件,用以放置不希望被记录在.gitignore文件中的忽略模式 |
hooks/ | 包含客户端或服务端的钩子脚本 |
objects/ | 存储所有数据内容 |
refs/ | 存储指向数据(分支)的提交对象的指针 |
index | 保存暂存区信息 |