分布式版本控制工具Git的安装与使用

分布式版本控制工具Git的安装与使用

命令速查

git常用命令


更多命令可见菜鸟教程

Git简介

为什么要使用git

真实生产环境中,代码通常由多人、甚至多个部门协作开发。如果靠 U 盘拷贝、手动合并代码,不仅效率极低,还极易出现代码覆盖、丢失、冲突等问题。因此,需要一套可靠的版本控制工具来管理代码,Git 正是当下最主流的解决方案。

Git 是分布式版本控制工具(Distributed Version Control System),与传统集中式版本控制工具,如 SVN有本质区别:

  • 集中式工具高度依赖中央服务器,开发者从服务器拉取代码,修改后再提交回服务器。一旦服务器宕机、或开发者网络异常,就无法正常协作与提交;
  • 分布式的 Git 让每个开发者本地都拥有完整的版本库,不依赖单一中央服务器,从根本上解决了单点故障和网络限制问题。

详细作用可见为什么程序员都要用git,Git能实现的功能主要如下:

  1. 版本回滚:git记录项目每次修改,新版本带来的问题可立即回滚为以往版本减小损失;
  2. 并行开发:多个开发者可在不同分支开发,git会智能合并各自的部分,多人合作可通过远程仓库获取资源,让协作变得更高效;
  3. 溯源:git会记录每次修改的说明和作者,避免bug扯皮;
  4. 数据安全:git将代码存储到个人仓库的分布式特性保证项目几乎永远不会丢失。

下载与安装

官网链接:https://git-scm.com/

官网下载


git安装界面


有关安装详细说明可见Git详细安装教程,还有选项涉及到黑命贵(master不尊重黑人要改成main???),这里一路next安装,右键菜单出现如下界面说明安装成功:

git新增右键菜单


也可以在cmd窗口中使用git -v命令查看版本,本次安装的是最新的2.53.0,提示如下:

C:\Users\hp>git -v git version 2.53.0.windows.1 

使用方法

git的工作原理

git根据代码位置将存储划分为四个区域,分别为工作区、暂存区、本地仓库和远程仓库。

  1. 工作区(Working Directory):工作区是开发代码的目录,也就是实际代码存放的文件夹,修改后的代码文件使用git add提交到暂存区;
  2. 暂存区(Staging Area):暂存区是一个临时保存的区域,保存了准备提交到仓库中的所有改动,为.git目录下的二进制文件,通过git commit提交到本地仓库;
暂存区给开发者提供了更细粒度的控制手段。一次修改可能包含多个不同内容的修复,暂存区分批提交可以细化提交工作。
  1. 本地仓库(Local Repository):存储在本地机器上的 Git 仓库,记录了项目的所有提交历史。可用命令有:git merge 分支名合并其他分支的代码到当前分支、git checkout 分支名切换到指定分支;
  2. 远程仓库(Remote Repository):位于服务器端的远程仓库,如github、国内的gitee(码云)和需要自己部署的gitlab,常用命令有
    git push本地仓库推送至远程服务器
    git clone远程仓库克隆到本地,通常只有第一次使用
    git fetch从远程服务器获取修改到跟踪分支,后续手动使用git merge合并
    git pull从远程服务器获取修改并自动合并,即pull=fetch+merge

相关流程可表示为下图:

git使用流程图

本地命令

  1. 状态转换

配置别名
我们要使用的有些命令较长,可以采用起别名的方法简化,新建.bashrc文件,写入alias 新命令 '原长命令',并使用source .bashrc编译即可,别名alias ll='ls -al'的示例如下:

配置别名示例

配置用户信息
git config --global user.name 用户名指定全局用户名
git config --global user.email 邮箱指定全局邮箱
git config --global user.name查看用户名
git config --list查看所有配置

git配置用户信息

初始化仓库
要使用的目录下右键进入git bash,输入命令git init,可见生成隐藏目录.git

初始化仓库
命令含义
git status查看文件状态
git add 文件名/通配符工作区添加至暂存区,.表示目录所有
git commit -m “注释”暂存区提交至本地仓库,可添加说明
git log查看日志,–graph展示分支
git reset --hard commitID回滚到以前版本,id在log,通常取前七位
git reflog查看所有提交记录,用于回滚的二次反悔
状态示例
  1. 忽略文件
    有些文件我们不希望参与git管理,可新建.gitignore文件,文件内写通配符或具体名称即可,如*.a为以a为扩展名结尾的文件不参与管理。

远程仓库

  1. 远程操作仓库
    git clone 仓库路径 本地目录,首次使用仓库需克隆,本地目录缺省会直接使用仓库名称新建,克隆包含所有分支的完整仓库,需特定分支可用参数-b 分支名指定;
    git fetch origin 分支名,抓取更新文件到远程跟踪分支
    git merge,合并更新至当前所在分支
    git pull origin 分支名,拉取并合并,等于fetch+merge
    git push origin 分支名,将本地分支上传到仓库,有则合并(本地分支落后时拒绝),无则创建
    git branch查看分支

分支保护
master是开发的主分支,各组件开发、功能修复等分支最后都往这个分支合并,必须对这个分支进行保护,可使用如下权限设置。

分支保护


主分支的合并需要审核和测试才能进行。

远程连接
ssh连接远程仓库需使用密钥,先使用ssh-keygen -t rsa生成rsa密钥,三次回车全选默认配置(第一次选项是换目录,换了会导致后续无法验证,要换目录验证时可用-i指定),图中是密钥保存位置。

生成密钥


Linux可使用cat打开,Windows找到对应目录自行打开,复制id_rsa.pub的密钥添加公钥。

复制公钥


使用 ssh -T [email protected]验证连接,出现如下界面说明密钥配置成功:

验证成功


git remote add origin 地址添加远程仓库,仓库名为origin

添加远程仓库

新建仓库
国内使用比较方便的代码平台是码云,官网为https://gitee.com,网页右上角,头像旁按键可新建仓库。

新建仓库


新建后选择仓库名称和介绍

新建参数


随后生成初始化readme

初始化readme

解决冲突

不同开发者更改了代码的相同几行即为冲突,如二者都根据登录模块同时添加功能,第一个提交者在行末添加,第二个开发者要提交时则会报冲突。

比如两个用户分别修改如下行:

冲突模拟


A用户上传成功,B用户要上传会提示错误,提示本地没有文件,本质是远程版本比本地的更新(更新基线问题),git会自动拒绝对更新版本的覆写。

版本落后错误


此时需要先使用git pull拉取最新版本,在本地解决冲突,冲突行git会标记提示,此时需要开发者自行解决,通常是挪动代码。

冲突提示


冲突标记包围的上方是待推送内容,下方是远程仓库拉取的最新内容,最下方的1是误报,删除标记整合重新提交即可。

gitadd 文件名 git commit -m"解决冲突:保留用户B前两行,下方1内容无差异"git push origin master 

扩展

git的智能合并

Git 保障合并操作安全的核心前提是合并双方拥有共同的提交基线(相同起点)。若本地分支与远程分支的基线不一致(本地落后于远程),Git 会要求先执行git pull同步远程最新内容,再进行本地提交和推送 ,这一机制能从根本上避免本地修改覆盖远程最新提交记录的风险。

需要注意的是,分支基线的同步状态依赖 Git 对提交历史的追踪:执行git pull后,本地分支的提交基线会与远程仓库保持一致;而本地执行git commit后,Git 会更新本地分支的提交历史记录,形成新的基线状态。

git的管理边界

git支持纯文本文件,可以实现冲突检测功能,但以TSV 结构化文本为例,Git 能识别并标记文件中发生修改的行,但无法感知行内列级别的数值变化,需手动定位和解决列级差异。

tsv格式


同时经过测试,图像、exe等二进制文件也可使用git进行管理,但git无法检测具体变化,每次更新只能全部覆盖,对二进制文件的管理效率低,开销大。

存储问题

git记录提交状态并可以随时恢复的功能十分强大,但保存如此多的状态是否可能导致存储压力过大。

我修改了一个17字节的文件,但.git文件夹内却有17KB的内容,那100MB的文件修改10次,其保存的状态文件会不会是1000MB呢?

这是不会发生的,git底层只存储变化的内容,无变化的内容复用,具体原因为:

  1. 文本文件复用:Git记录行级别差异,修改一行数据,只存储该行的修改记录加少量元数据。
  2. 二进制文件压缩快照:根据哈希值判断是否修改,git无法识别二进制文件的具体差异,git会存储变化文件的压缩快照,这也是为什么使用git管理二进制文件较为低效。

此外git还有垃圾回收机制,和专门针对大文件的管理程序git lfs

Read more

【C++】第二十六节—C++11(中) | 右值引用和移动语义(续集)+lambda

【C++】第二十六节—C++11(中) | 右值引用和移动语义(续集)+lambda

Hi,我是云边有个稻草人,C++领域博主与你分享专业知识(*^▽^*) 《C++》本篇文章所属专栏—持续更新中—欢迎订阅~ 目录 上节总览,详情见—>【C++】第二十五节—C++11 (上) | 详解列表初始化+右值引用和移动语义 本节总览 (4)右值引用和移动语义在传参中的提效 6. 类型分类 7. 引用折叠 8. 完美转发 四、lambda 1. lambda表达式语法 2. lambda的应用 3. 捕捉列表 4. lambda的原理 接着上节,正文开始—— (4)右值引用和移动语义在传参中的提效 * 查看STL文档我们发现C++11以后容器的push和insert系列的接口否增加的右值引用版本 * 当实参是一个左值时,容器内部继续调用拷贝构造进行拷贝,将对象拷贝到容器空间中的对象 * 当实参是一个右值,容器内部则调用移动构造,右值对象的资源到容器空间的对象上

By Ne0inhk
面试官最爱问:C++ 多态底层到底是怎么实现的?

面试官最爱问:C++ 多态底层到底是怎么实现的?

欢迎来到 s a y − f a l l 的文章 欢迎来到say-fall的文章 欢迎来到say−fall的文章 🌈say-fall:个人主页🚀专栏:《手把手教你学会C++》 | 《C语言从零开始到精通》 | 《数据结构与算法》 | 《小游戏与项目》💪格言:做好你自己,才能吸引更多人,与他们共赢,这才是最好的成长方式。 前言: 关于上一篇文章的多态原理他来啦! 在上一篇《多态核心:虚函数、override、final、纯虚函数总结》中,我们已经初步认识了 C++ 多态的语法层面:虚函数、重写、纯虚函数等关键知识点,并提到了多态的底层依赖于 vptr 虚指针 与 vtable 虚函数表。但很多同学在学习时,仍然会有这些疑问: * 为什么带虚函数的类,sizeof 大小会多出

By Ne0inhk
C++ 类和对象(二):默认成员函数详解

C++ 类和对象(二):默认成员函数详解

在 C++ 面向对象编程中,类的默认成员函数是非常重要的概念。当我们没有显式实现某些成员函数时,编译器会自动生成它们,这些函数被称为默认成员函数。本文将详细介绍 C++ 类的 6 个默认成员函数,包括构造函数、析构函数、拷贝构造函数、赋值运算符重载以及取地址运算符重载。 一、默认成员函数概述 默认成员函数是指用户没有显式实现,编译器会自动生成的成员函数。一个类在我们不写任何成员函数的情况下,编译器会默认生成以下 6 个默认成员函数:构造函数析构函数拷贝构造函数赋值运算符重载普通取地址运算符重载const 取地址运算符重载         其中前 4 个是我们需要重点掌握的,后两个在大多数情况下使用编译器自动生成的即可。另外,C++11 以后还增加了两个默认成员函数:移动构造和移动赋值,本文暂不讨论。 二、构造函数         构造函数是一种特殊的成员函数,其作用是在对象实例化时初始化对象,替代了我们以前手动调用的Init函数,并且会自动调用。 构造函数的特点:函数名与类名相同无返回值(不需要写void)对象实例化时系统会自动调用对应的构造函数可以重载

By Ne0inhk

Java正则表达式性能优化:为什么选择RE2J而非传统库?

Java正则表达式性能优化:为什么选择RE2J而非传统库? 【免费下载链接】re2jlinear time regular expression matching in Java 项目地址: https://gitcode.com/gh_mirrors/re/re2j 在Java开发中,正则表达式是处理文本的强大工具,但传统正则库在面对复杂模式时常常遭遇性能瓶颈。RE2J作为一款实现线性时间正则表达式匹配的Java库,正逐渐成为解决这一痛点的理想选择。本文将深入解析RE2J的核心优势、适用场景及实战应用,帮助开发者提升文本处理效率。 🚀 什么是RE2J?为何它如此重要? RE2J(Regular Expression 2 for Java)是Google开发的正则表达式引擎,其核心特性是线性时间复杂度。与传统基于回溯算法的正则库不同,RE2J通过NFA(非确定性有限自动机)和高效的编译优化,确保匹配时间与输入文本长度成正比,彻底避免了灾难性回溯导致的性能崩溃。 项目根目录下的README.md明确指出:"RE2/J: linear time regular

By Ne0inhk