【Git 全功能解析: 探索版本控制的强大工具】

news2024/11/27 4:24:23

文章目录

    • 概要
    • 集中式版本管理和分布式版本管理
    • Git 基础命令
    • 基本流程
    • 开发管理

概要

“Git 的历史与现状”

Git是Linux的创始人Linus Torvalds的又一力作。在2002年,他在Linux内核的版本控制中使用Bitkeeper,但由于Bitkeeper是一款受版权保护的软件,备受质疑。后来,Andrew Tridgell对Bitkeeper进行了逆向工程,导致BitMover收回了Linux开发者对Bitkeeper的免费使用权。Linus对此十分愤怒,于是花了10天时间编写了Git。

Git这个名字的含义是:“egotistical bastard”(自恋的混蛋)。

如今,Git已经成为绝大多数开发者的首选。由Tom Preston-Werner、Chris Wanstrath和PJ Hyett于2007年10月推出的GitHub已经发展成为全球最大的开发者网站,许多团队在上面做出了重要的贡献。
在这里插入图片描述

值得一提的是,即使是一直自家造轮子的微软,也计划将庞大的300GB Windows源代码迁移到Git上进行管理。为了应对巨大代码仓库的性能问题,他们为Git提供了全新的GVFS实现。
此外,还值得一提的是Docker的二进制镜像管理也是基于Git实现的。

集中式版本管理和分布式版本管理

Git和SVN在设计理念上存在根本区别。SVN采用中心化管理,具有更好的稳定性和安全性。相反,Git是一款去中心化的版本控制工具,最初是为了满足Linux操作系统开发的需求。它更适合多人协作的开源项目,允许在任何一个点将远程代码与本地代码合并。随着时间的推移,Git还演变出了更多强大的功能和完整的操作流程,使其也适用于商业软件的开发。
在这里插入图片描述

Git 基础命令

在这里插入图片描述
Git基础命令可根据不同场景分为以下几个场景:

Workspace(工作区):当前工作区,即修改的初始状态。
Staging(暂存区):修改后,添加到准备提交的缓存状态。
Local repository(本地代码库):本地的代码仓库,只对自己的代码生效。与SVN的一个区别在于,SVN commit之后直接提交到远程服务器,而Git commit之后只是到本地代码库。
Remote repository(远程代码库):远程代码库,用于同步本地代码库到远程,以供其他开发者分享。

以下是几个常用命令的简单介绍:

PS:图中未提及rebase和cherry-pick命令,这两个命令也非常强大,后文有提到,可关注一下。

补丁 diff:
之前提到过,补丁是Git/SVN代码版本管理的基础概念。它实际上是以行为单位的文件修改历史,增加行以+号开头,删除行以-号开头。而修改一行则是先删除再添加。

在Git中,可以通过git diff命令,或在Linux/Mac/Conemu中使用diff -Naur生成文件对比结果,类似于下图。这构成了整个代码管理的基础概念,所有分支、标签、远程都是在此基础上衍生的。

基本流程

1.克隆代码到本地开发环境 - Clone

$ git clone [REPOSITORY_URL]

类似于 SVN 的 checkout 命令,用于将远程代码克隆到本地。与 SVN 一样,REPOSITORY_URL 的协议非常灵活。之前常用的是 SSH/SCP 协议,但现在 HTTPS/HTTP 协议也逐渐流行。

2.更新代码 - Status/Commit/Log
使用 git status 命令查看四种场景中的前两种状态。新建的代码会显示为 Untracked files(Workspace)状态。执行 add 后,代码变为 Changes to be committed(Stage)状态。对 Stage 中的文件进行修改后,状态变为 Changes not staged for commit。执行 commit 后,代码从 Stage 转移到 Local repository 中。使用 git log 可查看代码提交历史。

3.Branch 和 Tag
Branch 和 Tag 都可视为补丁的时序化集合,Branch 可以相互合并。在克隆 repository 后,默认有一个主线分支称为 master。Tag 用于发布后标记版本。与 SVN 不同,SVN 的 Branch 和 Tag 是将整个 Trunk 代码库拷贝出来,而 Git 只是将补丁引用重新应用在当前代码上。因此,Git 的 Branch/Tag 非常轻量,切换起来非常便捷。在使用 Git 时,建议充分利用分支来提高开发效率。稍后在介绍 Git flow 时,将说明如何使用分支进行代码功能开发管理。

开发管理

3.1 新建分支的两种办法

$ git checkout -b [BRANCH_NAME] # 在当前版本切换并新建分支
$ git branch [BRANCH_NAME] # 直接新建分支

3.2 切换分支

$ git checkout [BRANCH_NAME]

3.3 合并分支的两种办法

$ git merge [BRANCH_NAME] # 将另外一个分支的代码,合并到当前分支之后。
$ git rebase [BRANCH_NAME] # 不推荐,对代码进行比较,将本分支修改后的代码合并到另外一个分支之后

rebase 通常情况下不推荐使用,因为 rebase 完下游分支,再从上游分支 merge 的时候会丢失分支合并的 commit。对于已经推到远程仓库的 commit,不建议 rebase,因为这会导致其他人 pull 时出现大量冲突。

3.4 删除分支

$ git branch -d [BRANCH_NAME] # 已经合并到 master
$ git branch -D [BRANCH_NAME] # 该分支未合并到 master,强制删除

即使删除了分支等,也可以用 git reflogs 找回来。

3.5 取消修改

git stash # 取消全部修改,它可以恢复过来
git reset --soft [REV] # 保留修改内容,从 Local repository 撤销,也可用于回退历史记录
git reset --hard [REV] # 丢掉修改内容,从 Local repository 撤销,也可用于回退历史记录

推送本地代码到远程仓库

$ git push [REMOTE] [BRANCH]

REMOTE 默认为 origin,如果不填,将推送到 origin。BRANCH 默认为当前分支,可省略。若要推送本地功能分支,建议使用 --set-upstream 参数。

郑重警告:永远不要对主线 master 分支执行 --force。

获取远程分支更新

$ git pull # 更新到 workspace
$ git fetch # 更新到 Local repository,可能需要通过 merge 合并到 workspace 一次

远程仓库
Clone 后会有一个默认的远程仓库 origin,如果需要添加其他远程仓库,可使用以下命令:

$ git remote add [REMOTE_NAME] [URL] # 添加远程仓库
$ git fetch [REMOTE_NAME] # 获取远程仓库更新
$ git branch -a # 查看所有分支,包括远程仓库内的
$ git push [REMOTE_NAME] [BRANCH_NAME] # 推送到远程仓库

GitHub在Git Remote的基础上引入了一套机制,以便更方便地参与开源项目。一般的开源项目参与流程是,首先注册一个GitHub账号,然后将感兴趣的开源项目Fork到自己的命名空间下。接下来,拆分分支进行修改,并提交到自己的GitHub存储库。然后,发起一个Pull Request(PR),请求项目维护者合并你的代码。在此过程中,项目维护者会对你的代码进行审查和点评,你需要按照维护者的要求进行修改(在这里,经常使用rebase来保持代码整洁)。一旦修改得到批准,并获得维护者的同意,维护者将代码合并到项目中。

具体的流程一经尝试就会明白,GitLab的Merge Request的原理与此一致。

Git Flow

Git Flow在Git分支的基础上实现了一套简单的功能模块化开发流程,主要思想是将分支划分为上下游几个层级,然后通过一套命令行工具进行维护。

master分支: 与线上版本保持一致,当出现线上问题时可以轻松修复。
develop分支: 功能开发的基线分支,功能开发完成后合并到此分支。所有功能开发完成后经过测试上线,然后合并回master。
*feature/功能开发分支: 从develop分支拆分,需要定期将develop的更新合并过来,保持与上游分支的一致性。功能开发完成后,可合并到develop。通过与上游分支保持一致,可以避免误删他人代码。所有代码冲突必须在下游分支解决,测试完毕后才可合并到上游分支。
*hotfix/热修复分支: 主要用于在线上修复bug,修复后应同时合并到master和develop两个分支。

然后,git flow提供了一套命令行工具,更轻松地进行这些代码合并的操作。

$ git flow init # 初始化git flow分支模型
$ git flow feature start [NAME] # 开始一个功能分支
$ git flow feature finish [NAME] # 将功能分支合并到develop
$ git flow hotfix start [NAME] # 开始一个热修复分支
$ git flow hotfix finish [NAME] # 将补丁合并到develop和master
$ git flow release [NAME] # 发布一个新版本,打标签

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

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

相关文章

什么是脏读、不可重复读、幻读讲解

数据库隔离级别是数据库管理系统中一个重要的概念,它定义了事务之间的可见性和影响。在多用户并发访问数据库时,隔离级别能够确保事务之间的相互独立性,避免数据不一致的问题。本文将深入探讨三种常见的并发问题:脏读、不可重复读…

TikTok运营干货——养号篇

随着国内抖音红利的进一步释放,越来越多人涌入了TikTok国内外市场。而TikTok作为海外新兴的社媒平台,也在迅速的发展着,吸引了大批的跨境电商玩家入驻。然而,TikTok运营的一大难点就是养号,许多人还没开始转化号就被封…

vue3别名配置(vite)

1、配置别名的优点: 在VUE项目中import导入文件时,可以写相对路径. 2、在vite.config.js中配置 a. 首先引入path import path from "path"/* */ b.在resolve添加别名,例如: alias:{"~":path.resolve(__di…

零基础快速上手FFmpeg!一篇就够啦~

在这个自媒体盛行的时代,音视频(电影、音乐)对于我们来说是再熟悉不过了吧。那么对于一个音视频文件,都有哪些属性呢?以视频为例,我们可以通过如下命令查看其信息。 > ffmpeg -i .\demo.mp4 ffmpeg ver…

探索arkui(2)--- 布局(列表)--- 2(支持分组/实现响应滚动位置)

前端开发布局是指前端开发人员宣布他们开发的新网站或应用程序正式上线的活动。在前端开发布局中,开发人员通常会展示新网站或应用程序的设计、功能和用户体验,并向公众宣传新产品的特点和优势。前端开发布局通常是前端开发领域的重要事件,吸…

通义灵码,阿里巴巴的编程辅助工具

一、官网 通义灵码_智能编码助手_AI编程_人工智能-阿里云 二、安装VSCode 如何下载安装VSCode 三、VSCode安装通义灵码 1.访问扩展详情界面 方式1 访问通义灵码安装教程页面 方法2 访问VSCode市场中的TONGYI Lingma 点击 Install 按钮访问扩展详情界面 2.打开VSCode …

udp多点通信-广播-组播

单播 每次只有两个实体相互通信,发送端和接收端都是唯一确定的。 广播 主机之间的一对多的通信所有的主机都可以接收到广播消息(不管你是否需要)广播禁止穿过路由器(只能做局域网通信)只有UDP可以广播广播地址 有效网络号全是1的主机号 192.1…

《成为一名优秀的架构师:从基础到实践》

文章目录 前言《高并发架构实战:从需求分析到系统设计》《架构师的自我修炼:技术、架构和未来》《中台架构与实现:基于DDD和微服务》《分布式系统架构:架构策略与难题求解》《流程自动化实战:系统架构和软件开发视角 》…

人工智能-深度学习之序列模型

想象一下有人正在看网飞(Netflix,一个国外的视频网站)上的电影。 一名忠实的用户会对每一部电影都给出评价, 毕竟一部好电影需要更多的支持和认可。 然而事实证明,事情并不那么简单。 随着时间的推移,人们对…

使用VC++实现分段线性变换,直方图均衡化、锐化处理(使用拉普拉斯算子)

图像锐化1 实验要求 5.1实验目的、要求 实验目的: (1)掌握图像增强的原理与相关方法。 (2)能使用VC实现图像增强的一些相关功能。 实验要求: A部分: (1)对一幅256级灰度…

Linux | 进程间通信

目录 前言 一、进程间通信的基本概念 二、管道 1、管道的基本概念 2、匿名管道 (1)原理 (2)测试代码 (3)读写控制相关问题 a、读端关闭 b、写端关闭 c、读快写慢 d、读慢些快 (4&a…

线程的面试八股

Callable接口 Callable是一个interface,相当于给线程封装了一个返回值,方便程序猿借助多线程的方式计算结果. 代码示例: 使用 Callable 版本,创建线程计算 1 2 3 ... 1000, 1. 创建一个匿名内部类, 实现 Callable 接口. Callable 带有泛型参数. 泛型参数表示返回值的类型…

高级数据结构——树状数组

树状数组(Binary Index Tree, BIT),是一种一般用来处理单点修改和区间求和操作类型的题目的数据结构,时间复杂度为O(log n)。 对于普通数组来说,单点修改的时间复杂度是 O(1),但区间求和的时间复杂度是 O(n…

【备忘】websocket学习之挖坑埋自己

背景故事 以前没有好好学习过websocket,只知道它有什么用途,也知道是个好东西,平时在工作中没用过,所以对它并不知所以然。如今要做个自己的项目,要在付款的时候实时播报声音。自己是个开发者,也不想用别人…

类加载中的执行顺序

结论: 先静态再实例 实例化一个子类(这个颜色主要是实例化会执行的部分): 父类静态属性->父类静态代码块->子类静态属性->子类静态代码块->父类代码块&…

jQuery【jQuery树遍历、jQuery动画(一)、jQuery动画(二)】(四)-全面详解(学习总结---从入门到深化)

目录 jQuery树遍历 jQuery动画(一) jQuery动画(二) jQuery树遍历 1、 .children() 获得子元素&#xff0c;可以传递一个选择器参数 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-…

【Effective C++ 笔记】(四)设计与声明

【四】设计与声明 条款18 &#xff1a; 让接口容易被正确使用&#xff0c;不易被误用 Item 18: 让接口容易被正确使用&#xff0c;不易被误用 Make interfaces easy to use correctly and hard to use incorrectly. “让接口容易被正确使用&#xff0c;不易被误用”&#xff0…

OpenCV基础应用(3)— 把.png图像保存为.jpg图像

前言&#xff1a;Hello大家好&#xff0c;我是小哥谈。本节课就手把手教你如何把.png图像保存为.jpg图像&#xff0c;希望大家学习之后能够有所收获~&#xff01;&#x1f308; 目录 &#x1f680;1.技术介绍 &#x1f680;2.实现代码 &#x1f680;1.技术介绍 如果在电脑某…

web缓存-----squid代理服务

squid相关知识 1 squid的概念 Squid服务器缓存频繁要求网页、媒体文件和其它加速回答时间并减少带宽堵塞的内容。 Squid代理服务器&#xff08;Squid proxy server&#xff09;一般和原始文件一起安装在单独服务器而不是网络服务器上。Squid通过追踪网络中的对象运用起作用。…

渗透测试--实战若依ruoyi框架

免责声明&#xff1a; 文章中涉及的漏洞均已修复&#xff0c;敏感信息均已做打码处理&#xff0c;文章仅做经验分享用途&#xff0c;切勿当真&#xff0c;未授权的攻击属于非法行为&#xff01;文章中敏感信息均已做多层打马处理。传播、利用本文章所提供的信息而造成的任何直…