说明:该文章是自己搜集了相关资料进行的汇总,其中的一些截图由于办公电脑不方便截图,只能用学习的帖子的图片进行展示,现在找不到之前看的帖子了。请谅解,如果有人知道图片的原帖麻烦踢一下我,我这里更新一下引入参考,感谢!!!
0. 概述
Git是一个开源的分布式版本控制系统。
Git一般工作的流程:
- 克隆Git资源作为工作目录
- 在克隆的资源上添加或修改文件
- 如果其他人修改了,可以进行资源的更新
- 在提交前查看修改
- 提交修改
- 在修改完成以后,如果发现错误,可以撤回提交并再次修改并提交 git指令图解:
1. 日常工作流程中用到的指令
git
# 查看当前仓库中已配置的远程仓库
git remote -v
# 如果是多仓需要建立本地与其他远程仓之间的联系
git remote add "另外远程仓的别名" "另外远程仓的链接"
# 切分支
git checkout -b "分支名称" "远程仓别名"/"远程仓需要切出分支的主干分支"
# 拉取最新代码
git pull "远端仓名称" "远端分支"
# 进行需求编码后,将工作区的代码添加到暂存区
git add .
# 提交代码
git commit -m "提交信息"
# 将代码推到远端
git push "需要推到远端仓别名" "需要推到的分支名称"
# 将自己远端分支的代码合入到主干分支
git checkout master
git pull # 拉取当前分支最新代码
git merge "修改的分支名称"
2. git stash指令
当我们在开发一个新需求的时候,我们需要切一个新的分支去进行开发。假定我们目前有个分支develop为正在开发的需求,但是突然有一个线上bug特别紧急需要去解决,并且之前的改动在另外一个分支test上面。我们想要去test分支上进行修改,发现我们直接切换分支是不可以的,会发生报错。更何况我们修改问题单的代码不想与需求的代码一同合入。这种情况下,我们就需要通过git stash系列指令去进行代码暂存操作。
- git stash save "暂存信息"------将修改的代码进行暂存操作
git
git stash save "develop-change"
经过上面的指令,我们就可以将我们当前修改的代码暂存起来,然后我们就可以进行分支切换,切换到test分支后,我们就可以进行线上bug的修改,然后直接提交代码
- git stash list------查看暂存列表
git
git stash list
当我们想确认我们的代码是否已经暂存起来,或者是想查看我们有那些暂存列表信息,我们就可以使用这个指令进行查看。
- git stash pop------恢复最近一次暂存的代码
git
git stash pop
当我们test分支的代码已经修改完成并且已经合入,这时候我们再次切换回develop分支下面,继续开发我们的需求。我们可以通过上面的指令去恢复我们之前暂存的代码
注:pop只能弹出最近一次暂存的代码
- git stash apply------指定恢复暂存的代码
git
git stash apply stash@{2}
当我们的暂存列表中有很多数据如下图:
我们想要恢复其中一个暂存的信息,但是又不是最近一次暂存的,我们使用git stash pop就无法满足我们的要求。因此我们就可以使用git stash apply去指定恢复暂存的信息。如上述指令,即可恢复我们列表中stash@{2}的暂存代码
- git stash drop------删除暂存列表中的代码
git
git stash drop
git stash drop stash@{2}
如上指令可以删除我们暂存列表中暂存的代码。当我们只有一条暂存信息或是只想删除最近一次暂存的代码,我们可以直接git stash drop进行删除。当有多个暂存信息时,并想要删除指定的暂存信息就通过暂存的序号(多个序号用空格进行分割,或stash@{1}-stash@{9},删除的是之间的范围)去删除即可。
- git stash clear------删除暂存列表中的所有暂存项
3. git reset指令
git reset指令是回退你已经提交的代码,并将提交的修改内容放回到暂存区中。
一般我们使用reset指令的时候,都会使用git reset --soft或者是git reset --hard
那么两者有什么区别呢?
- git reset --soft与git reset --hard的区别 首先我们先来看个图片:
当我们同样的想要回退到Commit ID:1的位置上:我们有两个选择soft以及hard
我们发现我们回退想要回退到节点后面还有四个提交记录,如果我们想要保留这部分代码回退到Commit ID:1,我们这时候就需要用到soft。这时候我们可以回退到Commit ID:1,后续提交的代码也并没有消失,而是暂存起来了。我们就可以带着这些代码完成改动后一起重新提交。 而我们使用了git reset --hard指令后,会强制的回到我们的Commit ID:1节点下,后续提交的代码并不会留存,而是直接回到Commit ID:1下的节点状态。因此git reset --hard需要慎用。
- git reset的使用场景
当然会有一些疑惑,为什么代码已经提交了还要回退到之前的节点呢?
场景:
- 有时候手滑不小心提交了不该提交的内容,突然发现了,想要进行修改,如果我们再commit一次就会多一些不必要的提交记录
- 团队对commit有明确的要求,要求职责明确,方便以后出现问题排查。将属于两个不同功能的模块修改后一起commit上去
- git reset命令的使用------以soft为例
git
# 恢复最近一次commit
git reset --soft HEAD^
git reset --soft
相当于给你一次重新改过的机会。面对上述场景就可以再次修改并提交,保持干净的提交记录。
注:上述说的都是还未push的commit。对于已经push的commit,也可以使用改命令,不过再次push时,由于远程分支和本地分支有差异,需要使用git push -f
强制推送来覆盖之前的commit
4. git cherry-pick指令
- 应用场景
在一个分支中提交的部分代码,需要合并到另一个分支
-
使用方法
假如我本地有两个分支,分别为prod和dev。我在dev分支上提交了一个commit。如果说我们想把dev分支上所有的代码直接合并到prod分支上,那么直接使用git merge就可以实现。但是我们知识想把本次的提交合并到prod分支上,并不打算把dev上其他commit合并到prod分支上,这个时候我们就需要使用git cherry-pick。具体实现步骤如下:- 查看我们的commitHash
git# 在dev分支commit后,终端输入git log,查看本地提交的commitHash git log
下图中框起来的部分就是commitHash
- 切换到prod分支
gitgit checkout prod
- 将上图中的commit合并到prod分支
gitgit cherry-pick <commitHash> # 即git cherry-pick 86601fdc89148ce7719bc5e20ad072b47284ab5b
-
合并多个请求
- 将A、B两个commit都合并
gitgit cherry-pick <commitHashA> <commitHashB>
- 合并A-B的提交(不包含A)
gitgit cherry-pick A..B
- 合并A-B的提交(包含A)
gitgit cherry-pick A^..B
-
cherry-pick解决冲突
在cherry-pick多个commit时,可能会遇到代码冲突,这时cherry-pick会中断,让开发者决定如何继续操作
假定我的dev有a,b,c,d四个提交需要合并到prod分支上,需要我们记录一下起点a以及终点d的commitHash的值
然后我们切到prod分支,使用cherry-pick进行区间合并
当我们c提交的代码中存在冲突时,cherry-pick执行到c会中断
这时候需要我们解决掉代码冲突,重新提交到暂存区
最后使用git cherry-pick --continue让cherry-pick继续进行下去
最后d也被合并进来,整个流程就完成了
以上是完整的流程,但是,当我们代码存在冲突我们不想合入就需要放弃或退出cherry-pick
- 放弃cherry-pick
git cherry-pick --abort
- 退出cherry-pick
git cherry-pick --quit
5. git revert指令
git revert
撤销某次操作,revert操作前后的的commit和history都会保留,并把这次提交作为一次新的提交
git revert HEAD
------撤销前一次提交git revert HEAD^
------撤销前一次的前一次提交git revert <commitHash>
------撤销指定的版本
5.1 revert的工作流程
假如,我们正在重新做一个新的项目,我们初始化了一个git项目
git init 项目名
第一个正式版本之前的最后一个commit点我们假设为A
这时候你突然猪脑过载,把后面的需求合入进去了,我们假设这次提交为B,节点就为A->B
这时候你就很慌,因为你的代码已经上到了正式版本
为了解决这个问题,你要把B这个提交的影响去掉
这时候就需要用到
git revert
去将B这个操作撤销撤销后我们重新提交C,这时候节点状态为:A->B->C(需要撤销的提交还是在的,来留住你的猪脑过载)
这时候虽然在A的基础上已经有B、C两个提交,但是我们revert后,A、C两个节点是一样的
5.2 git revert和git reset的区别
这时候就会有人问,git revert和git reset都可以实现撤销,git revert还会保留自己的黑历史,为什么要使用git revert呢?这就应该看下git revert和git reset的区别。
- git revert和git reset的区别:
-
git revert是新提交一个commit来覆盖掉错误,相当于你写错了字,用修正带把错误的字盖住后,重新写一个正确的;而git reset是将commit删除掉,相当于你在写一篇作文,这一页的字你写错了,你把这一页撕掉重新写。
-
git reset是将commit节点往前提一个,而git revert是直接在节点之后再新加一个commit节点
-
git revert由于是你覆盖掉了你的错误变更,因此即使与别的分支merge了,之前解决的问题也不会出现。而git reset是删除掉了commit,这就会导致merge时可能会将之前的问题重新弄出来
-