如何掌握Git的正确使用姿势并遵循最佳实践?

2026-04-12 05:011阅读0评论SEO资讯
  • 内容介绍
  • 相关推荐

本文共计3676个文字,预计阅读时间需要15分钟。

如何掌握Git的正确使用姿势并遵循最佳实践?

Git的正确使用姿势与最佳实践+本文不会全面介绍Git的很多命令,侧重于深入理解Git的基本原理,侧重于原理,带您分析.git文件夹下的东西是什么+Git是什么+基本原理+每个仓库都Git是什么+基本原理+每个仓库都包含哪些文件+文件的作用

Git 的正确使用姿势与最佳实践

本文并不会具体介绍 git 的很多命令,侧重于深入理解 git 的基本原理,侧重于原理,带你剖析 .git 文件夹下的东西到底是什么

Git 是什么

基本原理

  1. 每一个库都存有完整的提交历史,可以直接在本地进行代码提交
  2. 每次提交记录的都是完整的文件快照,而不是记录增量
  3. 通过 push 等操作来完成和远端代码的同步

优点

  1. 分布式开发,每一个库都是完整的提交流失,支持本地提交,强调个体
  2. 分支管理功能强大,方便团队管理,多人协同开发
  3. 校验和机制保证完整性,一般只添加数据,很少执行删除操作,不容器导致代码丢失

缺点

  1. 相对 SVN 来说更复杂,学习成本更高
  2. 对于大文件的支持不是很好(git-lfs 工具可以弥补这个功能)

Git 的出现就是为了当初为了维护 Linux 开发出现的,和 Linux 是同一个创始人

Git 的发展历史

  • Github 全球最大的代码托管平台

  • GitLab 全球最大的开源代码托管平台,项目的所有代码都是凯源的,便于自己在服务器上部署 GitLab

  • Gerrit 由谷歌开发的一个代码托管平台,Android 就托管在这个平台上,对于多仓库有更好的支持

  • Gitee 国内的代码托管平台

Git 基本使用方式

常见问题

  1. :tada: 为什么明明配置了 Git 配置,但是依然没有办法拉取代码

没有配置密钥,但最初遇到这个问题是在 push 到远端的时候一直无响应,后来发现要配置一下密钥,但是使用 github.com/

ssh 协议换 github.com/Tom-debug110/demo.git

配置好以后,可以打开 .git/config 看到一些东西

cat .git/config [core] repositoryformatversion = 0 filemode = true bare = false logallrefupdates = true ignorecase = true precomposeunicode = true [remote "origin"] url = github.com/Tom-debug110/demo.git fetch = +refs/heads/*:refs/remotes/origin/* [remote "origin_ssh"] url = git@github.com:Tom-debug110/demo.git fetch = +refs/heads/*:refs/remotes/origin_ssh/*

尤其是后面几行,就是 [remote] 相关的配置,甚至我们可以手动更改里面的配置项

其他配置

git remote rename <old> <new> #更改远端名称 git remote remove <name> #移除某一个远端 git remote -v #输出当前所有远端信息

能否设置同一个远端不同的 pushfetch

上面通过 git remote add 默认情况下, fetch push 是同一个源,但是是可以设置不同源的

git remote add origin git@github.com:Tom/project.git git remote set-url --add --push origin git@github.com:Other/project.git

通过 git remote -v 即可看到效果

接着来看看 .git/config 文件发生了什么变化

尤其是最后一条,相比于其他的 remote 多了一个 pushurl

http 和 ssh

访问远端仓库一般有两种协议,一种是 http ,另外一个就是ssh 无论是从安全性还是访问速度来看,都推荐使用 ssh 的方式来访问仓库,但是一定不能忘记配置公钥到服务器上,而且推荐使用 ed25519

具体方法

生成/添加SSH公钥 - Gitee.com

然后在 Github Gitee 平台中的个人账户设置中配置即可,如果要配置多个不同的密钥,参考以下:

Git配置多个SSH-Key - Gitee.com

Git Add

这里关于暂存区和工作区的介绍不再赘述

执行git add 前后的区别

<font color=pink>注意看线框中的部分</font>

多出来的这个东西,应该连起来才有意义,可以使用

git cat-file -p e69de29bb.....5319

输出的就是刚才我们README.md 中添加的内容

上面截图的时候忘记使用 vim 打开 README.md 文档添加内容啦,如果有读者读到,还请自行添加一些内容到 README.md 文档,否则将没有内容输出

Hello World Hello World

经过 git add . 操作,已经把文件添加到了暂存区

Git Commit

git commit -m 'add files'

执行命令后,发现

相比于 git add . 之后多了两个这些东西(暂时叫东西吧)

下面来看一下都是何方圣神

git cat-file -p 4690 #其实不输入完整也是可以的哈 # 输出 100644 blob 8254f875c6f8d41f9137917a46804bc5eb9e781f README.md

后面不就是我们的文件名吗,其实,上面的意思表示这个玩意是一个目录树类型的 object

再看一下另外一个

git cat-file -p b4e2af #输出 tree 4690e50c687a1e77c71bb5461ee3e4357df8d20c author mixinju <mixinju@outlook.com> 1676031166 +0800 committer mixinju <mixinju@outlook.com> 1676031166 +0800 add file

这不就是刚才的提交信息吗. 先看第一行, tree指明了目录树,后面的一串是不是很眼熟呢?不就是指明了目录树的校验和值吗

第二行指明了作者,第三行指明了提交者,大部分情况下作者就是提交者,但也有特殊情况吧

git log # 输出 commit b4e2af8233708a5dcb763f4dde699208d773af40 (HEAD -> main) Author: mixinju <mixinju@outlook.com> Date: Fri Feb 10 20:12:46 2023 +0800 add file (END)

出现的b4e2af8233708a5dcb763f4dde699208d773af40 不就是.git/object/ 下其中一个吗

:tangerine: **Git 中的 Object **

commit tree blob 在 Git 里面都统称为 Object ,除此之外还有一个 tagObject

  • Blob 存储文件的内容
  • Tree 存储文件的目录信息
  • Commit 存储提交信息,一个 commit 可以对应唯一版本的代码

除此之外,还有一个叫做 TagObject,下面说到Git tag 的时候会介绍到

:apple: 如何把这三个信息串联在一起呢?

  1. 通过 commit 找到 tree 信息,每一个 commit 对应着一个 tree的 id

  2. 通过 tree存储的信息,获取到对应的 目录树的信息(tree 中可能存有多个 blob)

  3. tree 中获取 blob 信息

➜ demo git:(main) tree .git/objects .git/objects ├── 46 │   └── 90e50c687a1e77c71bb5461ee3e4357df8d20c ├── 82 │   └── 54f875c6f8d41f9137917a46804bc5eb9e781f ├── b4 │   └── e2af8233708a5dcb763f4dde699208d773af40 ├── info └── pack 5 directories, 3 files ➜ demo git:(main) git cat-file -p b4e2 tree 4690e50c687a1e77c71bb5461ee3e4357df8d20c author mixinju <mixinju@outlook.com> 1676031166 +0800 committer mixinju <mixinju@outlook.com> 1676031166 +0800 add file ➜ demo git:(main) git cat-file -p 4690 100644 blob 8254f875c6f8d41f9137917a46804bc5eb9e781f README.md ➜ demo git:(main) git cat-file -p 8254 Hello World Hello World ➜ demo git:(main)

:warning: 一个 tree Objects 可能含有多个 blob 比如下面:

Git Refs

Branch

先简单说一下分支吧

git branch dev1 # 基于当前分支创建一个 dev1 的分支,但是不切换过去,还需要手动切换 git branch -a # 列出远端和本地的所有分支 git branch -d dev1 # 删除 dev1 分支 git branch -m dev1 dev2 # 重命名dev1 分支为 dev2 git checkout -b dev2 # 创建一个 dev2 分支并切换过去 git switch -c dev2 # 创建一个 dev2 分支并且切换过去 git checkout dev2 # 从当前分支切换到 dev2 分支 git switch dev2 # 从当前分支切换到 dev2 分支

对于分支切换和创建都建议使用 git switch 命令

Ref

接下来看一下 .git/refs 文件夹里面的内容

tree .git/refs .git/refs ├── heads │   └── main └── tags

然后查看一下这个 main 里面保存着什么

cat .git/refs/heads/main b4e2af8233708a5dcb763f4dde699208d773af40

接着继续查看这个 校验和表示的内容

cat-file -p b4e2af8233708 #输出 tree 4690e50c687a1e77c71bb5461ee3e4357df8d20c author mixinju <mixinju@outlook.com> 1676031166 +0800 committer mixinju <mixinju@outlook.com> 1676031166 +0800 add file

会发现,这不就是刚才的那个提交吗?

现在新建一个分支( branch )来看看

git switch -c test Switched to a new branch 'test' tree .git/refs .git/refs ├── heads │   ├── main │   └── test └── tags 2 directories, 2 files

会发现在 .git/refs/heads/ 目录下多了一个 test 条目,接下来看一下这个 test 里面存储的什么

.git/refs/heads/test b4e2af8233708a5dcb763f4dde699208d773af40

会发现和上面的 main 是相同的校验值,也就是同一个 commit ,因为我们的 test 分支就是从 main 分支切换过来的,而且目前还没有在 test 分支上做任何的事情,自然就和 .main 分支一样,指向了同一个分支

Tag

标签一般表示一个稳定版本,指向的 commit 一般不会变更

如何掌握Git的正确使用姿势并遵循最佳实践?

git tag v1.0.0. # 创建一个 tag

来查看一下 .git/refs 中的变化

tag v1.0.0 tree .git/refs .git/refs ├── heads │   ├── main │   └── test └── tags └── v1.0.0 2 directories, 3 files

可以看到 .git/refs/tags 下多出来的一个文件(校验值)

cat .git/refs/tags/v1.0.0 b4e2af8233708a5dcb763f4dde699208d773af40

还是 main 分支上的最后一个 commit

Annotation Tag

这个是附注标签,可以给 tag 添加一些额外的信息

git tag -a v2.0.0 -m "add feature1"

使用 -m 选项来添加附注,继续查看 .git/refs/tags 下变化

git tag -a v2.0.0 -m "add feature1" tree .git/refs/tags .git/refs/tags ├── v1.0.0 └── v2.0.0 0 directories, 2 files cat .git/refs/tags/v2.0.0 b63b9bc0d5c2aa210791266f20f5386eb50178de

这个时候我们会发现,此时的这个校验值已经不再是最新的那个 commit 啦. 查看 .git/objects 会发现新增了一个文件(夹)

使用 git cat-file 查看这个 id

这个和前面提到的那个 tag Object 就对应上了

总结一下

  1. refs 文件存储的内容就是对应的 commit id 可以把 ref 当作一个指针,指向对应的。commit 来表示当前 ref 对应的版本

  2. refs/heads 前缀表示的是分支(branch), 除此之外还有其他种类的 ref ,比如 refs/tags 前缀表示的是标签

追溯历史代码

:baby_bottle: 获取当前版本代码

可以通过 ref 指向的 commit 可以获取唯一的代码版本

:game_die: 获取历史版本代码

commit 里面存有 parent commit 字段,通过 commit 的串联获取历史版本代码

我们上面没有看到这个字段是因为没有进行连续的多个提交,就是没有产生迭代,自然也就没有 parent 只说啦

echo "Hello world KKKKKKKKKKK" > README.md git add . git commit -m 'add kkkkk'

查看 .git/objects 下的文件

新增了三个 object 其实这三个 object 分别是一个 commit 存储提交信息,一个 blob 存储文件信息,一个 tree 存储目录树信息

然后查看 commit ,到底哪一个是 commit 呢,使用 git log 来查看一下

q 退出即可

查看这个 commit 对应的信息

注意看,这里就出现了 parent 字段,而且的确是上一次 commitid ,同时,main 分支也更新到了最新的 commit ,在 .git/refs/heads

下,查看 main 分支当前的指向

修改历史版本

  • :lantern: commit --amend

通过这个命令来修改最近一次提交的 commit 信息,<font color=pink>修改之后的 commit id 会发生变化</font>,具体的不再通过查看 id 的形式演示了,就给一个图示吧

graph TD; A((commit1)) B((commit2)) C((commit3)) D(commit4 add file) E(修改commit4 提交信息) F((commit5)) A -->B B -->C C -.废弃.->D C -->E E -->F

其中的 commit4 也被称为悬空的 Object 可以使用 git fsck --lost-found 来查找这个悬空的 commit

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

  • :ear_of_rice: rebase

先学习一下使用吧,下面都是比较权威、清晰的讲解,建议先看文档,再看视频.

Git - 变基 (git-scm.com)

git rebase: 人生无法重来,但代码可以!

建议实际操作一下,就会对这两个玩意有更清楚的认识啦

总结

git rebase 是非常强大的命令,要搞懂它的基本使用,注意一点就是不要对还有他人引用进行 rebase 操作

git rebase的时候捅娄子了,怎么办?在线等…… - 掘金 (juejin.cn)

本文共计3676个文字,预计阅读时间需要15分钟。

如何掌握Git的正确使用姿势并遵循最佳实践?

Git的正确使用姿势与最佳实践+本文不会全面介绍Git的很多命令,侧重于深入理解Git的基本原理,侧重于原理,带您分析.git文件夹下的东西是什么+Git是什么+基本原理+每个仓库都Git是什么+基本原理+每个仓库都包含哪些文件+文件的作用

Git 的正确使用姿势与最佳实践

本文并不会具体介绍 git 的很多命令,侧重于深入理解 git 的基本原理,侧重于原理,带你剖析 .git 文件夹下的东西到底是什么

Git 是什么

基本原理

  1. 每一个库都存有完整的提交历史,可以直接在本地进行代码提交
  2. 每次提交记录的都是完整的文件快照,而不是记录增量
  3. 通过 push 等操作来完成和远端代码的同步

优点

  1. 分布式开发,每一个库都是完整的提交流失,支持本地提交,强调个体
  2. 分支管理功能强大,方便团队管理,多人协同开发
  3. 校验和机制保证完整性,一般只添加数据,很少执行删除操作,不容器导致代码丢失

缺点

  1. 相对 SVN 来说更复杂,学习成本更高
  2. 对于大文件的支持不是很好(git-lfs 工具可以弥补这个功能)

Git 的出现就是为了当初为了维护 Linux 开发出现的,和 Linux 是同一个创始人

Git 的发展历史

  • Github 全球最大的代码托管平台

  • GitLab 全球最大的开源代码托管平台,项目的所有代码都是凯源的,便于自己在服务器上部署 GitLab

  • Gerrit 由谷歌开发的一个代码托管平台,Android 就托管在这个平台上,对于多仓库有更好的支持

  • Gitee 国内的代码托管平台

Git 基本使用方式

常见问题

  1. :tada: 为什么明明配置了 Git 配置,但是依然没有办法拉取代码

没有配置密钥,但最初遇到这个问题是在 push 到远端的时候一直无响应,后来发现要配置一下密钥,但是使用 github.com/

ssh 协议换 github.com/Tom-debug110/demo.git

配置好以后,可以打开 .git/config 看到一些东西

cat .git/config [core] repositoryformatversion = 0 filemode = true bare = false logallrefupdates = true ignorecase = true precomposeunicode = true [remote "origin"] url = github.com/Tom-debug110/demo.git fetch = +refs/heads/*:refs/remotes/origin/* [remote "origin_ssh"] url = git@github.com:Tom-debug110/demo.git fetch = +refs/heads/*:refs/remotes/origin_ssh/*

尤其是后面几行,就是 [remote] 相关的配置,甚至我们可以手动更改里面的配置项

其他配置

git remote rename <old> <new> #更改远端名称 git remote remove <name> #移除某一个远端 git remote -v #输出当前所有远端信息

能否设置同一个远端不同的 pushfetch

上面通过 git remote add 默认情况下, fetch push 是同一个源,但是是可以设置不同源的

git remote add origin git@github.com:Tom/project.git git remote set-url --add --push origin git@github.com:Other/project.git

通过 git remote -v 即可看到效果

接着来看看 .git/config 文件发生了什么变化

尤其是最后一条,相比于其他的 remote 多了一个 pushurl

http 和 ssh

访问远端仓库一般有两种协议,一种是 http ,另外一个就是ssh 无论是从安全性还是访问速度来看,都推荐使用 ssh 的方式来访问仓库,但是一定不能忘记配置公钥到服务器上,而且推荐使用 ed25519

具体方法

生成/添加SSH公钥 - Gitee.com

然后在 Github Gitee 平台中的个人账户设置中配置即可,如果要配置多个不同的密钥,参考以下:

Git配置多个SSH-Key - Gitee.com

Git Add

这里关于暂存区和工作区的介绍不再赘述

执行git add 前后的区别

<font color=pink>注意看线框中的部分</font>

多出来的这个东西,应该连起来才有意义,可以使用

git cat-file -p e69de29bb.....5319

输出的就是刚才我们README.md 中添加的内容

上面截图的时候忘记使用 vim 打开 README.md 文档添加内容啦,如果有读者读到,还请自行添加一些内容到 README.md 文档,否则将没有内容输出

Hello World Hello World

经过 git add . 操作,已经把文件添加到了暂存区

Git Commit

git commit -m 'add files'

执行命令后,发现

相比于 git add . 之后多了两个这些东西(暂时叫东西吧)

下面来看一下都是何方圣神

git cat-file -p 4690 #其实不输入完整也是可以的哈 # 输出 100644 blob 8254f875c6f8d41f9137917a46804bc5eb9e781f README.md

后面不就是我们的文件名吗,其实,上面的意思表示这个玩意是一个目录树类型的 object

再看一下另外一个

git cat-file -p b4e2af #输出 tree 4690e50c687a1e77c71bb5461ee3e4357df8d20c author mixinju <mixinju@outlook.com> 1676031166 +0800 committer mixinju <mixinju@outlook.com> 1676031166 +0800 add file

这不就是刚才的提交信息吗. 先看第一行, tree指明了目录树,后面的一串是不是很眼熟呢?不就是指明了目录树的校验和值吗

第二行指明了作者,第三行指明了提交者,大部分情况下作者就是提交者,但也有特殊情况吧

git log # 输出 commit b4e2af8233708a5dcb763f4dde699208d773af40 (HEAD -> main) Author: mixinju <mixinju@outlook.com> Date: Fri Feb 10 20:12:46 2023 +0800 add file (END)

出现的b4e2af8233708a5dcb763f4dde699208d773af40 不就是.git/object/ 下其中一个吗

:tangerine: **Git 中的 Object **

commit tree blob 在 Git 里面都统称为 Object ,除此之外还有一个 tagObject

  • Blob 存储文件的内容
  • Tree 存储文件的目录信息
  • Commit 存储提交信息,一个 commit 可以对应唯一版本的代码

除此之外,还有一个叫做 TagObject,下面说到Git tag 的时候会介绍到

:apple: 如何把这三个信息串联在一起呢?

  1. 通过 commit 找到 tree 信息,每一个 commit 对应着一个 tree的 id

  2. 通过 tree存储的信息,获取到对应的 目录树的信息(tree 中可能存有多个 blob)

  3. tree 中获取 blob 信息

➜ demo git:(main) tree .git/objects .git/objects ├── 46 │   └── 90e50c687a1e77c71bb5461ee3e4357df8d20c ├── 82 │   └── 54f875c6f8d41f9137917a46804bc5eb9e781f ├── b4 │   └── e2af8233708a5dcb763f4dde699208d773af40 ├── info └── pack 5 directories, 3 files ➜ demo git:(main) git cat-file -p b4e2 tree 4690e50c687a1e77c71bb5461ee3e4357df8d20c author mixinju <mixinju@outlook.com> 1676031166 +0800 committer mixinju <mixinju@outlook.com> 1676031166 +0800 add file ➜ demo git:(main) git cat-file -p 4690 100644 blob 8254f875c6f8d41f9137917a46804bc5eb9e781f README.md ➜ demo git:(main) git cat-file -p 8254 Hello World Hello World ➜ demo git:(main)

:warning: 一个 tree Objects 可能含有多个 blob 比如下面:

Git Refs

Branch

先简单说一下分支吧

git branch dev1 # 基于当前分支创建一个 dev1 的分支,但是不切换过去,还需要手动切换 git branch -a # 列出远端和本地的所有分支 git branch -d dev1 # 删除 dev1 分支 git branch -m dev1 dev2 # 重命名dev1 分支为 dev2 git checkout -b dev2 # 创建一个 dev2 分支并切换过去 git switch -c dev2 # 创建一个 dev2 分支并且切换过去 git checkout dev2 # 从当前分支切换到 dev2 分支 git switch dev2 # 从当前分支切换到 dev2 分支

对于分支切换和创建都建议使用 git switch 命令

Ref

接下来看一下 .git/refs 文件夹里面的内容

tree .git/refs .git/refs ├── heads │   └── main └── tags

然后查看一下这个 main 里面保存着什么

cat .git/refs/heads/main b4e2af8233708a5dcb763f4dde699208d773af40

接着继续查看这个 校验和表示的内容

cat-file -p b4e2af8233708 #输出 tree 4690e50c687a1e77c71bb5461ee3e4357df8d20c author mixinju <mixinju@outlook.com> 1676031166 +0800 committer mixinju <mixinju@outlook.com> 1676031166 +0800 add file

会发现,这不就是刚才的那个提交吗?

现在新建一个分支( branch )来看看

git switch -c test Switched to a new branch 'test' tree .git/refs .git/refs ├── heads │   ├── main │   └── test └── tags 2 directories, 2 files

会发现在 .git/refs/heads/ 目录下多了一个 test 条目,接下来看一下这个 test 里面存储的什么

.git/refs/heads/test b4e2af8233708a5dcb763f4dde699208d773af40

会发现和上面的 main 是相同的校验值,也就是同一个 commit ,因为我们的 test 分支就是从 main 分支切换过来的,而且目前还没有在 test 分支上做任何的事情,自然就和 .main 分支一样,指向了同一个分支

Tag

标签一般表示一个稳定版本,指向的 commit 一般不会变更

如何掌握Git的正确使用姿势并遵循最佳实践?

git tag v1.0.0. # 创建一个 tag

来查看一下 .git/refs 中的变化

tag v1.0.0 tree .git/refs .git/refs ├── heads │   ├── main │   └── test └── tags └── v1.0.0 2 directories, 3 files

可以看到 .git/refs/tags 下多出来的一个文件(校验值)

cat .git/refs/tags/v1.0.0 b4e2af8233708a5dcb763f4dde699208d773af40

还是 main 分支上的最后一个 commit

Annotation Tag

这个是附注标签,可以给 tag 添加一些额外的信息

git tag -a v2.0.0 -m "add feature1"

使用 -m 选项来添加附注,继续查看 .git/refs/tags 下变化

git tag -a v2.0.0 -m "add feature1" tree .git/refs/tags .git/refs/tags ├── v1.0.0 └── v2.0.0 0 directories, 2 files cat .git/refs/tags/v2.0.0 b63b9bc0d5c2aa210791266f20f5386eb50178de

这个时候我们会发现,此时的这个校验值已经不再是最新的那个 commit 啦. 查看 .git/objects 会发现新增了一个文件(夹)

使用 git cat-file 查看这个 id

这个和前面提到的那个 tag Object 就对应上了

总结一下

  1. refs 文件存储的内容就是对应的 commit id 可以把 ref 当作一个指针,指向对应的。commit 来表示当前 ref 对应的版本

  2. refs/heads 前缀表示的是分支(branch), 除此之外还有其他种类的 ref ,比如 refs/tags 前缀表示的是标签

追溯历史代码

:baby_bottle: 获取当前版本代码

可以通过 ref 指向的 commit 可以获取唯一的代码版本

:game_die: 获取历史版本代码

commit 里面存有 parent commit 字段,通过 commit 的串联获取历史版本代码

我们上面没有看到这个字段是因为没有进行连续的多个提交,就是没有产生迭代,自然也就没有 parent 只说啦

echo "Hello world KKKKKKKKKKK" > README.md git add . git commit -m 'add kkkkk'

查看 .git/objects 下的文件

新增了三个 object 其实这三个 object 分别是一个 commit 存储提交信息,一个 blob 存储文件信息,一个 tree 存储目录树信息

然后查看 commit ,到底哪一个是 commit 呢,使用 git log 来查看一下

q 退出即可

查看这个 commit 对应的信息

注意看,这里就出现了 parent 字段,而且的确是上一次 commitid ,同时,main 分支也更新到了最新的 commit ,在 .git/refs/heads

下,查看 main 分支当前的指向

修改历史版本

  • :lantern: commit --amend

通过这个命令来修改最近一次提交的 commit 信息,<font color=pink>修改之后的 commit id 会发生变化</font>,具体的不再通过查看 id 的形式演示了,就给一个图示吧

graph TD; A((commit1)) B((commit2)) C((commit3)) D(commit4 add file) E(修改commit4 提交信息) F((commit5)) A -->B B -->C C -.废弃.->D C -->E E -->F

其中的 commit4 也被称为悬空的 Object 可以使用 git fsck --lost-found 来查找这个悬空的 commit

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

  • :ear_of_rice: rebase

先学习一下使用吧,下面都是比较权威、清晰的讲解,建议先看文档,再看视频.

Git - 变基 (git-scm.com)

git rebase: 人生无法重来,但代码可以!

建议实际操作一下,就会对这两个玩意有更清楚的认识啦

总结

git rebase 是非常强大的命令,要搞懂它的基本使用,注意一点就是不要对还有他人引用进行 rebase 操作

git rebase的时候捅娄子了,怎么办?在线等…… - 掘金 (juejin.cn)