网站:Learn Git Branching
分离HEAD
HEAD 是一个对当前检出记录的符号引用,也就是指向你正在其基础上进行工作的提交记录。HEAD 总是指向当前分支上最近一次提交记录。大多数修改提交树的 Git 命令都是从改变 HEAD 的指向开始的。HEAD 通常情况下是指向分支名的。在你提交时,改变了分支的状态,这一变化通过 HEAD 变得可见。
如果想看 HEAD 指向,可以通过 cat .git/HEAD 查看, 如果 HEAD 指向的是一个引用,还可以用 git symbolic-ref HEAD 查看它的指向。
相对引用
切换至上个版本git checkout HEAD^
切换至上上上版本git checkout HEAD~3
强制修改分支位置
我使用相对引用最多的就是移动分支。可以直接使用 -f 选项让分支指向另一个提交。例如:git branch -f main HEAD~3
,命令会将 main 分支强制指向 HEAD 的第 3 级父提交。
撤销变更
git reset
通过把分支记录回退几个提交记录来实现撤销改动。你可以将这想象成“改写历史”。git reset
向上移动分支,原来指向的提交记录就跟从来没有提交过一样。
为了撤销更改并分享给别人,我们需要使用 git revert
,在我们要撤销的提交记录后面居然多了一个新提交,此次提交是用来撤销上一次提交的,此次提交与上上一次提交状态相同。
Git Cherry-pick
如果你想将一些提交复制到当前所在的位置(HEAD)下面的话, Cherry-pick 是最直接的方式了。命令形式为:git cherry-pick <提交号>...
交互式的 Rebase
交互式 rebase 指的是使用带参数 –interactive 的 rebase 命令, 简写为 -i。
如果你在命令后增加了这个选项, Git 会打开一个 UI 界面并列出将要被复制到目标分支的备选提交记录,它还会显示每个提交记录的哈希值和提交说明,提交说明有助于你理解这个提交进行了哪些更改。Git会自动打开默认的文本编辑器,比如在我本地使用的是vim。在文本编辑器的开始几行会列出所有满足条件的提交记录,每个提交记录对应一行,每行开头单词代表要对这条提交记录实施的操作。
操作 | 说明 |
---|---|
pick | 采用该提交(默认行为) |
reword | 采用该提交,但要求修改提交记录的备注 |
edit | 采用该提交,但要求修改提交记录的信息,如:作者名称,邮箱地址等 |
squash | 采用该提交,但它会被并入前一条提交 |
fixup | 类似“squash”,但是会丢弃这条提交记录的日志信息 |
exec | 执行指定的shell脚本或命令 |
drop | 丢弃该提交 |
Git Describe
git describe 的语法是:git describe <ref>
<ref>
可以是任何能被 Git 识别成提交记录的引用,如果你没有指定的话,Git 会以你目前所检出的位置(HEAD)。
它输出的结果:<tag>_<numCommits>_g<hash>
tag 表示的是离 ref 最近的标签, numCommits 是表示这个 ref 与 tag 相差有多少个提交记录, hash 表示的是你所给定的 ref 所表示的提交记录哈希值的前几位。当 ref 提交记录上有某个标签时,则只输出标签名称。
Git Pull
git pull 就是 git fetch 和 git merge 的缩写!
rebase和merge区别【阅读原文】
使用git merge 命令将 master 分支合并到 feature分支中:git merge feature master
,git merge 会在 feature 分支中新增一个新的 merge commit,然后将两个分支的历史联系在一起。
- 使用 merge 是很好的方式,因为它是一种非破坏性的操作,对现有分支不会以任何方式被更改。
- 另一方面,这也意味着 feature 分支每次需要合并上游更改时,它都将产生一个额外的合并提交。
- 如果master 提交非常活跃,这可能会严重污染你的 feature 分支历史记录。不过这个问题可以使用高级选项 git log 来缓解。
使用git rebase 命令将 master 分支合并到 feature分支中:git rebase feature master
- rebase 会将整个 feature 分支移动到 master 分支的顶端,从而有效地整合了所有 master 分支上的提交。
- 但是,与 merge 提交方式不同,rebase 通过为原始分支中的每个提交创建全新的 commits 来重写项目历史记录,特点是仍然会在feature分支上形成线性提交。
- rebase 的主要好处是可以获得更清晰的项目历史。首先,它消除了 git merge 所需的不必要的合并提交;其次,正如你在上图中所看到的,rebase 会产生完美线性的项目历史记录,你可以在 feature分支上没有任何分叉的情况下一直追寻到项目的初始提交。
Pull Request
如果你是在一个大的合作团队中工作, 很可能是main被锁定了, 需要一些Pull Request流程来合并修改。如果你直接提交(commit)到本地main, 然后试图推送(push)修改, 你将会收到这样类似的信息:! [远程服务器拒绝] main -> main (TF402455: 不允许推送(push)这个分支; 你必须使用pull request来更新这个分支.)