SourceTree 拉取、重置提交、回滚、变基与合并
SourceTree的重置当前分支到此次提交
使用场景:“我想把已提交未推送的修改撤销”
使用模式 | 说明 |
---|---|
软合并 | 软合并是指将此次提交回滚到指定提交位置,但这个过程中会将修改过的文件暂存到暂存区。 |
混合合并 | 混合合并是指将此次提交回滚到指定的位置,但这个过程中不会将修改过的文件暂存到暂存区,而是将修改过的文件存放在未暂存文件区。 |
强行合并 | 强行合并是指将此次提交回滚到指定的位置,但这个过程中将直接丢弃之前修改的所有文件, 因此在选取此种合并时需要考虑清楚,避免一些不必要的麻烦。 |
SourceTree 拉取选项
第一个是你有改动的文件要提交,不然合并失败
第二个是你提交文件的描述在合并时也会显示,就是合并的内容是你提交的信息
第三个是将远程的修改首先放到暂存区,由自己来创建一个新的提交然后再推送到远程
第四个是接下来要说的变基与合并
git fetch 从远端仓库下载新分支与数据
git pull 从远端仓库提取数据并尝试合并到当前分支
Git 有两个命令用来从某一远端仓库更新。 git fetch 会使你与另一仓库同步,提取你本地所没有的数据,为你在同步时的该远端的每一分支提供书签。 这些分支被叫做“远端分支”,除了 Git 不允许你检出(切换到该分支)之外,跟本地分支没区别 —— 你可以将它们合并到当前分支,与其他分支作比较差异,查看那些分支的历史日志,等等。同步之后你就可以在本地操作这些。
第二个会从远端服务器提取新数据的命令是 git pull。 基本上,该命令就是在 git fetch 之后紧接着 git merge 远端分支到你所在的任意分支。 不太喜欢这命令 —— 也可以 fetch 和 merge 分开来做。少点魔法,少点问题。 不过,如果你喜欢,你可以看一下 git pull 的 官方文档。
假设你配置好了一个远端,并且你想要提取更新,你可以首先执行 git fetch [alias] 告诉 Git 去获取它有你没有的数据,然后你可以执行 git merge [alias]/[branch] 以将服务器上的任何更新(假设有人这时候推送到服务器了)合并到你的当前分支。
SourceTree 变基与合并
- 两者都可以把别人提交的代码,同步到自己的开发分支。
- “合并”,从SourceTree的图表上看,会有多条线。而“变基”只有一条蓝色的线(如下图)。
变基操作在SourceTree上的使用
假设“变基”的使用场景
多人同时开发,小明同学在dev1分支上开发,“我”在dev2分支上开发;
小明同学开发完成并提交了代码到他的dev1分支上,“我”也开发完成并提交到dev2上;
现在“我”要把小明的代码,同步到“我”的分支,也就是,dev1同步到dev2。
“变基”的操作步骤
- 小明同学提交代码到 develop,“我”把分支切换到 develop,并拉取最新代码
- 然后“我”切换到 fix-bug,并选中小明同学提交的 develop 分支代码
- 鼠标右击,选中“变基”
- 点击“确定”,变基完成
点击变基后可能直接完成变基,也可能会出现如下图情况,需要手动点击拉取按钮,如果没冲突“提交”按钮就会亮起,有冲突解决冲突后再提交,即可完成变基操作。
变基的影响
总结下来,Git变基的作用也是整合变更,首先在待合并分支执行变基,最后还是归于分支合并,但是在这个过程与直接合并分支还是有差别,正如本文的例子,可以看出变基会保留分支的提交历史,但是是通过将其并入主线保存的,之后关于该分支开发的具体历史及关系,已经被遮盖了,即历史已被休整,而我们通过直接合并分支方式整合变更时,分支的提交记录依然可以以分支的形式独立存在,历史未被修改。
选择变基还是合并
变基会修整历史,然后将分支历史并入主线,可以理解成美化过的历史,而合并则可以不修改历史,让分支历史依然独立存在,可以看作原始的历史。
所以选择变基还是合并,看具体需求,你只是想要一个清晰,明了的历史,并不关系历史的具体来源,你可以首选变基,但是如果你想比较清楚地了解项目不同阶段的原始历史,你可以选择直接合并。
一个原则:永远不要对已经推到主干分支服务器或者团队其他成员的提交进行变基,我们选择变基还是合并的范围应该在自己当前工作范围内。
SourceTree 回滚提交
使用场景:“我想把某一次的错误修改全部撤销”
已提交未推送,已提交已推送的都可以回滚到
Git中的HEAD
解释
HEAD
HEAD 指向当前所在分支提交至仓库的最新一次的 commit
# 使用最新一次提交重制暂存区
git reset HEAD -- filename
# 使用最新一次提交重制暂存区和工作区
git reset --hard HEAD
# 将 commit log 回滚一次 暂存区和工作区代码不变
git reset --soft HEAD~1
HEAD~{n}
~
是用来在当前提交路径上回溯的修饰符
HEAD~{n}
表示当前所在的提交路径上的前 n 个提交(n >= 0):
HEAD = HEAD~0
HEAD~ = HEAD~1
HEAD~~ = HEAD~2
HEAD{n个~} = HEAD~n
HEAD^n
^
是用来切换父级提交路径的修饰符。当我们始终在一个分支比如 dev 开发/提交代码时,每个 commit 都只会有一个父级提交,就是上一次提交,但当并行多个分支开发,feat1, feat2, feat3,完成后 merge feat1 feat2 feat3 回 dev 分支后,此次的 merge commit 就会有多个父级提交。
示例:
# 当前提交
HEAD = HEAD~0 = HEAD^0
# 主线回溯
HEAD~1 = HEAD^ 主线的上一次提交
HEAD~2 = HEAD^^ 主线的上二次提交
HEAD~3 = HEAD^^^ 主线的上三次提交
# 如果某个节点有其他分支并入
HEAD^1 主线提交(第一个父提交)
HEAD^2 切换到了第2个并入的分支并得到最近一次的提交
HEAD^2~3 切换到了第2个并入的分支并得到最近第 4 次的提交
HEAD^3~2 切换到了第3个并入的分支并得到最近第 3 次的提交
# ^{n} 和 ^ 重复 n 次的区别
HEAD~1 = HEAD^
HEAD~2 = HEAD^^
HEAD~3 = HEAD^^^
# 切换父级
HEAD^1~3 = HEAD~4
HEAD^2~3 = HEAD^2^^^
HEAD^3~3 = HEAD^3^^^
其他 Git 问题参考
Git飞行规则(Flight Rules) 40+k(star)
参考资料:
Git 变基-官网
Git 变基-w3cschool