git
是一个分布式版本控制软件,最初由 林纳斯·托瓦兹
开发,于2005年以GPL许可协议发布。最初目的是为了更好地管理 Linux 内核开发而设计。
安装
brew install git
yum install git -y
Git 简单工作原理
文件存放示例
$ mkdir test
$ cd test
$ git init
$ echo "hello git" >> README.md
# 获取 hash
$ git hash-object -w README.md
8d0e41234f24b6da002d962a26c2495ea16a425f
# 通过 hash 查看文件内容
$ git cat-file -p 8d0e41234f24b6da002d962a26c2495ea16a425f
hello git
# 查看文件存放位置,通过 hash 值存放,默认压缩的
$ tree .git/objects
.git/objects
├── 8d
│ └── 0e41234f24b6da002d962a26c2495ea16a425f
├── info
└── pack
3 directories, 1 file
- 修改文件,查看多了一个文件,当前看到每次更改都在 objects 中生成一个文件
$ echo "hello readme" >> README.md
$ git hash-object -w README.md
f64d6c4b7c1485b2047a2fad59ae22a34f7958e1
$ git cat-file -p f64d6c4b7c1485b2047a2fad59ae22a34f7958e1
hello git
hello readme
$ tree .git/objects
.git/objects
├── 8d
│ └── 0e41234f24b6da002d962a26c2495ea16a425f
├── f6
│ └── 4d6c4b7c1485b2047a2fad59ae22a34f7958e1
├── info
└── pack
4 directories, 2 files
目录介绍
目录结构:
$ tree .git
.git
├── HEAD
├── config
├── description
├── hooks
│ ├── applypatch-msg.sample
│ ├── commit-msg.sample
│ ├── fsmonitor-watchman.sample
│ ├── post-update.sample
│ ├── pre-applypatch.sample
│ ├── pre-commit.sample
│ ├── pre-merge-commit.sample
│ ├── pre-push.sample
│ ├── pre-rebase.sample
│ ├── pre-receive.sample
│ ├── prepare-commit-msg.sample
│ ├── push-to-checkout.sample
│ └── update.sample
├── info
│ └── exclude
├── objects
│ ├── 8d
│ │ └── 0e41234f24b6da002d962a26c2495ea16a425f
│ ├── f6
│ │ └── 4d6c4b7c1485b2047a2fad59ae22a34f7958e1
│ ├── info
│ └── pack
└── refs
├── heads
└── tags
10 directories, 19 files
$ git write-tree
4b825dc642cb6eb9a060e54bf8d69288fbee4904
# 查看类型和内容,blob表示文件,tree表示目录
$ git cat-file -t 4b825dc642cb6eb9a060e54bf8d69288fbee4904
tree
$ git cat-file -p 4b825dc642cb6eb9a060e54bf8d69288fbee4904
100644 blob f64d6c4b7c1485b2047a2fad59ae22a34f7958e1 README.md
$ tree .git/objects
.git/objects
├── 8d
│ └── 0e41234f24b6da002d962a26c2495ea16a425f
├── ce
│ └── bf2d7ab8c95ddddbfb83fe6c7a867624c12556
├── f6
│ └── 4d6c4b7c1485b2047a2fad59ae22a34f7958e1
├── info
└── pack
5 directories, 3 files
# commit
$ git commit-tree 4b825dc642cb6eb9a060e54bf8d69288fbee4904 -m "init"
1568b79e0eef703d9b47cf31c7c5c107d2fac4f3
# 查看 hash 类型为 commit
$ git cat-file -t 1568b79e0eef703d9b47cf31c7c5c107d2fac4f3
commit
# commit 信息
$ git cat-file -p 1568b79e0eef703d9b47cf31c7c5c107d2fac4f3
tree 4b825dc642cb6eb9a060e54bf8d69288fbee4904
author xiexianbin <me@xiexianbin.cn> 1653992896 +0800
committer xiexianbin <me@xiexianbin.cn> 1653992896 +0800
init
# tree
$ tree .git/objects
.git/objects
├── 15
│ └── 68b79e0eef703d9b47cf31c7c5c107d2fac4f3
├── 4b
│ └── 825dc642cb6eb9a060e54bf8d69288fbee4904
├── 8d
│ └── 0e41234f24b6da002d962a26c2495ea16a425f
├── f6
│ └── 4d6c4b7c1485b2047a2fad59ae22a34f7958e1
├── info
└── pack
6 directories, 4 files
$ echo "xie" >> README.md
$ git update-index --add README.md
$ git write-tree
b5795a17ef798c0455806950166dca8bce620a18
$ git commit-tree -m "update" b5795a17ef798c0455806950166dca8bce620a18 -p 1568b79e0eef703d9b47cf31c7c5c107d2fac4f3
886338f874daa718bb3afbed39a0b95a8e7d3e24
关联分支
$ echo 886338f874daa718bb3afbed39a0b95a8e7d3e24 > .git/refs/heads/main
$ git log
commit 886338f874daa718bb3afbed39a0b95a8e7d3e24 (HEAD -> main)
Author: xiexianbin <me@xiexianbin.cn>
Date: Tue May 31 18:31:45 2022 +0800
update
commit 1568b79e0eef703d9b47cf31c7c5c107d2fac4f3
Author: xiexianbin <me@xiexianbin.cn>
Date: Tue May 31 18:28:16 2022 +0800
init
版本信息
$ ls .git/refs
heads # head 信息
original # 源
remotes # 远程分支
tags # tags 标签
fetch vs pull
- fetch 下载远程仓库 refs 信息到
.git/refs/remotes
,下载缺失的 object,同时更新 .git/FETCH_HEAD
(示例:373c59b0f070213c63b4d007a3d3fcf9502723d7 branch 'main' of github.com:xiexianbin/xiexianbin.github.io
),即本地当前 fetch 的位置
- 信息指向:
.git/refs/remotes/origin/HEAD
-> .git/refs/remotes/origin/main
-> id
- pull
查看 ref
git show-ref
查看源端
git remote show origin
清除已删除远程分支
删除远端不存在的本地分支
git remote prune origin
或
git fetch -p
扩展
替代产品