1. git rebase
基础
在bugFix
分支操作:
git rebase main
会更新bugFix
分支,但不会更新main
。如何更新main?
git checkout main
git rebase bugFix
另:如果当前bugFix
分支有三个提交分叉,rebase会把这三个一溜连上去。
2. 分离HEAD
让其指向了某个具体的提交记录而不是分支名.
比如,现在在bugFix
分支
要分离HEAD
:
git checkout bugFix
3. 相对引用
-
方法一:用
^
向上移动一个记录移动到
main
分支上一个提交记录:
git checkout main^
(只移动HEAD
) -
方法二:用
~<num>
向上移动多个记录 如~3
一次把
HEAD
向前移4个提交记录:git checkout HEAD~4
main
分支强制指向 HEAD 的第 3 级父提交:git branch -f main HEAD~3
(
-f
强制让分支指向另一个提交, 后面的两个分支,前一个是要移动的分支,后一个是目标位置)提示:
checkout
移动HEAD
,branch -f <分支名>
强制移动该分支指向
4. 撤销变更
4.1 本地撤销 (远程无效)
在main
分支执行git reset HEAD^
, 相当于把main
分支向上移动一个提交。但是只对本地代码库有效。
4.2 远程撤销
git revert HEAD
会多一个新的提交。
如原本记录是:c1
<-- c2
,执行这一句会产生一个新的commit记录,HEAD
和main
都会指向这个记录。相当于自动commit。revert之后的记录是: c1
<–c2
<–c2'
其中c2'
的内容和c1
是一样的
5. 整理提交记录
5.1 cherry-pick
-
git cherry-pick <提交号>...
在
main
分支cherry-pick
, 会直接把c1 c2 放到main分支下面git cherry-pick c1 c2
如果需要某个分支的上一个提交记录
git cherry-pick c1 c2^
5.2 交互式rebase
加入 -i
选项,会有窗口让你选择哪些提交。(适用于不知道提交记录哈希值的情况)
git rebase -i HEAD~4
窗口里可以用pick i r等调整commit 记录
5.3 只取一个提交记录
git cherry-pick c1
6. 其他
6.1 git commit --amend
上一次commit msg写错了,可以重新修改上次的。如果是操作错了,不想修改上次的commit msg,但是想修改内容,可以用以下命令跳过commit msg:
git commit --amend --no-edit
6.2 git tag
永久指向某一提交记录
git tag v1 c1
6.3 git describe
git describe <ref>
其中是任何可被识别的提交记录标志(分支名,哈希值,HEAD)如果没有指定的话,会用HEAD
输出结果:<tag>_<numCommits>_g<hash>
tag
表示的是离ref
最近的标签numCommits
是表示这个ref
与tag
相差有多少个提交记录hash
表示的是你所给定的ref
所表示的提交记录哈希值的前几位
当 ref
提交记录上有某个标签时,则只输出标签名称
6.4 选择父提交记录
git默认选择第一个父记录。
git checkout main^2
移动到另一个父记录
支持连续的操作
git checkout HEAD~^2~2
~
向上移动一步
^2
选择走哪个父提交
~2
向上移动两步
7. 远程仓库相关
7.1 git fetch
相当于下载了所有远程的内容,但并不会更新本地仓库的内容。比如远程是c1
<-- c2
,本地test
指向c1
,远程test
指向c2
执行git fetch
之后本地更新为c1
<-- c2
,但本地的test
仍然指向c1
。
7.2 git pull
-
git pull
在main
分支与以下指令集等价:git fetch
git merge origin/main
-
git pull origin foo
相当于git fetch origin foo
git merge o/foo
-
git pull origin bar~1:bugFix
相当于git fetch origin bar~1:bugFix
git merge bugFix
如果本地没有
bugFix
,从本地bar~1
的位置创建一个。
7.3 git push
如何在push之前做rebase?
git fetch
git rebase origin/main
#这两条相当于git pull --rebase
,最新的是自己的提交而不是远程的。
git push
如何在push前merge?
git fetch
git merge origin/main
# 这两条相当于git pull
git push
7.4 本地同时修改多个功能
如果要远程清晰,需要使用多次rebase
假设feat1
,feat2
,feat3
在main
这里分叉,而且远程也分叉了。
现在在feat1
git pull origin main --rebase
git checkout feat2
git rebase feat1
git checkout feat3
git rebase --feat2
git checkout main
git rebase --feat3
git push
# 如果这个时候push不上去,再rebase一次远程(执行第一句)
7.5 merge和rebase
一些开发人员喜欢保留提交历史,因此更偏爱 merge。而其他人(比如我自己)可能更喜欢干净的提交树,于是偏爱 rebase。
7.6 track
-
方法一:通过远程分支检出新分支
git checkout -b totallyNotMain origin/main
此时
totallyNotMain
在本地,跟踪远程的main
-
方法二:
git branch -u o/main foo
如果当前在
foo
分支,还可以省略最后一个参数适用于
foo
在本地已经存在的情况
7.7 带参乱整
7.7.1本地和远程同名
git push origin main
这里的main
同时指定了本地分支和远程分支,跟HEAD
的位置没有关系。所以只适用于本地和远程分支名一样的情况。
如果直接git push
,如果此时HEAD
不在任何一个有分支对应的、追踪远程的节点上,就不会push,因为没有对应的远程位置。
7.7.2<source>:<destination>
-
git push origin <source>:<destination>
这里的两个参数可以用任意方法指定。
^
~
都能用如果
destination
不存在,远程会自动新建。 -
git fetch origin <source>:<destination>
和
git push
方向相反,在这里<source>
是远程分支名,<destination>
是本地分支名。如果
git fetch
会下载所有的远程仓库内容,只修改本地分支的远程节点指向
7.7.3 :<destination>
(source留空)
-
git push origin :foo
传空值给远程的
foo
分支,删除远程仓库的foo
分支 -
git fetch origin :bar
会在本地创建新分支(应该是在
HEAD
的位置)