我很喜欢跟着游戏学一些新上手的东西,比如学vim会找vim游戏来玩,这次发现了一个Git的游戏,所以也来试了一下。主要是之前学git其实学的并不好,有时候处理一些复杂的问题还是会粗暴地采用并不最优的方式。这次正好再来整理一下知识点。
本地操作
主要命令
提交内容
git commit
C2
的父节点是C1
- 父节点是当前提交中变更的基础
分支
- git 的分支非常轻量,它们只是简单地指向某个提交记录
- 创建再多分支也不会造成储存或内存上的开销
- `git
基于C1创建新的分支newImage
在新分支上提交内容 C2
,但是当前master
没有在新分支上
git checkout <name>
切换分支git checkout -b <name>
创建并切换到新分支
切换到新分支上,星号表示当前分支
分支与合并
- 在新分支上开发某些功能,开发完后再合并回主线
git merge
git merge
会产生一个特殊的提交记录,它有两个父节点。这个提交记录会把两个父节点本身及它们所有的祖先都包含进来
合并bugFix
分支到master
上,从master
开始沿着箭头向上看,master
包含了对代码库的所有修改
git checkout bugFix; git merge master
master
已经继承了bugFix
,所以Git只是把bugFix
移动到master
所指向的那个提交记录
现在每一个分支都包含了代码库的所有修改
git rebase
- rebase 实际上是取出一系列的提交记录,“复制”它们,然后在另外一个地方逐个地放下去
- rebase 的优势是可以创造更线性的提交历史
- 在
bugFix
分支上git rebase master
bugFix
分支上的工作转移到了master
的最顶端- 提交记录
C3
依然存在,C3’
是rebase到master
分支上的C3
的副本
git checkout master; git merge bugFix
- 由于
bugFix
继承自master
,所以只是简单地把master
分支的引用向前移动了一下
- 由于
高级操作
在提交树上移动
- HEAD 是一个对当前检出记录的符号引用 —— 也就是指向你正在其基础上进行工作的提交记录
- HEAD 总是指向当前分支上最近一次提交记录。大多数修改提交树的 Git 命令都是从改变 HEAD 的指向开始的
- HEAD 通常情况下是指向分支名的,当你提交时,改变了分支的状态,这一变化通过 HEAD 变得可见
cat .git/HEAD
查看 HEAD 的指向- 分离的 HEAD 是让其指向了某个具体的提交记录而不是分支名
相对引用
- 实际操作中需要使用
git log
查看提交记录的哈希值 - 使用相对引用可以从易于记忆的地方开始计算
- 使用
^
向上移动 1 个提交记录 - 使用
~<num>
向上移动多个提交记录
- 使用
*git checkout master^
从master
分支的最近一次提交向上移动一个节点
- 也可以将
HEAD
作为相对引用参照
git checkout C3; git checkout HEAD^; git checkout HEAD^; git checkout HEAD^;
“~” 操作符
git checkout HEAD~4
git branch -f master HEAD~3
可以让分支指向另一个提交(让master分支强制指向 HEAD 的第3级父提交)
git branch -f master HEAD~3
撤销变更
- 撤销变更由底层部分(暂存区的独立文件或者片段)和上层部分(变更到底是通过哪种方式被撤销的)组成
git reset
git reset HEAD~1
- 把
master
分支移回到C1
,现在本地代码库不知道有C2
这个提交了 - reset后,
C2
所做的变更还在,但是出于未加入暂存区状态 git reset
只对本地分支有效,对一起使用的远程分支无效
git revert
git revert HEAD
- revert后增加了
C2’
提交,C2’
引入了更改,这些更改用于撤销C2
这个提交,也就是说C2’
的状态与C1
是相同的
移动提交记录
git cherry-pick
- 将一些提交复制到当前所在位置
git cherry-pick C2 C4
交互式的 rebase
- 如果不清楚想要的提交记录的哈希值,那么使用交互式的 rebase 更好
git rebase —interactive
也可以写作git rebase -i
- 增加这个选项后,git会打开一个UI界面并列出要被复制到目标分支的备选提交记录,以及每个提交记录的哈希值和提交说明
- Rebase打开UI界面时,可以调整提交记录的顺序,删除不想要的提交,合并提交
git rebase -i HEAD~4
技巧
只取一个提交记录
![image-20190908185736968](/Users/nikkkki/Library/Application Support/typora-user-images/image-20190908185736968.png)
git tags
- 永远指向某个提交记录的标识
git tag v1 C1
git describe
- 用来描述离你最近的标签
git describe <ref>
多次 rebase
选择父提交记录
^
操作符后面也可以跟一个数字,用来指定合并提交记录的某个父提交git checkout master^2
git checkout HEAD~^2~2
远程仓库
git clone
- 创建一个远程仓库的拷贝
远程分支
- 反映远程仓库的状态
- 在你检出时自动进入分离 HEAD 状态
- 格式是
<remote name>/<branch name>
- 也可以切换到远程分支
git checkout o/master
git fetch
git fetch
用于从远程仓库获取数据,它实现了两件事:- 从远程仓库下周本地仓库中缺失的提交记录
- 更新远程分支指针
git fetch
不会更新本地仓库的状态,也不会更新master
分支,也不会修改磁盘上的文件
git pull
git fecth; git merge o/master
git pull
就是git fetch; git merge <just fetched branch>
的缩写
git push
偏离的工作
git fetch; git rebase o/master; git push
git fetch; git merge o/master; git push
推送主分支
跟踪远程分支
git checkout -b totallyNotMaster o/master
创建新分支,并跟踪远程分支o/master
git checkout -b foo o/master; git pull
git checkout -b foo o/master; git commit; git push
git branch -u