【Git】版本控制系统Git命令详解

2024.06.06   2024.06.06\ 2024.06.06 

Resources

强推:Pro Git - Book (git-scm.com).中文版.

强烈推荐网址:https://learngitbranching.js.org/?locale=zh_CN.

LearnGit Game:

基础(Git 主要命令)

Git Commit(提交)

提交记录保存的是你的目录下所有文件的快照

提交记录尽可能地轻量,因此将当前版本与仓库中的上一个版本进行对比,并把所有的差异打包到一起作为一个提交记录。

保存了提交的历史记录。这也是为什么大多数提交记录的上面都有 parent 节点。

Git Branch(分支)

只是简单地指向某个提交记录 —— 仅此而已。

因为即使创建再多的分支也不会造成储存或内存上的开销,并且按逻辑分解工作到不同的分支要比维护那些特别臃肿的分支简单多了。

使用分支其实就相当于在说:“我想基于这个提交以及它所有的 parent 提交进行新的工作。”

Git Switch(切换分支)

在 Git 2.23 版本中,引入了一个名为 git switch 的新命令,最终会取代 git checkout,因为 checkout 作为单个命令有点超载(它承载了很多独立的功能)。

创建:git branch <name>

创建同时切换分支:git checkout -b <your-branch-name>

Git Merge(合并)

在 Git 中合并两个分支时会产生一个特殊的提交记录,它有两个 parent 节点。翻译成自然语言相当于:“我要把这两个 parent 节点本身及它们所有的祖先都包含进来。”

切换分支:用 git checkout bugFix 命令切换到该分支。【*标识当前分支】

合并:git merge <name>。【示例里为什么还要合并回去?,保证两个分支都为最新的同步241227即答】

Git Rebase(合并)

取出一系列的提交记录,“复制”它们,然后在另外一个地方逐个的放下去。

可以创造更线性的提交历史,这听上去有些难以理解。如果只允许使用 Rebase 的话,代码库的提交历史将会变得异常清晰。

合并至:git rebase <main>。若初始在 bugFix上。【也可以 rabase 两个名称】

流程:创建并转到分支 bugFix,同时 main 有新提交,然后在 bugFix 上 rebase 到 main。

高级(Git 的超棒特性)

分离 Head

一种状态。在Git树上移动。如果想看 HEAD 指向,可以通过 cat .git/HEAD 查看。

HEAD 通常情况下是指向分支名的(如 bugFix)。在你提交时,改变了 bugFix 的状态,这一变化通过 HEAD 变得可见。

分离的 HEAD 就是让其指向了某个具体的提交记录而不是分支名。

执行命令:git checkout c1.【从指向 main 到指向 c1

相对引用 (^与~)

引用提交记录 如C1 的方式。

在实际应用时,并没有像本程序中这么漂亮的可视化提交树供你参考,所以你就不得不用 git log 来查看提交记录的哈希值。

比较令人欣慰的是,Git 对哈希的处理很智能。你只需要提供能够唯一标识提交记录的前几个字符即可。因此我可以仅输入fed2 而不是上面的一长串字符。

正如我前面所说,通过哈希值指定提交记录很不方便,所以 Git 引入了相对引用。这个就很厉害了!

相对引用非常给力,这里我介绍两个简单的用法:

  • 使用 ^ 向上移动 1 个提交记录【main^^相当于 main 的爷爷节点,^2是 parent2】
  • 使用 ~<num> 向上移动n个提交记录,如 ~3 【默认为1】

强制移动分支:git branch -f a b 移动 a 到 b。

撤销变更

和提交一样,撤销变更由底层部分(暂存区的独立文件或者片段)和上层部分(变更到底是通过哪种方式被撤销的)组成。

两种方法:一是 git reset(远程无效,仅自己),还有就是 git revert

git reset 通过把分支记录回退几个提交记录来实现撤销改动。你可以将这想象成“改写历史”。git reset 向上移动分支,原来指向的提交记录就跟从来没有提交过一样。

(译者注:在 reset 后, C2 所做的变更还在,但是处于未加入暂存区状态。)

新提交记录 C2' 引入了更改 —— 这些更改刚好是用来撤销 C2 这个提交的。也就是说 C2' 的状态与 C1 是相同的。

流程:git reset HEAD^checkout pushedrevert pushed

移动提交记录(自由修改提交树)

要讨论的这个话题是“整理提交记录” —— 开发人员有时会说“我想要把这个提交放到这里, 那个提交放到刚才那个提交的后面”, 而接下来就讲的就是它的实现方式,非常清晰、灵活,还很生动。

看起来挺复杂, 其实是个很简单的概念。

git cherry-pick【抓取任何】

抓过来放到当前分支下:git cherry-pick c2 c4

知道这些提交记录的哈希值 如 c2 时, 用 cherry-pick 再好不过。【最简单】

交互式的 rebase -i

若 hash 值未知。

交互式 rebase 指的是使用带参数 --interactive 的 rebase 命令, 简写为 -i

Git 会打开一个 UI 界面并列出将要被复制到目标分支的备选提交记录,它还会显示每个提交记录的哈希值和提交说明,提交说明有助于你理解这个提交进行了哪些更改。

当 rebase UI界面打开时, 你能做3件事:

  • 调整提交记录的顺序(通过鼠标拖放来完成)
  • 删除你不想要的提交(通过切换 pick 的状态来完成,关闭就意味着你不想要这个提交记录)
  • 合并提交。

流程:git rebase -i HEAD~4

杂项(Git 技术、技巧与贴士大集合)

本地栈式提交

流程:checkout main, cherry-pick c4rebase -i HEAD~3, rebase bugFix main

提交的技巧
  • 先用 git rebase -i 将提交重新排序,然后把我们想要修改的提交记录挪到最前
  • 然后用 git commit --amend 来进行一些小修改【修改最前端的记录
  • 接着再用 git rebase -i 来将他们调回原来的顺序
  • 最后我们把 main 移到修改的最前端(用你自己喜欢的方法),就大功告成啦!

技巧1流程:rebase -i HEAD~2, commit --amend, rebase -i HEAD~2, rebase HEAD main

技巧2流程:git checkout main, cherry-pick c2, commit --amend, cherry-pick c3

Git Tags

有没有什么可以永远指向某个提交记录的标识呢,比如软件发布新的大版本,或者是修正一些重要的 Bug 或是增加了某些新特性,有没有比分支更好的可以永远指向这些提交的方法呢?

就像是提交树上的一个锚点,标识了某个特定的位置。

把 v1 标签打在 c2 上:git tag v1 c2

流程:checkout c2, tag v1 c2, tag v0 c1

Git Describe

一个命令用来描述离你最近的锚点(也就是标签),它就是 git describe <ref>

它输出的结果是这样的:

<tag>_<numCommits>_g<hash>

tag 表示的是离 ref 最近的标签, numCommits 是表示这个 reftag 相差有多少个提交记录, hash 表示当前提交记录哈希值的前几位。

ref 提交记录上有某个标签时,则只输出标签名称。

流程:rebase main bugFix, rebase bugFix side, side another, another main

a远程仓库

远程仓库并不复杂, 在如今的云计算盛行的世界很容易把远程仓库想象成一个富有魔力的东西, 但实际上它们只是你的仓库在另个一台计算机上的拷贝。你可以通过因特网与这台计算机通信 —— 也就是增加或是获取提交记录

话虽如此, 远程仓库却有一系列强大的特性

  • 首先也是最重要的的点, 远程仓库是一个强大的备份。本地仓库也有恢复文件到指定版本的能力, 但所有的信息都是保存在本地的。有了远程仓库以后,即使丢失了本地所有数据, 你仍可以通过远程仓库拿回你丢失的数据。
  • 还有就是, 远程让代码社交化了! 既然你的项目被托管到别的地方了, 你的朋友可以更容易地为你的项目做贡献(或者拉取最新的变更)

现在用网站来对远程仓库进行可视化操作变得越发流行了(像 GitHub), 但远程仓库永远是这些工具的顶梁柱, 因此理解其概念非常的重要!

Git Clone

技术上来讲,git clone 命令在真实的环境下的作用是在本地创建一个远程仓库的拷贝(比如从 github.com)

远程分支 o/master

本地仓库多了一个名为 o/main 的分支,即为远程分支。

<remote name>/<branch name>】这个分支就叫 main,远程仓库的名称就是 o (其实默认为 origin

远程分支反映了远程仓库(在你最后一次和它通信时)的状态

远程分支有一个特别的属性,在你切换到远程分支时,自动进入分离 HEAD 状态Git 这么做是出于不能直接在这些分支上进行操作的原因, 你必须在别的地方完成你的工作, (更新了远程分支之后)再用远程分享你的工作成果。

Git Fetch

从远程仓库获取数据。同时更新远程分支。【可以理解为单纯的下载操作】

git fetch 通常通过互联网(使用 http://git:// 协议) 与远程仓库通信。

git fetch 并不会改变你本地仓库的状态。它不会更新你的 main 分支,也不会修改你磁盘上的文件。

理解这一点很重要,因为许多开发人员误以为执行了 git fetch 以后,他们本地仓库就与远程仓库同步了。它可能已经将进行这一操作所需的所有数据都下载了下来,但是并没有修改你本地的文件。

Git Pull

可以像合并本地分支那样来合并远程分支。也就是说就是你可以执行以下命令:

  • git cherry-pick o/mainrebasemerge

由于先抓取更新再合并到本地分支这个流程很常用,因此 Git 提供了一个专门的命令来完成这两个操作。它就是我们要讲的 git pull

  • git pull 就是 git fetch 和 git merge 的缩写!

Version Control(Git

Version control systems (VCSs) are tools used to track changes to source code (or other collections of files and folders).

追踪源代码改动.

现代的版本控制系统可以帮助您轻松地(甚至自动地)回答以下问题:

  • Who wrote this module?
  • 这个文件的这一行是什么时候被编辑的?By whom? Why was it edited?
  • 最近的1000个版本中,when/why 导致了单元测试失败?

Because Git’s interface is a leaky abstraction, learning Git top-down (starting with its interface / command-line interface) can lead to a lot of confusion.

抽象泄露问题,导致自顶向下很难学。

而优雅的底层设计则非常容易被人理解。自底向上。

目的:搞懂 Git 的数据模型。

Git’s data model

Snapshots

In Git terminology, a file is called a “blob”, and it’s just a bunch of bytes. A directory is called a “tree”, and it maps names to blobs or trees.【文件称 blob,目录称 tree】

A snapshot is the top-level tree that is being tracked.【快照是追踪最顶层的目录】

Modeling history: relating snapshots

历史记录建模。For many reasons, Git doesn’t use a simple model like this.【Git 没有采用】

Git calls these snapshots “commit”s.【快照 = 提交】

箭头:it’s a “comes before” relation, not “comes after”。

o <-- o <-- o <-- o <---- o
            ^            /
             \          v
              --- o <-- o

the os correspond to individual commits (snapshots).【提交不可更改】

Data model, as pseudocode

It’s a clean, simple model of history. 历史模型的伪代码。

// 文件就是一组数据  a file is a bunch of bytes
type blob = array<byte>

// 一个包含文件和目录的目录  a directory contains named files and directories
type tree = map<string, tree | blob>

// 每个提交都包含一个父辈,元数据和顶层树  a commit has parents, metadata, and the top-level tree
type commit = struct {
   parent: array<commit>
   author: string
   message: string
   snapshot: tree
}

24.07.16 − − E n d . 24.07.16--End. 24.07.16End.

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

华为云 | 快速搭建DeepSeek推理系统

DeepSeek&#xff08;深度求索&#xff09;作为一款国产AI大模型&#xff0c;凭借其高性能、低成本和多模态融合能力&#xff0c;在人工智能领域崛起&#xff0c;并在多个行业中展现出广泛的应用潜力。 如上所示&#xff0c;在华为云解决方案实践中&#xff0c;华为云提供的快速…

Unity 内置渲染管线各个Shader的用途和性能分析,以及如何修改Shader(build in shader 源码下载)

文章目录 所有Shader分析路径&#xff1a;Standard路径&#xff1a;Nature/路径&#xff1a;UI/路径&#xff1a;Particles/Particles/Standard SurfaceParticles/Standard Unlit 路径&#xff1a;Unlit/Unlit/TextureUnlit/ColorUnlit/TransparentUnlit/Transparent CutoutUnl…

概率分布与概率密度

前言 本文隶属于专栏《机器学习数学通关指南》&#xff0c;该专栏为笔者原创&#xff0c;引用请注明来源&#xff0c;不足和错误之处请在评论区帮忙指出&#xff0c;谢谢&#xff01; 本专栏目录结构和参考文献请见《机器学习数学通关指南》 正文 &#x1f50d; 1. 概率分布基…

【C++】类与对象:深入理解默认成员函数

类与对象&#xff1a;深入理解默认成员函数 引言1、默认成员函数概述2、构造函数与析构函数2.1 默认构造函数2.2 析构函数 3、拷贝控制成员3.1 拷贝构造函数3.2 赋值运算符重载 4、移动语义&#xff08;C11&#xff09;4.1 移动构造函数4.2 移动赋值运算符 5、三五法则与最佳实…

LINUX网络基础 - 网络编程套接字,UDP与TCP

目录 前言 一. 端口号的认识 1.1 端口号的作用 二. 初识TCP协议和UDP协议 2.1 TCP协议 TCP的特点 使用场景 2.2 UDP协议 UDP的特点 使用场景 2.3 TCP与UDP的对比 2.4 思考 2.5 总结 三. 网络字节序 3.1 网络字节序的介绍 3.2 网络字节序思考 四. socket接口 …

夸父工具箱(安卓版) 手机超强工具箱

如今&#xff0c;人们的互联网活动日益频繁&#xff0c;导致手机内存即便频繁清理&#xff0c;也会莫名其妙地迅速填满&#xff0c;许多无用的垃圾信息悄然占据空间。那么&#xff0c;如何有效应对这一难题呢&#xff1f;答案就是今天新推出的这款工具软件&#xff0c;它能从根…

Apache nifi demo 实验

Apache nifi 是个数据流系统&#xff0c;可以通过配置 自定义的流程来实现数据的转换。 比如可以配置一个流程&#xff0c;读取数据库里的数据&#xff0c;再转换&#xff0c;最后保存到本地文件。 这样可以来实现一些数据转换的操作&#xff0c;而不用特地编写程序来导入导出。…

VSCode知名主题带毒 安装量900万次

目前微软已经从 Visual Studio Marketplace 中删除非常流行的主题扩展 Material Theme Free 和 Material Theme Icons&#xff0c;微软称这些主题扩展包含恶意代码。 统计显示这些扩展程序的安装总次数近 900 万次&#xff0c;在微软实施删除后现在已安装这些扩展的开发者也会…

Java自动拆箱装箱/实例化顺序/缓存使用/原理/实例

在 Java 编程体系中&#xff0c;基本数据类型与包装类紧密关联&#xff0c;它们各自有着独特的特性和应用场景。理解两者之间的关系&#xff0c;特别是涉及到拆箱与装箱、实例化顺序、区域问题、缓存问题以及效率问题。 一、为什么基本类型需要包装类 泛型与集合的需求 Java…

蓝桥杯复盘记录004(2023)

涉及知识点 1.深搜 2.单调队列滑动窗口 3.位运算 4.并查集 题目 1.lanqiao3505 思路&#xff1a; dfs(index, weight, cnt) index表示瓜的索引&#xff0c; weight等于买瓜的重量&#xff0c; cnt表示买了多少瓜。 递归终止条件&#xff1a;1.如果瓜买完了&#xff0c;归…

【银河麒麟高级服务器操作系统】服务器测试业务耗时问题分析及处理全流程分享

更多银河麒麟操作系统产品及技术讨论&#xff0c;欢迎加入银河麒麟操作系统官方论坛 https://forum.kylinos.cn 了解更多银河麒麟操作系统全新产品&#xff0c;请点击访问 麒麟软件产品专区&#xff1a;https://product.kylinos.cn 开发者专区&#xff1a;https://developer…

【现代深度学习技术】卷积神经网络03:填充和步幅

【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈PyTorch深度学习 ⌋ ⌋ ⌋ 深度学习 (DL, Deep Learning) 特指基于深层神经网络模型和方法的机器学习。它是在统计机器学习、人工神经网络等算法模型基础上&#xff0c;结合当代大数据和大算力的发展而发展出来的。深度学习最重…

FPGA开发,使用Deepseek V3还是R1(3):系统级与RTL级

以下都是Deepseek生成的答案 FPGA开发&#xff0c;使用Deepseek V3还是R1&#xff08;1&#xff09;&#xff1a;应用场景 FPGA开发&#xff0c;使用Deepseek V3还是R1&#xff08;2&#xff09;&#xff1a;V3和R1的区别 FPGA开发&#xff0c;使用Deepseek V3还是R1&#x…

【含文档+PPT+源码】基于SpringBoot和Vue的编程学习系统

项目介绍 本课程演示的是一款 基于SpringBoot和Vue的编程学习系统&#xff0c;主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的 Java 学习者。 1.包含&#xff1a;项目源码、项目文档、数据库脚本、软件工具等所有资料 2.带你从零开始部署运行本套系统 3.该…

网页复制小妙招

当你遇到网页时不能复制时&#xff0c;不要慌&#xff0c;教你一招可让你为所欲为。 平时你们在网上查找资料想复制时&#xff0c;总是会出现付费限制提示&#xff08;我也是qwq&#xff09;&#xff0c;这时不要慌&#xff0c;在空白处右击选择检查 按开检查&#xff0c;然后…

聆听PostgreSQL数据库的使用

参考&#xff1a;&#xff08;1&#xff09;零基础入门PostgreSQL教程 &#xff08;2&#xff09;菜鸟教程 文章目录 一、PostgreSQL是什么&#xff1f;二、基本使用1.下载2.操作&#xff08;1&#xff09;数据库&#xff08;2&#xff09;表 一、PostgreSQL是什么&#xff1f;…

内核进程调度队列(linux的真实调度算法) ─── linux第13课

目录 内核进程调度队列的过程 一个CPU拥有一个runqueue(运行队列在内存) 活动队列(active) 过期队列(expired) active指针和expired指针 重绘runqueue linux内核O(1)调度算法 总结 补充知识: 封装链式结构的目的是: 仅使用封装链式结构可以得到全部的task_struct的信…

【算法】手撕二分查找

目录 二分查找 【左闭右闭】/【相错终止】 【循环不变量】 【四要素】 二分查找的任意模板 【一般】情形 【左闭右闭】总结 mid的防溢出写法 【左闭右开】/【相等终止】 【一般】情形 再谈初始值 【左闭右开】总结 二分查找本质 【左开右闭】/【相等终止】 【一般…

C++入门基础知识1

今天&#xff0c;我们正式来学习C&#xff0c;由于C是在C的基础之上&#xff0c;容纳进去了面向对象编程思想&#xff0c;并增加了许多有用的库&#xff0c;以及编程范式等。熟悉C语言之后&#xff0c;对C学习有一定的帮助。 现在我们这篇主要是&#xff1a; 1. 补充C语言语法…

Leetcode 57-插入区间

给你一个 无重叠的 &#xff0c;按照区间起始端点排序的区间列表 intervals&#xff0c;其中 intervals[i] [starti, endi] 表示第 i 个区间的开始和结束&#xff0c;并且 intervals 按照 starti 升序排列。同样给定一个区间 newInterval [start, end] 表示另一个区间的开始和…