对git更好的理解

This commit is contained in:
yinkanglong
2023-12-27 23:29:12 +08:00
parent 9c622e3441
commit 8185de976e
13 changed files with 207 additions and 131 deletions

View File

@@ -8,6 +8,8 @@ Git的本地操作
> * 分支操作,用于实现分布式管理。空间管理
> * 远程操作,用于远程仓库交互实现多人合作。时空共享
![](image/2023-12-27-22-24-10.png)
## 1 git安装
- Linux上通过命令行能够很轻松的部署好git

View File

@@ -1,61 +0,0 @@
## 10 标签管理
### **创建标签**
```
git tag v1.0
```
对当前版本打标签为v1.0
```
git tag
```
查看所有已经创建的标签
```
git tag v0.9 6.225
```
对指定id的版本打标签
```
git show v0.9
```
查看标签信息
```
git tag -a v0.1 -m "version 0.1 released" 3628164
```
创建带有标签说明的标签
### **操作标签**
```
git tag -d v0.1
```
删除制定版本的标签
```
git push origin v1.0
```
推送某个标签到远程
```
git push origin --tags
```
一次性推送所有标签。
```
git tag -d v0.9
git push origin :refs/tags/v0.9
```
从远程删除标签,先在本地删除标签,然后将操作推送到远程。

View File

@@ -1,44 +1,6 @@
# 4 版本操作
# 2 版本操作
## 0 命令手册
### git git add 文件名。
* 作用:将文件由 工作区 添加到 暂存区,暂存文件
* git add --all 或者 git add -A 或者git add .(简写) 添加所有文件
* git add a.txt b.txt 同时添加两个文件
* git add *.js 添加当前目录下的所有js文件
### git commit
* 作用:将文件由 暂存区 添加到 仓库区
* git commit -m "提交说明"
### git checkout 文件名
* 作用:暂存区的内容恢复到工作区。
* git checkout 1.txt 将暂存区中1.txt文件恢复到工作区
### git status
* 作用:查看文件的状态
* 命令git status
* 命令git stauts -s 简化日志输出格式
### git log
* 作用:查看提交日志
* git log 只能查看当前head以及以前的日志
* git log --oneline 简洁的日志信息
* git reflog 查看所有的提交变更日志
### git reset
* 作用:版本回退,将代码恢复到已经提交的某一个版本中。
* git reset --hard 版本号 将代码回退到某个指定的版本(版本号只要有前几位即可)
* git reset --hard head~1将版本回退到上一次提交
## 1 git的工作流
### 提交工作流
## 1 提交工作流
* 工作区即自己当前分支所修改的代码git add xx 之前的!不包括 git add xx 和 git commit xxx 之后的。
* 暂存区:已经 git add xxx 进去,且未 git commit xxx 的。
* 本地分支已经git commit -m xxx 提交到本地分支的。
@@ -46,7 +8,31 @@
![](../Git/image/2021-06-15-11-04-57.png)
### 回滚工作流
### git add 文件名。
* 作用:将文件由 工作区 添加到 暂存区,暂存文件
* git add --all 或者 git add -A 或者git add .(简写) 添加所有文件
* git add a.txt b.txt 同时添加两个文件
* git add *.js 添加当前目录下的所有js文件
### git status
* 作用:查看文件的状态
* 命令git status
* 命令git stauts -s 简化日志输出格式
### git commit
* 作用:将文件由 暂存区 添加到 仓库区
* git commit -m "提交说明"
## 2 回滚工作流
### git reset
* 作用:版本回退,将代码恢复到已经提交的某一个版本中。
* git reset --hard 版本号 将代码回退到某个指定的版本(版本号只要有前几位即可)
* git reset --hard head~1将版本回退到上一次提交
在上传代码到远程仓库的时候,不免会出现问题,任何过程都有可能要回滚代码:
@@ -64,21 +50,28 @@ git reset --mixed HEAD^(和不带参数是一样的)
```
往前回退一个版本,并且将这次错误的提交的代码改动,放在工作区里。
### git revert
## 2 进阶操作Git撤销&回滚操作
git reset 和 get revert
使用一次新的提交会滚上一次提交的内容。
```
git revert
```
### git checkout
* 作用:暂存区的内容恢复到工作区。
* git checkout 1.txt 将暂存区中1.txt文件恢复到工作区
### 在工作区的代码
```
git checkout -- a.txt # 丢弃某个文件,或者
git checkout -- . # 丢弃全部
```
* 注意git checkout . 丢弃全部,也包括:新增的文件会被删除、删除的文件会恢复回来、修改的文件会回去。
* 注意:`git checkout - . `丢弃全部,也包括:新增的文件会被删除、删除的文件会恢复回来、修改的文件会回去。
* 这几个前提都说的是回到暂存区之前的样子。对之前保存在暂存区里的代码不会有任何影响。对commit提交到本地分支的代码就更没影响了。当然如果你之前压根都没有暂存或commit那就是回到你上次pull下来的样子了。
### 代码git add到缓存区并未commit提交
### 回滚场景
**代码git add到缓存区并未commit提交**
```
git reset HEAD . 或者
git reset HEAD a.txt
@@ -86,7 +79,7 @@ git reset HEAD a.txt
* 这个命令仅改变暂存区,并不改变工作区,这意味着在无任何其他操作的情况下,工作区中的实际文件同该命令运行之前无任何变化
### git commit到本地分支、但没有git push到远程
**git commit到本地分支、但没有git push到远程**
```
git log # 得到你需要回退一次提交的commit id
@@ -104,30 +97,26 @@ git reset --mixed HEAD^ # 此时代码保留,回到 git add 之前,默认
* --mixed默认只改变分支和暂存区的内容不会改变工作区的内容。
* --soft分支回退到指定版本不会改变暂存区和工作区。
### git push把修改提交到远程仓库
**git push把修改提交到远程仓库**
1. 通过git reset是直接删除指定的commit
```
git log # 得到你需要回退一次提交的commit id
git reset --hard
git push origin HEAD --force # 强制提交一次,之前错误的提交就从远程仓库删除
```
2. 通过git revert是用一次新的commit来回滚之前的commit
1. 通过git revert是用一次新的commit来回滚之前的commit
```
git log # 得到你需要回退一次提交的commit id
git revert # 撤销指定的版本,撤销也会作为一次提交进行保存
```
3. git revert 和 git reset的区别
1. git revert 和 git reset的区别
- git revert是用一次新的commit来回滚之前的commit此次提交之前的commit都会被保留
- git reset是回到某次提交提交及之前的commit都会被保留但是此commit id之后的修改都会被删除
### 场景
### 回滚案例
* 场景一糟了我刚把不想要的代码commit到本地仓库中了但是还没有做push操作
* 场景二:彻底完了,刚线上更新的代码出现问题了,需要还原这次提交的代码!
### 针对场景一
**场景一糟了我刚把不想要的代码commit到本地仓库中了但是还没有做push操作**
在未进行git push前的所有操作都是在“本地仓库”中执行的。我们暂且将“本地仓库”的代码还原操作叫做“撤销”
@@ -175,7 +164,7 @@ git reset [--hard|soft|mixed|merge|keep] [commit|HEAD]
```
### 针对场景二
**场景二:彻底完了,刚线上更新的代码出现问题了,需要还原这次提交的代码!**
已进行git push即已推送到“远程仓库”中。我们将已被提交到“远程仓库”的代码还原操作叫做“回滚”注意对远程仓库做回滚操作是有风险的需提前做好备份和通知其他团队成员
@@ -253,9 +242,9 @@ git push origin master -f
通过上述操作如果你想对历史多个commit进行处理或者可以选择git rebase -i只需删除对应的记录就好。rebase还可对 commit 消息进行编辑以及合并多个commit
## 3 进阶操作查看历史git log
## 3 历史工作流
### 基本使用
### git log
git log能够交互式显示历史信息包括以下内容
* 版本id
* 作者
@@ -288,7 +277,7 @@ Date: Wed Dec 21 11:20:12 2022 +0800
### 显示格式
```sh
-p按补丁显示每个更新间的差异比下一条- -stat命令信息更全
-p按补丁显示每个更新间的差异比下一条`--stat`命令信息更全
--stat显示每次更新的修改文件的统计信息每个提交都列出了修改过的文件以及其中添加和移除的行数并在最后列出所有增减行数小计
--graph显示ASCII图形表示的分支合并历史
—pretty使用其他格式显示历史提交信息可选项有oneline,short,medium,full,fuller,email,raw
@@ -318,7 +307,7 @@ Date: Wed Dec 21 11:20:12 2022 +0800
5. 按文件
1. - -(空格)或[没有]
1. `--`(空格)或[没有]
2. 有时你可能只对某个文件的修改感兴趣, 你只想查看跟某个文件相关的历史信息, 你只需要插入你感兴趣文件的路径[对,是路径,所以经常是不太好用]就可以了
3. 比如git log -- foo.py bar.py 只返回和foo.py或bar.py相关的commit
4. 这里的--是告诉Git后面的参数是文件路径而不是branch的名字. 如果后面的文件路径不会和某个branch产生混淆, 你可以省略- -比如git log foo.py
@@ -332,12 +321,12 @@ Date: Wed Dec 21 11:20:12 2022 +0800
3. 需要放到参数中的最后位置处
4. 如果分支名与文件名相同,系统会提示错 误,可通过--选项来指定给定的参数是分支名还是文件名
5. 比如在当前分支中有一个名为v1的文件同时还存在一个名为v1的分支
6. git log v1 -- 此时的v1代表的是分支名字后边是空的)
7. git log -- v1 此时的v1代表的是名为v1的文件
8. git log v1 v1 代表v1分支下的v1文件
6. git log v1 -- 此时的v1代表的是分支名字`--`后边是空的)
7. `git log -- v1` 此时的v1代表的是名为v1的文件
8. `git log v1 v1` 代表v1分支下的v1文件
7. 按内容
1. -S"<string>"-G"<string>"
1. `-S"<string>"`、`-G"<string>"`
2. 有时你想搜索和新增或删除某行代码相关的commit. 可以使用这条命令
3. 假设你想知道Hello, World!这句话是什么时候加入到项目里去的可以用git log -S"Hello,World!"
4. 另外:如果你想使用正则表达式去匹配而不是字符串, 那么你可以使用-G代替-S.
@@ -345,7 +334,7 @@ Date: Wed Dec 21 11:20:12 2022 +0800
6. 注:-S后没有"=",与查询内容之间也没有空格符
8. 按范围
1. git log <since>..<until>
1. `git log <since>..<until>`
2. 这个命令可以查看某个范围的commit
3. 这个命令非常有用当你使用branch做为range参数的时候. 能很方便的显示2个branch之间的不同
4. 比如git log master..featuremaster..feature这个range包含了在feature有而在master没有的所有commit同样如果是feature..master包含所有master有但是feature没有的commit
@@ -353,13 +342,13 @@ Date: Wed Dec 21 11:20:12 2022 +0800
9. 过滤掉merge commit
1. --no-merges
1. `--no-merges`
2. 默认情况下git log会输出merge commit. 你可以通过--no-merges标记来过滤掉merge commitgit log --no-merges
3. 另外如果你只对merge commit感兴趣可以使用—mergesgit log --merges
10. 按标签tag
1. git log v1.0
1. `git log v1.0`
2. 直接这样是查询标签之前的commit
3. 加两个点git log v1.0.. 查询从v1.0以后的提交历史记录(不包含v1.0)
@@ -371,4 +360,65 @@ Date: Wed Dec 21 11:20:12 2022 +0800
4. 其中commit可以是提交哈希值的简写模式也可以使用HEAD代替
5. HEAD代表最后一次提交HEAD^为最后一个提交的父提交等同于HEAD1
6. HEAD2代表倒数第二次提交
## 4 标签工作流
### 创建标签
```
git tag v1.0
```
对当前版本打标签为v1.0
```
git tag
```
查看所有已经创建的标签
```
git tag v0.9 6.225
```
对指定id的版本打标签
```
git show v0.9
```
查看标签信息
```
git tag -a v0.1 -m "version 0.1 released" 3628164
```
创建带有标签说明的标签
### 操作标签
```
git tag -d v0.1
```
删除制定版本的标签
```
git push origin v1.0
```
推送某个标签到远程
```
git push origin --tags
```
一次性推送所有标签。
```
git tag -d v0.9
git push origin :refs/tags/v0.9
```
从远程删除标签,先在本地删除标签,然后将操作推送到远程。

View File

@@ -1,5 +1,5 @@
## 7 Git的远程操作
## 4 Git的远程操作
远程操作主要是指在不同的仓库之间进行提交和代码更改。是一个明显的对等的分布式系统。其中本地个仓库与远程仓库不同的远程仓库之间都可以建立这种关系。这种关系之间的操作主要有pull和push。

View File

@@ -1,5 +1,5 @@
## 9 多人协作
## 5 多人协作
通过远程库的push和pull操作实现夺人合作

85
Git/6 基本原理.md Normal file
View File

@@ -0,0 +1,85 @@
# 基本原理
## 1 基本对象
### 简介
git仓库版本控制相关的数据都存储在git的数据库中可以将它看做一个简单的KV数据库存储在根目录的.git/文件夹下面。他的Key依赖哈希算法生成。
在git数据库中主要有三种类型的对象所有的对象都是一个KV对象的形式存储。
* Blob对象
* Tree对象
* Commit对象
每个对象都有有个ObjectId进行索引。每个ObjectId会指向一个具体类型的对象。
### git cat-file
命令可以访问git数据库中的对象根据objectId搜索对象的值。
```
-e check if <object> exists
-p pretty-print <object> content
-t show object type (one of 'blob', 'tree', 'commit','tag', ...)
-s show object size
```
![](image/2023-12-27-23-03-05.png)
### ObjectId
使用哈希算法sha-1生成ObjectId
* 加密长度结果一致
* 输入数据确定,输出结果不变。
* 输入数据不同,输出结果不同
### Blog对象
git是一个快照式文件管理系统。与SVN不同SVN将文件作为管理对象保存文件的增量修改内容是增量式版本控制。只要文件有变更就会生成一个新的Blob并根据Blob的内容生成ObjectId如果文件没有变更则不会保存新文件直接复用直接ObjectId的对象。如果两个文件的内容王权相同也会直接复用Blob不会生成新的Blob对象。
优点是,如果版本切换,能够快速地根据当前的版本快照显示当前仓库中的所有内容,而不需要增量的查看某个文件的修改记录,组合出当前版本的内容。
### Tree对象
Tree对象存储了当前目录的结构。相当于目录结构的一个快照。
一个tree对象存储了多个Blob对象和Blob对象对应的文件路径。
### Commint对象
commit对象主要包括一下内容
* TreeObjectId指针指向一个唯一的目录结构快照。
* 父提交parentObjectId指针指向父提交同一个Commit可能有两个父提交。
* 创建者Author包括创建者名称、创建者邮箱、创建日期Date。是git commit命令执行时原始的数据。
* 提交Commit提交者的名称、提交者邮箱、提交日期Date。是Commit经过合并和merge后的最新的数据。
* 提交信息Messagegit commit提交的时候的说明。
### 分支指针
git通过不同类型的指针实现分支管理。不同的指针指向不同的Commit表示不同的分支。
* Head是工作去当前工作区的指针。
* 暂存区的指针
* master、header是提交去不同分支的指针
![](image/2023-12-27-23-22-21.png)
## 版本控制原理
git上的版本控制在纵向时间维度上基于Commit Object组成的链进行管理的。在横向空间维度上基于Commit、Tree、Blob组成的树状结构进行存储。
### 提交流原理
1. git add 生成新的Blob然后构建新的Tree并将暂存区的指针指向新的Tree
2. git commit 生成新的commit指向新的Tree。
3. 最后将当前分支的指针指向新的commit
![](image/2023-12-27-23-21-14.png)
### 分支合并原理
1. 如果fast-forward模式则直接改变指针的指向即可。
![](image/2023-12-27-23-25-53.png)
2. 如果存在冲突则会生成新的commit其父指针同时指向之前的两个commit。
![](image/2023-12-27-23-27-11.png)

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 705 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 309 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 187 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 161 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 478 KiB

BIN
abc.txt Normal file

Binary file not shown.