vscode中的git插件将git操作从git指令简化到简单的图形界面操作,不用再去记忆git指令,操作简单直观了很多。第一次使用时,为了加深理解,我将一些基本操作和该操作底层使用的命令结合起来,并包含实例,方便学习。
【git】(一)在vscode上使用git进行版本控制(结合指令、含示例)-CSDN博客
3.补充
关于上一篇文章中的版本回退部分,由于当时只安装了Git插件,找不到图形化操作的方式,所以使用Git插件查看版本号+终端输入Git指令的方式进行reset、revert。
单一的Git插件还没有达到可视化的最好效果,如果配合git history插件(一个可以可视化查看git 历史记录的工具),就可以实现图形化操作的回退,会更加方便,而且后文所提到的分支管理上,该插件也能更加直观,会使用到它。
安装该插件之后,回到Git插件,仓库后面会出现一个时钟图标,该图标就是Git History的入口。
【vscode中的操作】
点击时钟图标,进入Git历史,可以很轻易的对任意分支的任意版本作软回退、硬回退操作。
对于版本撤销的操作,点击上图的More->找到Revert命令,非常方便。
4.分支管理
在 Git 中,分支是项目代码的一个独立线,允许开发者并行工作而不互相干扰。分支使得特性开发、错误修复和实验可以在主线之外进行,简化了代码管理和协作流程。
4.1查看、创建、切换、删除分支
4.1.1查看当前分支
【vscode中的操作】
Git插件中:下图所框选区域,展现了当前分支。
vscode页面左下角,也有提示当前分支:
【对应的git指令】
查看当前分支
git branch
4.1.2 创建分支
(一)在当前版本创建分支
在 Git 中,创建分支本身不会影响工作区或暂存区的更改。当创建一个新分支时,Git 只是简单地创建一个新的引用(指针)来指向当前分支的最新的提交。工作区和暂存区的更改与分支的创建是独立的。因此,创建分支时,工作区和暂存区的更改会跟随到切换到的任何分支,一旦在新的分支上提交了,即使切换回去,也不会再出现了,只会保留该分支的最新提交版本。
->最好在切换分支之前,确保工作区是干净,即处理未提交的更改,这是一个好习惯。
【vscode中的操作】
点击当前分支,即上文中框选出来的区域,会弹出checkout弹窗,选择“创建新分支”,然后输入新的分支名。(假如这个分支由小郑负责,就用小郑命名)
此时,当前分支变成了“小郑”
【对应的git指令】
创建一个新分支(不切换)。将<branch_name>替换为分支名称(在这个例子中是“小郑”)。
git branch <branch_name>
创建并切换到新分支。这里的
-b
参数告诉 Git 创建一个新的分支,并且立即切换到这个分支。
git checkout -b <branch_name>
【结果】此时查看git history,有两个分支指向同一个版本:
(二)在指定版本创建分支
有时候,可能想要从一个特定的历史版本创建一个新的分支,而不是从当前分支的最新提交。一般场景:修复一个旧版本的bug,或者基于旧版本开发新功能时。
【vscode中的操作】
进入git history,找到指定版本,点击“+Branch”,即可在该版本创建分支,并命名该新分支。假如在初版0.1版本需要创建一个新分支“小胖”,则按照下图示例。
【对应的git指令】
首先需要找到该提交的版本号。使用git branch命令从特定提交创建新分支。将
<branch_name>
替换为新分支的名称,将
<commitID>
为特定提交的版本号。
git branch <branch_name> <commitID>
【结果】此时查看git history,历史版本中出现新分支“小胖”
4.1.3 切换分支
【vscode中的操作】
两种方法:
①git history中,点击绿色的分支名称,会直接切换。
②git插件/页面左下角,点击当前分支名称,列表最下方为所有分支,点击切换到目标分支。
【对应的git指令】
切换分支,将<branch_name>替换为分支名称。
git checkout <branch_name>
4.1.4 删除分支
对于不再需要的分支,例如已经合并到主分支并且完成了它们的功能的分支,可以进行删除。在 Git 中,不能直接删除当前所在的分支,要先切换到想要删除的分支以外的其他分支才能进行操作。
【vscode中的操作】
两种方法:
①git history中,点击绿色的分支名称旁边的红色叉叉,会直接删除。
②git插件中,如下图所示,点击Branch选项下的Delete Branch,vscode会引导用户从所在分支之外的所有分支进行选择、
【对应的git指令】
将<branch_name>替换为想要删除的分支名称。这个命令在删除前会进行检查,只有在该分支已经被合并的情况下才会成功。
git branch -d <branch_name>
如果想要强制删除一个还有未合并更改的分支,可以使用
-D
参数。
git branch -D <branch_name>
4.2 合并分支
在 Git 中,合并(Merge)操作是将两个分支的更改结合起来的过程。这通常发生在一个特性分支开发完成后,需要将更改合并到主分支时。操作时要注意合并的方向,是将其他分支的更改合并到当前的分支,因此该操作一般是在master分支上进行的
4.2.1 合并操作
【vscode中的操作】
git插件中,先切换到主分支,根据下图点击Branch选项下的Merge,vscode会引导用户从所在分支之外的所有分支选择待合并的分支。
【对应的git指令】
将<branch_name>替换为选择合并到当前分支的分支名称。如果合并过程中没有冲突,Git会自动创建一个新的合并提交,这个提交会包含两个分支的共同祖先以及<branch_name>分支的最新提交。
git merge <branch_name>
【示例】
(1)在“小郑”的分支中,对test1、test2都添加一行字符串,作为版本1.0,然后提交。
(2)仍然在“小郑”分支里,删掉一部分上次提交时添加的字符串,作为版本1.1,再次提交。
(3)回到master分支,该分支还停留在revert 0.2版本。此时源代码管理器只能显示该分支下的历史版本,而git history可以看到全部分支的信息。【这里指向有延迟问题,“小郑”分支的HEAD应当指向版本1.1】
(4)进行合并操作。再次观察该分支的历史版本和git history中的分支情况。此时,master分支的源代码管理图中延伸到了小郑的版本1.1,即合并了小郑的修改。【这里指向有延迟问题,master分支的HEAD应当指向版本1.1】【一些更正】
之前我误以为git history中各分支的图标不反映HEAD的指向,但经过再次验证,我发现这个图标实际上确实代表了当前HEAD的指向。我之前的观察可能是因为插件更新的延迟导致的误解。【git插件的源代码管理图是完全准确的,没有任何问题】
所以上面图中的分支指向的位置和分析并不完全正确,在第3步时小郑分支应当指向版本1.1,第4步时两个分支都应该指向版本1.1(如下图所示)。
【关于HEAD】
HEAD是一个引用,它指向当前分支的最新提交。当切换分支时,HEAD也会随之改变,指向新分支的最新提交。当合并其他分支到当前分支时,HEAD指向的分支的最新提交会更新为合并后的提交。
4.2.2 合并冲突
如果合并过程中出现冲突,Git会停止合并并让用户手动解决这些冲突。
(一)合并机制
1. 如何判断合并是否成功?
合并是否成功可以通过多种方式来判断,其中一种方法是查看HEAD指向是否一致。在合并之前,如果两个分支的HEAD指向不同的提交,那么合并后,如果HEAD指向更新为最新的共同祖先提交,则表明合并是成功的,没有冲突。
2. 为什么上面的示例中没有合并冲突?
在上面的例子中,“小郑”在
master
分支的
revert 0.2
版本基础上创建了一个新的分支,并在该分支上进行了修改。在这个过程中,
master
分支没有进行任何新的提交,这意味着两个分支在代码上是完全一致的,直到“小郑”分支的修改被合并回去。没有合并冲突的原因是两个分支在代码上没有重叠的修改。
3. 合并冲突通常发生在以下几种情况:
- 同一行数据两边都做了修改:这是最常见的合并冲突情况,两个分支在同一行都有不同的修改。
- 一个分支删除了一行,另一个分支修改了这一行:这种情况下,删除操作和修改操作冲突,因为一个分支认为这一行不存在,而另一个分支认为它存在并进行了修改。
- 一个分支添加了一行,另一个分支在同一位置也添加了一行:如果两个分支都在相同位置添加了不同的内容,这也会导致合并冲突。
4. 不会出现合并冲突的场景
- 一个分支修改了一行,另一个分支没有修改这一行:这种情况下,Git可以很容易地将修改应用到另一个分支。
- 一个分支删除了一行,另一个分支没有操作这一行:这种情况下,删除操作可以被应用,因为另一个分支没有冲突的操作。
- 一个分支添加了一行,另一个分支没有操作这一行:这种情况下,添加操作可以被应用,因为另一个分支没有冲突的操作。
- 代码重构不影响其他分支的修改:如果一个分支对代码进行了重构,但这些更改不影响另一个分支所做的修改,那么合并时不会有冲突。
- 格式修改与内容修改不冲突:如果一个分支修改了文件的格式(如添加空格、更改换行符),而另一个分支修改了文件的内容,通常这些修改可以合并,不会产生冲突。
在Git中,当你尝试合并两个分支时,Git首先会寻找这两个分支的共同祖先。共同祖先是两个分支最后分开的那个提交点,即两个分支的最近公共祖先提交。上述的“删除”、“修改”、“添加”
在进行合并时,Git会尝试自动按照4所述规则合并变更。如果合并过程中遇到无法自动解决的冲突(3所述场景),Git会将这些有冲突的位置指示出来,让开发者手动解决。即,手动合并的文件是Git已经按照规则合并后的文件,Git会尽可能地自动合并两个分支的更改,并将合并后的结果展示给开发者。显示出来的冲突部分并不代表两个文件的全部差别,仅表示Git无法自动解决,****需要手动解决的部分,该部分Git使用特殊的标记(如
<<<<<<<
,
=======
,
>>>>>>>
)来标识。
解决冲突后,需要使用git add命令将解决后的文件标记为已解决,然后通过git commit完成合并。
(二)解决合并冲突
当Git检测到合并冲突时,VS Code会提供一个直观的界面来帮助解决。
①打开冲突文件:VS Code会高亮显示所有存在冲突的文件,并在“源代码管理”边栏中列出它们。②查看冲突标记:在冲突文件中,Git的冲突标记(
<<<<<<<
,
=======
,
>>>>>>>
)会清晰地标识出不同分支的更改。
③编辑文件解决冲突:决定保留哪部分代码,或者结合两边的更改;删除Git添加的冲突标记。
【示例】
(1)在“Revert 初版0.2”版本创建一个分支“小庞”,此时小庞分支的test1、test2文件分别是0.2、0.1版本的。
(2)小庞在这个版本的基础上,对test1文件修改了一行名称,把地名反过来了;对test2文件修改了一行数值,去掉了小数点;并将两个文件都命名为1.2版本,然后暂存、提交。观察此时的git history,相比于git插件的管理图,这里就能展现出git history的多分支可视化优势了。
(3)切换到master分支,合并小庞分支
此时出现了合并冲突,两个文件的git状态变成了!,鼠标悬浮在上面,显示“冲突:两个都已修改”,告知了冲突的原因:两边分支同时修改了同一行数据(上面3所述场景中的第1个场景 )
(4)手动合并。打开test2文件,只显示了一个待手动解决的冲突,即所提示的两边同时修改的冲突,其他差异被自动合并了。文章上方给予了四个操作选项,可以使用该选项减少操作,或者直接在文件中编辑。假如使用“保留双方更改”,会将需要手动合并的部分同时保留。
(5)暂存、提交,完成合并。查看git history
版权归原作者 colfree 所有, 如有侵权,请联系我们删除。