add git rebase

This commit is contained in:
notfreshmbp
2023-02-02 19:23:49 +08:00
parent 2dfefd23bc
commit 8233cf12d0
2 changed files with 92 additions and 71 deletions

View File

@@ -15,7 +15,6 @@
1. 什么是索引区?工作区?版本区?
2. git diff 命令如何使用?
3.
# Git应用场景考试

162
README.md
View File

@@ -70,7 +70,7 @@ git的入门是真的难.
使用帮助系统, 如果你对 git add 或者 git log 命令不熟悉, 你可以使用 git log --help, 或者 man git 命令. 这是 Linux 的本地文档帮助系统.
使用官方在线文档系统. 网址是 https://git-scm.com, 点击去打开 documentation, 里面有详细的内容, 文档分为三个部分, reference, book( ProGit book), videos.
分别指的是 经典的文档系统, 这里面全部用英文写的, 里面有对于各个子命令的解读和各种参数的详细说明, 关于 Git 的一本在线书籍, 阅读起来更友好, 还有就是对于 Git的介绍视频. 可能视频暂时无法观看, 估计是用 Youtube 播放的.
分别指的是 经典的文档系统, 这里面全部用英文写的, 里面有对于各个子命令的解读和各种参数的详细说明, 关于 Git 的一本在线书籍, 阅读起来更友好, 还有就是对于 Git的介绍视频. 可能视频暂时无法观看, 估计是用 Youtube 播放的(需要翻墙).
我重点推荐那本 Git 的书(待会给出来链接) . 里面有各个语言版本的, 其中中文的链接在这里, https://git-scm.com/book/zh/v2 , 需要提的一点的是, 中文的翻译质量稍微低了一点, 如果英语好的同学自己去看英文.
@@ -86,6 +86,8 @@ git的入门是真的难.
最后还有去 stackoverflow.com 或者知乎等问答网站找自己想要的答案.
引用别人说的句话,**对于工具的学习,我认为应该多做减法,只捡最有用的学,那些奇技淫巧不学也罢,应该把时间投入更有价值的事情中**。
## 优秀的教程和文档
@@ -146,12 +148,14 @@ http://www.ruanyifeng.com/blog/2015/12/git-cheat-sheet.html
### 问: 这个教程我能学到什么?
答: 可以学到关于 Git 的基础入门知识和工作实用技巧,以及一些其他教程没有说透的知识点。
答: 可以学到关于 Git 的基础入门知识和工作实用技巧,以及一些其他教程没有说透的知识点。所以,本教程可以是上文章节“优秀的教程和文档”的补充,你可以先去阅读那些教材,等你有需要更多的文章或者补充细节,或者查漏补缺,再回过头来阅读本文。
### 问: 需要知道 Git 和其他版本控制工具的区别吗?
答: 不是必须知道的, 你至少需要了解 Git 就好了, 我认为做比较这种事需要了解或者熟悉比较对象. 如果你熟悉 Git或者 SVN, 或者 CVS, 还有很多别的版本管理工具, 你心里大概有数.
答: 不是必须知道的, 你至少需要了解 Git 就好了, 我认为做比较这种事需要了解或者熟悉比较对象. 如果你熟悉 Git或者 SVN, 或者 CVS, 还有很多别的版本管理工具, 你心里大概有数
我认为“比较”这件事本身是需要对被比较的事物都有一个了解,帮助用户从旧的迁移到新的,如果你不了解被比较的对象,就不需要知道区别,反而省去了历史包袱。
@@ -160,9 +164,7 @@ http://www.ruanyifeng.com/blog/2015/12/git-cheat-sheet.html
但是命令行因为不需要构建 GUI(用户界面), 开发工作量小, 可以接受的参数多, 使用灵活, 所以功能非常的强大. 缺点刚刚也说了, 就是要记住很多命令.
命令行还有一个缺点, 就是阅读体验不好, 尤其是比较两个文件差异的时候, 可读性比较差.
而 GUI 则操作简单, 非常的人性化, 上手很快, 阅读体验好. 但是实现的功能是命令行的子集.
用哪一种, 看自己的与需要, **我本人是两者结合着用**, 我喜欢的 GUI 是 Github 的 Git 本地客户端.
用哪一种, 看自己的与需要, **我本人是两者结合着用**, 我喜欢的 GUI 是 Github出品 的 Git 本地客户端 [GitHub Desktop](https://desktop.github.com/).
@@ -235,6 +237,12 @@ Git 主要的目的是通过操纵这三棵树来以更加连续的状态记录
为什么要有三个区呢(工作目录、暂存区、提交历史区)?
工作目录和提交历史我们可以理解,提交历史也可以理解,但是为什么要有暂存区?直接从工作目录到提交历史不可以吗?如果没有暂存区,我们工作目录的所有修改应该都要一次全部的放入提交历史了。所以说,暂存区的存在允许了指定一部分修改作为一次提交。
最后,使用工作场景回忆一下开始使用 Git 的命令, 然后下面挑几个常用的命令来重点介绍一下.
1. 下载别人的仓库: git clone 仓库地址
@@ -255,27 +263,31 @@ Git 主要的目的是通过操纵这三棵树来以更加连续的状态记录
### git 中的提交
在 git 中, 提交是最核心的概念, 提交涉及到很多的底层概念, 我知道的也不多, 因为我也不是专门研究 git的, 如果我专门去研究, 平时又用不到, 那么很快就会忘记.
在 git 中, 提交是最核心的概念, 提交涉及到很多的底层概念, 我知道的也不多, 因为我也不是专门研究 git的, 如果我专门去研究, 平时又用不到, 那么很快就会忘记
一次 git commit 就是一次提交, 会生成一个 40 位长的 16 进制 sha1编号, 根据文件大小, 时间,等多方因素生成的可保证唯一的一哈希字符.
一次提交记录了提交时间,提交人, 提交的标题, 详细的消息, 等等等等...
### git 中的分支
TODO
使用 git branch BRANCH_NAME [commit_hash | branch name | tag name] 来创建分支。如果不填写 commit_hash | branch name | tag name就会以当前的指针为参考建一个分支。
git checkout -b NEW_BRANCH_NAME [commit_hash | branch_name | tag_name] 也会创建一个分支,并且理解切换到该分支上去。
### 提交和分支的关系
假设有 10 个分支, 按时间从早到晚, C1, C2,.., C10.
有一个分支 master. master 现在指向 C5,起点是 C1.
假设有 10 个提交, 按时间从早到晚, C1, C2,.., C10.
有一个分支 master. master 现在指向 C5,起点是 C1.
在C2 的时候, 创建了branchX, 然后 branchX 目前指向 C5, 包含了 4 个分支, 那么如果删掉分支 branchX, C2~C5会被删除吗?
不会. 因为 master 还有一段指向 C2~C5
再假设, 在C2 的时候, 创建了branchX, 然后 branchX 目前指向 C10, 包含了 9 个分支, 那么如果删掉分支 branchX, 哪些分支被删除?
不会. 因为 master 还有一段指向 C2~C5
再假设, 在C2 的时候, 创建了branchX, 然后 branchX 目前指向 C10, 包含了 9 个提交, 那么如果删掉分支 branchX, 哪些提交被删除?
自然是 C6-C10, 因为包含他们的分支 branchX 已经被删除了.
而 C2-C5 不能被删除, 因为还有 master 分支包含着它们.
@@ -293,14 +305,14 @@ TODO
## git 高频命令
我们经常使用到
我们经常使用到几个命令,而其他的命令相对较少,因此我们需要对这些常用的命令多多掌握和学习。
git add、git status、git log、git commitgit checkout, git push等命令是比较常见的。
### git add命令和 git status 命令
git管理下的文件有几个状态如下图所示
- 没有跟踪的状态
@@ -375,8 +387,6 @@ index e69de29..58c9bdf 100644
### git log 命令
git log 查看一个文件的提交历史, 也可以查看整个仓库的的提交历史。
@@ -404,7 +414,7 @@ Date: Thu Jun 18 10:42:32 2020 +0800
展示了太多没用的信息,当我们想要查看更加详细的、可视化的信息的时候,我们可以在终端执行如下操作:
```shell
git config --global alias.l "log --color --graph --all --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s%Creset %Cgreen(%cd) %C(bold blue)<%an>%Creset' --abbrev-commit --date='format:%Y- %m-%d %H:%M:%S'"
git config --global alias.l "log --color --graph --all --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s%Creset %Cgreen(%cd) %C(bold blue)<%an>%Creset' --abbrev-commit --date='format:%Y-%m-%d %H:%M:%S'"
```
这条命令为 git log 配置了一个别名,附带了很多的参数,我们可以使用 git l 查看效果:
@@ -421,17 +431,11 @@ git config --global alias.l "log --color --graph --all --pretty=format:'%Cred%h%
* c1a68d9 - create 1.txt (2020-06-18 08:42:29) <notfreshmbp>
```
具体的参数可以去官方该网站或者 ProGit 上查找对应配置信息,方便个性化设置。
我们还可以给 git log 增加一个参数, git log FILE_PATH, 以此查看某个文件的提交信息。
此外git log 还支持 grep 命令查询提交信息(只支持提交信息查询),使用 `git log *--all --grep=KEY_WORD` 可以搜索某些提交
此外git log 还支持 grep 命令查询提交信息(只支持提交信息查询),使用 `git log * --all --grep=KEY_WORD` 可以搜索某些提交
此外git log 还支持 其他特定字段的查询,比如根据作者查询`git log --author=AUTHOR_NAME`
@@ -466,8 +470,6 @@ git branch NewBranch [FromBranch] (或者commitID),
答: 想要搞懂 checkout 命令,首先要理解分支的概念.
大名鼎鼎的 master 分支, 我们都熟悉, 自然起点是最早的那个提交, 而终点, 我们可以使用 git show master 查看master的终点.
我们先搁置这个问题, 继续往下看.
@@ -475,12 +477,8 @@ $ git checkout 1a
> 1a 表示一个分支,或者一个 commit上面的打的标签
如下:这就是 checkout 命令的工作原理
<img src="https://typora-1256991781.cos.ap-beijing.myqcloud.com/uPic/image-20200618095257616.png" alt="image-20200618095257616" style="zoom:50%;margin:0" />
#### 新增的文件和修改的文件的区别对待
@@ -493,7 +491,7 @@ $ git checkout 1a
### git reflog 命令
TODO
可以查看HEAD指针的移动情况。
@@ -512,10 +510,12 @@ git reset 命令是一个非常复杂、让人迷惑、危险的命令,下面
我们看到有3个提交从早到晚分别是 eb43, 9e5e, 38db 现在指针指向 38db。
**第 1 步:移动 HEAD**
reset 做的第一件事是移动 HEAD 的指向。reset 移动HEAD 指向的分支。 这意味着如果 HEAD 设置为 master 分支(例如,你正在 master 分支上,运行 git reset 9e5e 将会使 master 指向 9e5e。
reset 做的第一件事是移动 HEAD 的指向。reset 命令移动HEAD 指向的提交。 这意味着如果 HEAD 在 master 分支上,运行 git reset 9e5e 将会使 HEAD指针指向 9e5e。
无论你调用了何种形式的带有一个提交的 reset它首先都会尝试这样做。
> 使用reset的时候如果存在回退的行为提交历史会被擦除这个时候需要使用 git reflog 命令找到丢失的提交。
**使用 reset --soft它将仅仅停在那儿。**
现在看一眼上图,理解一下发生的事情:**它本质上是撤销了上一次 git commit 命令**。
@@ -525,7 +525,7 @@ reset 做的第一件事是移动 HEAD 的指向。reset 移动HEAD 指向的分
**第 2 步:更新索引(--mixed**
**第 2 步:更新索引(--mixe**默认的,不带参数的。
注意,如果你现在运行 git status 的话,就会看到新的 HEAD 和以绿色标出的它和索引之间的区别。
接下来reset 会用 HEAD 指向的当前快照的内容来更新索引。
@@ -536,8 +536,6 @@ reset 做的第一件事是移动 HEAD 的指向。reset 移动HEAD 指向的分
现在再看一眼上图,理解一下发生的事情:它不仅会撤销一上次提交,还会取消暂存区的所有的东西,也就是说,**Git会用历史区的HEAD指针指向的版本内容覆盖暂存区**。 于是,我们回滚到了所有 git add 和 git commit 的命令执行之前。
第 3 步:更新工作目录(--hard
reset 要做的的第三件事情就是让工作目录看起来像索引。 如果使用 --hard 选项,它将会继续这一步。
@@ -559,12 +557,6 @@ reset 要做的的第三件事情就是让工作目录看起来像索引。 如
再举个例子,分支 master 含有 c1, c2, c3,共3个提交 分支 dev 含有 c1, c2, c4 共4个提交即 dev 分支有包含 master 分支没有的内容,如果使用 git merge dev master, 意思就是让 master 合并 dev 分支了里的内容。merge 完成后master也有了 c1c2, c3, c5, 共4个分支c5里包含着 c4 提交的内容而dev没有任何变化。这种合并为合并了分叉内容会自动创建一个提交例如c5分支。
### git pull
git pull = git fetch + git merge
@@ -573,8 +565,6 @@ git pull --rebase = git fetch + git rebase origin
## git 低频命令
我会就 rebase、cherry-pick、rm、
@@ -585,10 +575,10 @@ git pull --rebase = git fetch + git rebase origin
rebase 变基, 打个比方, 分支 master 包含 C1,C2,C3, 分支 branchX 包含 C2, C4, C5.
采用普通的merge策略, 会新建一个提交C6, 让C3, C5都指向C6. C6的内容包含master和branchX都有的内容.
采用rebase, 命令格式为 git rebase BASE_BRANCH TO_REPLAY_BRANCH
采用rebase, 命令格式为 git rebase BASE_BRANCH TO_MERGE_BRANCH
在这里使用 `git rebase master branchX`就是把 C4-C5在C3后续上, 然后branchX指针指向C5, master位置不变, 也就是说分支的指向位置都没变, 只不过提交历史的形状变了.
如果没有冲突顺利合并, 如果有冲突解决冲突.
如果 只写git rebase BASE_BRANCH, 那么git就会假定当前分支就是TO_REPLAY_BRANCH.
如果 只写git rebase BASE_BRANCH, 那么git就会假定当前分支就是TO_MERGE_BRANCH.
<br>
总结: 什么是rebase? 变基, 变谁的基? 就拿刚才一个具体的命令来说吧, 当前分支是branchX, 执行`git rebase master branchX`, 或者`git rebase master`, 我们这么理解, 变得就是branchX的基, 基, 英语base, 我们不妨理解为起点. 重新修改branchX的起点, 之前branchX的起点是C2, 现在我们让它的起点改为C3.
@@ -607,7 +597,40 @@ git pull --rebase = git fetch + git rebase origin
#### git rebase 合并提交
如果提交历史存在多个提交,但是感觉没必要拆解成多个,可以使用合并提交的功能进行重写历史。
重写历史的命令是 git rebase -i 截止历史hash
```
* d2c68c0 - (HEAD -> master) try randomNumber (2023-02-02 16:50:59) <notfreshmbp>
* e3895eb - rename csv (2022-09-21 14:52:32) <notfreshmbp>
* 31c85ac - (tag: v0.0.14, origin/master) update csvfile (2022-09-19 12:13:00) <notfreshmbp>
* b43d8f8 - (tag: v0.0.13) add new csv reader fix bug (2022-09-14 16:43:05) <notfreshmbp>
* 8c7135d - (tag: v0.0.12) add new csv reader (2022-09-14 16:41:06) <notfreshmbp>
* cb486e4 - (tag: v0.0.11) add csv reader (2022-09-14 16:37:54) <notfreshmbp>
```
举个例子,> git rebase 31c85ac, 命令行就会出现以下窗口,我们可以选择其中一个提交,指定特定命令,进行历史的重写。
```
1 pick e3895eb rename csv
2 pick d2c68c0 try randomNumber
3
4 # Rebase 31c85ac..d2c68c0 onto 31c85ac (2 commands)
5 #
6 # Commands:
7 # p, pick <commit> = use commit
8 # r, reword <commit> = use commit, but edit the commit message
9 # e, edit <commit> = use commit, but stop for amending
10 # s, squash <commit> = use commit, but meld into previous commit
11 # f, fixup <commit> = like "squash", but discard this commit's log message
12 # x, exec <command> = run command (the rest of the line) using shell
13 # d, drop <commit> = remove commit
14 # l, label <label> = label current HEAD with a name
15 # t, reset <label> = reset HEAD to a label
```
### git fetch 命令
@@ -620,7 +643,7 @@ git fetch 命令 表示把远程仓库拉下来,但是不合并到当前分支
git tag -m "打个标签" TagName ===》这是轻量级的标签
git show TagName ===>查看标签代表的提交
##
### git diff
@@ -643,7 +666,7 @@ git diff branch1 branch2 比较branch2和branch1的区别, git diff commit1 comm
如图所示假设如下场景我在b4分支的编辑的时候接到一个临时任务那么我需要把当前的工作临时保存起来但不提交那么我使用 git stash命令即可。然后我切换到其他分支去工作那我我现在的提交历史如下
> 想要看到这种效果,配置如下:
> git config --global alias.l "log --color --graph --all --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s%Creset %Cgreen(%cd) %C(bold blue)<%an>%Creset' --abbrev-commit --date='format:%Y- %m-%d %H:%M:%S'"
> git config --global alias.l "log --color --graph --all --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s%Creset %Cgreen(%cd) %C(bold blue)<%an>%Creset' --abbrev-commit --date='format:%Y-%m-%d %H:%M:%S'"
>
> 然后使用 git l 即可查看。
@@ -692,10 +715,6 @@ Dropped refs/stash@{0} (1c03cfd8d607a723be6d8afd270fba4d734e3b29)
现在提交历史又恢复了,我们可以继续编辑了。
注意,如果我们
@@ -713,6 +732,25 @@ Dropped refs/stash@{0} (1c03cfd8d607a723be6d8afd270fba4d734e3b29)
## 如何规范你的commit
从公司多人角度考虑, 如何规范你的 Git Commit message
如何规范你的Git commit - 阿里技术的文章 - 知乎
https://zhuanlan.zhihu.com/p/182553920
## Tricks
--name-only 在 git diff 和 git show 等命令中,如果指向看文件维度的,就可以加上这个配置
## github国内加速方法
参见这个网址,非常的好用。
https://www.cnblogs.com/july-sunny/p/13697156.html
## 维护者
[@notfresh](https://github.com/notfresh)
@@ -791,8 +829,6 @@ https://stackoverflow.com/a/22750480/9561380
https://github.com/EbookFoundation/free-programming-books/blob/master/free-programming-books.md#git
1@[21]我用四个命令,总结了 Git 的所有套路
https://mp.weixin.qq.com/s/VdeQpFCL3GGsfOKrIRW6Hw
@@ -821,21 +857,7 @@ https://www.yupengsir.com/topic/content?i=52
CC4.0 自由转载-保持署名 © 2020 notfresh
## 如何规范你的commit
从公司多人角度考虑, 如何规范你的 Git Commit message
如何规范你的Git commit - 阿里技术的文章 - 知乎
https://zhuanlan.zhihu.com/p/182553920
## Tricks
--name-only 在 git diff 和 git show 等命令中,如果指向看文件维度的,就可以加上这个配置
# github国内加速方法
参见这个网址,非常的好用。
https://www.cnblogs.com/july-sunny/p/13697156.html
# 子模块的使用submodule
如何使用子模块进行管理代码呢?参见以下文章,写的很好:
https://zhuanlan.zhihu.com/p/87053283