掌握Git核心:版本控制、分支管理与远程操作

news2025/6/9 6:02:45

前言

无论热爱技术的阅读者你是希望掌握Git的企业级应用,能够深刻理解Git操作过程及操作原理,理解工作区暂存区、版本库的含义;还是想要掌握Git的版本、分支管理,自由的进行版本回退、撤销、修改等Git操作方式与背后原理和通过分支创建、切换、合并、删除整个声明周期,灵活进行各种场景的分支管理,学习常见的分支策略;亦或是掌握Git远程仓库与本地仓库,理解分布式的版本控制系统,远程仓库和本地仓库的交互操作,理解企业中常见的分支(master/release/develop/feature/hotfix等)策略掌握多人开发模式,这篇文章都能帮助到你,希望你能从中获得启发。

一、Git的版本控制

1.1、情景引入 

我们在进行求学的过程中,撰写实验报告是常有的事情,当我们进行上交第一版实验报告时,假如我们这个导师比较严格,为我们指出许多不足的地方,于是我们进行修改出第二版,还是没有通过老师的审核,继续进行更改出第三版......一直到第六版,老师说越改越糊涂,第三版是你这几版中最好的,你直接进行交第三版就行了,这时候你傻眼了,我哪记得第三版是什么样的啊,我都是直接在每一版的上一版的基础上进行修改的,此时直接寄了。。

即使是将每一版进行修改的时候进行拷贝一份,当要进行查看这一版相对于上一版的变化时,要是内容少还好,要是内容较多(比如代码)进行观察也是很麻烦的。

1.2、版本控制器

1.2.1、版本控制器的作用

为了能够更方便我们管理这些不同版本的文件,便有了版本控制器。Git是当下主流的版本控制器。

所谓的版本控制器就是可以控制电脑上所有格式文件,对于我们开发人员来说主要维护项目中的源码文件(本质上就是文本文件),对于文本文件,可以进行清晰的描述出进行增删的内容具体到某一行,但是对于二进制文件(照片、视频)只能进行粗略记录大小的变动

相信通过上面Git 版本控制的演示,已经激起了对于版本控制的求知欲,那么下面就来介绍如何进行使用Git 进行版本控制 

1.2.2、版本控制器的使用

Git 的安装(Linux)
  • centos:

以我的centos7.6为例:

sudo yum -y install git

检查是否安装成功 

git --version
  • ubuntu:

以我的ubuntu20.04为例:

sudo apt-get install git -y

 检查是否安装成功 

git --version
Git 的基础操作

要想使用 git 进行版本控制,首先要进行创建本地仓库,只有在本地仓库下,才能使用git 对本地仓库下的文件进行版本控制

  • 创建本地仓库

  •  配置本地仓库

首先要进行设置仓库(当前)的使用者名称和邮箱

git config user.name "XXX"
git config user.email "XXXXXXXXXXXXXXXXX"

补充:删除操作

 如果想要进行全部的 git 仓库进行配置执行下面的命令

git config --global user.name "XXX"
git config --global user.email "XXXXXXXXXXXXXXXXX"

 进行删除时,执行上面那种配置当前仓库的删除命令是无法进行删除的,需要执行下面的命令

git config --global unset user.name
git config --global unset user.email
版本控制的底层结构

工作区、暂存区以及版本库的认识

向上面那样在 gitcode_temp 文件下进行和.git 在同一目录下进行创建了code,文件,但是目前情况下 git 并不能对 code 文件进行管理,上面我们提及,放入本地仓库中的文件是可以被管理的,这里为什么又不能被管理了呢?其实这里是概念混淆了,我们gitcode_temp 这个目录并不是本地仓库,这个 .git 才是真正的本地仓库,通常称为版本库。

那直接将进入 .git 下 进行创建目录吗?

当然不可以,.git 下结构是不能手动进行修改的,直接在git 下进行创建目录会导致 git 结构错乱,不在能够进行版本控制。

这里采用的策略是,通过add 将工作区的修改进行放入版本库中的暂存区,commit 将暂存区的内容进行提交到master 分支,只有经历过这一步才能称为将文件进行放入到git中进行管理。

版本控制是如何做到的??

通过 git add 命令,将工作区(Working Directory)中的修改保存到暂存区(Stage / Index);然后通过 git commit,将暂存区中的快照生成一个新的提交对象(commit),并更新当前分支(如 master)指向该提交。

当工作区发生修改会在对象区进行新增一个对象,而暂存区中的分支都是指向对象区的,master 当中的分支结构也是指向对应的对象,这也是 .git 非常轻量的原因。

容易混淆的点

暂存区(Stage/Index),它是一个二进制文件(.git/index),确实存储在版本库(.git 目录中。 

但在 Git 的概念模型中,暂存区通常被视作一个“中间区域”,不是版本库真正的提交历史部分。

如何进行理解不是真正的提交历史部分?

版本库(提交历史)就像是一本日记,里面每一页都记录了历史上的一次改动(一个提交)。暂存区就像是“准备写到日记里的内容的草稿纸”。

添加文件
  • 先将工作区的文件进行添加到版本库的暂存区
    • 指定文件去新增版本库的暂存区
      git add .
    • 将工作区中的所有文件全部新增到版本库的暂存区
      git add + 指定文件名
  • 在将暂存区中的文件进行添加到分支结构中
    git commit -m "这里进行输入提交的日志信息"

通过

 git log 

进行打印 提交的信息

其中进行标注的这一列是通过哈希映射出来的提交ID

查看git文件

找到master分支中的提交管理的id后直接进行打印即可。

修改文件

git 进行管理的修改,并不是文件。

这是没有将工作区中的内容进行添加到暂存区 

 将工作区中的数据进行放到mater 进行分支管理后,通过进行产看code的状态:工作区是干净的了。

版本回退

这是git非常核心的功能

工作区暂存区版本库本质是回退版本库的内容
Invalid content:
hello git
hello world
(其中第一条是第一次进行提交的,其他都是第二次进行提交的)
Invalid content:
hello git
hello world
Invalid content:
hello git
hello world
git reset + 选项 + commit ID (使HEAD进行指向此commit ID)
Invalid content:
hello git
Invalid content:
hello git
Invalid content:-soft (选项选择)
Invalid content:
hello git
Invalid content:Invalid content:-mixed (默认选项)
Invalid content:Invalid content:Invalid content:-hard
  • -soft : 只进行回退版本库中的内容,工作区和暂存区的内容并未回退 
  • -mixed : 进行回退版本库中和暂存区的内容,工作区并未回退 
  • -hard: 工作区、暂存区、版本库中的内容全部进行回退

版本回退的原理

 本质就是更新HEAD的指向,是的HEAD指针之后的内容失效

撤销修改

如果我们在我们的⼯作区写了很长时间代码,越写越写不下去,觉得⾃⼰写的实在是垃圾,想恢复到上⼀个版本。

对于撤销修改又分为三种情况,只撤销工作区、只撤销工作区和暂存区、将工作区、暂存区、版本库中的都进行撤销。

工作区暂存区版本库解决方式
xxx code
git checkout -- filename
xxx codexxx code
git reset --mixed HEAD

然后就回到的第一种情况

xxx codexxx codexxx code前提条件: commit 之后没有进行push
git reset --hard HEAD^

先进行将代码库进行回退一个版本,然后就变成了上面的第二种情况。

删除文件

将我们的修改进行提交到版本库我们是使用的  git add 和 git commit ,其实删除文件也是这样进行的,只不过增加了一个先使用rm 进行删除本地文件的操作。

  1. rm + 要删除的文件名
  2. git add + rm删除的文件名
  3. git commit -m "日志信息"

其中可以将上述的1 、2 步骤进行简化成一个步骤

git rm + 文件名

二、Git的分支管理

2.1、理解分支

2.2、分支管理的操作 

2.2.1、创建、切换分支、合并分支、删除分支

  • 进行产看当前的本地仓库的分支结构
git branch
  • 创建分支 
git branch + 分支名称

通过tree命令进行查看.git 发现确实新增了一个分支。 并且进行新建分支的时候,都是指向最新的提交,通过下面进行输出master 和 dev 指向的commit ID 都是一致的即可证明

  •  切换分支
git checkout + 想要进行切换到的分支名称
  • 合并分支

通过切换分支进行的提交,另一个分支是没有进行更新的,在哪个分支上进行的提交在哪个分支上生效,要想进行在别的分支上也生效,需要进行合并分支。
进行合并分支的时候需要进行切换到主分支(master)上然后进行执行合并命令 

git merge + 想要进行合并的分支

合并冲突 

当在不同的分支下都对同一个文件进行修改,在进行合并分支时就会出现合并冲突,通过进行输出文件中的信息发现会出现如下图所示的情况,然后需要进行手动进行删除冲突,最后在进行删除分支即可

  • 删除分支

当分支进行合并后分支就没有用了,需要进行删除分支,进行删除分支的时候需要在别的分支上进行,不能在该分支上进行删除该分支

git branch -d + 要删除的分支的名称

 既然我们进行创建分支后,还需要进行删除,为什么不在master上直接进行提交呢?

因为创建、合并和删除分支非常快,所以git鼓励使用分支进行完成某个任务,合并后再删掉分支,这和 直接在master分支工作效果是⼀样的,但过程更安全。 

2.2.2、合并的模式

fast-forword模式

什么是fast-forword 模式??

如上图所示的,当通过分支进行提交然后从主分支上进行将其他分支进行合并,通过 git log --graph --abbrev-commit 来进行打印提交的分支结构,可以看出通过分支进行提交后,然后将分支进行合并无法进行辨别是否由分支进行提交,这样就会出现一个重要的问题,当进行在公司进行协同开发时,当有一段代码出现了问题,无法进行定位是那个具体的开发人员也就无法进行追责

注:命令的含义

git log --graph --abbrev-commit
  • git log:查看提交历史记录

  • --graph:用 ASCII 字符画出提交历史的分支结构(合并、分支关系)

  • --abbrev-commit:只显示提交 ID 的前几位(简短版),不显示完整的 40 位哈希

禁用fast-forward模式 

 不使用fast-forward 进行提交,通过上图可以明显看到分支进行提交的记录信息。

如何使用禁用fast-forward 进行提交??

git merge --no-ff -m "merge with no-ff" + 要进行合并的分支

2.3、分支管理要遵循的原则

2.3.1、在dev分支上进行开发,测试稳定后的版本在进行合并到master 分支

在实际开发中,我们应该按照几个基本原则进行分支管理: 首先,master分支应该是非常稳定的,也就是仅用来发布新版本,平时不能在上面干活;那在哪干活呢?干活都在dev分支上,也就是说,dev分支是不稳定的,到某个时候,比如1.0版本发布 时,再把dev分支合并到master上,在master分支发布1.0版本 。

 你和你的小伙伴们每个⼈都在dev分支上干活,每个人都有自己的分支,时不时地往dev分支上合并就 可以了。 所以,团队合作的分支看起来就像上图这样。

2.3.2、bug分支用来单独进行bug的修复的

当我们在dev 上进行开发,开发到一半时,突然发现 master 分支上出现了BUG,需要进行解决,但是呢现在工作区的代码正在进行开发到一半,也无法进行提交,这该怎么处理呢?

首先我们需要进行明确的是,进行修复BUG我们是需要通过单独创建一个用来修复BUG分支来进行的,

然后将dev工作区中的内容进行储藏,通过下面命令

git stash

当想要将储藏的内容进行放回到原来位置时,通过下面命令

git stash pop

 通过bug进行修复的主要步骤以为思想

Master 分支目前最新的提交,是要领先于新建 dev2 时基于的 master 分⽀的提交的,所以我们 在 dev2 中当然看不见修复bug的相关代码。

我们的最终⽬的是要让 master 合并 dev2 分⽀的,那么正常情况下我们切回 master 分⽀直接合 并即可,但这样其实是有⼀定风险的。 是因为在合并分⽀时可能会有冲突,⽽代码冲突需要我们⼿动解决(在 master 上解决)。我们⽆法 保证对于冲突问题可以正确地⼀次性解决掉,因为在实际的项目中,代码冲突不只⼀两行那么简单, 有可能几十上百行,甚至更多,解决的过程中难免手误出错,导致错误的代码被合并到 master 上。 此时的状态为: 

解决这个问题的⼀个好的建议就是:最好在⾃⼰的分⽀上合并下 master ,再让 master 去合并 dev ,这样做的目的是有冲突可以在本地分⽀解决并进⾏测试,⽽不影响 master 。此时的状态 为: 

最后删除bug 分支和dev分支即可。 

2.4、强制进行删除分支

我们之前进行通过git branch -d 命令进行删除的分支都是向mater 进行合并之后的,要是出现了上面这种情况,想要进行删除时,git是会保护这个分支的,因为这个分支没有参与合并,要想进行删除,只能采用强制删除的方式。

git branch -D + 想要删除的分支名称

三、Git的远程操作

3.1、分布式版本控制的认识

前面我们进行学习了通过进行创建本地分支进行协同开发,但是这个分支都是本地的,也就是说在同一台服务器上进行,这样的话一人进行开发一会不但不会进行提高效率,甚至还会降低开发效率。

基于上面分析的弊端,我们将A程序员的本地仓库进行拷贝一份,然后A,B两个程序员就可以同时进行开发,开发某一部分完成时相互向对方进行推送,使得双方的仓库保持同步。

但是这种方式也是存在弊端的,当想要与对方进行同步时,对方关机的状态就直接寄了。

最终
于是就有了代码托管平台githup 和 gitee , 这两个平台的服务器是永远在线的,进行提交直接在平台上进行提交,其他人想要进行同步代码时,直接进行push拉取即可。 这种方式也成为分布式版本控制。

3.2、创建远程仓库

以码云(gitee)为例进行创建远程仓库进行演示

在进行创建仓库时建议按照上述的方式进行创建,关于勾选的选项,后面都会进行介绍

选项  Issues的作用

有问题的人和创建仓库的人进行交流的地方,当我们的这个仓库是开源的,当访问我们这个仓库的人发现一些BUG或者有一些更好的思维可以通过Issues 进行向指定仓库成员进行反应。

选项 Pull Requests 的作用

当我们进行合并分支时,并不是直接向我们之前的那种方式进行合并的,而是需要进行提交合并的申请,该仓库的相关人员进行审查后才将分支进行合并到master中,防止在master中出现BUG。

3.3、克隆远程仓库

通过HTTP协议进行克隆远程仓库

1、首先先将git中HTTPS协议的连接进行复制

2、然后在我们本地仓库之外的文件目录下进行执行一下命令

git clone + 刚刚进行复制的协议链接

进行执行完上述两个命令,克隆仓库就完成了,远程仓库和本地仓库就建立了关系,可以通过推拉进行维持仓库的关系

通过SSH协议进行克隆远程仓库

ssh 使用的是公钥加密,将本地服务器的公钥进行放到git服务器上进行管理,如下图中的步骤

第⼀步:
创建SSHKey。在用户主目录下,看看有没有.ssh目录,如果有,再看看这个目录下有没有 id_rsa 和 id_rsa.pub 这两个⽂件,如果已经有了,可直接跳到下⼀步。如果没有,需要创建 SSH——Key:

ssh-keygen -t rsa -C "自己的邮箱"

 第二步:

先找到创建的密钥的目录,然后将密钥进行复制到git中进行添加。

第三步: 

git clone + ssh的链接即可

3.4、向远程仓库进行推送

首先进行说明push 的条件:

本地仓库的开发是领先于远程仓库的。

 本地分支和远程分支的交互

git push origin master:master

3.5、拉取远程仓库

首先进行说明pull 的条件:

远程仓库的开发是领先于本地仓库的。

当多人进行协同开发时,别人在远程仓库进行push了,这时候远程仓库中的内容版本是领先于这个用户的本地仓库的。通过下面的命令可以进行将版本进行推进。

git pull origin master:master

3.6、忽略特殊文件

在⽇常开发中,我们有些⽂件不想或者不应该提交到远端,⽐如保存了数据库密码的配置⽂件,那怎 么让Git知道呢?在Git⼯作区的根⽬录下创建⼀个特殊的 .gitignore ⽂件,然后把要忽略的⽂件 名填进去,Git就会⾃动忽略这些⽂件了。 不需要从头写 .gitignore ⽂件,gitee在创建仓库时就可以为我们⽣成,不过需要我们主动勾选⼀ 下:

如果已经进行创建了本地仓库, 通过增加配置文件来规避

另一种方式就是通过更改.gitignore 文件

# 排除所有.开头的隐藏⽂件: 
.*
# 不排除.gitignore 
!.gitignore

git add -f +想要进行添加的文件名,将忽略的文件进行添加到远程仓库

进行检查某个文件为什么被忽略了

git check-ignore

3.7、配置命令别名

当一个命令太长时,进行执行该命令太麻烦,比如

git log --pretty=oneline --abbrev-commit

我们可以进行使用以下命令进行将这个命令进行起别名,下次进行使用时直接使用别名即可。

git config --global alias.lpa 'log --pretty=oneline --abbrev-commit'

 以后直接使用git lpa 即可。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2405030.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

c#,Powershell,mmsys.cpl,使用Win32 API展示音频设备属性对话框

常识(基础) 众所周知,mmsys.cpl使管理音频设备的控制面板小工具, 其能产生一个对话框(属性表)让我们查看和修改各设备的详细属性: 在音量合成器中单击音频输出设备的小图标也能实现这个效果&a…

STM标准库-TIM旋转编码器

文章目录 一、编码器接口1.1简介1.2正交编码器1.3编码器接口基本结构**1. 模块与 STM32 配置的映射关系****2. 设计实现步骤(核心流程)****① 硬件规划****② 时钟使能****③ GPIO 配置(对应架构图 “GPIO” 模块)****④ 时基单元…

【原创】基于视觉模型+FFmpeg+MoviePy实现短视频自动化二次编辑+多赛道

AI视频处理系统功能总览 🎯 系统概述 这是一个智能短视频自动化处理系统,专门用于视频搬运和二次创作。系统支持多赛道配置,可以根据不同的内容类型(如"外国人少系列"等)应用不同的处理策略。 &#x1f3d…

C++----剖析list

前面学习了vector和string,接下来剖析stl中的list,在数据库中学习过,list逻辑上是连续的,但是存储中是分散的,这是与vector这种数组类型不同的地方。所以list中的元素设置为一个结构体,将list设计成双向的&…

纳米AI搜索与百度AI搜、豆包的核心差异解析

一、技术定位与设计目标 1、纳米AI搜索:轻量化边缘计算导向
专注于实时数据处理与资源受限环境下的高效响应,通过算法优化和模型压缩技术,实现在物联网设备、智能终端等低功耗场景的本地化部署。其核心优势在于减少云端依赖,保障…

不到 2 个月,OpenAI 火速用 Rust 重写 AI 编程工具。尤雨溪也觉得 Rust 香!

一、OpenAI 用 Rust 重写 Codex CLI OpenAI 已用 Rust 语言重写了其 AI 命令行编程工具 Codex CLI,理由是此举能提升性能和安全性,同时避免对 Node.js 的依赖。他们认为 Node.js “可能让部分用户感到沮丧或成为使用障碍”。 Codex 是一款实验性编程代理…

Python60日基础学习打卡Day46

一、 什么是注意力 注意力机制的由来本质是从onehot-elmo-selfattention-encoder-bert这就是一条不断提取特征的路。各有各的特点,也可以说由弱到强。 其中注意力机制是一种让模型学会「选择性关注重要信息」的特征提取器,就像人类视觉会自动忽略背景&…

WEB3全栈开发——面试专业技能点P1Node.js / Web3.js / Ethers.js

一、Node.js 事件循环 Node.js 的事件循环(Event Loop)是其异步编程的核心机制,它使得 Node.js 可以在单线程中实现非阻塞 I/O 操作。 🔁 简要原理 Node.js 是基于 libuv 实现的,它使用事件循环来处理非阻塞操作。事件…

Vscode下Go语言环境配置

前言 本文介绍了vscode下Go语言开发环境的快速配置,为新手小白快速上手Go语言提供帮助。 1.下载官方Vscode 这步比较基础,已经安装好的同学可以直接快进到第二步 官方安装包地址:https://code.visualstudio.com/ 双击一直点击下一步即可,记…

Go语言--语法基础5--基本数据类型--输入输出(1)

I : input 输入操作 格式化输入 scanf O : output 输出操作 格式化输出 printf 标准输入 》键盘设备 》 Stdin 标准输出 》显示器终端 》 Stdout 异常输出 》显示器终端 》 Stderr 1 、输入语句 Go 语言的标准输出流在打印到屏幕时有些参数跟别的语言…

永磁同步电机无速度算法--自适应龙贝格观测器

一、原理介绍 传统龙伯格观测器,在设计观测器反馈增益矩阵K时,为简化分析与设计,根据静止两相坐标系下的对称关系,只引入了K、K,两个常系数,且在实际应用时,大多是通过试凑找到一组合适的反馈增益系数缺乏…

LangChain工具集成实战:构建智能问答系统完整指南

导读:在人工智能快速发展的今天,如何构建一个既能理解自然语言又能调用外部工具的智能问答系统,成为许多开发者面临的核心挑战。本文将为您提供一套完整的解决方案,从LangChain内置工具包的基础架构到复杂系统的工程实践。 文章深…

【razor】x264 在 的intra-refresh和IDR插帧

你提到的是这样一个情况: 使用 DirectShow 采集,帧率稳定(如回调了20帧)使用 x264 的 total intra refresh 模式(intra-refresh=1) 进行编码但编码过程中「隔几十秒才有一帧intra(关键帧)」这不正常,具体分析如下: 🎯 一、问题核心 x264 的 intra refresh 模式(特…

随机算法一文深度全解

随机算法一文深度全解 一、随机算法基础1.1 定义与核心特性1.2 算法优势与局限 二、随机算法经典案例2.1 随机化快速排序原理推导问题分析与策略代码实现(Python、Java、C) 2.2 蒙特卡罗方法计算 π 值原理推导问题分析与策略代码实现(Python…

在 Conda 环境下配置 Jupyter Notebook 环境和工作目录

作为数据科学家或Python开发者,Jupyter Notebook 是我们日常工作的得力工具。本文将详细介绍如何在 Conda 环境中配置 Jupyter Notebook,包括环境设置和工作目录管理,帮助你打造高效的工作流程。 为什么要在 Conda 环境中使用 Jupyter Noteb…

MS39531N 是一款正弦驱动的三相无感直流电机驱动器,具有最小振动和高效率的特点

MS39531N 是一款正弦驱动的三相无感直流电机驱动器,具有最小振动和高效率的特点 简述 MS39531 是一款正弦驱动的 三相无感直流电机驱动器 ,具有最小振动和高效率的特点。该驱动器内部集成了基本的闭环速度控制功能,能够根据特定的应用定制电…

web3-基于贝尔曼福特算法(Bellman-Ford )与 SMT 的 Web3 DeFi 套利策略研究

web3-基于贝尔曼福特算法(Bellman-Ford )与 SMT 的 Web3 DeFi 套利策略研究 如何找到Defi中的交易机会 把defi看做是一个完全开放的金融产品图表,可以看到所有的一切东西;我们要沿着这些金融图表找到一些最优的路径,就…

分析 java 的 Map<String,Map<String, List<Map<String,Integer>>>>

import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map;public class Test02 {public static void main(String[] args) {//分析方法:由外层向内层逐渐拆解要定义的变量。再由内向外进行变量赋值//外层第一层&#x…

ChatterBox - 轻巧快速的语音克隆与文本转语音模型,支持情感控制 支持50系显卡 一键整合包下载

ChatterBox 是一个近期备受关注的开源语音克隆与文本转语音(TTS)模型,由 Resemble AI 推出,具备体积轻巧及超快的推理速度等特色。它也是首个支持情感夸张控制的开放源代码 TTS 模型,这一强大功能能让您的声音脱颖而出…

前端开发面试题总结-HTML篇

文章目录 HTML面试高频问答一、HTML 的 src 和 href 属性有什么区别?二、什么是 HTML 语义化?三、HTML的 script 标签中 defer 和 async 有什么区别?四、HTML5 相比于 HTML有哪些更新?五、HTML行内元素有哪些? 块级元素有哪些? 空(void)元素有哪些?六、iframe有哪些优点…