1. Git
Git是一种版本控制系统,是一种工具,用于代码的存储和版本控制。
而我们常见的Gitee和Gitehub都是基于Git(Git是开源的)实现的在线代码仓库,而前者服务器位于中国,后者服务器位于美国。
总的来说,Git就是一个版本控制的工具,在现实中有很多用途:
Git与Linux的关系
Git的历史可以追溯到2005年,它的诞生与Linux内核项目的发展密切相关。
1. **Linux内核项目的需求**:在1991至2002年间,Linux内核项目的开发主要依赖于提交补丁和保存归档的方式,这种方法效率低下。2002年,Linux内核项目开始使用一个专有的分布式版本控制系统BitKeeper来管理和维护代码。
2. **与BitKeeper的合作结束**:2005年,开发BitKeeper的商业公司结束了与Linux内核开源社区的合作关系,收回了免费使用BitKeeper的权力。这迫使Linux社区,特别是Linus Torvalds,开发自己的版本控制系统。
3. **Git的诞生**:基于使用BitKeeper时的经验,Linus Torvalds制订了新系统的目标,包括速度、简单设计、对非线性开发模式的支持、完全分布式以及高效管理大规模项目的能力。Git在这些目标的指导下被开发出来,并在短短十天后诞生。
4. **Git的开发和维护**:Linus Torvalds完成了Git的初始开发后,不久将其维护工作交给了Junio Hamano,他至今仍在维护Git。
5. **Git的特点**:Git是一个开源的分布式版本控制系统,它以速度快、设计简单、支持非线性开发模式、完全分布式和高效管理大规模项目而著称。
6. **Git的普及**:Git自诞生以来,逐渐成熟并完善,它的速度飞快,非常适合管理大型项目,并且拥有强大的分支管理系统。2008年,GitHub的上线进一步推动了Git的普及,为开源项目免费提供Git存储,吸引了许多项目迁移至GitHub。
Git的发展历程显示了它如何从一个紧急需求中诞生,并迅速发展成为全球最流行的分布式版本控制系统之一。
因此,Git只是一个工具,在Linux中可以通过来安装:
sudo yum install git
既然能安装上Git,那作为一种工具就需要我们来简要学习。
Gitee及其在Linux上对应的操作
原理:
操作:先到gitee上创建一个仓库,然后clone到linux本地,
git clone URL
在这个仓库中创建一个源文件,这个文件与gitee没有任何关系。
换句话说,现在的git不会自动管理这个写好的文件,需要你自己手动上传。
git add filename
git add test.c只是将原码添加到git的一个暂存区,算临时添加
git commit -m "a test for git"
git commit -m "11111" 作为日志,建议写上。
如果此时输入git status,就会出现:
一次提交形成一个唯一的id值
多次提交形成的就是版本链。
还可以通过git commit --amhead来只更改上一次提交。
最后一步,push
git push
这时候再刷新一下网络端的gitee,就能发现已经有文件提交上去了。
并且,如果我们再status一次:
就是clean的。
多用户使用同一个gitee仓库
在windows端克隆一个仓库,来模拟两个人的使用
A(windows)先提交,B(linux)不知道,B的仓库和远端仓库不同步,因此B就不能提交,必须要B的仓库和远端仓库(A同理)一致才能再提交,因此引出了pull的使用。
这样就强制了必须先和远端同步。
在windos的仓库里提交一个文档
回到linux中拷贝一份之前的代码。
此时就需要:
这样就拿下来了:
再回到gitee的网页端,就发现已经全部上传了。
如果A和B对同一个文件进行修改,再打开文件,就会变成:
因此,需要程序员自己把代码自行进行合并与修改。
总结:
git clone
git pull//拉取
git push//推送
git add
git commit -m
git status
2. 调试器-gdb/cgdb
安装gdb和cgdb
如果已经安装,可以使用gdb--version查看当前工具的版本和信息。
测试代码:
#include <stdio.h>
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;
printf("I will begin\n");
int n = Sum(start, end);
printf("running done, result is: [%d-%d]=%d\n", start, end, n);
return 0;
}
对于一个源文件,想调试,必须是debug版本。在gcc编译时,需要带上选项:-g,否则默认是realease版本的
debug需要的指令:-g
可以用readelf(显式文件ELF的指令)查看两个文件和debug相干的内容。
写makefile:
此时用readelf看,并没有预期现象
原因是,调试信息是在编译阶段加入的,在可执行文件链接时加一个-g没有起作用
所以要把-g的位置换在第一步里。
ubuntu下用file查看的话,两个文件会有差别。
进入gdb
gdb myexe
请注意不要gdb源码,源码是打不开的,请打开可执行程序。
使用quit直接退出,l指令查看代码,l接数字,直接到想查看的行数,l接函数名称也可以,
或者还可以l文件名+行号:
会尽量让想被查看的处于代码的中间。
小结:
l 行号(默认打印10行)
l main
l myexe.c : 5
断点:
使用"b"打断点,b后面接行数:b 19
在19行打断点。
info b 查看打的断点。
加断点的时候可以按照行数加,但是删断点必须通过断点序列去删,
在一个调试周期,断点的序列号不会重复,打了123,删除123,再打的时候就是从4开始。
断点编号现行递增。
断点的删除 : d 断点序号(通过info查看序号)
使能:
断点的禁用 : disable 1
使能:enable 1(即激活或启用断点)
可以在info中,看是否被使能。y/n
运行:
打好断点之后,就可以r了(run),会自动停到打了断点的位置。
对应vs的F10 F11
n(next),对应逐过程(会把函数当作一个过程,直接执行一个函数,相当于F10)
s(step),对应逐步(会进入每一个函数)
display(不简写)常显示
undisplay ,后面也是接编号,而不是变量名(编号也是线性递增)
p,暂时打印
until 12 跳转,比如确定了一个循环没有问题,可以跳出
c/continue都可以
从一个断点直接执行到下一个断点。
finish 跑完当前所在的函数
如果需要图形化界面,可以安装cgdb
其指令和gbd是一样的,但是可以执行分屏,可视化效果更好
指令小结
list / l :
l 1
l code.c : 5
l main
run/r
step/s(F11)
next/n(F10)
b 19
b main
info b
enable 1
disable 1
finish
until 12(until只能接行号)
c/continue 从当前断点执行到下一个断点
display n(变量名)
undisplay (变量名的编号)
d breakpoints
d breakpoints 1
每次被watch的数据,变化的时候就会被
set var
watch与条件断点:
watch
执⾏时监视⼀个表达式(如变量)的值。如果监视的表达式在程序运⾏期间的值发⽣变化,GDB 会暂停程序的执⾏,并通知使⽤者
比如,要在sum函数中监视i的每次变化
watch i
watch也可以在info b中观察到。
条件断点
新增: b ⾏号/⽂件名:⾏号/函数名 if i == 30(条件)给已有断点追加:condition 2 i==30, 其中2是已有断点编号,没有if
给已有断点添加条件(注意没有if):
直接设置条件断点:
finish不能直接跳过条件断点
finish也不能跳过watch
set var
(gdb) set var flag= 1 # 更改 flag 的值,确认是否是它的原因