* 8d2f27f (HEAD -> master) Merge branch 'test_one'
| * 490bd8f (test_one) two
* | 4858021 master:3
* 19970a8 fix conflict
不想要快速合并,那么我们可以强制指定为非快速合并,只需加上--no-ff参数
git merge –no-ff test
快速合并:
优点:速度快,没有文件的操作,仅仅是指针操作
缺点:合并记录不清晰
非快速合并:
优点:非快进式合并会生成新的提交,可以让提交历史更加的清晰
缺点:速度慢
rebase 变基合并
rebase 合并分支
git rebase master # 将master的代码合并到当前分支
rebase和merge都是合并分支的一种方法,但是和merge的动作行为却不一样。rebase是待合并分支的提交记录在本分支上重新创建一遍,完成两个分支的合并。这种动作是有破坏性的。
优点
:可以获得更清晰的项目历史,会产生完美线性的项目历史记录,你可以在 feature分支上没有任何分叉的情况下一直追寻到项目的初始提交。
缺点
: 对分支的原状态具有破坏性,被合并分支会丢失提交的上下文。
rebase的使用需要遵循 Rebase黄金法则
: 永远不要在公共分支上使用它
rebase和merge比较:
变基是将一系列提交按照原有次序依次应用到另一分支上,而合并是把最终结果合在一起。
变基:将两个分支的提交变成一条线性节点
合并:保留两个分支的提交记录,增加新的节点
查看记录记录
查看 git 所有操作命令
git reflog 所有分支的操作
git reflog master master分支的操作
丢弃工作区修改
丢弃工作去的修改。对暂存区和版本库都不起作用
git checkout -- file
git restore file
丢弃暂存区修改
将暂存区的内容返回到工作区
git restore --staged <file_name> 将暂存区的修改重新放回工作区(包括对文件自身的操作,如添加文件、删除文件)。此时工作区显示有文件未被追踪。
暂存区的修改撤销到工作区。
对于使用git add -A 从工作区提交到暂存区的命令可以再次reset到工作区。此时工作区显示有文件未被追踪。
git reset HEAD file
从git分支上删除文件,取消git管理。该命令会同时删除文件。如果想不删除文件而只是取消git对文件的跟踪,使用.gitinore 忽略该文件。
git rm file
git 标签
git 标签
Git 可以给仓库历史中的某一个提交打上标签,以示重要。 比较有代表性的是人们会使用这个功能来标记发布结点( v1.0 、 v2.0 等等)
列出 标签 git tag
创建标签 附属标签 git tag -a -m 'v1.4'
轻量级标签 git tag -m 'v1.4'
stash 暂存修改
git 暂存修改
在A分支上做的修改,没有保存切换到B分支。这是A分支的修改也会带到B分支,如果在B分支提交了修改,那么A分支的修改清空,B分支会有一个commit记录。
将内容暂存,包括工作区和暂存区都可以:
git stash git stash push
将暂存的内容恢复
git stash apply
查看暂存过的记录
git stash list
如果远程主机的版本比本地版本更新,推送时Git会报错,要求先在本地做git pull合并差异,然后再推送到远程主机。这时,如果你一定要推送,可以使用--force选项。
git push --force origin branch_name
git的后悔药
git 撤销命令reset简介
git 撤销命令 reset
git reset 可以回退git的版本,将git的记录回退到某一次commit之后的状态。
git reset [--soft | --mixed | --hard] [HEAD]
git reset 有三个参数,不加参数默认使用 --mixed
hard 版本回退到commit之后的状态,在重置HEAD 和 branch 的同时,重置暂存区和工作区的内容,也就是丢弃掉暂存区和工作的修改。
soft 不会重置工作区,把版本回退带来的改变放在暂存区,比如版本新增的代码,减少的代码都在暂存区。直接commit还能恢复到reset之前。
mixed 将暂存区修改回退到工作区,将reset导致的改变也放在暂存区。
使用模式区别
reset三种模式区别
--hard:重置位置的同时,直接将 working Tree工作目录、 index 暂存区及 repository 都重置成目标Reset节点的內容,所以效果看起来等同于清空暂存区和工作区。
--soft:重置位置的同时,保留working Tree工作目录和index暂存区的内容,只让repository中的内容和 reset 目标节点保持一致,因此原节点和reset节点之间的【差异变更集】会放入index暂存区中(Staged files)。所以效果看起来就是工作目录的内容不变,暂存区原有的内容也不变,只是原节点和Reset节点之间的所有差异都会放到暂存区中。
--mixed(默认):重置位置的同时,只保留Working Tree工作目录的內容,但会将 Index暂存区 和 Repository 中的內容更改和reset目标节点一致,因此原节点和Reset节点之间的【差异变更集】会放入Working Tree工作目录中。所以效果看起来就是原节点和Reset节点之间的所有差异都会放到工作目录中。
参考链接:https://www.jianshu.com/p/c2ec5f06cf1a
使用场景:
--hard:
(1) 要放弃目前本地的所有改变時,即去掉所有add到暂存区的文件和工作区的文件,可以执行 git reset -hard HEAD 来强制恢复git管理的文件夹的內容及状态;
(2) 真的想抛弃目标节点后的所有commit(可能觉得目标节点到原节点之间的commit提交都是错了,之前所有的commit有问题)。
--soft:
合并多个commit节点为一个commit,减少commit,让分支更清晰
节点和reset节点之间的【差异变更集】会放入index暂存区中(Staged files),所以假如我们之前工作目录没有改过任何文件,也没add到暂存区,那么使用reset --soft后,我们可以直接执行 git commit 將 index暂存区中的內容提交至 repository 中。为什么要这样呢?这样做的使用场景是:假如我们想合并「当前节点」与「reset目标节点」之间不具太大意义的 commit 记录(可能是阶段性地频繁提交,就是开发一个功能的时候,改或者增加一个文件的时候就commit,这样做导致一个完整的功能可能会好多个commit点,这时假如你需要把这些commit整合成一个commit的时候)時,可以考虑使用reset --soft来让 commit 演进线图较为清晰。总而言之,可以使用--soft合并commit节点。
--mixed(默认):
(1)使用完reset --mixed后,我們可以直接执行 git add 将這些改变果的文件內容加入 index 暂存区中,再执行 git commit 将 Index暂存区 中的內容提交至Repository中,这样一样可以达到合并commit节点的效果(与上面--soft合并commit节点差不多,只是多了git add添加到暂存区的操作);
(2)移除所有Index暂存区中准备要提交的文件(Staged files),我们可以执行 git reset HEAD 来 Unstage 所有已列入 Index暂存区 的待提交的文件。(有时候发现add错文件到暂存区,就可以使用命令)。
(3)commit提交部分错误代码,或者没有必要的文件也被commit上去,不想再修改错误再commit(因为会留下一个错误commit点),可以回退到正确的commit点上,然后所有原节点和reset节点之间差异会返回工作目录,假如有个没必要的文件的话就可以直接删除了,再commit上去就OK了。
revert
revert是放弃指定提交的修改,但是会生成一次新的提交,需要填写提交注释,以前的历史记录都在。
git reset 是将回退的提交记录都删掉,如下:
C和D的记录都会消失。这其实不是一个好主意,如果发现C和D都还需要也找不到了。
而 git revert则是将指定的commit撤销,并且会生成一次提交记录。使用revert可以保证错误的提交记录还在,所以是一种优雅的撤销方式。
commit e104cc032d6e1fb262c0910749946946a58d46d3
Author: goldsunshine <892697603@qq.com>
Date: Thu Jan 13 22:00:17 2022 +0800
有如上提交,如果想撤回的话,使用命令
➜ test git:(master) git revert e104cc032d6e1fb262c0910749946946a58d46d3
[master a130b0c] Revert "4"
1 file changed, 3 deletions(-)
这时提交的内容会被撤销,同时生成新的提交记录
commit a130b0c2566898f9fe73cf2a811ae9489c233d22
Author: goldsunshine <892697603@qq.com>
Date: Thu Jan 13 22:00:35 2022 +0800
Revert "4"
This reverts commit e104cc032d6e1fb262c0910749946946a58d46d3.
commit e104cc032d6e1fb262c0910749946946a58d46d3
Author: goldsunshine <892697603@qq.com>
Date: Thu Jan 13 22:00:17 2022 +0800
如果想撤销多次,那么一个一个revert,那么使用 git revert -n commit-idA..commit-idB
撤销A到B之间所有的提交。
https://blog.csdn.net/allanGold/article/details/111372750
merge 冲突
首先来看一下冲突的产生过程,看仔细咯
在git管理的目录下有一个hello_git.txt,里面有内容:
write you branch name:
当前在master分支。
➜ git_test git:(master) ✗ git branch
br_dev
* master
从master分支创建一个叫 br_dev 的新分支
➜ git_test git:(master) git switch -c br_dev
Switched to a new branch 'br_dev'
➜ git_test git:(br_dev)
修改hello_git.txt,并保存
write you branch name: br_dev
➜ git_test git:(br_dev) vim hello_git.txt
➜ git_test git:(br_dev) ✗ git add -A
➜ git_test git:(br_dev) ✗ git commit -m 'br_dev:one'
[br_dev 5d4e531] br_dev:one
1 file changed, 1 insertion(+), 1 deletion(-)
切换到master分支,修改hello_git.txt
write you branch name: master
➜ git_test git:(br_dev) git switch master
Switched to branch 'master'
➜ git_test git:(master) vim hello_git.txt
➜ git_test git:(master) ✗ git add -A
➜ git_test git:(master) ✗ git commit -m 'master:one'
[master 8b384b7] master:one
1 file changed, 1 insertion(+), 1 deletion(-)
在master分支merge br_dev 分支,产生冲突
➜ git_test git:(master) git merge br_dev
Auto-merging hello_git.txt
CONFLICT (content): Merge conflict in hello_git.txt
Automatic merge failed; fix conflicts and then commit the result.
总结一下上面的操作:
在 master 分支切换出一个新分支 br_dev
在 br_dev 分支修改第一行
在 master 分支修改第一行
master 分支 merge br_dev分支,产生冲突。
那么为什么会产生冲突呢,读者是否发现其中规律?
简单来说:两个分支有一个相同的节点,当两个分支在这个共同节点的基础上都做了各自的修改,并且是对同一行代码修改,这时一个分支merge另一个分支时,就会产生冲突。
深层次原因
:git是记录的是每次修改,一个分支只会有一份记录。当一次记录时,如果两个分支对同一个行代码做了修改,就相当于两个新增记录,这时git无法判断记录哪一个,所以就会有冲突。
git merge的冲突判定机制如下:先寻找两个commit的公共祖先,比较同一个文件分别在ours和theirs下对于公共祖先的差异,然后合并这两组差异。如果双方同时修改了一处地方且修改内容不同,就判定为合并冲突,依次输出双方修改的内容。
解决办法
:不要擅自决定保存什么代码,要找到两个分支的提供者,共同决定。