前言

Git 是一个分布式版本控制系统,每次用户提交更新或在 Git 中保存项目状态时,它主要对当时的全部文件制作一个快照并保存这个快照的索引。 为了高效,如果文件没有修改,Git 不再重新存储该文件,而是只保留一个连结指向之前存储的文件。 Git 对待数据更像是一个 快照流

Git Flow

Git 数据库中保存的信息都是以文件内容的哈希值(SHA-1)来索引,而不是文件名,Git 中所有数据在存储前都计算校验和,然后以校验和来引用

Git 主要工作区域:Git 存储仓库1、工作目录2、暂存区域3

Git WorkSpace

安装 Git

不同系统下安装 Git 过程略微有些不同,请参阅 Git - Downloads

配置用户信息

安装完 Git 后首要任务是配置你的用户名(username)邮件地址(email address),接下来我们在 Git 中的每一次提交都会使用这些信息

$ git config --global user.name "[username]"
$ git config --global user.email "[email address]"
# [可选] 启用带帮助的彩色命令行输出
$ git config --global color.ui auto
# 对于 Windows 用户,建议额外执行下面两条配置
$ git config --global core.autocrlf true
$ git config --global core.safecrlf warn

--global 参数表示全局配置选项,带上该参数后我们在这台计算机上所有的 Git 操作默认情况下都会使用上面这些信息

如果要在某个 Git 存储仓库设置其他的的用户信息,可以在这个存储仓库内单独设置用户名程和邮件信息(不带 --global 参数)

检查配置

配置完成后,检查下你的配置

# 检查现在的配置
$ git config --list
# 获得 config 命令手册
$ git help config

创建新存储库

如果要创建一个新的存储库,可以从本地创建,也可以在 GitHub 上 clone 一个现有的存储库

创建本地存储库

比如,我现在想要用来演示的 Git 存储库名为 git-tour

第一种方式是在当前目录下新建一个 Git 存储库

# 手动新建一个名为 git-tour 的文件夹(如果该目录不存在)
$ mkdir git-tour && cd git-tour
# 初始化 Git 存储库
$ git init

还有一种方式是创建一个空白目录,并在该目录初始化一个 Git 存储库

# 用法: git init [git-repo-name]
# 比如: 创建一个名为 git-tour 的文件夹并初始化为一个 Git 存储库
$ git init git-tour

从远程拉取存储库

如果想要创建一份现有 Git 存储仓库上的拷贝到本地,使用 git clone [url] 命令,默认情况下,会将该 Git 仓库的所有版本历史都克隆下来

# GitHub HTTPS 协议
$ git clone https://github.com/MoeOffice/git-tour.git
# 或者使用 GitHub SSH,用法: git clone user@server:path/to/repo.git
$ git clone git@github.com:MoeOffice/git-tour.git

Git 下的文件生命周期

在一个 Git 存储仓库下,所有的文件只有两种状态:已追踪(tracked)4和未追踪(untracked)5

Git Life Cycle

跟踪文件

使用 git add 命令指定对特定文件的追踪,比如在 git-tour 工作目录下新建一个 a.txt 文件(内容为 Hello World!),要对其进行追踪

$ git add a.txt

使用 git status 命令查看当前 Git 工作目录下的文件变动状态

$ git status
On branch master
Your branch is up to date with 'origin/master'.

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        new file:   a.txt

关于 git status -s 命令6,举个例子:

$ git status -s
M LICENSE        # LICENCE 文件被修改了单还没放入暂存区域
MM README.md      # README.md 在工作区被修改后提交到暂存区域然后在工作区又被修改了
A  HEAD.md        # HEAD.md 文件被新添加到暂存区域 
M  src/index.html # src/index.html 文件被修改后添加到暂存区域
?? 1.txt          # 1.txt 文件是新添加且未跟踪

忽略文件

我们不希望一些文件被纳入 Git 管理或被跟踪,比如:一些涉及秘密的文件、编译输出文件、临时文件,我们可以在 Git 存储仓库根目录下创建一个特殊的 .gitignore 文件,它其实是一个纯文本文件,可以使用标准的 glob 模式匹配7,此外:

  • 所有空行或者以 开头的行都会被 Git 忽略
  • 匹配模式可以以 / 开头防止递归
  • 匹配模式可以以 / 结尾指定目录
  • 要忽略指定模式以外的文件或目录,可以在模式前加上惊叹号 ! 取反

GitHub 官方维护了一个仓库 github/gitignore,包含了常用语言和项目的 .gitignore 模板

查看修改

git status 可以查看哪些文件修改了,但是看不到具体修改了哪些地方,我们使用 git diff 命令查看已暂存/未暂存文件的修改,比如:

# 查看尚未暂存的文件修改差异,直接使用 git diff
# 对于已经暂存的文件,使用 git diff --statged 或 git diff --cached 查看修改差异
$ git diff --staged
diff --git a/a.txt b/a.txt
new file mode 100644
index 0000000..c57eff5
--- /dev/null
+++ b/a.txt
@@ -0,0 +1 @@
+Hello World!
\ No newline at end of file

提交修改

暂存区域处理完成了,现在想要把我们的文件修改记录提交到 Git 存储仓库,就需要使用 git commit 命令进行提交

# 后面带上 -m 参数可以添加提交信息,规范的提交记录都应该加上提交信息,方便协作的其他人理解修改
$ git commit -m "add a.txt"
[master 7896990] add a.txt
 1 file changed, 1 insertion(+)
 create mode 100644 a.txt

现在,完成了我们的第一次提交了,master 表示我们提交所在的分支,7896990 是这次提交的 SHA-1 校验和

有时候,人们觉得使用暂存区域的过程过于繁琐,就可以在 git commit 后带上 -a 参数跳过手动 git add 步骤,这可以将所有已跟踪过的文件自动暂存并一起提交

# 对于已跟踪文件
$ git commit -a -m 'tips: tracked file without git add'
[master 0afe637] tips: tracked file without git add
1 file changed, 3 insertions(+), 1 deletion(-)

# 对于未跟踪文件是不能省略 git add 步骤的
$ git commit -a -m 'error: untracked file without git add'
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
(use "git push" to publish your local commits)

Untracked files:
(use "git add <file>..." to include in what will be committed)
     b.txt

nothing added to commit but untracked files present (use "git add" to track)

查看历史

使用 git log 命令回顾 Git 提交的历史记录,这会显示所有的提交历史

# git log 使用 -p 参数加上数字显示最近的几次提交,比如显示最近两次的提交
$ git log -p -2
commit 29484f3084f2510438ac4038b678b426c9aeb38d (HEAD -> master)
Author: DejavuMoe <admin@dejavu.moe>
Date:   Tue Apr 5 00:19:34 2022 +0800

    steps: untracked files need git add before git commit

diff --git a/b.txt b/b.txt
new file mode 100644
index 0000000..8a92e27
--- /dev/null
+++ b/b.txt
@@ -0,0 +1 @@
+有时候,人们觉得使用暂存区域的过程过于繁琐,就可以在 git commit 后带上 -a 参数跳过手动 git add 步骤,这可以将所有已跟踪过的文件自动暂存并一起提交
\ No newline at end of file

commit 0afe6378e9353aeb03375cf54bf661aa22618a91
Author: DejavuMoe <admin@dejavu.moe>
Date:   Tue Apr 5 00:02:37 2022 +0800

    tips: tracked file without git add

diff --git a/a.txt b/a.txt
index c57eff5..c45b31a 100644
--- a/a.txt
+++ b/a.txt
@@ -1 +1,3 @@
-Hello World!
\ No newline at end of file
+---
+Hello World!
+---
\ No newline at end of file

另一个常用的参数就是 --pretty

# 比如只用一行显示提交历史
$ git log --pretty=oneline
29484f3084f2510438ac4038b678b426c9aeb38d (HEAD -> master, origin/master) steps: untracked files need git add before git commit
0afe6378e9353aeb03375cf54bf661aa22618a91 tips: tracked file without git add
7896990461d9ba994e8ec47ac15cb1c614f6524f add a.txt
a89eb2e2ec720b7094e80108d5f3cffd4d6beb95 init LICENSE

更多用法和说明,使用 git log --help 命令 查看

此外,也可以在 Git 存储仓库下使用 gitk (任何平台) 和 gitx (仅有 macOS) 命令使用 Git 内置的图形化浏览器查看文件变更

gitk

😋 第一部分暂时就到这里吧~

参考信息:


  1. Git 存储仓库(Repository)是 Git 用来保存项目的元数据和对象数据库的地方, 这是 Git 中最重要的部分,从其它计算机克隆仓库时,拷贝的就是这里的数据 ↩︎

  2. 工作目录(Working Directory)是对项目的某个版本独立提取出来的内容。 这些从 Git 仓库的压缩数据库中提取出来的文件,放在磁盘上供你使用或修改 ↩︎

  3. 暂存区域(Staging Area)是一个文件,保存了下次将提交的文件列表信息,一般在 Git 仓库目录中。 有时候也被称作 索引,不过一般说法还是叫暂存区域 ↩︎

  4. 已跟踪的文件是指那些被纳入了版本控制的文件,在上一次快照中有它们的记录,在工作一段时间后,它们的状态可能处于未修改,已修改或已放入暂存区 ↩︎

  5. 工作目录中除已跟踪文件以外的所有其它文件都属于未跟踪文件,它们既不存在于上次快照的记录中,也没有放入暂存区 ↩︎

  6. 等同于 git status --shortM 可以出现在两个位置:靠右边的 M 表示文件被修改了但还没放入暂存区域,靠左边的 M 表示文件被修改了并已经放入了暂存区域;A 表示文件新添加到暂存区域;?? 表示新添加且未被跟踪的文件 ↩︎

  7. glob 是用于匹配符合指定模式的文件集合的一种语言, 类似于正则表达式, 但更加简单,可以参考 命令行通配符教程 - 阮一峰的网络日志 ↩︎