一、git介绍

1. 发展过程

Git最初是由Linux开发者Linus用了仅仅两周时间纯C语言编写而成,在编写完成之后就立马上手接管Linux源代码,不过在此之前Linux是由BitMover公司开发的BitKeeper分布式版本控制系统所管理源代码,它是商业收费的分布式版本控制器,但BitMover公司看中Linux开源精神,免费授权给Linux社区使用,在2002年时,Linux开始使用BitKeeper分布式版本控制系统管理源代码,但好景不长,有一天Linux社区成员Andrew(samba(局域网共享文件c/s程序)的作者)试图破解BitKeeper共享给所有人使用,被BitMover公司发现并收回了免费使用的版权,随后Linus就用了两周时间开发出了git(两周时间包括测试),也就是目前为止最好用的分布式版本控制系统。

大名鼎鼎的github用的就是git系统来管理它们的网站,这里需要区分一下,github和git是两个东西,github是一个社区,git是一个服务系统,github只支持git分布式系统,所以故名成为github。

2. 集中式与分布式的区别

除了git还有svn、cvs这样的版本控制系统,它们的区别在于一个是分布式一个是集中式

集中式就是svn和csv这样的版本控制系统,分布式是git

区别在于集中式的版本控制系统每次在写代码时都需要从服务器中拉取一份下来,并且如果服务器丢失了,那么所有的就都丢失了,你本机客户端仅保存当前的版本信息,换句话说,集中式就是把代码放在一个服务器上集中管理,你的所有回滚等操作都需要服务器的支持。

分布式的区别在于,每个人的电脑都是服务器,当你从主仓库拉取一份代码下来后,你的电脑就是服务器,无需担心主仓库被删或者找不到的情况,你可以自由在本地回滚,提交,当你想把自己的代码提交到主仓库时,只需要合并推送到主仓库就可以了,同时你可以把自己的代码新建一份仓库分享给其它人。

像集中式它们都有一个主版本号,所有的版本迭代都以这个版本号为主,而分布式因为每个客户端都是服务器,git没有固定的版本号,但是有一个由哈希算法算出的id,用来回滚用的,同时也有一个master仓库,这个仓库是一切分支仓库的主仓库,我们可以推送提交到master并合并到主仓库上,主仓库的版本号会迭代一次,我们客户端上的git版本号无论迭代多少次,都跟master无关,只有合并时,master才会迭代一次。

二、命令

1. 初始化配置

配置git环境

1
git config --global

config:参数是用来配置git环境的

–global:长命令表示配置整个git环境

–system:系统配置,对所有用户生效

用户名配置

user 代表用户,name代表配置用户的名称

1
git config --global user.name "你的用户名"

邮箱配置

user代表用户,.email代表配置用户的邮箱

1
git config --global user.email "你的邮箱"

如果不配置,当遇到要求权限的远程仓库会让你在手动输入用户名、邮箱、以及密码

查看配置

1
git config --global --list

2. 新建仓库

创建本地仓库

1
git init

创建后会出现 .git 目录

输入以下命令显示仓库所有文件

.git目录是隐藏目录所以需要加 -a

1
ls -a

克隆远程仓库

1
git clone <远程仓库链接>

3. 工作区域和文件状态

工作区域:

  • 工作区(Working Directory):电脑空间 .git所在的目录
  • 暂存区(Staging Area/Index):用于保存即将提交到Git仓库的修改内容
  • 本地仓库(Local Repository):是Git存储代码和版本信息的主要位置

image-20240614100652685

文件状态:

  • 未跟踪(Untrack):新创建的,还没有被Git管理起来的文件
  • 未修改(Unmodified):被Git管理,但是文件的内容没有发生变化
  • 已修改(Modified):已经修改了文件,但是还没有添加到暂存区里面
  • 已暂存(Staged):修改后,并且已经添加到了暂存区域内的文件

image-20240614101237840

4. 添加和提交文件

查看仓库状态

1
git status

如果仓库里有文件,但是没有添加到暂存区。可以看到有一行红色字体的目录,此目录处在未被跟踪的状态

image-20240614101439770

添加到暂存区

1
git add

git add 支持使用通配符

例如:我想要添加目录中的所有文件到暂存区

1
git add .

提交后可以看到目录已变成绿色字体并提示等待被提交,并可以使用以下命令来把添加到暂存区的文件在取消暂存

1
git rm --cached <file>

image-20240614101448754

提交

git commit 命令在提交的时候需要使用 -m 参数来指定提交的信息,如果不指定 -m 这个参数,git会进入交互式的界面,默认会使用vim来编辑提交信息

git commit 只会提交暂存区的文件

1
git commit -m "提示信息"

查看提交记录

1
git log

image-20240614101458513

如果觉得提示信息过于繁杂,可以使用 –oneline 来查看简洁的提交记录,这样就只显示每次提交的ID和提交信息了

1
git log --oneline

5. 回退版本

reset命令用于回退版本,可以退回到之前的某一个提交的状态

1
git reset

git reset的三种模式

soft 参数表示回退到某个版本,并且保留工作区和暂存区的所有修改内容

1
git reset --soft

hard 参数表示回退到某个版本,并且丢弃工作区和暂存区的所有修改内容

1
git reset --hard

mixed 这个参数就是介于 soft 和 hard 这两个参数之间

它表示回退到某个版本,并且只保留工作区的修改内容而丢弃暂存区的修改内容

mixed 也是 reset的默认参数

1
git reset --mixed

image-20240614101506014

回溯

git 中的所有操作都是可以回溯的

使用 git reflog 命令来查看我们操作的历史记录

1
git reflog

使用 git reset <版本号> 回到某个操作之前

6. 查看差异

git diff 它可以用来查看文件在工作区、暂存区以及版本库之间的差异,它还可以查看不同版本之间的差异或者文件在两个分支之间的差异

工作区与暂存区差异

1
git diff

工作区 + 暂存区 与 本地仓库差异

1
git diff HEAD

暂存区与本地仓库差异

1
git diff --cached
1
git diff --staged

比较两个版本之间的差异

1
git diff <版本ID> <版本ID>

HEAD 代表最新版本 HEAD~ 代表上一版本 ^ 号也可以

可以快速比较上一版本和最新版本的差异

1
git diff HEAD~ HEAD
1
git diff HEAD^ HEAD

在 ~ 后加上数字,代表最新版本前几个版本

查看前二个版本和最新版本的差异

1
git diff HEAD~2 HEAD

在最后加上文件名,这样就只会查看指定文件的差异内容

1
git diff HEAD~3 HEAD <文件名>

比较不同分支差异,在diff后加上分支名称即可

1
git diff <分支名称> <分支名称>

7. 删除文件

如果我们直接删除工作区的文件,在暂存区中文件并没有被删除,需要再次执行 git add 。暂存区中的文件才会被删除

所以我们可以直接使用 git rm 同时删除工作区和暂存区中的文件

1
git rm <文件名>

把文件从暂存区删除,但保留在当前工作区中

1
git rm --cached <文件名>

递归删除某个目录下的所有子目录和文件

1
git rm -r *

8. 忽略文件

.gitignore :这个文件的作用就是可以让我们忽略掉一些不应该被加入到版本库中的文件

image-20240614101516817

如果我想要忽略 other.log

1
echo other.log > .gitigonre

如果我想要忽略 .log 格式文件

在.gitigonre 中添加

1
*.log

如果我想要忽略文件夹

在.gitigonre 中添加

1
文件夹名称/

.gitignore 生效有一个前提,那就是忽略的文件不能是已经被添加到版本库中的文件

.gitignore文件的匹配规则

从上到下逐行匹配,每一行表示一个忽略模式

git官网匹配规则

  • 空行或者以#开头的行会被Git忽略。一般空行用于可读性的分隔,#一般用作注释
  • 使用标准的Blob模式匹配,例如:
    • 星号*通配任意个字符
    • 问号?匹配单个字符
    • 中括号[]表示匹配列表中的单个字符,比如:[abc]表示a/b/c
  • 两个星号**表示匹配任意的中间目录
  • 中括号可以使用短中线连接,比如:
    • [0-9]表示任意一位数字,[a-z]表示任意一位小写字母
  • 感叹号!表示取反
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 忽略所有的 .a 文件
*.a

# 但跟踪所有的 lib.a,即便你在前面忽略了 .a 文件
!lib.a

# 只忽略当前目录下的 TODO 文件,而不忽略 subdir/TODO
/TODO

# 忽略任何目录下名为 build 的文件夹
build/

# 忽略 doc/notes.txt,但不忽略 doc/server/arch.txt
doc/*.txt

# 忽略 doc/目录及其所有子目录下的 .pdf 文件
doc/**/*.pdf

提示:在github上提供了各种常用语言的忽略文件的模版,在新建仓库的时候可以直接使用,也可以根据自己的需要修改

模版仓库

9. 推送和拉取

git push命令允许将本地git仓库中的本地分支的提交推送到远程仓库

1
git push <仓库名> <远程分支名>:<本地分支名>

如果远程分支名和本地分支名相同可以只写一个

拉取

1
git pull <远程仓库名> <远程分支名>:<本地分支名>

10. 关联本地仓库和远程仓库

1
git remote add <别名> <远程仓库地址>

11. 切换分支

使用 git checkout -b参数来创建一个分支,创建完成分支后会自动切换过去

1
git checkout -b dev

使用 git branch 来查看当前属于哪个分支,也就是查看HEAD的指向

1
git branch

git checkout -b 等价于

1
2
git branch dev
git checkout dev

git branch 如果后面跟着名字则会创建分支,但不会切换

git checkout 后面如果是分支名称则切换过去

切换分支

当我们向切换分支可以使用 git checkout 来切换,如刚刚我们创建了一个分支dev并切换了过去,现在切换回master

1
git checkout master

git checkout的作用是检出,如果是文件的话,会放弃对文件的缓存区操作,但是要使用reset重置一下变更才行。

如果是分支的话会切换过去。

合并分支

当我们新建分支并做完工作之后,想要把分支提交至master,只需要切换到master仓库,并执行git merge 分支名就可以了

持续更新中