当前分支图git
切换到以前的某一次提交shell
执行命令bash
$ git checkout de11fa87ea
复制代码
提示,当前位于“分离头指针”状态编辑器
分支图gitlab
注意测试
使用场景fetch
此处演示分离头指针丢失commit的状况和补救措施ui
使用IDE修改文件并提交,忽略全部警告,修改后分支图以下this
此时接到其余需求,须要切换分支进行紧急修复spa
执行命令
$ git checkout master
复制代码
分支切换成功,并弹出提示和告警
Warning: you are leaving 1 commit behind, not connected to any of your branches:
199ac20 游离状态修改文件
If you want to keep it by creating a new branch, this may be a good time to do so with:
git branch 199ac20
Switched to branch 'master' Your branch is up to date with 'origin/master'.
此时查看分支图,刚才的commit已经不可见
此时发现刚才的commit十分重要,可根据git的提示进行补救
执行命令
$ git branch hot-fix 199ac20
复制代码
再次查看分支图,可见commit已经恢复
如下操做仅适用于本地分支,无远程分支协同工做的状况
amend
当前分支图
执行命令
$ git commit --amend
复制代码
自动弹出编辑器
修改后保存并关闭编辑器便可,输出以下
再次查看分支图
rebase
现计划修改以下message
使用IDE拷贝其父提交的SHA值
执行命令,-i
表示交互式执行
$ git rebase -i 199ac203c90f881024c6870d56517df9e2080841
复制代码
自动弹出编辑器
同时包含提示操做
Rebase 199ac20..bfe2b7f onto 199ac20 (3 commands)
Commands: p, pick = use commit r, reword = use commit, but edit the commit message e, edit = use commit, but stop for amending s, squash = use commit, but meld into previous commit f, fixup = like "squash", but discard this commit's log message x, exec = run command (the rest of the line) using shell b, break = stop here (continue rebase later with 'git rebase --continue') d, drop = remove commit l, label
These lines can be re-ordered; they are executed from top to bottom.
If you remove a line here THAT COMMIT WILL BE LOST.
However, if you remove everything, the rebase will be aborted.
Note that empty commits are commented out
因而可知“变基”支持不少操做,此处须要使用的是reword
,修改目标提交的命令为r
保存并关闭编辑器,会自动弹出新编辑器界面
修改后保存并关闭便可,输出以下
查看分支图
rebase
现计划合并3个commit
使用IDE拷贝其父SHA值
执行命令
$ git rebase -i 199ac203c90f881024c6870d56517df9e2080841
复制代码
此处使用squash
,官方介绍以下
s, squash = use commit, but meld into previous commit
修改内容以下,说明将中间两个合并进第一个commit中
保存后关闭,会弹出新的编辑器界面,提示能够输出合并commit的message
编写message
保存后关闭,提示修改为功
查看分支图
演示不一样分支合并策略效果,当前的分支图以下
如今将hot-fix合并进master
merge commit
gitlab默认合并请求使用的策略
因为没有冲突,能够线上直接合并
其对应执行的命令以下
Step 1. Fetch and check out the branch for this merge request
$ git fetch origin $ git checkout -b hot-fix origin/hot-fix 复制代码
Step 2. Review the changes locally
Step 3. Merge the branch and fix any conflicts that come up
$ git fetch origin $ git checkout origin/master $ git merge --no-ff hot-fix 复制代码
Step 4. Push the result of the merge to GitLab
$ git push origin master 复制代码
合并完成
查看分支图,故当前分支会影响特性分支并产生新的提交
提交合并请求的时候勾选策略Squash commits when merge request is accepted
其对应执行的命令以下(与默认策略一致)
Step 1. Fetch and check out the branch for this merge request
$ git fetch origin $ git checkout -b hot-fix origin/hot-fix 复制代码
Step 2. Review the changes locally
Step 3. Merge the branch and fix any conflicts that come up
$ git fetch origin $ git checkout origin/master $ git merge --no-ff hot-fix 复制代码
Step 4. Push the result of the merge to GitLab
$ git push origin master 复制代码
合并成功
查看分支图,可见其影响特性分支,会产生新的提交,同时覆盖特性分支最后一次提交
squash merge
GitHub支持squash merge
合并策略,此处经过命令行执行测试
$ git merge --squash origin/hot-fix
$ git commit -m "squash commit"
复制代码
查看分支图,特性分支不变,目标分支合并提交后产生一条提交,效果与GitLab合并提交相似,但命令使用方式不一样
注意:squash merge
会变动提交者做者信息,这是一个很大的问题,后期问题追溯很差处理
rebase merge
该策略也是GitHub支持的合并策略,可能会产生较多冲突
选择合并策略,最后一种即变基合并策略
合并成功
查看分支图,其产生的三次提交即变基合并的结果,不会影响特性分支,也不会变动提交人,相似cherry pick
回滚策略分为两种,一种是合并后回滚,一种是普通提交回滚,不一样回滚策略操做方法不一样
当前分支图,计划回滚最新提交
直接在IDE中执行revert
操做便可
回滚会产生新的提交,回滚结束
此时分支图,使用merge commit
方式进行过一次合并,此时不想要合并的结果,想恢复到未合并状态
revert
此时IDE已经不支持经过revert进行回滚合并操做,经过命令行强行执行
查找SHA值
回滚merge
须要加上-m
参数git就知道到底要revert哪个merge
$ git revert -n 25d7b405a4d50fe1b36019d90276973a8ed9160d -m 1
复制代码
回滚后作一次commit便可,使用默认的message后以下
验证回滚结果,使用两个提交进行差别比对
无差别,回滚看似成功了
此时在原分支作了修复后再进行合并
报没法合并,由于分支已经进行过合并
reset
使用reset操做到上一次提交
使用--hard
参数,丢弃后续的commit
此时继续进行操做,并支持从新合并
说明:禁止类说明是对开发人员禁止,而该命令在必要时候依然须要由配置管理员使用
push -f
官方使用说明
-f, --force force updates
缘由:
-f
以后,本地分支会强行推送到远端,若本地分支落后于远端分支也不会弹出提示,由此致使远程commit丢失适用场景:
rebase
此处对场景进行模拟,正常状况下,多位开发者对公共分支common-branch
进行修改,分支图以下
另外一开发者在本地修改后执行变基操做,此处以修改历史提交message为例
变基
录入变基信息
变基成功
此时查看本地分支图,可见产生了新的分支路径,同时远程message并无变化,故rebase对存在远程分支的状况无效
变基后推送到远端分支,提示须要合并,选择“合并”
合并后分支图以下
此时其余开发者修改文件后并fetch
远程分支查看变动状况以下
此时没法对远程分支进行push
操做
pull远程分支在本地合并后从新推送,此时在本地再产生一次合并
此时能够成功推送
由此一来一回操做致使大量没必要要的合并操做,并可能致使大量冲突,而且没有解决问题
reset --hard
官方对reset
操做用法说明
usage: git reset [--mixed | --soft | --hard | --merge | --keep] [-q] [] or: git reset [-q] [] [--] ... or: EXPERIMENTAL: git reset [-q] [--stdin [-z]] [] or: git reset --patch [] [--] [...]
-q, --quiet be quiet, only report errors --mixed reset HEAD and index --soft reset only HEAD --hard reset HEAD, index and working tree --merge reset HEAD, index and working tree --keep reset HEAD but keep local changes --recurse-submodules[=<reset>] control recursive updating of submodules -p, --patch select hunks interactively -N, --intent-to-add record only the fact that removed paths will be added later -z EXPERIMENTAL: paths are separated with NUL character --stdin EXPERIMENTAL: read paths from <stdin> 复制代码
缘由:
适用场景