【Linux】从版本控制到代码调试:Git 入门与 GDB 调试器学习指南

【Linux】从版本控制到代码调试:Git 入门与 GDB 调试器学习指南

前言

 作为 Linux 开发的 “左膀右臂”,Git 管版本、gdb 调程序 —— 前者搞定代码的迭代与协同,后者专治程序里的各种 “疑难杂症”。这篇博客就从 Git 的核心概念、基础操作,讲到 gdb 的调试指令,把这俩工具的高频用法讲透,帮你把开发效率直接拉满。


目录

一、Git 版本控制器

1.1 什么是 Git?

【问题】:什么是分布式?

【问题】:什么是集中式?

1.2 Git 核心概念 

1.3 GitHub 与 Gitee

二、Git 基础操作

1. Git安装

2. 远程仓库与本地仓库联动(以 Gitee 为例)

3. 身份配置

4. 代码提交的 “三板斧”

5. git其他选项

【git log命令】

【git status命令】

【.gitignore文件】

三、gdb前置知识

【readelf指令】

四、gdb相关调试指令

4.1 进入gdb和退出gdb指令

4.2 查看源代码指令

4.3 run/r指令

4.4 断点相关调试指令

4.4.1 break/b指令

4.4.2 d 指令

4.4.3 disable/enable breakpoints 指令

4.4.4 info breakpoints 指令

4.5 next/n 指令

4.6 step/s 指令

4.7 finish 指令

4.8 print/p 指令

4.9 set var指令 

4.10 continue(或 c)指令

4.11 display指令

4.12 undisplay指令

4.13 until指令

4.14 breaktrace (或 bt)指令

4.15 info (i) locals指令


一、Git 版本控制器

1.1 什么是 Git?

Git 是一款分布式版本控制系统,可以理解为代码的 “时光机”—— 它能记录代码的每一次修改,让你随时回退到历史版本,还能支持多人协作开发。和传统的 SVN(svm只能通过服务端查看历史记录) 相比,Git 是 “客户端 - 服务端一体” 的设计,既可以本地单机管理代码,也能通过远程仓库(如 GitHub、Gitee)实现团队协作。

【问题】:什么是分布式?

【分布式的核心概念】:

将整体的任务、数据或功能分散部署到多个独立的节点(如计算机、服务器等)上,使各节点能并行处理任务;每个节点可拥有完整或部分资源,支持独立工作,节点之间通过网络进行协同与同步无需依赖单一中心节点来驱动整个系统运行。

【分布式的典型特点】:并行执行:多节点可同时处理任务,提升整体效率;去中心化:无单一故障点,某一节点故障不影响系统整体运行;弹性扩展:可通过新增节点快速拓展系统能力。

简单类比(以 Git 为例)

Git 作为分布式版本控制系统,核心特点是每个用户的本地都拥有完整的版本库:既可以连接远端服务端(如 GitHub、GitLab)进行代码推送、拉取,实现团队协作;也能在本地完全独立地完成提交、分支管理、版本回滚等所有版本控制操作;多个用户可在各自本地 “并行” 开展开发,之后再通过同步操作整合修改,完美体现了分布式 “多节点独立工作 + 协同同步” 的特性。

【问题】:什么是集中式?

【集中式的核心概念】:

将系统的任务、数据或功能集中部署在单一的中心节点(如中央服务器)上,所有操作(如数据存储、任务处理)都依赖该中心节点完成;用户或从属节点需连接到中心节点才能开展工作,本地通常仅保留临时的工作副本,不具备独立处理核心任务的能力。

【集中式的典型特点】:单一中心:系统依赖唯一的中心节点驱动,逻辑集中、管理便捷;强依赖性:用户或从属节点必须连接中心节点才能完成核心操作,若中心节点故障,整个系统将无法正常运行;扩展受限:系统能力受中心节点的硬件、性能上限约束,难以快速弹性扩展。

简单类比(以 SVN 为例)

SVN 作为集中式版本控制系统,核心特点是仅中央服务器保存完整的版本库:用户必须连接到中央服务器,才能执行提交、更新、分支管理等版本控制操作;本地仅保留当前工作副本,无完整版本库,无法在断网或中心服务器不可用时独立进行版本管理;多用户需串行或依赖中心节点的调度开展协作,体现了集中式 “单一中心驱动 + 节点强依赖” 的特性。

1.2 Git 核心概念 

  • 仓库(Repository):分为本地仓库(你电脑里的代码库)和远程仓库(如 GitHub 上的共享代码库);
  • 版本控制:像管理实验报告版本一样,Git 能记录代码的每一次修改(比如 “实验报告 v1”“实验报告究极版”),随时回溯;
  • 分布式协作:每个开发者都有完整的代码库,既可以本地开发,又能通过远程仓库同步协作(比如张三、李四可以分别改代码,再合并到同一个远程仓库)。

1.3 GitHub 与 Gitee

Git 是版本控制工具,而 GitHub、Gitee 是基于 Git 的商业化代码托管平台—— 你可以把它们理解为 “代码的社交网络”,既能存代码,又能和全球开发者协作、学习优质项目。类似地,基于 Linux 内核也衍生出了 CentOS、Ubuntu 等商业化操作系统,原理是相通的~

二、Git 基础操作

1. Git安装

  • 安装 Git:在 Linux 上可通过包管理器快速安装,比如 CentOS 用 yum install git,Ubuntu 用 apt install git

2. 远程仓库与本地仓库联动(以 Gitee 为例)

【新建仓库】:

进入gitee后点右上角的+,点击后就能看到新建仓库这一选项,点击后就到了下述界面

在这里,选择你需要的代码语言来保存版本。README文件用于仓库的说明,创建时会自动生成中英文版本。在分支选项中,这里推荐选择单分支是为了简化项目管理,特别是在项目初期或只是用于代码托管时,不需要复杂的分支结构。单分支模式更适合简单的版本控制,避免了多分支带来的合并冲突和管理开销。

【将远端仓库拉到本地】:

点击新建仓库右上角的克隆和下载:

克隆成功!!!

#将远端仓库克隆到本地的命令 git clone 仓库地址

Test仓库此时就在我们的当前目录下,大家使用时尽量放在普通用户下,我这只是示范,所以就没有切换用户了。

3. 身份配置

当我们将远端仓库拉取到本地,为了确保提交的代码身份被Gitee/GitHub正确识别,需要在本地进行相关配置

git config --global user.email "你的邮箱" git config --global user.name "你的名字"

Git 配置 user.name 和 user.email,是为了给代码提交打上专属身份标签,方便后续查看提交历史、追溯修改责任。

4. 代码提交的 “三板斧”

【第一招】:git add—— 把文件加入 “待提交队列”把需要版本管理的文件告知 Git,命令格式:

git add 文件名 # 单个文件 git add . # 当前目录所有文件 

【第二招】:git commit—— 提交修改到本地仓库把 “待提交队列” 的修改保存到本地仓库,同时写提交日志(描述这次改了啥,这块不能随便填写):

git commit -m "提交日志:比如‘新增登录功能’" 

【第三招】:git push—— 同步修改到远程仓库把本地仓库的修改推送到 GitHub 等远程仓库,命令:

git push 

首次推送可能需要输入 GitHub 账号密码(或配置 SSH 密钥免密,新手不建议配置免密),在圈的地方输入你的账号和密码即可,账号会回显,密码不会回显。

配置免密码提交】:https://blog.ZEEKLOG.net/camillezj/article/details/55103149

Git 工作流程围绕工作区、暂存区、本地仓库三个区域展开,操作需在仓库目录内进行:工作区:项目目录中可见的文件(如仓库下的代码文件、文档),修改后仅存于此,未被 Git 跟踪为新版本;执行 git add 命令,将工作区的修改加入暂存区(可理解为 “待提交清单”);执行 git commit 命令,将暂存区内容提交到本地仓库.git 目录是本地仓库的核心,提交后形成版本记录并保存);最后通过 git push 可将本地仓库的变更同步到远程仓库。

5. git其他选项

【git log命令】

作用:查看历史提交记录     

历史提交记录的信息,包含你的信息、日志、提交时间等等


【git status命令】

  作用:查看当前目录状态

显示当前没有东西可以提交的内容,工作区已清理


【.gitignore文件】

作用:指定 Git 版本控制中需要忽略的文件或目录,让这些文件 / 目录不被纳入版本管理,简单来说就是去掉杂项文件,只保留需要使用的文件 

在 .gitignore 文件中,通过通配符(如 *.exe*.out)可以指定 “匹配该后缀的所有文件都被忽略,不推送到远程仓库”。如果要添加自定义的杂项文件,需要用 *后缀 的格式(比如要忽略所有 .tmp 临时文件,就写 *.tmp);如果只写后缀(如 tmp),Git 会把它当作 “名为 tmp 的文件” 来处理,无法实现批量忽略同后缀文件的效果。

三、gdb前置知识

程序的发布方式有两种,debug模式和release模式Linux gcc/g++出来的二进制程序,默认是release模式要使用gdb调试,必须在源代码生成二进制程序的时候, 加上 -g 选项gdb是系统默认安装的,所以可以直接使用

【如何确认gcc/g++默认编译出来的结果是release版本还是debug版本

没带 "-g" 选项编译出来的结果:

带 "-g" 选项编译出来的结果:

可以看到两次编译后的文件大小不同,那么带 "-g" 选项编译后的可执行程序多了什么呢?

多出来的就是调试信息,这样也可以间接证明gcc默认编译出来的结果是release版本

【readelf指令】语法readelf [选项] [ELF文件]功能:用于显示 ELF 格式文件(如可执行文件、库文件)的详细信息,可查看文件头、节信息、符号表等内容常用选项-h 显示 ELF 文件头信息-l 显示程序头表信息-S 显示节头表信息-s 显示符号表信息-d 显示动态段信息-w 显示调试信息--help 查看所有选项说明

在 Linux 系统中,虽然可执行文件是二进制格式,但其内部结构采用了 ELF (Executable and Linkable Format/可执行与可链接格式)格式,可以通过 readELF 工具查看。

四、gdb相关调试指令

4.1 进入gdb和退出gdb指令

进入gdb指令:gdb可执行文件名称退出gdb指令:quit(q) 或者 ctrl + d

4.2 查看源代码指令

list / l 行号:显示指定行号附近的源代码,从上次位置继续向下列,每次列 10 行。list / l 函数名:列出指定函数的源代码。
注意:gbd会默认记录最近一次的指令,可以回车执行最近一次指令。

【用行号查看演示】:

l 5就是显式第五行上面的5行和下面的5行也就是每次显式10行

输入一次指令后,按回车就会自动向下再输出10行,输出完就显示有多少行

这个时候想要再从头看可以输入l 0,一般从头开始的话,只输输入 l的话会自动输出10行

【查看函数演示】:

显式sum函数附近的10行代码,反正也是每次输出10行,按空格就继续输出10行,输出完就显示一共多少行

4.3 run/r指令

作用:运行程序

核心特点:执行后会直接启动程序并运行至结束(类似 IDE 中的 “运行” 功能,如 VS 的 F5 键);若程序无断点,会一次性跑完所有逻辑,因此通常需要结合断点指令(如 b 行号 或 b 函数名 来实现调试暂停,进而逐步分析程序流程。

没打断点就一次性跑完了,要像vs那样调试的话得必须打断点,确实有点烦人,不好用!!!

4.4 断点相关调试指令

4.4.1 break/b指令
这是 GDB 调试中用于设置断点的 break(简写 b)指令,有四种常见用法:break 行号(或 b 行号:在代码的指定行设置断点,程序运行到该行时会暂停。例如 break 20(或 b 20),会在第 20 行设置断点。break 函数名(或 b 函数名:在指定函数的开头设置断点,程序进入该函数时会暂停。例如 break main(或 b main),会在 main 函数的开头设置断点。break 文件名:行号(或 b 文件名:行号):在指定文件的指定行设置断点。例如 break test.c:20(或 b test.c:20),会在 test.c 文件的第 20 行设置断点。break 文件名:函数名(或 b 文件名:函数名):在指定文件的指定函数开头设置断点。例如 break test.c:sum(或 b test.c:sum),会在 test.c 文件的 sum 函数开头设置断点。在 GDB 中如果不指定文件名,break 指令会默认在当前调试的主文件(通常是包含 main 函数的文件)中设置断点

分别在20行和main函数处打断点:

如果在第 20 行或main函数入口设置断点时,该行是空行,GDB 会自动定位到下方最近的有效语句处暂停执行,main函数的情况同理。

指定文件打断点:

4.4.2 d 指令
这是 GDB 调试中用于删除断点的 delete breakpoints 指令(简写d),有两种常见用法::删除所有断点。d  n:删除序号为n的断点。

第一个指令是删除序号为3的断点,第二个指令是删除所有断点,Num下的编号就对应了每个断点的序号

4.4.3 disable/enable breakpoints 指令
功能完整指令简写指令(常用)示例
禁用指定断点disable breakpoints 序号disable 序号 /dis 序号(gdb) dis 1(禁用序号 1 的断点)
禁用所有断点disable breakpointsdisable / dis(gdb) dis(禁用所有)
启用指定断点enable breakpoints 序号enable 序号 /en 序号(gdb) en 1(启用序号 1 的断点)
启用所有断点enable breakpointsenable / en(gdb) en(启用所有)

禁用断点后就不会生效了

4.4.4 info breakpoints 指令
这是 GDB 调试中用于查看断点信息的 info breakpoints(简写 info(或i) breakpoints)指令:info (或 i) breakpoints:参看当前设置了哪些断点,包括断点行号、状态、数量等详细信息。
列名核心含义(图标版)
Num🔢 断点序号(操作标识),序号呈线性增长,前面用过的序号纵使删除当前序号指定的断点,依旧不会用到
Type📌 断点类型(普通 / 观察等)
Disp⚙️ 处置方式(保留 / 自动删)
Enb🚦 启用状态(y = 启用 /n = 禁用)
Address📍 内存地址(机器码位置)
What📄 具体位置(文件 + 行号 / 函数)

4.5 next/n 指令

这是 GDB 调试中用于单条执行代码的 next(简写 n)指令:n 或 next:单条执行(逐行执行,跳过函数内部调用,将函数调用视为 “一行” 执行)。

当前运行到第一个断点(main 函数处),输入n执行两次后却进入了sum函数,按理next不该进入函数才对?

这是因为 sum函数内部设置了断点next执行sum函数调用时,会在函数的断点处暂停(此为断点触发的暂停,并非next主动进入函数内部单步)。

4.6 step/s 指令

这是 GDB 调试中用于逐语句执行代码的 step(简写 s)指令:s 或 step:进入函数调用(若当前行是函数调用,会进入函数体内部逐句执行)。

4.7 finish 指令

这是 GDB 调试中用于执行到函数返回的 finish 指令:finish:执行到当前函数返回,然后停下来等待命令。

main函数中用finish,没有实际调试作用,不能这么用~

在sum函数中用会直接跳到函数调用处

4.8 print/p 指令

打印表达式值支持修改变量(修改后并打印)调用函数

p 变量 是其简写形式,用于快速打印单个变量值,二者功能本质一致,p 是更简洁的常用操作方式。

GDB 中$1 $2这类序号,是同一个 GDB 调试会话内 **print/p操作的临时计数标记,按执行顺序线性递增;只有完全退出 GDB 并重新启动调试会话时,序号才会从$1重新开始;仅重新运行程序(不退出 GDB)时,序号会持续累加,不会重置。**

临时修改变量值:

直接调用函数,不论函数是否被执行,都会打印该函数的结果

4.9 set var指令 

set var 变量名=新值(例如 set var a=20,纯修改变量值,执行后无自动输出)

4.10 continue(或 c)指令

c(例如输入 c,程序从当前断点位置继续连续执行,直到遇到下一个断点或程序结束)

在运行后,输入c,无断点就直接运行结束了

4.11 display指令

display 变量名(例如 display a,跟踪查看变量 a,程序每次暂停时都会自动显示其当前值)

相当于vs监视窗口

4.12 undisplay指令

undisplay 序号(例如 undisplay 1,取消序号为 1 的变量跟踪;若要取消所有,可多次执行或用 delete display 系列指令)

4.13 until指令

until 行号(例如 until 50,程序从当前位置连续执行到第 50 行后暂停,适合快速跳过循环等场景),只能往后跳

4.14 breaktrace (或 bt)指令

bt(例如输入 bt,查看当前程序的函数调用栈,包括各级函数的调用关系、参数和返回地址等)

这张图完美展示了函数调用栈(栈帧)随程序执行的动态变化过程阶段 1(add 函数中):调用栈有 3 层(main→sum→add),因为 add 还在执行,没返回 sum阶段 2(sum 函数中)add 执行完返回,调用栈变为 2 层(main→sum),因为 sum 还在执行,没返回 main阶段 3(main 函数中)sum 执行完返回,调用栈只剩 1 层(main),因为所有子函数都已返回。

每一次函数调用会 “压栈”(新增栈帧),函数返回会 “出栈”(移除栈帧),这就是调用栈的动态变化逻辑~

4.15 info (i) locals指令

info locals(或 i locals,例如输入 info locals,查看当前栈帧中所有局部变量的名称和值)

 类似于调试器的 **“自动监视窗口”,它会实时显示当前栈帧(即当前执行的函数)中所有局部变量的名称和值 **,只聚焦于程序运行到 “当前代码块” 时的变量状态,非常方便查看函数内局部变量的实时变化。

 不是常显示的,运行到下一句就不会显示,需要你再次手动操作

Read more

【Linux】VSCode Remote-SSH 无法连接并反复要求输入密码问题详解

【Linux】VSCode Remote-SSH 无法连接并反复要求输入密码问题详解

文章目录 * 一、问题现象描述 * 1. 典型表现 * 2. 常见的误区尝试 * 二、原因分析 * 三、解决方案详解 * 1. 首选方式:清除服务器上的 vscode-server * 2. 备选方式:使用 Remote-SSH 提供的清理命令 * 3. 验证连接是否恢复正常 * 四、其他可能性排查 * 1. 检查 SSH 密钥方式是否启用 * 2. 确保服务器未被防火墙或权限阻止 * 3. 更新 Remote-SSH 插件 Visual Studio Code(简称 VS Code)作为一款广受欢迎的轻量级编辑器,其 Remote-SSH 插件为开发者带来了便捷的远程开发体验。然而,在使用 Remote-SSH 插件连接远程服务器的过程中,很多用户会遇到输入密码后仍无法连接的问题,甚至被持续提示输入密码。

By Ne0inhk
Flutter 三方库 dart_style — 鸿蒙应用全方位代码格式化与规范治理神器,实现鸿蒙深度适配下的工程化整洁代码规范全实战

Flutter 三方库 dart_style — 鸿蒙应用全方位代码格式化与规范治理神器,实现鸿蒙深度适配下的工程化整洁代码规范全实战

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net。 Flutter 三方库 dart_style — 鸿蒙应用全方位代码格式化与规范治理神器,实现鸿蒙深度适配下的工程化整洁代码规范全实战 前言 在鸿蒙(OpenHarmony)大型项目的多人协作中,代码风格的不统一是引发合并冲突(Merge Conflict)和降低 Code Review 效率的首要原因。有人喜欢两格缩进,有人喜欢四格;有人喜欢在 Widget 的末尾加逗号,有人则反其道而行。 dart_style 提供了一个官方推荐的、具有“强迫症风格”的代码格式化程序。它是 dart format 指令背后的灵魂所在。在 Flutter for OpenHarmony 的工程化体系中,强制落地 dart_style 规范,不仅能让鸿蒙应用的代码变得美观统一,更能通过消除非必要的空白字符差异,显著降低

By Ne0inhk
【2026 OPC计划】3分钟部署OpenClaw(Mac/Windows/阿里云)

【2026 OPC计划】3分钟部署OpenClaw(Mac/Windows/阿里云)

3分钟部署OpenClaw(Mac/Windows/阿里云 * 一、MacOS主流部署方案 * 二、Windows部署流程 * 三、基于阿里云的Moltbot部署流程 * 1 选购轻量服务器 * 2 创建阿里百炼API-KEY * 3 开启服务 一、MacOS主流部署方案 首先是MacOS上如何安装OpenClaw。可以说截止目前,OpenClaw对Mac系统是最友好的,不仅安装流程简单、运行稳定,甚至还推出了专门的MacOS App。 在Mac中安装OpenClaw,首先我们需要先安装Node.js基础运行环境,登陆nodejs.org即可下载对应操作系统的安装包, 具体的Node.js的安装过程非常简单,根据提示,一路点击下一步即可,安装完成后按住command+空格,搜索并打开终端,先输入node -v确认Node.js的版本号,需要确保大于V22, node -v 然后输入npm install命令,来安装OepnClaw, npm install -g openclaw@

By Ne0inhk
Flutter 三方库 midi_util 的鸿蒙化适配指南 - 实现标准 MIDI 协议的消息解析、支持电子乐器底层的指令通讯与音符数据处理

Flutter 三方库 midi_util 的鸿蒙化适配指南 - 实现标准 MIDI 协议的消息解析、支持电子乐器底层的指令通讯与音符数据处理

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 三方库 midi_util 的鸿蒙化适配指南 - 实现标准 MIDI 协议的消息解析、支持电子乐器底层的指令通讯与音符数据处理 前言 在进行 Flutter for OpenHarmony 的音乐编创、教学或专业音频应用开发时,与电子乐器(如电子琴、打击垫)进行数字通信是不可或缺的功能。midi_util 是一个专注于 MIDI(Musical Instrument Digital Interface)协议编解码的轻量级工具库。它能让你在鸿蒙端以对象化的方式处理复杂的字节流指令。本文将探讨如何在鸿蒙系统下构建专业的 MIDI 交互流。 一、原原理性解析 / 概念介绍 1.1 基础原理 midi_util 核心是对 MIDI 1.

By Ne0inhk