代码编织梦想

【IDEA结合Git实现项目管理实战】四、git冲突篇

前言

本系列将结合我个人参与团队协作开发项目的经验来介绍如何使用IDEA结合Git实现项目管理,因此可能与真正的企业开发协作存在差异,且文章所涉及的解析可能存在个人理解与实际的偏差。

本系列主讲如何具体操作,因此对于Git内部的原理将不会过多深究

本文严禁任何形式的转载、搬运!

在使用Git进行项目管理时,代码合并是一项常见而重要的操作。本文将重点探讨两种常用的代码合并操作:合并(merge)和变基(rebase)。在进行代码合并时,我们难免会遇到Git冲突的情况。本文也将通过举例详细介绍如何通过IDEA使用Git进行合并或变基操作时可能遇到的代码冲突情况,并提供解决方法。

什么是git冲突

在多分支并行处理时,每个分支可能基于不同版本的主干分支创建。如果每个分支都独立开发而没有进行代码合并,自然不会出现代码冲突。但是,当两个分支同时修改同一文件时,在代码合并时就会出现冲突。

下图为两个分支分别使用合并/变基操作解决冲突后的提交树。

解决git冲突

介绍完冲突出现的原因,那么如何解决冲突呢?在解决git冲突时,我们需要确定以哪个分支的文件版本为准,或者取两个分支的文件的部分片段进行整合。

IDEA提供了强大的冲突解决功能,供用户处理git冲突。下面将进行详细介绍。

当前分支dev1的代码:

package com.hmdp;

import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.redisson.api.RedissonClient;
import org.springframework.boot.test.context.SpringBootTest;

import javax.annotation.Resource;

@Slf4j
@SpringBootTest
class JavaTest {

    @Resource
    private RedissonClient redissonClient;

    @Test
    void method1() {
        // 打印hello world
        System.out.println("hello world");

    }
    void method2() {
        // 打印你好 世界
        System.out.println("你好 世界");
    }
}

目标分支dev的代码:

package com.hmdp;

import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.redisson.api.RedissonClient;
import org.springframework.boot.test.context.SpringBootTest;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;

@Slf4j
@SpringBootTest
class JavaTest {

    @Resource
    private RedissonClient redissonClient;


    @Test
    void access() {
        //打印Red Dead:redemption2
        System.out.println("Red Dead:redemption2");

    }

    @Test
    void access2() {
        //打印荒野大镖客:救赎2
        System.out.println("荒野大镖客:救赎2");

    }

}

我们现在的目标是让两个分支合并后的代码中同时出现method1、method2、access和acess2这四个方法

执行合并后,出现界面:

左侧为当前分支dev1的提交记录,中间为合并前的预览结果,右侧为目标分支dev的提交记录。

其中红色区域为代码存在差异的部分。

先来看第一块红色区域的中间部分的代码。大家一定会疑惑预览结果里出现这段代码是什么意思?为什么会出现报错呢?

<<<<<<< HEAD
=======
import java.util.concurrent.TimeUnit;
>>>>>>> dev

这里其实是git对于左右侧存在差异的代码的标记。符号<<<<<<< xxx的下方是左侧存在差异的代码,符号>>>>>> xxx的上方是右侧存在差异的代码,比如<<<<<<< HEAD箭头所指方向也就是我们当前分支的方向(在左侧),在该箭头下面的部分是当前分支的与目标分支的差异代码,这里因为左侧比右侧少了一段代码,因此下面啥东西没有;=======代表分割符号,该分割符号的下面就是目标分支的代码,即import java.util.concurrent.TimeUnit>>>>>>> dev也就代表目标分支的方向(在右侧)

那么如何解决冲突呢?对于我们的目标来说,我们的输出语句自然不需要导入这个包,因此把语句import java.util.concurrent.TimeUnit;给删除即可。

点击左侧的箭头符号,可以把中间区域被替换成左侧的红色区域(那根细线,也就是没有代码)。

点击后中间区域消失。

再来看第二个红色区域,根据我们的目标,我们要将这四个方法都添加进入中间区域。

先点击左侧的箭头。可以发现中间区域被替换为左侧代码,右侧向左箭头变成了向左下箭头。

这个向左下的箭头代表将右侧的代码添加到中间代码的下方

点击后如图:

那么一切就大功告成了,冲突解决成功,点击右下角应用按钮。

git提示还有冲突未处理,这是为什么?

把界面翻到上面,发现这个红色区域还没有处理,我们点击那个叉号,作用是将冲突标记为已解决

这时IDEA提示所有变更已被处理,那么我们就可以放心大胆的合并了。

合并成功!

合并/变基详解

合并(git merge)

当前分支和目标分支执行合并操作时,Git会将当前分支的最新提交记录与目标分支的最新提交记录合并,并在当前分支形成一个新的提交记录

示例1

当前分支为dev1,目标分支为dev,目标分支dev中存在两条当前分支dev1分支没有的提交记录。

执行合并操作,dev中的提交记录添加到了分支dev1中。

示例2

当前分支为dev1,目标分支为dev,当前分支dev1中存在两条目标分支dev分支没有的提交记录。

执行合并操作,git给出提示(已是最新 删除dev),当前分支dev1没有变动。

示例3

当前分支为dev1,目标分支为dev,当前分支dev1中有新的提交记录添加测试类,目标分子dev中有新提交记录添加新文件(该示例由于都是添加新文件,没有对同一文件进行更改,因此不存在代码冲突)

dev1中添加了一个JavaTest文件。

dev分支中添加了一个test.lua文件。

执行合并操作,在目标分支dev1中生成一个新的提交记录Merge branch 'dev' into dev1,该提交记录包含了这两个提交记录的变更,如图。

在提交树中,可以看到两个提交记录合并为一个记录。

变基(git rebase)

当前分支和目标分支执行变基操作时,Git会将目标分支的最新提交记录依次应用到当前分支的每个新的提交记录中。

示例1

当前分支为dev1,目标分支为dev,目标分支dev中存在两条当前分支dev1分支没有的提交记录。

执行变基操作,dev中的两条记录添加到了dev1中。

示例2

当前分支为dev1,目标分支为dev,当前分支dev1中存在两条目标分支dev分支没有的提交记录。

执行变基操作,没有发生变化。

示例3

当前分支为dev1,目标分支为dev,当前分支dev1中有新的提交记录添加测试类,目标分子dev中有新提交记录添加新文件(该示例由于都是添加新文件,没有对同一文件进行更改,因此不存在代码冲突)

dev1中添加了一个JavaTest文件。

dev分支中添加了一个test.lua文件。

执行变基操作,dev分支的提交记录添加到了dev1分支中。

总结

可以发现,无论是对于合并还是变基操作的示例1和示例2,最终执行操作后的结果都是一样的。对于合并操作,git将两个分支进行合并,最后生成一个新的提交记录,提交树存在交叉。对于变基操作,git将目标分支的提交记录应用到当前分支,提交树仍然是线性的。如图所示。

至于在实际开发中选择合并还是变基,还是看个人喜好了。

代码冲突示例

注意:本文为方便理解,所有示例均简单的修改项目中的md文件,实际开发中可能存在对多个文件的冲突,但万变不离其宗,只要你具备了解决单个文件代码冲突的能力,那么多个文件的冲突也能轻松应对。

合并/变基分支1

分支情况,当前dev1的两个提交记录博文1博文2都在dev的提交记录博文3之前,其余分支一样

时间顺序:博文1->博文2->博文3

合并

此时合并有代码冲突,解决这个冲突。

发现该冲突只针对博文2,也就是最后一个提交记录

变基

该冲突为博文1博文3的冲突

该冲突为变基后的博文1博文2的冲突

合并/变基分支2

分支情况:

dev中的博文3在dev1中的博文1博文2之间

时间顺序:博文1->博文3->博文2

合并

基于上述情况,合并分支存在代码冲突

在代码冲突中,存在博文2和博文3的冲突,

冲突解决后如图所示。

这里紫色因为博文3是属于别的分支过来的,其父提交是add README.md.。所以从add README.md.出发,与dev1原本的提交记录博文2结合形成一个新的提交记录Merge branch 'dev' into dev1

结论:分支以时间顺序进行排序,合并分支永远是两个分支的最后一个提交历史进行合并。

变基

博文1博文3存在冲突

冲突解决后,选择提交消息不变

依然存在冲突

可以发现该冲突来自于已经变基的提交博文1和之后的博文2

得到变基后的提交树

合并/变基分支3

分支情况:

dev1中的两个提交记录博文1博文2在dev中的博文3提交之后

时间顺序:博文3->博文1->博文2

合并

博文2博文3存在代码冲突

变基

冲突来自于博文3博文1

冲突来自变基后的博文1博文2

总结

通过这三个代码冲突的示例,看到区别了吗?

在合并操作时,冲突通常发生在两个分支的最新提交记录上。这是因为合并是将两个不同的分支合并为一个,而最新的提交记录是两个分支的端点。如果两个分支都对同一文件进行了修改,Git 无法确定应该选择哪个更改,因此会产生冲突。

在变基操作时,冲突可能发生在当前分支的提交记录和目标分支的提交记录之间的每个提交记录上。这是因为变基是将一系列提交应用到另一个分支上,而不仅仅是最新的提交。如果两个分支都修改了相同的文件,冲突可能会在每个提交记录上发生,而不仅仅是最新的提交。

总的来说,冲突是由于两个分支都对同一文件进行了修改,而 Git 无法自动解决冲突的情况下发生的。在合并操作中,冲突通常发生在最新的提交记录上;在变基操作中,冲突可能发生在多个提交记录上。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/k123456kah/article/details/135394867

基于idea 工程项目的git实操_nanke_yh的博客-爱代码爱编程

目录 一、从远程仓库clone项目到本地,修改后推送 1、clone仓库到本地 2、修改、添加、提交和push文件 〇新建分支: ①用命令git add告诉 Git,把文件添加到仓库: ②用命令git commit告诉 Git,把文件提交到仓库: ③向远程仓库推送修改得代码文件 二、Idea新建项目并推送到远程仓库 1、创建本地仓库 2

git实战篇,教你如何使用git可视化工具_github绿色按钮可视化操作-爱代码爱编程

系列文章目录 手把手教你安装Git,萌新迈向专业的必备一步 GIT命令只会抄却不理解?看完原理才能事半功倍! 快速上手GIT命令,现学也能登堂入室 GIT实战篇,教你如何使用GIT可视化工具 系列文章目

mac idea 自动补全mybatis sql语句-爱代码爱编程

导航 Mac IDEA 自动补全mybatis sql语句一、点击IDEA 右侧Database选项二、选择添加对应数据库三、输入数据库信息和方案四、输入数据库信息和方案五、成功 Mac IDE

基于idea快速创建一个springmvc项目并且配置tomcat-爱代码爱编程

1,打开IDEA,新建Maven项目【使用web模板创建】 使用社区版的同学创建普通的maven项目,并配置项目的webapp,详情可参考 快速创建一个SpringMVC项目(IDEA) 2,在main目录下创建Jav

【idea结合git实现项目管理实战】三、实战篇-爱代码爱编程

IDEA结合Git实现项目管理实战——实战篇 前言 本系列将结合我个人参与团队协作开发项目的经验来介绍如何使用IDEA结合Git实现项目管理,因此可能与真正的企业开发协作存在差异,且文章所涉及的解析可能存在个人理解

jetbrain | idea的启动logo替换成可爱的vtuber-爱代码爱编程

看了这个,好可爱 【上Github热榜了!当编程语言的Logo变得可爱起来~】  又看了这个 光速整活,强啊 看到很多人整IDEA的logo包括我自己,都不是特别方便的搞,我就直接把文件放在绑定资源里直接下吧 然后直接找到本体的安装文件夹下找到lib文件夹 IntelliJ IDEA Ultimate\lib 然后找到jar

idea 引导-爱代码爱编程

1、常用插件: 阿里代码规范插件:Alibaba Java CodingGuidelinesai 编程辅助插件:GitHub CopilotMyBatis 辅助插件:MyBatisX 2、MyBatisX 由于和 lombok 有冲突,会出现某些奇怪的爆红问题,如果出现可参考: IDEA中MyBatis的mapper文件 实体类名报红 Canno

idea新建项目/模块找不到spring initializr-爱代码爱编程

idea创建项目找不到spring intellij,如下图 解决 可能是没有下载spring的相应插件,或者没有启用对应的插件 我这里就是没有启用插件,导致的创建项目时找不到按件。 全部启用后,重启idea即可。 重

idea2023的激活与安装-爱代码爱编程

IDEA2023是一款功能强大的集成开发环境(IDE),被广泛用于Java开发和其他编程语言开发。它提供了丰富的功能和工具,可以帮助开发人员更高效地编写、调试和测试代码。下面是关于IDEA2023的激活和安装的详细步骤和说明,全文约一万字。 第一部分:激活 第一步:下载安装包 首先,你需要下载IDEA2023的安装包。你可以在官方网站上找到适用于你操作系

idea中一些常见操作【持续更新】-爱代码爱编程

文章目录 前言善用debugidea中debug按钮不显示自动定位文件【始终选择打开的文件】idea注释不顶格【不在行首】快速定位类的位置【找文件非常快】创建文件添加作者及时间信息快速跳转到文件顶端 底端