什么是Git,以及其有什么作用呢?

1、什么是git

Git是一个开源的分布式版本控制系统,是目前世界上最先进,最流行的版本控制系统。其特点是项目越大越复杂时,协同开发者越多,越能体现出Git的高性能和高可用性。git快速和高效,一是因为它能直接记录快照,而非差异比较;二是几乎所有操作都是本地执行。

Git对象

2、git的基本使用

git可以帮助我们做很多的事情,比如代码的版本控制,分支管理等。git里面主要包含的几个概念有远程仓库,克隆,本地仓库,分支,提交,拉取,合并,推送等。远程仓库是指我们代码存储在服务器的地方,这个仓库是我们整个团队中所有人都可以访问的地方。【git工作目录下对于文件的修改(增加、删除、更新)会存在几个状态,这些修改的状态会随着我们执行git的命令而发生变化。】

git commit:暂存区-->本地仓库

git add:工作区-->暂存区

  • 克隆:从远程仓库克隆到本地的过程。本地仓库指的是我们开发人员从远程仓库克隆一份代码之后,保存在我们本地的代码,这份代码只有克隆的代码的开发人员可以看到。
  • 分支:我们在开发中可能会遇到多个分支进行,比如主分支(master分支),开发分支(develop分支),但我们开发的时候,一般不在master上面进行开发,而是我们自己单独的从主分支或者开发分支中在分出来一条分支(比如test分支),然后我们就在test分支上进行开发,每个分支都有自己的代码。
  • 提交:在我们的代码开发完成之后,需要将代码进行提交,提交的时候需要我们将修改的文件进行提交,并说明修改的内容。注意,此时代码提交只会提交到我们本地的仓库,远程仓库此时还不会修改。
  • 拉取:开发中,同一个项目可能是多人协作开发,这个时候,我们就需要将别人修改的代码拉去下来合并到我们自己的代码中。但是如果不同的开发人员修改了统一部分代码,那么就可能发冲突,这时候我们需要解决完冲突时候,才能继续将代码进行提交。
  • 合并:在上面我们自己的分支开发完成之后,没有问题之后,需要将我们的分支合并到主分支上面。
  • 推送:之前的所有操作都是在我们本地进行的,远程仓库的代码并没有任何的改变,这个时候就需要我们将本地的代码推送到远程的仓库中,更新远程仓库代码。在推送的过程中,如果我们本地的代码不是最新版本的,就需要我们先将远程代码拉去下来(如果有冲突重新解决冲突,提交),然后在重新推送。

3、获取本地仓库

1)在电脑的任意位置创建一个空目录(例如test01)作为我们的本地git仓库

2)进入这个目录中,点击右键打开git bash窗口

3)执行命令git init(初始化当前目录为一个git仓库)

4)如果创建成功后可在文件夹下看到隐藏的.git目录。

4、git常用命令

1、提交步骤

git init:初始化git仓库

git status:查看文件状态

git add:文件列表追踪文件

git commit -m:提交信息,向仓库中提交代码

git log:查看提交记录

2、撤销

用暂存区中的文件覆盖工作目录中的文件: git checkout 文件名
将文件从暂存区中删除: git rm --cached 文件名
将 git 仓库中指定的更新记录恢复出来,并且覆盖暂存区和工作目录:git reset --hard commitID

3、暂时保存更改

在git中,可以暂时提取分支上所有的改动并存储,让开发人员得到一个干净的工作副本,临时转向其他工作。
使用场景:分支临时切换
存储临时改动:git stash
恢复改动:git stash pop

5、git分支常用命令

git branch 查看分支
git branch 分支名称 创建分支
git checkout 分支名称 切换分支
git merge 来源分支 合并分支 (备注:必须在master分支上才能合并develop分支)
git branch -d 分支名称 删除分支(分支被合并后才允许删除)(-D 强制删除)

6、查看某些状态(重点)

1、查看修改的状态(status)  git status

作用:查看的修改的状态(暂存区、工作区)

2、添加工作区到暂存区(add) git add 单个文件名|通配符

作用:添加工作区一个或多个文件的修改到暂存区

3、提交暂存区到本地仓库(commit)     git commit -m '注释内容'

作用:提交暂存区内容到本地仓库的当前分支

4、查看提交日志(log)  git log

作用:查看提交记录

7、应用场景中常遇到的问题

1)与其他人同时修改远程仓库的同一个文件的不同部分,例如不同行代码,其他人先执行git push,然后自己再执行git pull更新后,会导致其他人对这个文件的修改覆盖自己对这个文件的修改吗。?

解答:通常不会直接覆盖,但可能会产生合并冲突,需要开发人员手动解决。

核心原则:git的合并机制。Git不是简单地用“新文件”覆盖“旧文件”。

当你执行git pull时,它实际上是两个命令的组合:

  • git fetch:将远程仓库的最新内容下载到本地,但不修改你的工作文件。
  • git merge:尝试将远程的更改(别人提交的)和你本地的更改(你还没提交的)合并到一起。

场景推演:

假设初始文件状态为版本A:

1.你和其他人同时基于版本A开始修改:

  • 你修改文件的第10-20行
  • 你的同事修改了文件的第50-60行
  • 你们修改的是不同的行

2.同事先推送

  • 同事完成修改,提交(commit),然后执行git push
  • 现在远程仓库的文件状态为版本B(包含同事对50-60行的修改)

3.你在本地提交,然后尝试拉取

  • 你在本地完成了对10-20行的修改,并执行了git commit,生成了你的本地提交
  • 此时,你本地的历史是:版本A->你的提交
  • 远程的历史是:版本A->同事的提交

4.你执行git pull

  • git fetch将远程的版本B下载下来
  • git merge开始工作,它会比较三个版本

          1)共同祖先:版本A

          2)远程分支的头:版本B(同事的修改)

          3)你当前分支的头:你的本地提交(你的修改)

  • git会进行只能分析:从分析A开始,同事改了50-60行,你改了10-20行。这些修改互不干扰。
  • 在这种情况下,git可以自动完成合并!它会生成一个新的合并提交,这个提交同时包含了你们两个的修改(即文件现在既有你对10-20行的改动,也有同事对50-60行的改动)。
  • 此时,你的工作目录中的文件就是合并后的完美版本。没有冲突,你的修改也没有被覆盖。

什么情况下会产生冲突?

如果你们的修改有交集,git无法自动决定保留哪个,就会产生冲突。例如:

  • 修改了同一行或相邻行:你对第15行做了修改,同时也对第15行做了不同的修改。
  • 其中一人删除了另一个人修改的行:第修改了第15行,但同事删除了第15-20行。
  • 文件结构发生复杂变化:比如同事命名了函数,而你在老函数名的地方添加了代码。

冲突发生时的表现:

1、当你执行git pull遇到冲突时,过程会暂停。Git会:

<<<<<<< HEAD 这是你本地修改的内容 ======= 这是远程拉取下来的内容 >>>>>>> commit-hash-of-remote

2、你需要手动打开这些文件,检查标记之间的内容,决定保留哪一部分,或者进行融合修改。

3、修改完成后,用 git add <文件名> 标记冲突已解决,然后执行 git commit 来完成这次合并。

最佳实践方案:

修改情况结果你的操作
不同部分(无重叠)自动合并成功直接推送git push即可。
相同部分(有重叠)产生合并冲突

1、手动解决冲突文件。

2、git add标记解决。

3、git commit完成合并。

4、git push

工作中最佳实施方案:

  1. 勤拉取:在开始工作前和提交前,都先执行一次 git pull,保持本地代码尽可能新,减少冲突范围和概率。
  2. 分段提交:不要一次性修改太多东西然后做一个大提交。小的、目的明确的提交更容易理解和合并。
  3. 沟通:如果团队在紧密协作同一个模块或文件,提前沟通可以避免很多冲突。
  4. 理解 pull --rebase:另一种工作流是使用 git pull --rebase。它会将你的提交“变基”到远程最新提交之后,形成一条线性的历史,有时可以使历史更整洁,但原理和 merge 不同,需要额外学习。

2)与其他人同时修改远程仓库的同一个文件的相同部分,例如修改同一行代码。其他人先执行git push,然后自己再执行git pull更新后,会导致其他人对这个文件的修改覆盖自己对这个文件的修改吗?

解答:你的本地修改不会被直接覆盖,但会产生合并冲突,你需要手动解决这个冲突。

场景推演

假设初始文件状态为版本A

1.你和其他人同时修改同一行:

  • 文件中第15行原来是:var x = 10;
  • 你将其修改为:var x = 20; // 提高性能
  • 你的同事将其修改为:var x = 15; // 折中方案
  • 你们都修改了完全相同的位置

2.同事先推送:

  • 同事提交并执行git push
  • 远程仓库变为版本B(包含同事的修改)

3.你提交后拉取:

  • 你在本地提交了你的修改,然后执行git pull
  • git会尝试合并,但发现从版本A到版本B和从版本A到你的本地提交都修改了同一行。

4.git的应对:

  • git无法自动决定应该保留谁的修改,因为这涉及到语义冲突,git无法智能判断。
  • git会暂停合并过程,并在文件中标记冲突。

3)如果两个人修改的是文件夹里的不同文件呢?

解答:完全不会覆盖,Git会非常顺利地进行合并。

场景推演

假设有一个文件夹包含两个文件:

  • file1.txt
  • file2.txt

1.初始状态:

  • 两个文件都是版本A的一部分。

2.两人同时修改不同文件:

  • 你修改了file1.txt
  • 你的同事修改了file2.txt

3.同事先推送:

  • 同事提交了对 file2.txt 的修改,并执行 git push
  • 远程仓库变为版本B(包含同事对 file2.txt 的修改)

4.你提交后拉取

  • 你在本地提交了对 file1.txt 的修改
  • 执行 git pull

git的合并过程

当你执行 git pull 时:

  1. Git会比较三个版本:
    • 共同祖先:版本A(两个文件都是原始状态)
    • 远程分支头:版本B(只有 file2.txt 被修改)
    • 你的本地提交:只有 file1.txt 被修改
  2. Git会分析:从版本A开始,远程修改了 file2.txt,你修改了 file1.txt
  3. Git能够轻松地将这两个独立的修改自动合并,因为它们是完全不相交的更改。

8、总结

修改情况git处理结果你的操作
不同文件自动合并成功直接推送即可
同一个文件的不同部分自动合并成功直接推送即可
同一个文件的相同部分产生合并冲突需要手动解决冲突
文件重命名/删除冲突可能产生冲突可能需要手动解决

最佳实践建议

  1. 保持原子提交:每个提交只修改相关的文件,便于理解和合并。
  2. 拉取频率:即使修改不同文件,也建议在开始工作前和推送前先拉取最新代码。
  3. 沟通协调:对于大的重构(如文件重命名、移动),提前通知团队成员。
  4. 使用分支策略:在功能分支上工作,定期合并主分支的更新,减少冲突可能性。

Read more

Java 大视界 -- 5230 台物联网设备时序数据难题破解:Java+Redis+HBase+Kafka 实战全解析(查询延迟 18ms)(438)

Java 大视界 -- 5230 台物联网设备时序数据难题破解:Java+Redis+HBase+Kafka 实战全解析(查询延迟 18ms)(438)

Java 大视界 -- 5230 台物联网设备时序数据难题破解:Java+Redis+HBase+Kafka 实战全解析(查询延迟 18ms)(438) * 引言: * 正文: * 一、技术选型:务实为王,拒绝炫技 * 1.1 核心技术栈选型对比 * 1.2 选型核心原则(10 余年实战经验总结) * 二、架构设计:闭环为王,层层兜底 * 2.1 整体架构图 * 2.2.1 生产设备层(数据源头) * 2.2.2 边缘网关层(数据预处理) * 2.2.3 消息接入层(数据缓冲) * 2.

By Ne0inhk
Java连接电科金仓数据库(KingbaseES)实战指南

Java连接电科金仓数据库(KingbaseES)实战指南

摘要:本文分享了KingbaseES V8.6数据库与SpringBoot 2.7.x框架的集成实战经验。内容包括:1. 环境准备(Ubuntu系统安装配置、驱动获取方式);2. JDBC基础操作(连接、查询、事务处理);3. SpringBoot项目完整配置(pom依赖、数据源配置);4. MyBatis-Plus集成(实体类、Mapper、Service层实现);5. RESTful接口开发示例。文章提供了详细的代码示例,涵盖从数据库安装到应用开发的完整流程,帮助开发者快速实现国产数据库适配。 目录 前言 一、环境准备与驱动获取 1.1 数据库安装与配置 1.2 JDBC驱动获取与配置 1.3 创建测试数据库 二、基础JDBC连接与操作 2.1 最基础的JDBC连接示例 2.

By Ne0inhk
【Linux系统】理解管道通信,匿名管道实现进程池+命名管道实现服务端客户端通信模型(附源码)

【Linux系统】理解管道通信,匿名管道实现进程池+命名管道实现服务端客户端通信模型(附源码)

文章目录 * 一、进程间通信是什么 * 二、管道 * 1. 什么是管道 * 2. 匿名管道 * 3. 命名管道 * 三、实例:匿名管道实现进程池 * 四、实例:命名管道实现服务端客户端通信模型 一、进程间通信是什么 进程间通信(IPC),顾名思义,进程之间需要进行信息交换。 如:数据传输、资源共享、通知事件、进程控制。 进程间通信的方式有:管道、System V IPC、POSIX IPC。 由于进程具有独立性,进程间通信的前提就是,不同的进程能看到同一份资源。 二、管道 1. 什么是管道 管道是类Unix系统中最古老的进程间通信的方式。我们把从一个进程连接到另一个进程的数据流称为一个“管道”。 管道是单向通信的,称为单工通信。 管道分为匿名管道和命名管道。 2. 匿名管道

By Ne0inhk
【Java 开发日记】我们来说一下无锁队列 Disruptor 的原理

【Java 开发日记】我们来说一下无锁队列 Disruptor 的原理

目录 一、为什么需要 Disruptor?—— 背景与问题 二、核心设计思想 三、核心组件与原理 1. 环形缓冲区(Ring Buffer) 2. 序列(Sequence) 3. 序列屏障(Sequence Barrier) 4. 等待策略(Wait Strategy) 5. 事件处理器(EventProcessor) 6. 生产者(Producer) 四、工作流程示例(单生产者 -> 单消费者) 五、多消费者与依赖关系 六、总结:Disruptor 高性能的秘诀 一、为什么需要 Disruptor?—— 背景与问题 在高并发编程中,传统的队列(如 java.

By Ne0inhk