Git 基本原理与使用 | 青训营笔记

136 阅读4分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的第4篇笔记

基本介绍

原理:

  1. 每个库都有完整的提交历史,可以在本地进行代码提交;
  2. 每次提交记录都是完整的文件快照,而不是记录增量;
  3. 通过 Push Pull 等操作完成和远端代码的同步。 优点:
  4. 分布式开发,每个库都有完整的提交历史,支持本地提交,强调个体;
  5. 分支管理功能强大,方便团队合作,多人协作开发;
  6. 校验和机制保证完整性,一般只添加数据,很少执行删除操作,不容易导致代码丢失。 缺点:
  7. 相对 SVN 更复杂,学习成本更高;
  8. 对于大文件支持一般(可使用 git-lfs 弥补)

init

初始化一个 Git 仓库

git init

参数: --initial-branch 初始化的分支 --bare 创建一个裸仓库(纯 Git 目录,没有工作目录) --template 通过模板创建预先构建好的自定义 Git 目录

config

基本命令

git config --system 配置项 参数
git config --global 配置项 参数
git config --local 配置项 参数

配置命令别称

git config --global alias.cin "commit --amend --no-edit"
# cin = commit --amend --no-edit

remote

远程仓库管理

基本使用

查看所有远程服务器

git remote -v

输出示例

origin_http     https://github.com/git/git.git (fetch)
origin_http     https://github.com/git/git.git (push)

查看配置文件,可以直接修改 .git/config 配置文件以修改 remote。

cat .git/config
​
[core]
        repositoryformatversion = 0
        filemode = false
        bare = false
        logallrefupdates = true
        symlinks = false
        ignorecase = true
[remote "origin_ssh"]
        url = git@github.com:git/git.git
        fetch = +refs/heads/*:refs/remotes/origin_ssh/*
[remote "origin_http"]
        url = https://github.com/git/git.git
        fetch = +refs/heads/*:refs/remotes/origin_http/*

同一个 Origin 设置不同的 Push 和 Fetch 路径:

git remote set-url --add --push origin [push url]
git remote set-url --add --fetch origin [push url]

免密配置

# 将密码保存在内存中
git config --global credential.helper cache --timeout=3600'
# 将密码保存在磁盘中
git config --global credential.helper store 

SSH Remote

通过 SSH 公私钥的机制实现免密访问,密钥类型有:

  • DSA (不推荐)
  • RSA(不推荐)
  • ECDSA
  • ED25519

add & commit

git add .

将工作区的修改加入暂存区,存储于 .git/objects/ 文件夹中。

git commit -m "readme"
[master (root-commit) 0fbab7f] readme
 1 file changed, 1 insertion(+)
 create mode 100644 README.md
​
git cat-file -p  0fbab7f
tree db78f3594ec0683f5d857ef731df0d860f14f2b2
author XXX 1653394554 +0800
committer XXX 1653394554 +0800
​
readme

通过 Commit 的 TreeID 寻找 Tree,寻找

Objects

Blob:存储文件内容 Tree:存储文件的目录信息 Commit:存储提交信息

  1. 通过 Commit 寻找 TreeID
  2. 通过 TreeID 获取目录树
  3. 从目录树中获取 BlobID
  4. 通过 BlobID 获取文件文件内容

Tag:存储版本信息以及版本说明

Tag

git tag v0.0.1
git tag -a v0.0.2 -m "Add feature 1"
cat .git/refs//tags/v0.0.1
0fbab7ff5def6345e53a42c878718f21cc4c43ff
# 这里是 Commit ID,指向一个 Commit
cat .git/refs/tags/v0.0.2
9559fc5035d6b5764b32096af91042e72e1b243b
# 指向一个 Tag Object
​
git cat-file -p 9559fc5035d6b5764b32096af91042e72e1b243b
object 0fbab7ff5def6345e53a42c878718f21cc4c43ff # 这里还是 Commit ID
type commit
tag v0.0.2
tagger XXX 1653442595 +0800
​
add feature 1

追溯历史版本

进行第二次提交,ref 指向了新的版本,查看 Object 内容:

git cat-file -p 31db32cf6c374bd21e1ddcb740da705fc41cf6e6
tree 22e3db29d5f8afddff55a957299a6fdca1713c21
parent 0fbab7ff5def6345e53a42c878718f21cc4c43ff #通过 parent 获取上一个版本
author XXX 1653443065 +0800
committer XXX 1653443065 +0800
​
update README

修改历史版本

# 修改最近的一次 commit
commit --amend
# 修改最近 N 次 Commit
rebase -i HEADD~N
# 从所有提交中删除某个文件
filter --branch 

修改 Commit:新增 Commit Object,不删除旧的 Commit Object

查看悬空的 Commit

git fsck --lost-found   
Checking object directories: 100% (256/256), done.
dangling blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
dangling commit 31db32cf6c374bd21e1ddcb740da705fc41cf6e6

删除多余的 Object(Git GC)

Reflog 记录操作日志,防止误操作后数据丢失

 git reflog expire --expire=now --all
git gc
#指定修剪多久之前的对象,默认两周前
git gc --prune=now 

会将 Object 打包为 Pack

Clone & Pull & Fetch

Clone:拉取完整仓库,可以指定分治

Fetch:将某些分支拉到本地

Pull:git fetch + git merge

Push

git push origin master

代码合并

Fast-forward:不产生 Merge 节点

git merge test --ff-only

Tree-way-merge:产生新的 Merge 节点

git merge test --no-ff

\