Linux开发中Git版本控制和GDB调试的核心技巧分享
<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li>一、Git:从基础到实践的版本控制<ul class="second_class_ul"><li>1.1为什么需要版本控制?</li><li>1.2 Git简史:从Linux内核开发需求诞生的工具</li><li>1.3Git环境搭建:Linux下的安装和初始化配置</li><li>1.4 进阶技巧:.gitignore忽略文件与免密提交</li></ul></li><li>二、GDB:Linux下的C/C++程序调试利器<ul class="second_class_ul"><li>2.1调试前准备:编译时添加-g选项(生成调试信息)</li><li>2.2 GDB基础操作:启动、退出与核心调试命令</li><li>2.3 GDB进阶技巧:监视变量、条件断点与栈帧查看</li><li>2.4 优化调试体验:安装cgdb(代码分屏的GDB)</li></ul></li><li>快速排查问题<ul class="second_class_ul"><li>continue 调式指令</li><li>finish 调式指令</li><ul class="third_class_ul"><li>next和finish区别</li></ul><li>until调式指令</li><ul class="third_class_ul"></ul><li>set var调式指令</li><ul class="third_class_ul"></ul></ul></li></ul></div><p>在Linux开发流程中,版本控制与程序调试是保障项目稳定性和开发效率的两大核心环节。Git作为当前最主流的分布式版本控制系统,能高效管理代码迭代、追踪修改记录并支持多人协同开发;GDB(GNU调试器)是Linux下调试C/C++程序的利器,可帮助开发者定位代码逻辑错误、跟踪变量变化,快速排查运行时问题。本文将从实战角度出发,详细拆解GIt的核心操作与GBDB的调试技巧。</p><p class="maodian"></p><h2>一、Git:从基础到实践的版本控制</h2>
<p class="maodian"></p><h3>1.1为什么需要版本控制?</h3>
<p>版本控制的价值:记录代码每一次修改(谁改、改了什么、什么时候改),支持一键回滚到历史版本,实现多人并行开发时的代码同步与冲突解决 对比传统“复制副本”方式:告别 “项目 - v1.doc”“项目 - 最终版 2.doc” 的混乱命名,用 Git 统一管理版本,减少冗余文件</p>
<p class="maodian"></p><h3>1.2 Git简史:从Linux内核开发需求诞生的工具</h3>
<p>背景:2005年,Linux内核开发团队因商业版本控制系统BitKeeper终止授权,由Linus Torvalds主导开发Git 核心设计目标: 速度快:高效处理超大规模项目(如Linux内核,百万级代码量) 完全分布式:无需依赖中央服务器,本地可完成版本管理,联网后同步即可 支持非线性开发:轻松创建、合并分支,满足多人并行开发需求</p>
<p class="maodian"></p><h3>1.3Git环境搭建:Linux下的安装和初始化配置</h3>
<p>(1)在Linux安装Git(以Centos/Ubuntu为例) Centos系统:</p>
<div class="dxycode"><pre class="brush:bash;"> //1.先下载git
sudo yum install git
//2.再查看git版本,确认是否下载下来了
git --version</pre></div>
<p>Ubuntu系统:</p>
<div class="dxycode"><pre class="brush:bash;">sudo apt install git -y
git --version</pre></div>
<p>(2)在github/gitee创建项目(下面以gitee为例)</p>
<p>注册账号:按照网站提示写即可</p>
<p><img alt="1.3Git环境搭建:Linux下的安装和初始化配置" src="https://zhuji.jb51.net/uploads/allimg/20251208/2-25120QGS4916.png" /></p>
<p>创建仓库:</p>
<p>登录成功后,进入个人主页,在右上方➕按钮,点击新建仓库</p>
<p><img alt="1.3Git环境搭建:Linux下的安装和初始化配置_图2" src="https://zhuji.jb51.net/uploads/allimg/20251208/2-25120QGS5348.png" /></p>
<p>跳转到新页面输入项目名称及其他设置:<br /><img alt="1.3Git环境搭建:Linux下的安装和初始化配置_图3" src="https://zhuji.jb51.net/uploads/allimg/20251208/2-25120QGS5O1.png" /></p>
<p>创建完后,在创建好的仓库页面中复制仓库链接,以备接下来进行下载:<br /><img alt="1.3Git环境搭建:Linux下的安装和初始化配置_图4" src="https://zhuji.jb51.net/uploads/allimg/20251208/2-25120QGS52R.png" /></p>
<p>(3)将仓库克隆到Linux下 创建一个放置代码的目录(往后的要提交到远程仓库的代码最好放在这个目录下)</p>
<div class="dxycode"><pre class="brush:bash;">git clone //url就是上一步复制的仓库链接</pre></div>
<p><img alt="1.3Git环境搭建:Linux下的安装和初始化配置_图5" src="https://zhuji.jb51.net/uploads/allimg/20251208/2-25120QGS5394.png" /></p>
<p>Git“三板斧”–提交代码到远程仓库: 操作步骤 命令 作用 示例</p>
<table><tbody><tr></tr><tr><td>1.暂存代码</td><td>git add 文件名</td><td>将修改的文件加入 “暂存区”,标记为待提交状态</td><td>暂存单个文件:git add main.c;暂存所有修改:git add .</td></tr><tr><td>2.本地提交</td><td>git commit -m "提交说明"(提交说明一定要有,即使不写,也要写上双引号)</td><td>将暂存区的修改提交到 “本地仓库”,并添加说明(必须写清楚修改内容)</td><td>git commit -m “修复main函数中的逻辑错误,添加参数校验”</td></tr><tr><td>3.远程同步</td><td>git push</td><td>将本地仓库的提交同步到远程 Gitee 仓库</td><td>执行后输入 Gitee用户名和密码</td></tr></tbody></table>
<p>(4)首次使用配置:设置用户信息(关键!!!)</p>
<p>Git需要知道提交者的姓名和邮箱,用于标记每一次代码的归属,配置命令如下:</p>
<div class="dxycode"><pre class="brush:bash;"># 全局配置(对当前用户所有Git仓库生效)
git config --global user.name "你的姓名" # 如"Zhang San"
git config --global user.email "你的邮箱" # 如"zhangsan@example.com"
# 查看配置是否生效
git config --list # 输出中应包含user.name和user.email的配置</pre></div>
<p><img alt="1.3Git环境搭建:Linux下的安装和初始化配置_图6" src="https://zhuji.jb51.net/uploads/allimg/20251208/2-25120QGS5N7.png" /></p>
<p>(5)常用辅助命令:查看状态与历史 查看当前代码修改状态:git status(显示哪些文件被修改、哪些被暂存) 查看提交历史:git log(显示所有提交记录) 拉取远程仓库最新代码:git pull(建议先拉取再提交,避免冲突)</p>
<p class="maodian"></p><h3>1.4 进阶技巧:.gitignore忽略文件与免密提交</h3>
<p>(1).gitignore:忽略无需版本控制的文件</p>
<p>有些文件(如编译生成的.o文件、可执行文件、日志文件)无需纳入 Git 管理,可通过创建.gitignore文件指定忽略规则:<br />1. 在仓库根目录创建.gitignore:</p>
<div class="dxycode"><pre class="brush:bash;">vim .gitignore</pre></div>
<p>2.写入忽略规则(示例):</p>
<div class="dxycode"><pre class="brush:bash;"> # 忽略所有.o文件
*.o
# 忽略可执行文件(如main)
main
# 忽略日志目录
log/</pre></div>
<p><img alt="1.4 进阶技巧:.gitignore忽略文件与免密提交" src="https://zhuji.jb51.net/uploads/allimg/20251208/2-25120QGS6258.png" /></p>
<p>3.提交.gitignore到仓库(同代码提交步骤)</p>
<div class="dxycode"><pre class="brush:bash;"> git add .gitignore
git commit -m "添加.gitignore,忽略编译产物和日志"
git push</pre></div>
<p>(2)配置免密提交:避免每次push输入账号密码 方法一:SSH密钥 步骤一:检查本地是否已存在SSH密钥,执行命令:</p>
<div class="dxycode"><pre class="brush:bash;">ls -la ~/.ssh/</pre></div>
<p>若输入中包括id_rsa(私钥)和id_rsa.pub(公钥),即已存在密钥,直接跳到步骤三;若无,继续第二步</p>
<p>步骤二:执行以下命令生成RSA类型的SSH密钥,过程中无需输入复杂密码(按3次回车键即可)</p>
<div class="dxycode"><pre class="brush:bash;">ssh-keygen -t rsa -C "你的 Gitee 绑定邮箱" # 替换为你注册 Gitee 时用的邮箱</pre></div>
<p>输出示例:<br /><img alt="1.4 进阶技巧:.gitignore忽略文件与免密提交_图2" src="https://zhuji.jb51.net/uploads/allimg/20251208/2-25120QGS63Y.png" /></p>
<p>步骤三:查看并复制SSH公钥,执行以下命令</p>
<div class="dxycode"><pre class="brush:bash;"> cat ~/.ssh_rsa.pub/</pre></div>
<p>如下,复制密钥即可:<br /><img alt="1.4 进阶技巧:.gitignore忽略文件与免密提交_图3" src="https://zhuji.jb51.net/uploads/allimg/20251208/2-25120QGSA00.png" /></p>
<p>步骤四:在gitee上配置 SSH公钥</p>
<p>登录Gitee账号,点击右上角设置</p>
<p>在左侧菜单找到安全->SSH公钥,点击添加公钥,如下<br /><img alt="1.4 进阶技巧:.gitignore忽略文件与免密提交_图4" src="https://zhuji.jb51.net/uploads/allimg/20251208/2-25120QGSC26.png" /></p>
<p>点击确定,并验证账号密码,完成公钥配置。</p>
<p>步骤五:验证SSH连接并修改仓库远程地址 执行如下命令:</p>
<div class="dxycode"><pre class="brush:bash;"> ssh -T git@gitee.com</pre></div>
<p><img alt="1.4 进阶技巧:.gitignore忽略文件与免密提交_图5" src="https://zhuji.jb51.net/uploads/allimg/20251208/2-25120QGSK52.png" /></p>
<p>查看当前远程地址(确认是否是HTTPS格式)</p>
<div class="dxycode"><pre class="brush:bash;"> git remote -v</pre></div>
<p>若输出含https://gitee.com/...,不包括你的用户名和仓库名,需要进行下一步修改;</p>
<p>修改远程地址为SSH格式:</p>
<div class="dxycode"><pre class="brush:bash;"> git remote set-url origin git@gitee.com:你的用户名/你的仓库名.git </pre></div>
<p>验证修改结果:</p>
<div class="dxycode"><pre class="brush:bash;"> git remote -v</pre></div>
<p>输出如下效果即成功:<br /><img alt="1.4 进阶技巧:.gitignore忽略文件与免密提交_图6" src="https://zhuji.jb51.net/uploads/allimg/20251208/2-25120QGSH11.png" /></p>
<p>步骤六:测试免密码提交<br />执行git push提交代码,此时无需输入账号密码,直接完成同步(首次使用SSH可能需要确认密钥,后续永久免密)</p>
<p><img alt="1.4 进阶技巧:.gitignore忽略文件与免密提交_图7" src="https://zhuji.jb51.net/uploads/allimg/20251208/2-25120QGSM50.png" /></p>
<p>方法二:系统配置 步骤一:在根目录创建文件.git-credentials,并进入文件,输入内容plaintext https://{username}:{password}@github.com</p>
<div class="dxycode"><pre class="brush:bash;">cd ~
touch .git-credentials
vim .git-credentials
https://{username}:{password}@github.com//username即用户名,password即用户密码</pre></div>
<p>步骤二:在终端输入以下命令</p>
<div class="dxycode"><pre class="brush:bash;">git config --global credential.helper store</pre></div>
<p>步骤三:打开~/.gitconfig文件,会发现多了一项</p>
<div class="dxycode"><pre class="brush:plain;">
helper = store</pre></div>
<p><img alt="1.4 进阶技巧:.gitignore忽略文件与免密提交_图8" src="https://zhuji.jb51.net/uploads/allimg/20251208/2-25120QGSJK.png" /></p>
<p>步骤四:测试免密提交,执行git push提交代码,此时无需输入账号密码,直接完成同步(与法一效果相同)</p>
<p class="maodian"></p><h2>二、GDB:Linux下的C/C++程序调试利器</h2>
<p class="maodian"></p><h3>2.1调试前准备:编译时添加-g选项(生成调试信息)</h3>
<p>程序的发布方式有两种,debug模式和release模式,Linux下用gcc/g++编译程序时,默认是release模式(无调试信息,无法用GDB调试),需添加-g选项开启debug模式:</p>
<div class="dxycode"><pre class="brush:bash;">//编译test1.c,生成带调试信息的可执行文件test1
gcc test1.c -o test1 -g
//查看调试信息
gdb test1</pre></div>
<p><img alt="2.1调试前准备:编译时添加-g选项(生成调试信息)" src="https://zhuji.jb51.net/uploads/allimg/20251208/2-25120QGSN19.png" /></p>
<p class="maodian"></p><h3>2.2 GDB基础操作:启动、退出与核心调试命令</h3>
<p>(1)启动与退出GDB 启动GDB:gdb 可执行文件名(如上图),进入GDB交互页面(提示符为gdb) 退出GDB:输入quit或ctrl+d (2)GDB基础命令 命令 作用 样例</p>
<table><tbody><tr></tr><tr><td>list(l) 行号或函数名或文件名:行号</td><td>显示源代码,从上次位置开始列出n行或指定函数的源代码或指定文件的源代码</td><td>list 10或mian或test1.c:2</td></tr><tr><td>run®</td><td>从程序开始连续执行</td><td>run®</td></tr><tr><td>next(n)</td><td>单步执行,不进入函数内部</td><td>next(n)</td></tr><tr><td>step(s)</td><td>单步执行,且进入函数内部</td><td>step(s)</td></tr><tr><td>break(b) 文件名:(可省略)行号或函数名</td><td>在指定行数设置断点或在函数开头设置断点</td><td>break test1.c:10或main</td></tr><tr><td>info(i) break(b)/breakpoints</td><td>查看当前所有断点信息/断点列表</td><td>info b/breakpoints</td></tr><tr><td>info(i) locals</td><td>查看当前栈的局部信息(查看临时变量)</td><td>info locals</td></tr><tr><td>finish</td><td>执行到当前函数返回,然后停止</td><td>finish</td></tr><tr><td>print§ 表达式/变量</td><td>打印表达式的值/指定给变量的值</td><td>print a+b/x</td></tr><tr><td>set var 变量=值</td><td>修改变量的值</td><td>set var i=10</td></tr><tr><td>delete(d) breakpoints -/序号n(可省略)</td><td>删除所有断点/删除序号为n的断点</td><td>d breakpoints 1</td></tr><tr><td>disable/enable breakpoints</td><td>禁用/启用所有断点</td><td>disable/enable breakpoints</td></tr><tr><td>display 变量名</td><td>跟踪显示指定变量的值(每次停止)</td><td>display x</td></tr><tr><td>undisplay 编号</td><td>取消对指定编号变量的跟踪</td><td>undisplay x</td></tr><tr><td>backtrace(bt)</td><td>查看当前执行栈的各级函数条用及参数</td><td>bt</td></tr><tr><td>quit(q)</td><td>退出GDB调试器</td><td>q</td></tr></tbody></table>
<p class="maodian"></p><h3>2.3 GDB进阶技巧:监视变量、条件断点与栈帧查看</h3>
<p>示例代码sum.c:</p>
<div class="dxycode"><pre class="brush:cpp;">#include <stdio.h>
// 求和函数:计算s到e的累加和
int Sum(int s, int e) {
int result = 0;
for (int i = s; i <= e; i++) {
result += i;
}
return result;
}
int main() {
int start = 1;
int end = 100;
int total = Sum(start, end);
printf("1到100的和:%d\n", total);
return 0;
}</pre></div>
<p>(1)watch:监视变量的变化(变量修改时自动断点)</p>
<p>示例:<br /><img alt="2.3 GDB进阶技巧:监视变量、条件断点与栈帧查看" src="https://zhuji.jb51.net/uploads/allimg/20251208/2-25120QGSK01.png" /></p>
<p>(2)条件断点:满足特定条件才触发断点</p>
<p>当循环次数较多(如100次),只想在某一次循环(如i=50)时断点,用条件断点:</p>
<p>方式一:新增断点时直接加条件:b 行号 if 条件</p>
<div class="dxycode"><pre class="brush:cpp;">(gdb) b 6 if i == 50 # 在第6行(result += i)设断点,仅当i=50时触发
Breakpoint 3 at 0x40052a: file sum.c, line 6.</pre></div>
<p>方式二:给已有断点追加条件:condition 断点编号 条件</p>
<div class="dxycode"><pre class="brush:cpp;">(gdb) b 6 # 先设普通断点(编号假设为3)
(gdb) condition 3 i == 50 # 给3号断点加条件
(gdb) info b # 查看断点,会显示“stop only if i == 50”</pre></div>
<p><img alt="2.3 GDB进阶技巧:监视变量、条件断点与栈帧查看_图2" src="https://zhuji.jb51.net/uploads/allimg/20251208/2-25120QGSU20.png" /></p>
<p>(3)栈帧查看:bt 与info locals 定位函数调用链</p>
<p>当程序崩溃或执行到深层函数时,用bt(backtrace)查看函数调用栈,用info locals查看当前函数的局部变量:</p>
<p><img alt="2.3 GDB进阶技巧:监视变量、条件断点与栈帧查看_图3" src="https://zhuji.jb51.net/uploads/allimg/20251208/2-25120QGSW13.png" /></p>
<p class="maodian"></p><h3>2.4 优化调试体验:安装cgdb(代码分屏的GDB)</h3>
<p>默认 GDB 为纯命令行界面,无法同时显示代码和调试命令,cgdb是 GDB 的增强工具,支持 “代码分屏”:</p>
<p>安装:(centos/Ubuntu)</p>
<div class="dxycode"><pre class="brush:bash;">#Centos
sudo yum install cgdb -y
#Ubuntu
sudo apt install cgdb -y</pre></div>
<p>使用:cgdb 可执行文件名(如cgdb sum),界面分为上下两部分:上半部分显示源代码,下半部分显示GDB命令行 快捷键:按ESC切换到代码区(可用方向键滚动代码),按i切换回命令行<br />效果如下:<br /><img alt="在这里插入图片描述" src="https://zhuji.jb51.net/uploads/allimg/20251208/2-25120QGSS64.png" /></p>
<p class="maodian"></p><h2>快速排查问题</h2>
<p>【问题】:无论是使用 VS 调试器还是 gdb 调用调试,核心目标是什么?</p>
<p>并不是单纯地通过调试就能解决所有问题,而是找到代码中的具体问题,并针对性地分析和修复。归根结底,调试的核心在于发现问题。</p>
<p>通过设置断点,可以将程序执行划分为不同的范围。如果某个范围内发生崩溃,就可以对这一范围进行局部调试。断点的作用就是帮助我们快速缩小问题范围,尤其在面对冗长的代码时,断点能显著提高排查效率。</p>
<p class="maodian"></p><h3>continue 调式指令</h3>
<p>【<strong>c/continue</strong>】:断点处跳跃</p>
<p><img alt="在这里插入图片描述" src="https://zhuji.jb51.net/uploads/allimg/20251208/2-25120QGSQ93.png" /></p>
<p class="maodian"></p><h3>finish 调式指令</h3>
<p><strong>【finish】指令</strong>:直接运行完当前所在的函数并停下。使用 finish 时,调试器不会逐步执行函数内部的代码,而是快速跳出函数,直接返回调用点。这在函数内部细节不重要、或者希望快速查看函数返回结果时非常实用。</p>
<p><img alt="在这里插入图片描述" src="https://zhuji.jb51.net/uploads/allimg/20251208/2-25120QGSY50.png" /></p>
<p class="maodian"></p><h4>next和finish区别</h4>
<p>因此,n 和 finish 的关键区别在于 finish 能让你在函数返回后停留并显示返回值,而 n 只是跳过整个函数调用,<strong>并不提供返回值的详细信息。</strong></p>
<p class="maodian"></p><h3>until调式指令</h3>
<p><strong>【until】指令</strong>:将程序运行到指定的行号并暂停,期间的代码会被正常执行。<strong>这非常适合快速跳过某段代码,直接查看指定位置的运行状态</strong></p>
<p><img alt="在这里插入图片描述" src="https://zhuji.jb51.net/uploads/allimg/20251208/2-25120QGSb39.png" /></p>
<p class="maodian"></p><h3>set var调式指令</h3>
<blockquote><p>set var 变量名 = 新值,这个指令非常适合调试复杂逻辑时临时调整变量值!</p></blockquote>
<p><strong>【set var】</strong>:用于在调试过程中直接修改变量的值,从而影响程序的运行状态</p>
<p><img alt="在这里插入图片描述" src="https://zhuji.jb51.net/uploads/allimg/20251208/2-25120QGSa15.png" /></p>
<p>以上就是Linux开发中Git版本控制和GDB调试的核心技巧分享的详细内容,更多相关资料请阅读琼殿技术社区其它文章!</p>
頁:
[1]