Git使用爬坑记录

分离头指针

当前分支图

image-20200313100955490

切换到之前的某一次提交

image-20200313101041682

执行命令

$ git checkout de11fa87ea

提示,当前位于“分离头指针”状态

image-20200313101137934

分支图

image-20200313101230748

注意

  • 在分离头指针状态下没有绑定分支
  • 产生的commit不会被保存
  • 分支切换后在分支图中看不到该commit
  • 一段时间后会被git自动清除

使用场景

  • 尝试性做一些变更,可以随时丢弃

此处演示分离头指针丢失commit的情况和补救措施

丢失commit

使用IDE修改文件并提交,忽略所有警告,修改后分支图如下

image-20200313101811004

此时接到其他需求,需要切换分支进行紧急修复

执行命令

$ 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'.

image-20200313101817932

此时查看分支图,刚才的commit已经不可见

image-20200313102044269

补救

此时发现刚才的commit十分重要,可根据git的提示进行补救

执行命令

$ git branch hot-fix 199ac20

再次查看分支图,可见commit已经恢复

image-20200313102203644

本地分支操作

以下操作仅适用于本地分支,无远程分支协同工作的情况

修改当前commit的message——amend

当前分支图

image-20200313102633268

执行命令

$ git commit --amend

自动弹出编辑器

image-20200313102714191

修改后保存并关闭编辑器即可,输出如下

image-20200313102735178

再次查看分支图

image-20200313102751917

修改前面某次commit的message——rebase

现计划修改如下message

image-20200313102837128

使用IDE拷贝其父提交的SHA值

image-20200313102938536

执行命令,-i表示交互式执行

$ git rebase -i 199ac203c90f881024c6870d56517df9e2080841

自动弹出编辑器

image-20200313103103273

同时包含提示操作

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

image-20200313103140977

保存并关闭编辑器,会自动弹出新编辑器界面

image-20200313103156452

修改后保存并关闭即可,输出如下

image-20200313103234131

查看分支图

image-20200313103250780

整理连续多个commit——rebase

现计划合并3个commit

image-20200313104229297

使用IDE拷贝其父SHA值

image-20200313104256202

执行命令

$ git rebase -i 199ac203c90f881024c6870d56517df9e2080841

此处使用squash,官方介绍如下

s, squash = use commit, but meld into previous commit

修改内容如下,说明将中间两个合并进第一个commit中

image-20200313104553536

保存后关闭,会弹出新的编辑器界面,提示可以输出合并commit的message

image-20200313104708882

编写message

image-20200313104849690

保存后关闭,提示修改成功

image-20200313105805083

查看分支图

image-20200313105829642

分支合并策略

演示不同分支合并策略效果,当前的分支图如下

1584157562406

现在将hot-fix合并进master

GitLab默认合并策略——merge commit

gitlab默认合并请求使用的策略

1584157617890
1584157635041

由于没有冲突,可以线上直接合并

其对应执行的命令如下

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

合并完成

1584157751505

查看分支图,故当前分支会影响特性分支并产生新的提交

1584157894622

GitLab合并提交策略

提交合并请求的时候勾选策略Squash commits when merge request is accepted

1584158031481
1584158086855

其对应执行的命令如下(与默认策略一致)

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

合并成功

1584158157862

查看分支图,可见其影响特性分支,会产生新的提交,同时覆盖特性分支最后一次提交

1584158250648

分支合并策略——squash merge

GitHub支持squash merge合并策略,此处通过命令行执行测试

$ git merge --squash origin/hot-fix
$ git commit -m "squash commit"

查看分支图,特性分支不变,目标分支合并提交后产生一条提交,效果与GitLab合并提交类似,但命令使用方式不同

1584158902921

注意:squash merge会变更提交者作者信息,这是一个很大的问题,后期问题追溯不好处理

变基合并策略——rebase merge

该策略也是GitHub支持的合并策略,可能会产生较多冲突

1584159613476

选择合并策略,最后一种即变基合并策略

1584159638818
1584159659905

合并成功

1584159671515

查看分支图,其产生的三次提交即变基合并的结果,不会影响特性分支,也不会变更提交人,类似cherry pick

1584159735805

分支回滚策略

回滚策略分为两种,一种是合并后回滚,一种是普通提交回滚,不同回滚策略操作方法不同

普通提交回滚

当前分支图,计划回滚最新提交

image-20200317114811482

直接在IDE中执行revert操作即可

image-20200317114905943
image-20200317114935874

回滚会产生新的提交,回滚结束

image-20200317114957310

合并后回滚

此时分支图,使用merge commit方式进行过一次合并,此时不想要合并的结果,想恢复到未合并状态

image-20200317115211900

错误操作——直接执行revert

此时IDE已经不支持通过revert进行回滚合并操作,通过命令行强行执行

查找SHA值

image-20200317115622215

回滚merge需要加上-m参数git就知道到底要revert哪一个merge

$ git revert -n 25d7b405a4d50fe1b36019d90276973a8ed9160d -m 1

回滚后做一次commit即可,使用默认的message后如下

image-20200317120022233

验证回滚结果,使用两个提交进行差异比对

image-20200317122223636

无差异,回滚看似成功了

image-20200317122240317

此时在原分支做了修复后再进行合并

image-20200317141053618

报无法合并,因为分支已经进行过合并

image-20200317141147054

正确操作——reset

使用reset操作到上一次提交

image-20200317141254057

使用--hard参数,丢弃后续的commit

image-20200317141341299
image-20200317141418080

此时继续进行操作,并支持重新合并

image-20200317141504021

禁止类操作

说明:禁止类说明是对开发人员禁止,而该命令在必要时候依然需要由配置管理员使用

push -f

官方使用说明

-f, --force force updates

原因:

  • 默认情况下远端分支若能顺利合并(fast forward),则会顺利合并
  • 若远端分支产生冲突,则会停止push,同时提示错误,要pull到本地处理冲突后重新push
  • -f之后,本地分支会强行推送到远端,若本地分支落后于远端分支也不会弹出提示,由此导致远程commit丢失

适用场景:

  • 远程分支已经混乱,本地分支符合需要,需要强制整理远程分支

公共分支禁止rebase

此处对场景进行模拟,正常情况下,多位开发者对公共分支common-branch进行修改,分支图如下

image-20200313144526583

另一开发者在本地修改后执行变基操作,此处以修改历史提交message为例

image-20200313150137509

变基

image-20200313150232682

录入变基信息

image-20200313150328135

变基成功

image-20200313150426190

此时查看本地分支图,可见产生了新的分支路径,同时远程message并没有变化,故rebase对存在远程分支的情况无效

image-20200313150514493

变基后推送到远端分支,提示需要合并,选择“合并”

image-20200313150709744

合并后分支图如下

image-20200313151107792

此时其他开发者修改文件后并fetch远程分支查看变更情况如下

image-20200313151245155

此时无法对远程分支进行push操作

image-20200313151349842

处理方法

pull远程分支在本地合并后重新推送,此时在本地再产生一次合并

image-20200313151452121

此时可以成功推送

image-20200313151550190

由此一来一回操作导致大量不必要的合并操作,并可能导致大量冲突,并且没有解决问题

警告类操作

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[=]
                      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 

原因:

  • 在分支上执行该操作会丢失目标commit以后的所有commit

适用场景

  • 用于分支回滚且不打算保留其后的所有变更

你可能感兴趣的:(Git使用爬坑记录)