目录
Git用法移动提交记录在上一篇文章中Learn Git Branching 学习笔记(移动提交记录篇)_流年--by gone的博客-CSDN博客
这篇文章主要来介绍取、提交记录、git rebase -i、git cherry-pick、git tag、git describe的用法。
一、Git 技术、技巧与贴士集合篇
1.只取一个提交记录
在解决某个特别棘手的 Bug,为了便于调试而在代码中添加了一些调试命令并向控制台打印了一些信息。这些调试和打印语句都在它们各自的提交记录里。最后就差把 bugFix 分支里的工作合并回 master 分支了。
可以选择通过 fast-forward 快速合并到 master 分支上,但这样的话 master 分支就会包含我这些调试语句了。你肯定不想这样,应该还有更好的方式……
实际我们只要让 Git 复制解决问题的那一个提交记录就可以了。跟之前我们在“整理提交记录”中学到的一样,我们可以使用git rebase -i、git cherry-pick来达到目的。
题目:
答案:
git rebase -i HEAD~3 //忽略debug/print分支,只把bugFix分支移动到master下
git merge main //bugFix是"当前分支",但master是bugFix的父节点
//系统提示分支已经是最新啦
git merge bugFix //必须把"当前分支"调整为master之后,再操作合并
2.提交技巧 #1:使用rebase -i
之前在 newImage 分支上进行了一次提交,然后又基于它创建了 caption 分支,然后又提交了一次。此时你想对的某个以前的提交记录进行一些小小的调整。比如设计师想修改一下 newImage 中图片的分辨率,尽管那个提交记录并不是最新的了。
- 先用 git rebase -i 将提交重新排序,然后把我们想要修改的提交记录挪到最前
- 然后用 git commit --amend 来进行一些小修改
- 接着再用 git rebase -i 来将他们调回原来的顺序
- 最后我们把 master 移到修改的最前端(用你自己喜欢的方法),就大功告成啦!
当然完成这个任务的方法不止上面提到的一种(我知道你在看 cherry-pick 啦),最后有必要说明一下目标状态中的那几个' —— 我们把这个提交移动了两次,每移动一次会产生一个 ';而 C2 上多出来的那个是我们在使用了 amend 参数提交时产生的,所以最终结果就是这样了。
也就是说,我在对比结果的时候只会对比提交树的结构,对于 ' 的数量上的不同,并不纳入对比范围内。
只要你的 master 分支结构与目标结构相同,就算通过。
题目:
答案:
git rebase -i HEAD^^ //调整c2c3,得到c3' c2'
git commit --amend //修改c2',得到c2''
git rebase -i HEAD^^ //调整c2'' c3',得到c2''' c3''
git checkout main
git merge caption //caption指向c3'',合并到master
3.提交技巧 #2:使用cherry-pick实现相同效果
上一关可以看到,我们可以使用rebase -i对提交记录进行重新排序。只要把我们想要的提交记录挪到最前端,我们就可以很轻松的用--amend修改它,然后把它们重新排成我们想要的顺序。
但这样做就唯一的问题就是要进行两次排序,而这有可能造成由rebase而导致的冲突,来看看git cherry-pick时怎么做的。
要在心里牢记cherry-pick可以将提交树上任何地方的提交记录取过来追加到HEAD上(只要不是HEAD上游的提交就没问题)
输入git cherry-pick C2
题目:
这一关的目标和上一关一样,通过--amend改变提交记录C2,但不能用rebase-i。
提交记录上面的'的数量并不重要,只是引用的不同而已。也就是说如果最终结果在摸个提交记录上多了个',也算通过。
答案:
git checkout main
git cherry-pick C2 //把C2转到master分支下,得到C2'
git commit --amend //修改c2',得到c2''
git cherry-pick C3 //把C3转到master分支下(c2''下),得到C3'
4.git tag
相信通过前面课程的学你已经发现了:分支很容易被人为移动,并且当有新的提交时,它也会移动。分支很容易被改变,大部分分支还只是临时的,并且还一直在变。
有没有什么可以永远指向某个提交记录的标识呢,比如软件发布新的大版本,或者是修正一些重要的 Bug 或是增加了某些新特性,有没有比分支更好的可以永远指向这些提交的方法呢?
Git的tag可以实现这个功能,它们可以(在某种程度上——因为标签可以被删除后重新在另外一个位置创建同名的标签)永久地将某个特定的提交命名为里程碑,然后就可以像分支一样引用了。
更难得的是,它们并不会随着新的提交而移动。你也不能检出到某个标签上面进行修改提交,它就像是提交树上的一个锚点,标识了某个特定的位置。
我们先建立一个标签,指向提交记录C1,表示这是我们1.0版本。
输入git tag v1 C1
我们将这个标签命名为v1,并且明确地让它指向提交记录C1,如果不指定提交记录,Git会用HEAD所指向的位置。
题目:
在这个关卡中,按照目标建立两个标签,然后检出到 v1 上面,要注意你会进到分离 HEAD 的状态——这是因为不能直接在v1 上面做 commit。
答案:
git tag v0 C1
git tag v1 C2
git checkout C2
5.git describe
标签在代码库中起着“锚点”的作用,Git 为此专门设计的一个命令用来描述离你最近的锚点(也就是标签)。
Git Describe 能帮你在提交历史中移动了多次以后找到方向;当你用 git bisect(一个查找产生 Bug 的提交记录的指令)找到某个提交记录时,或者是当你坐在你那刚刚度假回来的同事的电脑前时,可能会用到这个命令。
git describe 的语法是:git describe <ref>
<ref> 可以是任何能被 Git 识别成提交记录的引用,如果你没有指定的话,Git 会以你目前所检出的位置(HEAD)。
它输出的结果是这样的:<tag>_<numCommits>_g<hash>
tag 表示的是离 ref 最近的标签,numCommits 是表示这个 ref 与 tag 相差有多少次提交记录,hash 表示的是你所给定的 ref 所表示的提交记录哈希值的前几位。
当 ref 提交记录上有某个标签时,则只输出标签名称。
输入git tag v2 C3
git describe main会输出:
v1_2_gC2
git describe side会输出:
v2_1_gC4
题目:
答案:
git checkout bugFix
git commit
Git 技术、技巧与贴士集合篇完结撒花~