[ Git | 青训营笔记 ]
标题:Git的前世今生 - 掘金
网址:
juejin.cn/course/byte… 标题:Git的基本使用方式 - 掘金
网址:
一、Git概念
Git 目前绝大多数公司都使用 Git 进行代码管理,并且绝大多数开源项目都是基于 Git 进行维护的。
Git 是一个开源的分布式版本控制系统,可以有效、高速地处理从很小到非常大的项目版本管理。也是Linus Torvalds为了帮助管理Linux内核开发而开发的一个开放源码的版本控制软件。
1.1 版本控制
版本控制主要分为本地版本控制、集中版本控制、分布式版本控制
1. 本地版本控制
通过本地复制文件夹,来完成版本控制。一般可以通过不同的文件名来区分版本
2. 集中版本控制(SVN)
提供一个远端服务来保存文件,所有用户的提交都提交到该服务中
增量保存每次提交的Diff,如果提交的增量中和远端现存的文件存在冲突,则需要本地提前解决冲突。
3. 分布式版本控制(Git)
每个库都存有完整的提交历史,可以直接在本地进行代码提交
每次提交记录的都是完整的文件快照,而不是记录增量
通过 Push 等操作来完成和远端代码的同步
二、Git 基本使用方式
我使用的是 Ubuntu 系统进行 Git 的配置和使用
2.1 使用流程
步骤1. 创建文件夹
步骤2. 然后进入文件夹,在里面打开终端
步骤3. 输入
git init 命令 来建立一个 Git 仓库
需要注意的是,创建后的.git文件是隐藏的,需要显示隐藏文件才可以看到
git init 可以通过添加参数来实现其他功能
--initial-branch 初始化的分支
--bare 创建一个裸仓库(纯 Git 目录,没有工作目录)
--template 可以通过模板来创建预先构建好的自定义 git 目录
使用 tree .git 可以通过树的形式观察目录结构
或者打开文件夹,也可以直接查看
.git文件内容
HEAD 文件(存放refs/heads/master内容,也就是指当前指向的分支是master)
config 文件(指的是当前仓库的一些配置)
hooks 文件夹(配置一些 hook)
objects 文件夹(存储一些文件信息)
refs 文件夹(存放一些分支信息)
2.2 Git Config
Git 配置有不同的级别(--global[全局级别配置]、--system[系统级别配置]、--local[本地级别配置])
每个级别的配置可能会重复,但是低级别的配置会覆盖高级别的 配置(级别大小:系统>全局>本地)
用户名配置
git config --global user.name "LiuXinDG"
git config --global user.email A1559540917@163.com
可以在终端通过 git config user.name/user.email命令进行查看
Instead of 配置
可以做一些url的替换,比如将http协议替换成ssh协议。
git config --global url.git@github.com:.insteadOf https://github.com/
Git 命令别名配置
可以简化一些命令,如将commit --amend --no-edit命令改成cin,只用输入git cin即可。
git config --global alias.cn "commit --amend --no-edit"
2.3 Git Remote
Remote 配置,表示的是本地和远端的一些关联信息。Remote 一般会分为 http 和 ssh 两种。
查看 Remote
git remote -v
添加 Remote
再次进行查看 Remote
同一个 Origin 设置不同的 Push 和 Fetch URL
HTTP Remote
不推荐使用,不安全,比较麻烦
免密配置
SSH Remote
推荐使用
免密配置:
SSH 可以通过公私钥的机制,将生成的公钥存放在服务端,从而实现免密访问。
目前的 key 的类型有四种(dsa、rsa、ecdsa、ed25519);默认使用的是 rsa,优先推荐使用 ed25519。
Github 添加公私钥
一、打开 Terminal(终端)
二、输入`ssh-keygen -t ed25519 -C "your_email@example.com" 秘钥默认存在 ~/.ssh/id_ed25519.pub
打开 id_rsa.pub 复制里面的所有信息,到 Github 的 SSH 中进行添加
登录 github 在 settings 页面
选择在左边的 SSH and GPG keys
在选择右上角的 New SSH Key,由于我这里之前添加过了,所以有显示。
2.4 Git Add
通过使用 git add 命令,可以将文件提交到暂存区
可以从上述图中看出,由于没有提交,所以不会显示在 .git文件中
我们需要通过使用git add 命令进行一次提交。
可以发现在 objects 文件夹下有了一个新的文件,我们可以通过使用 git cat-file -p 文件id 来查看内容
这里由于我在 readme.md 文件中写入了 Hello, world 所以会显示 Hello, world
2.5 Git commit
由于已经通过 git add 命令将文件提交到暂存区了,此时需要使用 git commit 命令来使文件真正提交到目录中。
这时候可以发现,在objects文件夹下面又新增了2个文件,这时查看一下 83 开头的文件
这个表示的是,它是一个目录树类型的 object ,存储的是目录信息。
在查看一下 3a 开头的文件
这个表示的是,他存的是一个 commit 的记录,如 tree是什么、author和committer 都是谁。
2.6 Objects
Blob(存储文件的内容)、Tree(存储文件的目录信息)、Commit(存储提交信息,一个 Commit 可以对应唯一版本的代码)
- 通过 commit 寻找到 Tree 信息,每个 Commit 都会存储对应的 Tree ID
- 通过 Tree 存储的信息,获取到对应的目录树信息。
3. 从 tree 中获得 blob 的 ID,通过 Blob ID 获取对应的文件内容
2.7 Refs
当我们去查看这个在 refs/heads 下面新增的文件内容时,可以发现就是 commit id
新增一个分支,并切换到新增的分支
git checkout -b test
在进行查看 .git 文件结构时,会发现在 refs/heads 下面会新增一个 test 文件夹
当我们去查看这个 test 的内容时候,会发现跟 master 一样。
refs 的内容就是对应的 commit ID
因此把 ref 当做指针,指向对应的 Commit 来表示当前 Ref 对应的版本
ref/heads 表示分支、ref/tags 表示标签
Branch
git checkout -b 可以创建一个新的分支。分支一般用于开发阶段,是可以不断添加 Commit 进行迭代的
Tag
标签一般表示一个稳定的版本,指向的 Commit 一般不会变更
可以使用git tag 版本号进行创建一个版本
可以发现在 refs/tags 下新增了一个 v0.0.1 文件夹,查看这个文件的内容
2.8 Annotation Tag
Annotation Tag(附注标签):一种特殊的 Tag,可以给 Tag 提供一些额外的信息
通过使用git tag -a 命令来完成附注标签的创建
会发现 tags 里面新增了 v0.0.2 以及 objects 里面新增了 74开头的文件
我们查看一下新增的 v0.0.2的内容以及 objects 里面新增的内容
会有 tag 以及 tagger 的信息,还有 message 的信息
2.9 追溯历史版本
获取当前版本代码
通过 Ref 指向的 Commit 可以获取唯一的代码版本
获取历史版本代码
首先,我们需要修改 readme.md 文件里面的内容,并进行提交。
我们可以发现新增了3个 object,我们可以通过 git log 查看最新的 commit 信息
再通过
git cat-file -p命令查看 这个commit 信息
可以发现里面多了个 parent commit信息,这个就是通过它来跟前一个 commit 进行串联。可以发现有一个新的 tree,这是因为这个新的 tree 的blob id 不一样。
因为文件内容发生了改变,我们可以查看一下这个文件内容
可以发现,文件内容发生了改变。
2.10 修改历史版本
1.commit --amend
通过这个命令可以修改最近一次 commit 信息,修改之后 commit id 会改变
2.rebase
通过 git rebase -i HEAD~3 可以实现对最近三个 commit 的修改
1.合并commit、2.修改具体的 commit message、3.删除某个commit
3.filter --branch
该命令可以指定删除所有提交中的某个文件或者全局修改邮箱地址等操作
2.11 Objects
修改 Commit 后我们可以发现 git obejct 又出现了变化,新增了 commit object ,但是旧的 commit object 并没有删除
悬空的Object
通过使用 git fsck --lost-found命令来查找仓库是否有悬空的 Object
2.12 Git GC
GC
通过 git gc 命令,可以删除一些不需要的 object,以及会对 object 进行一些打包压缩来减少仓库的体积。
Reflog
reflog 是用于记录操作日志,防止误操作后数据丢失,通过 reflog 来找到丢失的数据,手动将日志设置为过期。
指定时间
git gc purne=now 指定的是多久之前的对象,默认是两周前
查看树
2.13 Git clone & Pull & Futch
Clone
拉取完整的仓库到本地目录,可以指定分支,深度
Fetch
将远端某些分支最新代码拉取到本地,不会执行 merge 操作,会修改 refs/remote 内的分支信息,如果需要和本地代码合并需要手动操作
Pull
拉取远端某分支,并和本地代码进行合并,操作等同于 git fetch + git merge,也可以通过 git pull --rebase 完成 git fetch + git rebase 操作。
(可能存在冲突,需要解决冲突)
2.14 Git Push
Push 是将本地代码同步至远端的方式
常用 git push origin master 命令完成。
如果有冲突,前提是该分支就自己一人使用,或者团队内确认过可以修改历史则可以通过 git push origin master -f 来强制推送。