目录
一. git的功能和使用
1.1 git的功能
1.2 git三板斧
1.3 git使用中的其他问题
二. 使用gdb调试代码
2.1 生成带有调试信息的可执行程序
2.2 gdb调试代码的方法
git是一块开源、免费的版本管理系统,能够高效敏捷地处理任何大型或小型项目。
问题:什么是版本管理?
这里以一个生活中的例子来讲解,假设程序员A写了一份实验报告,最初版本我们称之为v1,程序员去拿给项目经理进行审阅,项目经理提出修改意见,程序员A下去修改。程序员A在修改前先将v1版本进行备份,修改后获得v2版本,程序员A再去拿给项目经理审阅,项目经理再次提出修改意见,程序员A再次将v2版备份后,修改获得了v3版本。项目经理看了v3版本后,认为程序员A修改的v3版本还不如之前的v2版本,因此让程序员B在v2版本的基础之上,修改获得了v3.2版本,项目经理最终决定采用v3.2版本。
上述过程中,修改、保存每个版本过程中的操作,实际上就是在进行版本管理。
git可以实现对项目代码进行版本管理,是一款企业级的多人协同操作软件。通过gitee可以实现对代码的托管,人们可以向指定的仓库上传、修改和删除指定的代码,每一步操作都强行写"日志",以便追踪特定仓库的修改记录。在项目代码不断进行完善的过程中,产生的不同版本的项目代码,都可以在git的远程仓库中得以保存,每当项目代码发生改变,通过将修改后的代码上传至远程仓库,实现新版本的记录。
准备工作 -- 在git上创建远程仓库并克隆到本地
登录gitee网站,点击右上角的+,选择新建仓库,自定义仓库名、仓库介绍等内容后,点击创建,这样就在远程创建了代码仓库。
注意这里的添加.gitignore选项,是指引入忽略黑名单,将指定后缀名的文件自动屏蔽,使垃圾文件不会被上传至远程仓库。这里我们在.gitignore选项中选择C++,其中就包含了生成C++可执行文件过程中常见的应当被加入黑名单的文件的后缀名。
一般而言,只需要上传.c/.cpp、.h文件即可。
在进行这项工作之前,我们首先检查自己的Linux系统下面是否安装了git,检查方法为输入指令:git --version,这条指令的功能是输出当前环境下git的版本,如果输出成功(如图1.3),那么表示git已经安装,如果没有安装git,则需要通过指令yum -y install git来安装git。
将远端仓库克隆到近端的指令:git clone [远端仓库链接]
这一步会提示我们输入用户名和密码,我们只需要输入注册gitee账号时使用的用户名和密码即可。执行完git clone指令后,我们通过ll,可以看到远端仓库已经被拉取到了近端。
第一板斧:git add [文件名] -- 将用git管理的文件告知git
如图1.5所示,我们希望将文件test1.cpp传入远程仓库,首先应当让git知道test1.cpp要被git管理,那么应当执行指令git add test1.cpp。
在实际项目中。我们可能会失误add,如果想撤销对某个文件的add,指令为:
第二板斧:git commit -- 提交改动到本地
语法:git commit -m "日志信息"
注意,这里的日志信息不可以省略,修改仓库必须要记录对应的修改日志。如图1.6所示,将test1.cpp文件提交改动到本地,记录日志信息包括进行修改操作的用户(zhang)和修改仓库的时间(2023.06.18)。如果我们希望撤销git commit操作,指令为:git reset --soft HEAD^。
第三板斧:git push -- 将修改同步到远程仓库
如图1.7所示,使用git push指令,输入用户名和密码之后,到远程仓库中,查看发现,test1.cpp被成功提交,相应的日志信息也得以被记录。
(1) git log查看提交记录
(2) .gitignore
.gitignore为黑名单文件,用于屏蔽指定后缀名的文件为黑名单文件,禁止特定的文件被同步到远程仓库。使用vim打开.gitignore文件,可以对黑名单文件进行设置。
(3) git push无法提交文件的问题
如果我们的仓库在近端和远端不同步(在Linux和Windows下都对仓库进行了操作),那么提交文件可能会失败,这是只要无脑git pull即可。
git pull极有可能会出现警告信息,我们不用在意,只需要shift + : 进入底行模式,然后wq!强制退出即可。这时再次git push,提交成功。
(4) 在近端操控远程仓库删除文件
注意,不可以省略git,直接rm,这样会造成近端删除了文件,而远端仓库没有删除的问题。
我们默认使用gcc/g++编译源文件生成的可执行程序,是Release版本,不带有调试信息。使用g++,编译源文件test.cpp(见代码2.1),生成可执行程序mytest.exe。
使用指令readelf -S mytest.exe | grep -i debug,获取可执行文件中的调试信息,看到没有捕捉到任何含有debug的内容(见图2.1)。
代码2.1:test.cpp文件
1 #include
2
3 int AddToTop(int top)
4 {
5 int sum = 0;
6 for(int i = 0; i <= top; ++i)
7 {
8 sum += i;
9 }
10
11 return sum;
12 }
13
14 int main()
15 {
16 int top = 100;
17
18 int res = AddToTop(top);
19
20 printf("res = %d\n", res);
21
22 return 0;
23 }
如果想要程序能够调试,就必须生成Debug版本,在gcc/g++编译程序时添加-g选项,就能够生成Debug版本的可执行程序。如图2.2所示,生成debug版本的可执行程序mytest-debug.exe,获取其内部的调试信息,可见有内容输出。
还是以代码2.1的程序为例,讲解如何使用gdb调试代码。
输入list 0后,持续按回车键,可以显示出全部代码,因为gdb会记录最近一条的指令,如果接下来要执行的指令没有改变,可以直接回车执行。
注意:如果多次连续执行r指令,并不是执行到下一处断点,而是重写开始调试。
最上层的调用堆栈,为当前函数的调用堆栈。