git学习笔记

一级目录

名称 描述
src 源代码
release 发布结果
test 单元测试用例
doc 文档
example 示例

简介

起步

三种状态

Git有三种状态:==已提交(committed)、已修改(modified)和已暂存(staged)==。

状态 描述
committed 数据已经安全的保存在本地数据库中
modified 修改了文件,但还没保存到数据库中
staged 对一个已修改文件的当前版本做了标记,使之包含在下次提交的快照中

Git项目的三个工作区域

==Git仓库、工作目录以及暂存区域==。

工作区域 描述
Git仓库目录 Git中最重要的部分。用来保存项目的元数据库
工作目录 对项目某个版本独立出来的内容
暂存区域 保存了下次将提交的文件列表信息,一般在Git仓库目录中

image

基本的Git工作流程:

  1. 在工作目录中修改文件。
  2. 暂存文件,将文件的快照放入暂存区域
  3. 提交更新,找到暂存区域的文件,将快照永久性存储到Git仓库目录

工作目录下Git文件两种状态

==已跟踪和未跟踪==。

已跟踪文件:

  • 被纳入了版本控制的文件
  • 在上一次快照中有记录
  • 状态可能处于未修改、已修改或已放入暂存区

为跟踪文件:

  • 除已跟踪文件外的所有文件

使用Git时文件的生命周期:
image

Git基础

获取Git仓库

有两种获取Git仓库的方法:

在现有项目或目录下导入所有文件到Git中
1
git init

该命令创建一个名为.git的子目录,包含初始化的Git仓库中所有的必须文件,这些文件是Git仓库的主干。

.git文件夹

image

文件(夹) 描述
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
2
//本地文件夹名为 name
git clone [url] name

记录更新到仓库

工作目录下的每个文件都不外乎两种状态:已跟踪和未跟踪。

已跟踪文件:

  • 被纳入了版本控制的文件
  • 在上一次快照中有记录
  • 状态可能处于未修改、已修改或已放入暂存区

为跟踪文件:

  • 除已跟踪文件外的所有文件

使用Git时文件的生命周期:
image

检查当前文件状态
1
2
3
4
git status

//状态简揽
git status -s
状态 描述
?? 未跟踪
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
2
//创建名为testing的分支
git branch testing

这会在当前所在的提交对象上创建一个指针。

==Git中有一个名为HEAD的特殊指针,指向当前所在的本地分支==。git branch命令仅仅创建一个分支,并不会自动切换到新分支中去。

1
2
//查看各个分支当前所指的对象
git lot --oneline --decorate

分支切换

1
2
//切换到testing分支
git checkout testing

切换分支会使HEAD指向分支(testing),并且将工作目录恢复成分支(testing)所指向的快照内容。
在切换分支时,工作目录里的文件会被改变。如果是切换到一个较旧的分支,工作目录会恢复到该分支最后一次提交时的样子。如果Git不能干净利落地完成这个任务,它将禁止切换分支。

分叉历史

输出提交历史、各个分支的指向以及项目分支分叉情况:

1
git log --oneline --decorate --graph --all

Git分支实质上仅是包含所指对象校验和的文件。

分支的新建与合并

新建分支
1
2
//新建issue分支,并切换到该分支
git checkout -b issue
删除分支
1
2
//删除issue分支
git branch -d issue
分支的合并

若合并分支issue到master

1
2
git 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 保存暂存区信息
Git对象