Git教程
Reference
官网(英):https://git-scm.com (opens new window)
官网(中):https://git-scm.cn/ (opens new window)
Git logo:https://git-scm.com/downloads/logos (opens new window)
用户参考手册:https://git-scm.com/docs/user-manual (opens new window)
命令参考手册:https://git-scm.com/docs (opens new window)
Pro Git 电子书(中):https://git-scm.com/book/zh/v2 (opens new window)
Pro Git 电子书(英):https://git-scm.com/book/en/v2 (opens new window)
参考视频:https://www.bilibili.com/video/BV1HM411377j/ (opens new window)
Installation
Linux:发行版官方仓库下载
Windows:官网下载安装即可/使用winget install git
Git configuration
git config --global user.email "[email protected]"
git config --global user.name "Your name"
#--local(可省略) 本地配置,只对本地仓库有效
#--global 全局配置,所有仓库生效
#--system 系统配置,对所有用户生效
#优先级从上到下依次递减
git config --global credential.helper store
#这条命令本身并不会要求你输入用户名和密码
#这只是设置了一个全局的 Git 配置,告诉 Git 在需要身份验证时使用 store 凭证助手
git config --global --list
#查看git的配置信息
2
3
4
5
6
7
8
9
10
11
12
13
基本概念
Synopsis of Area

Working Directory
工作区
当前文件夹(除.git/的部分)
Staging Area/Index
暂存区
.git/index/临时存储区域,用于保存即将提交到Git仓库的修改内容
Local Repository
本地仓库
.git/objects/文件夹,包含完整的项目历史和元数据
Status of file 文件状态
git status #查看仓库的状态

Untrack files
新创建还未被Git追踪的文件
Unmodified files
已经被Git管理起来但是文件内容没有变化
Modified files
已经修改但是未放入暂存区中
Staged files
已经添加到暂存区中文件
Located Repository
Create a located repository
Create a directory
又称为Working Directorymkdir ~/Code/Repo1Initialization
在该文件夹下创建.git文件夹又称为Version Repository
包含暂存区stage/index,创建的第一个分支master(main),以及指向master(main)的一个指针叫HEAD
cd ~/Code/Repo git init #在文件夹下创建.git文件夹 git init /learn-git #在当前文件夹下创建learn-git目录作为Repo,并在/learn-git下创建.git文件夹 #Git 3.0 版本后主分支默认名称为 main (先前为master) git branch -m <name> #重命名当前分支1
2
3
4
5
6
7
8
9
Clone a remote Repository
git clone URL
Remote Repository
Create a remote Repository
常见的代码仓库托管平台
GitHub: github.com
Gitee : gitee.com
GitLab : gitlab.com
Relate local Repo and remote Repo
#建立本地仓库与远程仓库连接
git remote add <自定义短名> <仓库URL>
#例子
git remote add origin [email protected]
#查看当前本地仓库对应远程仓库的别名和地址
git remote -v
#展示远程仓库分支
git remote show <branch_name>
#指定本地分支为main
git branch -M main
#把本地main分支和远程origin仓库main分支关联起来
git push -u origin main:main
#-u,--upstream
#把本地Repo和远程origin Repo关联起来
#main:main (可简写为main)
#之后运行 git push 或 git pull,Git自动知道操作哪个远程分支和本地分支
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
git pull
把远程Repo某branch的修改拉取合并到本地Repo的某个branch
git pull <远程仓库名><远程分支名>:<本地分支名>
#<远程仓库名><远程分支名>可以省略,默认拉取仓库别名origin的main分支、
#作用是拉取分支,并且自动合并到本地分支
2
3
git fetch
只获取远程仓库修改,并不自动合并到本地仓库
# 获取所有远程分支信息
git fetch
# 列出所有远程分支(例如 origin/main, origin/develop)
git branch -r
# 查看本地和所有远程分支的完整列表
git branch -a
# 只从 origin 获取 main 分支的更新
git fetch origin main
2
3
4
5
6
7
8
9
10
11
git push
把本地Repo的某个branch修改推送到远程Repo的对应branch
git push <远程仓库名> <本地分支名>:<远程分支名>
#远程仓库名:默认是 origin(clone 时自动设置)。
#本地分支名:要推送的本地分支。
#远程分支名:目标远程分支(通常与本地分支同名,可省略)。
2
3
4
Common Commands
git init 创建仓库
git status 查看仓库的状态
当前仓库处于哪一个分支
有哪些文件以及这些文件处在怎样状态
git status -s 简略模式
git add 添加到暂存区
#例
git add filename
git add directory
git add . #当前文件夹全部文件夹
2
3
4
git commit 提交
只会提交暂存区中文件,不提交工作区中其他文件
git commit -m '提交信息'
git commit #进入vim编辑提交信息
git commit -a -m '提交信息'
git commit -am '提交信息'
#两者等同,对已经被追踪的所有文件添加暂存并提交
2
3
4
5
6
git log 查看提交记录
git log
commit 475c14ea046dd20d7e2201a1b300369f3f291dc5
Author: JavidPack <[email protected]>
Date: Mon May 19 13:49:25 2025 -0600
Updated Basic Netcode (markdown)
#commit:每次提交都有唯一ID
#Author提交者 Email邮箱
#Date 提交日期
#annotation 注释信息
2
3
4
5
6
7
8
9
10
11
12
13
git log --oneline
#查看简洁的提交记录
529680a Updated Basic Tile Entity (markdown)
2
3
4
5
git log --graph --oneline --decorate --all
#查看分支图
2
git reflog 查看操作的历史记录
git中所有操作都可以回溯,可以找到版本号回退
git diff 查看差异
查看文件在工作区,暂存区,版本库之间差异
还可以查看文件在两个特定版本之间的差异,或者文件在两个分支之间的差异
可在命令最后加上文件名,只查看该文件的差异内容
git diff HEAD^ HEAD~3 test1
显示发生更改的文件和更改的详细信息
git diff
diff --git a/test2 b/test2
index be10852..ba76164 100644
--- a/test2
+++ b/test2
@@ -1 +1,3 @@
+
+ss
???
#提示发生变更的文件
#git会将文件的内容使用hash算法生成40位hash值,只显示hash值前7位,最后是文件权限
#绿色文字是新添加内容,红色文字表示删除的内容
2
3
4
5
6
7
8
9
10
11
12
13
14
git diff 比较工作区和暂存区之间差异
git diff HEAD 比较工作区和版本库之间差异
git diff --cached 比较暂存区和版本库之间差异
git diff ID1/HEAD ID2/HEAD 比较两个特定版本之间的差异
git diff 分支名1 分支名2 比较两个分支之间差异
git rm 删除文件
git rm 同时删除工作区和暂存区文件
git rm test2
#被删除的文件仍然存在于版本库
2
git rm --cached 只删除暂存区文件
git rm --cached other.log
#被删除的文件仍然存在于版本库和工作区
2
git ls-files 按文件状态列出文件
-c,--cached (无参数默认选项) 列出暂存区(staged)中所有文件
-d,--deleted 列出暂存区(staged)中存在而中已删除的文件
-m,--modified 列出工作区中修改但未暂存的文件
-o,--others 显示未跟踪的文件
--unmerged 显示存在合并冲突且未合并的文件
Revocation Commands
git撤销操作:https://www.bilibili.com/video/BV1ne4y1S7S9/ (opens new window)
撤销工作区(working area)文件修改
git checkout <change_file>
git restore <change_file>
撤销暂存区(staging)文件修改,但保留工作区(working area)的修改 (即撤销git add操作)
git reset <change_file>
git restore --staged <change_file>
撤销暂存区(staging)文件修改,也撤销工作区(working area)的修改 (三个区域同步回到本次commit的状态)
git checkout HEAD <change_file>
仅撤销本次commit,保留暂存区和工作区修改
git reset --soft HEAD~1 //回到上次commit(HEAD~1),--soft保留暂存区和工作区
撤销本次commit和暂存区修改,保留工作区
git reset HEAD~1
git reset --mixed HEAD~1
撤销本次commit,暂存区和工作区修改 (三个区域同步回到上次commit的状态)
git reset --hard HEAD~1
git reset 回退版本
HEAD指向分支的最新提交节点
HEAD^ HEAD1 指向当前版本的上一个版本
HEAD^^ HEAD2 指向当前版本的上两个版本
HEAD~8 指向当前版本的前8个版本
git reset --soft
回退到某个版本,并保留暂存区和工作区的内容
git reset --soft 版本ID前7位
git reset HEAD^ #HEAD指针
#例
git reset --soft 529680a
2
3
4
5
git reset --hard
回退到某个版本,并清空暂存区和工作区的内容
git reset --mixed
回退到某个版本,清空暂存区,保留工作区的内容
--mixed 是留空默认参数
git revert 添加负向提交抵消先前修改
本质是添加一个commit,而这个commit刚好是先前的commit反过来
git revert的好处是能够撤销中间任意一个commit
对于远程仓库的公有分支,只应前进不应后退,只能使用git revert不能使用git reset
Branch Commands
分支的使用场景
多个开发人员在自己的分支上进行开发,最后再合并到主线代码库
在一个分支上进行新功能的开发,或者建立问题修复分支来处理bug
让主线代码仓库处于一个随时可用的稳定状态
主分支
main/master
Linus Torwards开发git时使用master作为仓库的主分支,但由于政治文化因素,master有主人掌控的歧视以为,现在推荐使用main作为主分支名称
原则:应当始终保持main分支处于随时可以发布的状态
开发分支
推荐名称:dev(development)
所有新的开发都应当提交到该分支中,进行CI,测试,集中许多提交后将dev分支一次性合并git merge回main分支,保证main分支提交记录整洁
稳定分支
推荐名称:stable
定期从main分叉出stable分支,每隔一段时间将bug fix向后移植得到稳定版本,维护较长一段时间丢弃
可以有多个stable分支,长期维护多年
git branch
git branch 查看分支,以及当前处于哪个分支
git branch branch-name 创建名为branch-name的新分支(但并未切换到新分支)
git branch -d name 删除名为branch-name且已经被合并的分支(不能删除未被合并的分支)
git branch -D name 强制删除名为branch-name分支
git switch
git switch name 切换到name分支
git checkout
git checkout既可用于切换分支,又可用于恢复文件,如果分支名和文件名相同,优先切换分支。容易引起歧义
不同分支的文件在同一个目录下, 切换时会出现文件的变化
git merge
将不同分支合并到主线分支中,并在主线中增加一次提交记录
优点:不破坏原分支的提交历史,方便回溯和查看
缺点:会产生额外的提交节点,分支图复杂
git merge <将被合并的分支名>
# 当前分支为合并的主分支,合并默认要提交信息
#合并分支并不会删除分支
git merge --abort
#终止合并
2
3
4
5
6
git rebase
将不同分支合并到主线分支,并将分支的所有修改记录添加到主线
可以在将主线合并到其他分支
优点:不会新增额外的提交记录,形成线性历史,直观干净
缺点:会改变提交历史,避免在共享分支使用。多用于单人开发

git rebase main
#将当前所在分支变基到main分支上
2
Resolve merge confilcts
如果两个分支修改内容没有重合部分,则没有冲突,git会自动合并
如果两个分支修改了同一文件同一行代码,需要手工修改冲突文件,再提交
Git仓库内配置文件
.gitignore
参考文档:https://github.com/github/gitignore.git (opens new window)
.gitignore文件应当被git追踪
仓库中不应被git追踪的文件:能够自动生成的文件,不希望别人知道的文件
- 系统,软件自动生成的文件
- 编译构建文件
- 程序运行生成的日志,缓存等临时文件
- 涉及身份,密码,口令,密钥等敏感文件
语法规则
- ## 开头的行是 注释
- 空行会被忽略
.gitignore中记录的文件名会被git忽略(前提是不能是已经被添加到版本库中的文件)
.gitignore中可记录文件夹,文件夹名以/结尾(注意:git默认不将空文件夹添加到仓库中)
# 忽略所有 .o 和 .exe 文件
*.o
*.exe
# 但跟踪 lib.o(否定示例)
!lib.o
# 忽略根目录下的 /debug 目录(整个目录)
/debug/
# 忽略任意目录下的 /temp 目录(注意:没有前导斜杠,会递归匹配)
temp/
# 忽略 docs/ 目录下所有 .bak 文件,但不忽略 docs/ 子目录中的 .bak
docs/*.bak
# 忽略 docs/ 目录下的所有子目录中的 .bak 文件
docs/**/*.bak
# 忽略所有 .log 文件,但 important.log 除外
*.log
!important.log
# 忽略 build/ 目录下所有内容,但保留 build/README.md
build/*
!build/README.md
# 忽略 .config 目录下所有内容,同时忽略 .config/ 目录本身
.config/
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
补充说明
- .gitignore以放在仓库的任意目录中,其作用域为当前目录及所有子目录。
- 子目录中的.gitignore 会覆盖父目录的规则(更具体优先)。
- 已经被Git跟踪的文件不受.gitignore 影响
- 要停止跟踪,需要使用 git rm --cached <file>。
.gitmodules
参考文章: https://zhuanlan.zhihu.com/p/87053283 (opens new window)
简介: .gitmodules 是 Git 项目中用来管理子模块(submodule)的配置文件。当你的仓库需要引用另一个外部 Git 仓库,且希望保持两个仓库相对独立时,子模块功能会派上用场,而 .gitmodules 文件则记录了这些子模块的元信息。
面对比较复杂的项目,我们有可能会将代码根据功能拆解成不同的子模块。主项目对子模块有依赖关系,却又并不关心子模块的内部开发流程细节。这种情况下,通常不会把所有源码都放在同一个Git仓库中。
.gitmodules典型使用场景
- 依赖外部库:希望将第三方库固定在某一个提交,随主项目一起构建。
- 大型项目拆分:将不同模块独立成仓库,但需要统一管理。
- 共享通用组件:多个项目复用同一份子模块代码。
.gitattributes
参考文章:https://zhuanlan.zhihu.com/p/108266134 (opens new window)
简介:.gitattributes 是一个让 Git 的工作方式变得“听话”的配置文件,可以从根源上解决跨平台协作时最令人头疼的换行符混乱、文件损坏等问题。通过它,可以为不同的文件精准定义 Git 的处理方式。
当执行 git 动作时,.gitattributes 文件允许你指定由 git 使用的文件和路径的属性,例如:git commit 等。换句话说,每当有文件保存或者创建时,git 会根据指定的属性来自动地保存。