1 基本理念

Git是一种用于对项目版本进行控制管理的工具。不同于其他存储差异的版本控制工具,Git基于快照索引。每次保存项目更新,建立项目所有改动文件的快照,然后以快照索引表示一个版本。文件没有变动则指向上一个版本的快照。这里的索引实际上就是哈希值。

因为基于快照,所以Git一般情况下不存在删除的概念。Git存在三种状态:

  • 已修改(modified):表示修改了文件,但还没保存到数据库中。
  • 已暂存(committed):对一个已修改文件的当前版本做了标记,使之包含在下次提交的快照中。
  • 已提交(staged):表示数据已经安全地保存在本地数据库中。

基于三种状态,可以将Git项目分为三个区域:

  • 工作区:从仓库中提取某个版本,供用户编辑修改。
  • 暂存区:一个用于保存本次修改文件列表信息的文件。
  • 仓库目录:保存项目的元数据和对象数据库,仓库克隆就是克隆仓库目录。

2 运行配置

git存在三级配置,分别是系统级,用户级,仓库级。对应的变量为 --system​、--global​ 以及--local​,默认是仓库级配置。

使用前需要配置用户信息:

1
2
$ git config --global user.name username
$ git config --global user.email [email protected]

3 基础操作

3.1 获取仓库

3.1.1 本地初始化

在项目的根目录下执行相关命令:

1
2
3
git init #初始化
git add #建立追赠
git commit -m 'inital project version ' #提交原始版本

初始化后,会生成.git​文件,存储git的所有有关信息。然后建立对项目文件的追踪,然后将其作为原始版本提交到git仓库中。

3.1.2 克隆仓库

如果想要在一个已存在的仓库上进行操作,可以通过克隆仓库。克隆仓库的命令是 git clone <url> <local path>​ 。

3.2 文件管理

3.2.1 文件状态

项目中的文件只存在两种状态:已跟踪或未跟踪。通过git status​ 来查看当前项目的文件状态。使用git status -s​命令或git status --short​命令可以获得紧凑输出。通过"git add <filename>..."​来对文件进行跟踪。

1
2
3
4
5
6
7
8
9
(base)ubuntu:~/Learn/git $git status
位于分支maste2
尚无提交

未跟踪的文件:
(使用"git add <文件>..."以包含要提交的内容)
test1

提交为空,但是存在尚未跟踪的文件(使用"git add"建立跟踪)

需要注意git add​命令本意并不是添加追踪而是,将修改添加到下次提交中,即添加到暂存区。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
(base) ubuntu:$ git status
位于分支 master
尚无提交
要提交的变更:
(使用 "git rm --cached <文件>" 以取消暂存)
新文件: test1
尚未暂存以备提交的变更:
(使用 "git add <文件>" 更新要提交的内容)
(使用 "git restore <文件>" 丢弃工作区的改动)
修改: test1

(base) ubuntu:$ git add test1

(base) ubuntu:$ git status
位于分支 master
尚无提交
要提交的变更:
(使用 "git rm --cached <文件>..." 以取消暂存)
新文件: test1

通过命令 git rm <filename>​ 将文件从跟踪状态转换为未跟踪状态。

3.2.2 忽略文件

创建 .gitignore​ 文件,通过该文件控制哪些文件无需纳入Git管理。文件.gitignore​的格式规范如下:

  • 所有空行或者以#开头的行都会被Git忽略。
  • 可以使用标准的glob模式匹配,它会递归地应用在整个工作区中。
  • 匹配模式可以以(/)开头防止递归。
  • 匹配模式可以以(/)结尾指定目录。(build/)
  • 要忽略指定模式以外的文件或目录,可以在模式前加上叹号(!)取反。

    glob 模式:

星号(*)匹配零个或多个任意字符;

使用两个星号(**)表示匹配任意中间目录.

[abc] 匹配任何一个列在方括号中的字符 (这个例子要么匹配一个 a,要么匹配一个 b,要么匹配一个 c);

问号(?)只匹配一个任意字符;

如果在方括号中使用短划线分隔两个字符, 表示所有在这两个字符范围内的都可以匹配 (比如 [0-9] 表示匹配所有 0 到 9 的数字)。

3.3 提交

未暂存修改:git diff

提交命令:git commit​ ,命令 git commit -a​相当于git add​和git commit​的组合。

查看历史:git log

3.4 撤销操作

可以通过git commit --amend​来实现重新提交:

1
2
3
$ git commit -m 'initial commit'  
$ git add forgotten_file
$ git commit --amend

git checkout --<filename>​可以撤销修改,但是不推荐危险系数很高。

3.5 远程仓库

添加远程仓库:git remote add <remote> <url>​。

从远程仓库抓取:git fetch <remote>​访问远程仓库,从中拉取所有本地还没有的数据。

从远程仓库拉取:git pull <remote>​ 自动抓取后合并该远程分支到当前分支。

推送:git push <remote> <branch>​ 将相应的分支推送至远程仓库。

重命名远程仓库: git remote rename <oldremote> <newremote>

移除远程仓库:git remote remove <remote>

3.6 标签

附着标签:git tag -a <tag> -m "<message>"

轻量化标签:git tag <tag>

推荐使用附着标签

4 分支

4.1 存储结构

使用链表存储commit,每个commit指向当前快照,每个快照都是一个树结构指向具体的文件。

DM_20250106201113_001

DM_20250106201142_001

而分支则是指向commit链上节点的指针,通过Head指针确定当前分支。

DM_20250106201153_001

4.2 分支基础操作

分支创建:git branch <branch>

分支切换:git checkout <branch>​ 添加 -b​实现创建于切换。

分支合并:git merge <branch>​如果存在完整的指针链可以直接移动过去。如果存在支路则需要创建新的commit。

优势存在分支冲突,需要手动的选择保留的代码。

推送: git push <remote> <localbranch>:<remotebranch>

跟踪远程分支 git checkout --track <remote>/<branch>​等价于git checkout -b <branch> <remote>/<branch>

4.3 变基

变基就是将当前分支的操作在目标分支上进行重操作,变基的目的是为了让提交看起来更简洁。如果提交存在于本地仓库之外,而别人可能基于这些提交进行开发,那么不要执行变基。

1
2
$ git checkout <当前分支>
$ git rebase <目标分支>