Git工作原理和常见问题处理方案

  • 博客定位
  • Git工作区域
            • 工作区域划分
            • 暂存区设计目的
  • Git基本操作
            • 核心操作
            • 初始化和配置指令
  • HEAD指针
  • Git版本回滚
            • 指令介绍
            • reset模式
            • reset hard使用场景
            • reset soft使用场景
            • reset mixed使用场景
            • reset使用注意事项
            • checkout使用场景
  • Git分支管理
            • 什么是分支
            • 分支应用场景
            • 分支相关指令
            • 被合并分支和目标分支
            • merge模式
            • merge和rebase的区别
            • 分支合并的正确方式
            • merge合并完整流程
            • rebase合并完整流程
            • 常见的分支划分方案
  • Git分支仓库
            • fork操作完整流程
            • 本地仓库
  • 版本号标签
  • 文件对比
  • Git常见问题处理方案
            • Git是如何判断和解决冲突的
            • 提交代码的正确步骤是
            • 为什么push代码前,一定要先pull
            • 为什么pull代码前,一定要先commit
            • 怎么减少冲突的可能性
            • 想pull远程代码,又不想commit本地改动,怎么办

博客定位

本篇博客主要讲解Git应用场景和工作原理,以及核心用法

Git的每一个指令,都有非常多灵活的用法,这里不会将单个指令细化讲解

但是会比较全面地涵盖所有常用知识,对于非深度用户来说,用一辈子已经够了

Git工作区域

工作区域划分
  • Remote:远程仓库
  • Repository:本地仓库
  • Index:暂存区
  • Workspace:工作区
暂存区设计目的
  • 不必立刻将代码改动提交到仓库,可以等用户确认无误后再一次性提交
  • 可以有效减少错误提交的次数,并且可以随时通过Index查看改动了哪些代码

Git基本操作

上面的图片基本包含了Git系统的核心需求,其它需求都是围绕这些,在多人多仓库的情景下产生的

核心操作
  • add:将工作目录中新增或修改的内容,提交到暂存区
  • commit:将暂存区中所有的改动,一次性提交到本地仓库
  • push:将本地仓库中所有的改动,推送给远程仓库
  • fetch:将远程仓库的最新改动拉取到本地,但并不会将代码合并到本地,用于查看其他人对远程仓库的改动
  • merge:将一个仓库的代码合并到指定仓库,并更新工作区(准确说是合并分支,后面再说)
  • checkout:将工作区文件恢复到最近一次add/commit时的状态(也可用于分支切换,后面再说)
  • pull:拉取远程仓库代码,再合并到本地仓库,同时更新工作区,相当于fetch+merge
初始化和配置指令
  • init:在空目录创建一个Git仓库
  • config:配置或查询变量值,如配置账号
  • remote:添加或修改远程仓库,本地仓库可以同时和多个远程仓库进行互动
  • clone:从远程克隆仓库到本地,相当于init+remote+pull

HEAD指针

HEAD指针,是为了方便描述Git中的复杂操作,而抽象出来的一个概念

再Git系统中,所有仓库、所有分支中代码版本,都是用commit-id来表示的

Git系统简单概述起来,就是一个文本对比系统+commit-id-tree管理系统

HEAD指针,指向的就是本地仓库当前的commit-id

所有的Git合作,无非就是仓库切换,分支切换,pull到本地,push到远程

这些操作都要经过本地仓库,因此HEAD指针在描述复杂操作时,十分重要,但它本身仅仅代表本地仓库的commit-id而已

HEAD指针可以通过以下方式进行移动

  • 移动本地HEAD指针:git checkout commit-id
  • 移动特定分支的HEAD指针:git branch -f branch-name commit-id

Git版本回滚

Git用于版本回滚的有reset,revert,checkout三个指令,查看版本记录用log指令

指令介绍
  • log:查看提交历史,可以拿到每次提交对应的commit-id
  • reset:将本地仓库代码回退到指定的版本,并将中间的commit记录全部删除。此时在push,远程记录也会被删除
  • revert:将本地仓库代码回退到指定的版本,并保留所有更改记录。本质是将旧代码拉到本地,作为一个新版本去提交
  • checkout:将工作区代码回退到暂存区或本地仓库中的状态,即最近一次add/commit时的状态,不影响本地仓库和远程仓库代码
  • revert会产生新的commit-id,但reset不会

reset有三种模式,它们对本地仓库的改动都是一样的,但是对暂存区和工作区的处理方式有所不同

reset模式
  • hard模式:暂存区和工作区也会被重置
  • soft模式:暂存区和工作区仍然保留改动
  • mixed模式:暂存区被重置,工作区被保留
reset hard使用场景
  • 将本地所有改动回退到目标版本,并清除中间所有的提交记录
  • 使用方式:git reset --hard commit-id
reset soft使用场景
  • 提交了错误的commit,想要撤回记录
  • 发现merge处理方式错误,但想保留工作区最新代码
  • commit提交到错误的分支
reset mixed使用场景
  • 想保留工作区最新代码,同时想清空暂存区add记录
reset使用注意事项
  • reset只会回退本地代码,并不会回退远程仓库,如果想回退远程仓库,必须手动push本地代码
  • 由于HEAD指向的是已存在的旧版commit-id,远程仓库出于保护并不允许直接push,需要强制push
  • 强制推送指令:git push origin:main -f
  • GitLab会开启ForcePush保护,push -f 可能会识别,需要自己去网页关闭Repository Protect
checkout使用场景
  • checkout用于恢复工作区文件,指令不改变本地仓库和暂存区
  • 如果暂存区有未提交的add记录,则将工作区回退到上次add时的状态
  • 如果暂存区无记录,则将工作区回退到上次commit时的状态
  • 回退全部文件:git checkout – .
  • 回退指定文件:git checkout file1 file2

Git分支管理

什么是分支
  • 在单人开发、单版本开发的情景下,Git的版本记录是一个链表结构,版本要么新增,要么回退
  • 在多人开发、多个子功能同时开发、不同版本之间需要进行功能合并的情景下,链表结构的版本管理便无法再满足需求
  • 于是便诞生了树结构的版本管理方式,版本号允许新开分支进行单独的版本管理,而不影响主分支版本
  • 需要合并不同分支功能的时候,允许不同分支之间进行代码合并
分支应用场景
  • 开发版本和发布版本要独立维护
  • BUG修复和新功能开发需要独立进行
  • 两个小组开发不同功能,功能完成之前,不想同步彼此的代码
  • 不同服务器、不同客户的产品版本号不一样,需要独立维护
分支相关指令
  • 查看分支:git branch
  • 创建分支:git branch branch-name
  • 切换分支:git checkout branch-name
  • 合并分支:git merge branch-name 注意,merge只是将分支合并到本地仓库,并不会自动push到远程仓库
  • 删除分支:git branch -d branch-name
  • 取消分支合并:git reset --hard HEAD~
被合并分支和目标分支
  • 假定我们现在有两个分支,master和bugfix
  • bugfix分支修复了一些问题,现在要将这些修复合并到master
  • 此时我们称bugfix为被合并分支(merged-branch),master为目标分支(target-branch)
merge模式
  • fast-forward模式:当master分支没变动过时,如果想要合并bugfix的改动,直接将master头指针移动到bugfix头指针位置
  • no-fast-forward模式:即使master分支没有变动,仍然生成一个新的合并版本号,而不是快速移动指针
  • squash模式:合并方式和no-fast-forward一致,但合并时会将bugfix的所有中间提交记录合并成一个commit
  • git合并默认采用的是fast-forward模式,通过–no-ff,–squash参数指定另外两个模式
  • 这三种模式都是针对master本身没有变动的情况,在master有变动时,处理方式都是一样的
  • 在master有变动时,会采用类似于squash的方式,将bugfix所有改动合并成一个commit,合并到master
merge和rebase的区别
  • 合并指令除了merge之外,还有rebase指令,他们的主要区别在于生成commit记录的方式不同
  • merge会将bugfix的所有commit合并成一个新commit,合并到master上,同时移动master的HEAD指针到最新commit节点上
  • rebase会将bugfix的所有commit逐个合并到master上,形成多个新的commit节点,同时移动bugfix的HEAD指针到最新commit节点上
  • merge的目的在于将bugfix的改动合并到master,rebase的目的在于将master的改动合并到bugfix
  • merge和rebase,都只会改变其中一个分支的HEAD,如果想将两个分支合而为一,需要手动将另外一个分支的HEAD指针也移动到最新的commit节点
  • merge和base最大的区别在于,merge的记录比较简洁,rebase的记录比较详细,根据需要选择
分支合并的正确方式
  • 合并前请先将本地最新代码push到所在远程仓库,避免操作出错时导致本地改动丢失

  • 分支合并只会影响本地仓库,推送到远程仓库需要手动push

merge合并完整流程
  • 提交本地改动:git commit

  • 推送本地改动:git push

  • 切换到目标分支:git checkout master

  • 合并BUG分支:git merge bugfix

  • 推送合并结果到master:git push origin master

  • 移动bugfix到最新位置:git push -f origin bugfix

  • 以上代码根据实际需要来执行,不需要的步骤可以跳过

rebase合并完整流程
  • 提交本地改动:git commit
  • 推送本地改动:git push
  • 切换到目标分支:git checkout bugfix
  • 改变目标分支的基线:git rebase master
  • 推送合并结果到bugfix:git push origin bugfix
  • 移动master到最新位置:git push -f origin master
  • 以上代码根据实际需要来执行,不需要的步骤可以跳过
常见的分支划分方案
  • master:用于发布管理的分支,每个版本会贴上版本号标签
  • develop:日常开发用的分支
  • feature:独立功能开发用的分支,开发完毕合并到develop
  • release:为发布做准备的分支,来自develop,合并到master
  • hotfix:对已发布的版本做紧急BUG修复

Git分支仓库

Git可以通过Fork功能,创建一个拥有一模一样版本记录的仓库副本,并且允许这两个副本直接相互合并代码

GitHub开源项目的管理方式,运用的便是这一种方式,开发者不允许直接修改仓库,只能自己Fork一份仓库进行修改

修改结束后,可以向父仓库发起Merge Request,管理员审核通过后才会合并成功

fork操作完整流程
  • 从父仓库的Git页面中,点击Fork按钮,复制一份到自己的仓库
  • 将fork仓库拉到本地:git clone fork-git-url(fork仓库在本地的别名默认为origin)
  • 查看远程仓库配置:git remote -v
  • 添加父仓库配置到本地:git remote add parent parent-git-url(parent是父仓库的别名)
  • 拉取父仓库信息:git fetch parent
  • 合并父仓库分支代码:git merge parent/main
  • 推送分支代码到fork仓库:git push origin main
本地仓库
  • 本地仓库本身相当于一个独立的分支仓库,可以创建子分支,可以从任何分支拉取代码,也可以向任何分支推送代码
  • Git也可以没有远程仓库,只创建本地仓库,此时仍然能使用commit和revert,但不能再使用push和pull
  • Git的大多指令,都是针对本地仓库进行操作的,只有经过push后,才会推送到远程仓库
  • Git中通过树结构,记录了所有分支的版本号演变过程,如果push会导致版本树后退,那么必须使用push -f才能强制推送
  • 如果我们不想手动解决冲突,并且确定自己的代码是最终的、正确的,也可以通过push -f来强制推送

版本号标签

标签是给版本号起的一个别名,方便记住和操作

  • 查看标签列表:git tag
  • 给当前分支最新版本打标签:git tag tag-name
  • 给指定版本打标签:git tag tag-name commit-id
  • 删除指定标签:git tag -d tag-name
  • 推送标签到远程仓库:git push origin --tags
  • 添加和删除标签都需要push,才能对远程仓库生效

文件对比

  • 对比分支差异:git diff <branch-name-1> <branch-name-2> [specified-path] [specified-file]
  • 查看工作区和指定分支差异:git diff <branch-name>
  • 对比版本号差异:git diff <commit-id-1> <commit-id-2>

Git常见问题处理方案

Git是如何判断和解决冲突的

Git是基于文件名和文本行来判断冲突的

如果两个来自不同用户的commit,都修改了同一个文件的同一行文本,即被视为冲突

Git命令行工具会列出具体冲突的文件和行数,手动编辑文件解决冲突后,再重新合并代码

如果用的是图形化工具或IDE插件的话,一般会自己弹出对比窗口,方便用户去预览和修改冲突

提交代码的正确步骤是

add => commit => pull => push

为什么push代码前,一定要先pull

因为从上次拉取代码,到现在提交代码,中间远程仓库的代码可能已经被修改了

这样就有可能和我们的修改产生冲突,所以必须先pull远程代码改动,解决冲突后再提交

为什么pull代码前,一定要先commit

因为pull代码可能会和工作区代码产生冲突

只有将工作区的改动commit到本地仓库,Git才能在pull时对比出冲突的地方

如果不commit的话,pull会将远程仓库的代码同时拉到本地仓库和工作区,这样未提交的本地改动将会丢失

怎么减少冲突的可能性

每次准备修改代码前,先pull远程代码

每次push代码前,先pull远程代码

不要隔很久才push代码,做完一小块完整任务就可以push

这些措施虽然不能避免冲突,但是可以将冲突限制在小范围内,降低了merge难度

想pull远程代码,又不想commit本地改动,怎么办

git stash save指令可用于将本地改动缓存到暂存区

这样本地的代码就还原到改动前的状态,就可以从远程pull代码了

pull完代码之后再通过git stash pop,可以再将之前的改动合并到pull后的代码当中

如果pull的代码和save的代码有冲突的话,需要手动去解决冲突

git stash savegit pullgit stash pop

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

10 MIT线性代数-四个基本子空间 four fundamental subspaces

1. 四个子空间 Four subspaces (mxn) 列空间 Column space C(A) in 零空间Nullspace N(A) in 行空间Row space all combs of rows all combs of columns of AT C(AT) in 左零空间Left nullspace Nullspace of AT N(AT) left nullspace of A in 2. 基和维数 Basis&…

nodejs+vue黄花岗社区核酸检测站-计算机毕业设计python-django-php

对黄花岗社区核酸检测站系统进行大力的研究&#xff0c;主要是因为黄花岗社区核酸检测站系统对于社区的推进有着十分重要的作用&#xff0c; 对于社区的管理来说&#xff0c;黄花岗社区核酸检测站系统是十分有效的一个途径&#xff0c;也正是因为这样的特殊性使得在对社区进行管…

[SpringCloud] Feign 与 Gateway 简介

目录 一、Feign 简介 1、RestTemplate 远程调用中存在的问题 2、定义和使用 Feign 客户端 3、Feign 自定义配置 4、Feign 性能优化 5、Feign 最佳实践 6、Feign 使用问题汇总 二、Gateway 网关简介 1、搭建网关服务 2、路由断言工厂 3、路由的过滤器配置 4、全局过…

钢琴培训答题服务预约小程序的效果怎样

很多家长都会从小培养孩子的兴趣&#xff0c;钢琴便是其中热度较高的一种&#xff0c;而各城市也不乏线下教育培训机构&#xff0c;除了青少年也有成年人参加培训&#xff0c;市场教育高需求下&#xff0c;需要商家不断拓展客户和转化。 那么通过【雨科】平台制作钢琴培训服务…

协程框架nty_co

一、为什么要有协程&#xff1f; 以DNS请求为例子&#xff0c;客户端向服务器发送域名&#xff0c;服务器回复该域名对应得IP地址。 我们想要以同步的编程方式获得异步的性能&#xff01;&#xff01;&#xff01; 在Linux下&#xff0c;常使用IO多路复用器epoll来管理客户端…

英语——歌曲篇——500 Miles(离家五百里)

乡村音乐&#xff08;country music&#xff09;《500 Miles(离家五百里)》以一种怀乡、寻根 的意识&#xff0c;用思念留住时光还有一点哲理的味道&#xff0c;乡村音乐多年以来都不曾淡出大家的视野&#xff0c;确实有值得留恋的情怀。 500 Miles [The Brothers Four离家五…

用前端框架Bootstrap和Django实现用户注册页面

01-新建一个名为“mall_backend”的Project 命令如下&#xff1a; CD E:\Python_project\P_001\myshop-test E: django-admin startproject mall_backend02-新建应用并注册应用 执行下面条命令依次创建需要的应用&#xff1a; CD E:\Python_project\P_001\myshop-test\mall…

【计算机视觉】相机

文章目录 一、原始的相机&#xff1a;针孔相机&#xff08;Pinhole Camera&#xff09;二、针孔相机的数学模型三、真实相机四、透镜的缺陷 我的《计算机视觉》系列参考UC Berkeley的CS180课程&#xff0c;PPT可以在课程主页看到。 成像原理 一、原始的相机&#xff1a;针孔相机…

信息安全与网络安全的关系

前言 说说信息安全与网络安全的关系 如果你对网络安全入门感兴趣&#xff0c;那么你需要的话可以点击这里&#x1f449;【入门&进阶全套282G学习资源包免费分享&#xff01;】 一、包含和被包含的关系 信息安全包括网络安全&#xff0c;信息安全还包括操作系统安全&…

云计算的基本概念

目录 云计算基本概念 什么是云计算 云计算的优势&#xff08;关键特征&#xff09; 云计算发展历程 云计算发展阶段 云计算的三种服务模式 云计算的四类部署模式 云计算的应用 云计算基本概念 什么是云计算 云计算的基本概念 云计算&#xff08;Cloud Computing&…

J2EE项目部署与发布(Linux版本)

目录 一.jdk&tomcat安装 1.jdk的安装 1.2解压对应的安装包 1.3配置环境变量 2.tomcat的安装 二.mysql的安装 三.后端接口部署 后端部署 导入war包 修改端口 开启访问 一.jdk&tomcat安装 1.jdk的安装 登录VMware Workstation Pro 然后连接MobaXterm 将 jd…

BI零售数据分析,告别拖延症,及时掌握一线信息

在日常的零售数据分析中&#xff0c;经常会因为数据量太大&#xff0c;分析指标太多且计算组合多变而导致数据分析报表难产&#xff0c;零售运营决策被迫拖延症。随着BI数据可视化分析技术的发展&#xff0c;智能化、可视化、自助分析的BI数据分析逐渐成熟&#xff0c;形成一套…

精品站长网交易系统源码/虚拟交易网站程序源码/虚拟交易平台带店铺处罚商品处罚

精品站长网交易系统源码&#xff0c;虚拟交易网站程序源码&#xff0c;虚拟交易平台带店铺处罚商品处罚。带申诉功能&#xff0c; 带提现通知功能&#xff0c; 带熊掌号推送功能&#xff0c; 带站内信息功能。 下载地址&#xff1a;https://bbs.csdn.net/topics/617494651

C++学习笔记之四(标准库、标准模板库、vector类)

C 1、C标准库2、C标准模板库2.1、vector2.1.1、vector与array2.1.2、vector与函数对象2.1.3、vector与迭代器2.1.4、vector与算法 1、C标准库 C C C标准库指的是标准程序库( S t a n d a r d Standard Standard L i b a r a y Libaray Libaray)&#xff0c;它定义了十个大类…

如何使用IP归属地查询API加强网络安全

引言 在当今数字化时代&#xff0c;网络安全对于个人和组织来说至关重要。恶意网络活动的威胁不断增加&#xff0c;因此采取有效的措施来加强网络安全至关重要。其中之一是利用IP归属地查询API。这个工具可以为您的网络安全策略提供宝贵的信息&#xff0c;帮助您更好地保护自己…

huggingface离线模式及默认保存路径

T5Tokenizer.from_pretrained()函数会在线下载huggingface上的模型&#xff0c;并自动保存在C盘的.cache路径下&#xff1a; C:\Users\xxxxx\.cache\huggingface\hub\models--google--t5-v1_1-base # 这里xxxxx代表自己电脑用户名huggingface离线下载 以google/t5-v1_1-base为…

win10 下编译ffmpeg3.36.tar.gz

所需工具&#xff1a; win10 ffmpeg3.36.tar.gz。 或其他版本&#xff0c;下载地址&#xff1a;Index of /releases msys2。 下载地址&#xff1a;http://www.msys2.org。 Visual Studio 2017。 1. 安装MSYS MSYS2像是windows下的一个子系统&#xff0c;…

hadoop权威指南第四版

第一部分 HaDOOP基础知识 1.1 面临的问题 存储越来越大&#xff0c;读写跟不上。 并行读多个磁盘。 问题1 磁盘损坏 – 备份数据HDFS 问题2 读取多个磁盘用于分析&#xff0c;数据容易出错 --MR 编程模型 1.2 衍生品 1 在线访问的组件是hbase 。一种使用hdfs底层存储的模型。…

CSS3盒模型

CSS3盒模型规定了网页元素的显示方式&#xff0c;包括大小、边框、边界和补白等概念。2015年4月&#xff0c;W3C的CSS工作组发布了CSS3基本用户接口模块&#xff0c;该模块负责控制与用户接口界面相关效果的呈现方式。 1、盒模型基础 在网页设计中&#xff0c;经常会听到内容…

DSP 开发例程(5): tcp_server

目录 DSP 开发例程(5): tcp_server创建工程源码编辑tcp_echo.chelloWorld.c 调试说明 DSP 开发例程(5): tcp_server 此例程实现在 EVM6678L 开发板上创建 TCP Server进程, 完成计算机与开发板之间的 TCP/IP 通信. 例程源码可从我的 gitee 仓库上克隆或下载. 点击 DSP 开发教程…