duhelan07@outlook.com


[Git] 01 – Git 首次配置和基础操作

1.1 – Git 入门

一、关于版本控制

版本控制是一套系统,该系统按时间顺序记录某一个或一系列文件的变更,让你可以查看其以前的特定版本。

版本控制系统:Version Control System (VCS)

(一)本地版本控制系统

  • 将文件复制到另一个文件目录下,加上时间戳,是最简单但也最容易出错的版本控制方式;
  • RCS:常用 VCS 工具,通过叠加保存在磁盘上的补丁集(patch set)使文件恢复到某个历史状态;

(二)集中式版本控制系统 CVCS

  • 有一个包含所有修订版本的单一服务器,多个客户端可以从这个中心位置检出文件;
  • 缺点:服务器如果宕机,任何人都无法协作或提交更改;如果磁盘受损,可能丢失历史记录。

(三)分布式版本控制系统 DVCS

  • 客户端对代码仓库(repository)进行完整镜像,而不仅是检出文件的快照;


二、关于 Git

(一)快照而非差异

  • Git 与其他 VCS 的最大区别是对待数据的方式。
  • Git 将数据视为一个微型文件系统的一组快照:
    • 每次提交或在 Git 中保存项目状态时,Git 会抓取一张所有文件当前状态的快照,然后存储一个指向该快照的引用;
    • 如果文件未发生变动,Git 则不会重新保存文件,而是留下一个指向先前已经保存过的相同文件的链接;

传统版本控制系统,存储对每个文件的基础版本做出的改动

Git 将数据存储为随时间变化的项目快照

(二)几乎所有操作都在本地执行

  • Git 的大部分操作只需要应用到本地文件和资源,使 Git 的速度惊人;
  • 可以在离线状态下继续大部分工作。

(三)Git 的完整性

  • Git 中所有的数据在存储前都会执行校验和计算,随后以校验和来引用对应的数据,意味着 Git 对所有文件/目录的更改都知情;
  • Git 采用 SHA-1 散列(一个由 40 个十六进制字符组成的字符串)进行校验。

(四)Git 通常只增加数据

  • Git 中基本所有的操作都只是向 Git 数据库中添加数据,很难让系统执行无法撤销的操作;
  • Git 中你有可能弄丢/弄乱未提交的变更,但一旦提交就基本不可能丢失。

(五)三种状态

  • 在 Git 中,文件可以处于以下三种状态之一:
    • 已提交(committed):数据被安全地存入本地数据库中;
    • 已修改(modified):已经改动了文件,但尚未提交;
    • 已暂存(staged):对已修改文件的当前版本做出了标识,并将其加入下一次要提交的快照中;
Git 项目的三个主要区域
  • Git 项目的三个主要区域:
    • Git 目录:最重要的部分,是 Git 保存项目元数据和对象数据库的地方,也是克隆仓库时要复制的内容;
    • 工作目录:项目某个版本的单次检出,从 Git 目录下的压缩数据库内被提取出,放置在磁盘上以供使用和修改;
    • 暂存区:单个文件,一般位于 Git 目录下,保存了下次所要提交内容的信息;
  • Git 的基本工作流:
    • 修改工作目录中的文件;
    • 暂存文件,将这些文件的快照加入暂存区;
    • 提交暂存区的文件,将快照永久保存在 Git 目录中;
  • 状态的判断:
    • 处在 Git 目录中的文件版本就被认为是 已提交 状态;
    • 如果该文件被修改,且处于暂存区,就处于 已暂存 状态;
    • 如果检出后发生了变更,但未被暂存,则处于 已修改 状态。


三、安装 Git


四、Git 的首次配置

Git 包含了名为 git config 的配置工具,可获取和设置配置变量。

配置变量存储的三个位置

  • [path]/etc/gitconfig 文件:
    • 包含系统中所有用户及其仓库的值;
    • --system 选项;
  • ~/.gitconfig or ~/.config/git/config 文件:
    • 针对你自己;
    • -- global 选项;
  • 当前仓库的 Git 目录(即 .git/config)中的 config 文件:
    • 针对单个仓库;
    • -- local 选项。

常用操作

  • 设置用户身份:
    • 设置用户名和电子邮件地址:
      $ git config --global user.name "Du Guiyu"
      $ git config --global user.email duhelan07@outlook.com
    • 只需要进行一次配置,Git 此后的每一次提交都使用这些信息,非常重要;
  • 设置个人编辑器:
    • 例如 Emacs:
      $ git config --global core.editor emacs
    • 例如在 Windows 系统中使用 Nodepad++:
      $ git config --global core.editor "'C:/Program Files/Notepad++/notepad++.exe' -multiInst -notabbar -nosession -noPlugin" (路径后的选项是启动参数,是 Nodepad++ 自己定义并解析的命令行选项)
    • 当 Git 需要输入消息时会用到该编辑器,如果不配置编辑器,在 Git 发起编辑操作时可能会提前终止;
  • 检查个人设置:
    • 使用 git config --list 命令即可列出当前 Git 可找到的所有设置;
    • 使用 git config <key> 命令可查看 Git 配置中当前某个键的值。


五、获取帮助

使用以下三种方式可查看 Git 命令的帮助:

PowerShell
$ git help <verb>
$ git <verb> --help
$ man git-<verb>

例如 git help config


1.2 – Git 基本操作

一、获取 Git 仓库

建立 Git 项目的方法有两种:

  • 把现有的项目 / 目录导入 Git;
  • 从服务器上克隆现有的 Git 仓库。

(一)在现有目录中初始化 Git 仓库

进入项目目录并输入:git init ;

在 Windows 系统文件管理器中,打开项目文件夹,点击路径栏,输入 cmd / powershell 并回车,可快速在 cmd / powershell 中进入该目录
在目录右键菜单中选择“Open Git Bash here”,快速打开 Git Bash

(二)克隆现有仓库

进入项目目录并输入:git clone <url> ,该命令提供了许多可选项:

Bash
# 当前在 C:\projects

$ git clone https://github.com/user/repo.git
# 结果:C:\projects\repo\...

$ git clone https://github.com/user/repo.git myrepo
# 结果:C:\projects\myrepo\...

$ git clone https://github.com/user/repo.git .
# 结果:C:\projects\...(要求当前目录为空)

$ git clone https://github.com/user/repo.git path/to/dir
# 结果:C:\projects\path\to\dir\...(dir 目录必须为空)


二、在 Git 仓库中记录变更

工作目录下的每个文件都处于两种状态之一:

  • 已跟踪(tracked):上一次快照中包含的文件;
    • 又可分为:已修改;未修改;已暂存;
  • 未跟踪(untracked):除已跟踪外的所有文件,即 不在上一次快照中,也不在暂存区中的文件。

(一)查看当前文件状态

检查文件状态使用 git status 命令。

Bash
# 克隆仓库后立即使用 git status 命令:
$ git status
On branch master
Your branch is up-to-date with 'origin/main'.

nothing to commit, working tree clean

如果向项目中添加一个 README 文件,再使用命令。Git 不会主动添加新文件到下一次的提交范围,所以该文件会处于 未跟踪 状态:

Bash
# 新建 README.md 文件并写入内容
$ echo 'hello, world' > README.md
$ git status
On branch master

No commits yet

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

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

(二)跟踪新文件

使用 git add <file/path> 命令让 Git 跟踪新文件:

  • 如果参数为目录,则递归跟踪目录下的所有文件。
Bash
$ git add README.md
$ git status
On branch master

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
        new file:   README.md

(三)暂存已修改的文件

git add 是多功能命令,其核心操作是把内容写入暂存区,所以既可用来跟踪新文件,也可用来暂存文件。

Bash
# 添加一些内容到 README.md 末尾
$ echo "Welcome to salmon-isle.com!" >> README.md
$ git status
On branch master

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
        new file:   README.md

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   README.md

$ git add README.md
$ git status
On branch master

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
        new file:   README.md

为什么第一次的 git status 中 README.md 同时出现在了已暂存和未暂存列表中?

  • 暂存文件时,Git 保存该文件在 git add 时的样子;
  • 如果现在执行 git commit,则会提交该文件上次 git add 时的版本,而不是当前工作目录中的版本;
  • 所以,若暂存区中文件发生修改,需再执行一次 git add;

(四)显示更简洁的状态信息

执行 git status -s 或 git status --short 显示更简洁的状态信息:

Bash
$ git status -s
 M README
MM Rakefile
A  lib/git.rb
M  lib/simplegit.rb
?? LICENSE.txt
字母含义
Mmodified,已修改
Aadded,新增并已暂存
Ddeleted,已删除
Rrenamed,重命名
Ccopied,复制
Uupdated but unmerged,冲突未解决
??untracked,未跟踪
!!ignored,被忽略

(五)忽略文件

如果不希望某类文件被 Git 自动添加 / 出现在 Untracked 列表中(如日志文件、构建文件),可创建 .gitignore 文件,列出带匹配文件的模式(pattern):

  • 空行 / 以 # 开头的行会被忽略;
  • 支持标准 glob 模式;
  • 正斜杠(/)开头的模式,禁止递归匹配。
  • 正斜杠(/)结束的模式,表示目录。
  • 感叹号(!)开头的模式,表示取反。
Bash
*.a            # 忽略所有 .a 文件
!lib.a         # 但跟踪 lib.a,即使上面忽略了 .a 文件
/TODO          # 只忽略当前目录下的 TODO 文件,而不是 subdir/TODO
build/         # 忽略任何名为 build 的目录中的所有文件
doc/*.txt      # 忽略 doc/notes.txt,但不忽略 doc/server/arch.txt
doc/**/*.pdf   # 忽略 doc/ 目录及其所有子目录中的所有 .pdf 文件

参考资料:

glob (programming) – Wikipedia
https://en.wikipedia.org/wiki/Glob_(programming)

GitHub 官方 .gitignore 模版库,涵盖了百余种不同项目和语言
https://github.com/github/gitignore

[Git] 01 – Git 首次配置和基础操作

1.1 – Git 入门

一、关于版本控制

版本控制是一套系统,该系统按时间顺序记录某一个或一系列文件的变更,让你可以查看其以前的特定版本。

版本控制系统:Version Control System (VCS)

(一)本地版本控制系统

  • 将文件复制到另一个文件目录下,加上时间戳,是最简单但也最容易出错的版本控制方式;
  • RCS:常用 VCS 工具,通过叠加保存在磁盘上的补丁集(patch set)使文件恢复到某个历史状态;

(二)集中式版本控制系统 CVCS

  • 有一个包含所有修订版本的单一服务器,多个客户端可以从这个中心位置检出文件;
  • 缺点:服务器如果宕机,任何人都无法协作或提交更改;如果磁盘受损,可能丢失历史记录。

(三)分布式版本控制系统 DVCS

  • 客户端对代码仓库(repository)进行完整镜像,而不仅是检出文件的快照;


二、关于 Git

(一)快照而非差异

  • Git 与其他 VCS 的最大区别是对待数据的方式。
  • Git 将数据视为一个微型文件系统的一组快照:
    • 每次提交或在 Git 中保存项目状态时,Git 会抓取一张所有文件当前状态的快照,然后存储一个指向该快照的引用;
    • 如果文件未发生变动,Git 则不会重新保存文件,而是留下一个指向先前已经保存过的相同文件的链接;

传统版本控制系统,存储对每个文件的基础版本做出的改动

Git 将数据存储为随时间变化的项目快照

(二)几乎所有操作都在本地执行

  • Git 的大部分操作只需要应用到本地文件和资源,使 Git 的速度惊人;
  • 可以在离线状态下继续大部分工作。

(三)Git 的完整性

  • Git 中所有的数据在存储前都会执行校验和计算,随后以校验和来引用对应的数据,意味着 Git 对所有文件/目录的更改都知情;
  • Git 采用 SHA-1 散列(一个由 40 个十六进制字符组成的字符串)进行校验。

(四)Git 通常只增加数据

  • Git 中基本所有的操作都只是向 Git 数据库中添加数据,很难让系统执行无法撤销的操作;
  • Git 中你有可能弄丢/弄乱未提交的变更,但一旦提交就基本不可能丢失。

(五)三种状态

  • 在 Git 中,文件可以处于以下三种状态之一:
    • 已提交(committed):数据被安全地存入本地数据库中;
    • 已修改(modified):已经改动了文件,但尚未提交;
    • 已暂存(staged):对已修改文件的当前版本做出了标识,并将其加入下一次要提交的快照中;
Git 项目的三个主要区域
  • Git 项目的三个主要区域:
    • Git 目录:最重要的部分,是 Git 保存项目元数据和对象数据库的地方,也是克隆仓库时要复制的内容;
    • 工作目录:项目某个版本的单次检出,从 Git 目录下的压缩数据库内被提取出,放置在磁盘上以供使用和修改;
    • 暂存区:单个文件,一般位于 Git 目录下,保存了下次所要提交内容的信息;
  • Git 的基本工作流:
    • 修改工作目录中的文件;
    • 暂存文件,将这些文件的快照加入暂存区;
    • 提交暂存区的文件,将快照永久保存在 Git 目录中;
  • 状态的判断:
    • 处在 Git 目录中的文件版本就被认为是 已提交 状态;
    • 如果该文件被修改,且处于暂存区,就处于 已暂存 状态;
    • 如果检出后发生了变更,但未被暂存,则处于 已修改 状态。


三、安装 Git


四、Git 的首次配置

Git 包含了名为 git config 的配置工具,可获取和设置配置变量。

配置变量存储的三个位置

  • [path]/etc/gitconfig 文件:
    • 包含系统中所有用户及其仓库的值;
    • --system 选项;
  • ~/.gitconfig or ~/.config/git/config 文件:
    • 针对你自己;
    • -- global 选项;
  • 当前仓库的 Git 目录(即 .git/config)中的 config 文件:
    • 针对单个仓库;
    • -- local 选项。

常用操作

  • 设置用户身份:
    • 设置用户名和电子邮件地址:
      $ git config --global user.name "Du Guiyu"
      $ git config --global user.email duhelan07@outlook.com
    • 只需要进行一次配置,Git 此后的每一次提交都使用这些信息,非常重要;
  • 设置个人编辑器:
    • 例如 Emacs:
      $ git config --global core.editor emacs
    • 例如在 Windows 系统中使用 Nodepad++:
      $ git config --global core.editor "'C:/Program Files/Notepad++/notepad++.exe' -multiInst -notabbar -nosession -noPlugin" (路径后的选项是启动参数,是 Nodepad++ 自己定义并解析的命令行选项)
    • 当 Git 需要输入消息时会用到该编辑器,如果不配置编辑器,在 Git 发起编辑操作时可能会提前终止;
  • 检查个人设置:
    • 使用 git config --list 命令即可列出当前 Git 可找到的所有设置;
    • 使用 git config <key> 命令可查看 Git 配置中当前某个键的值。


五、获取帮助

使用以下三种方式可查看 Git 命令的帮助:

PowerShell
$ git help <verb>
$ git <verb> --help
$ man git-<verb>

例如 git help config


1.2 – Git 基本操作

一、获取 Git 仓库

建立 Git 项目的方法有两种:

  • 把现有的项目 / 目录导入 Git;
  • 从服务器上克隆现有的 Git 仓库。

(一)在现有目录中初始化 Git 仓库

进入项目目录并输入:git init ;

在 Windows 系统文件管理器中,打开项目文件夹,点击路径栏,输入 cmd / powershell 并回车,可快速在 cmd / powershell 中进入该目录
在目录右键菜单中选择“Open Git Bash here”,快速打开 Git Bash

(二)克隆现有仓库

进入项目目录并输入:git clone <url> ,该命令提供了许多可选项:

Bash
# 当前在 C:\projects

$ git clone https://github.com/user/repo.git
# 结果:C:\projects\repo\...

$ git clone https://github.com/user/repo.git myrepo
# 结果:C:\projects\myrepo\...

$ git clone https://github.com/user/repo.git .
# 结果:C:\projects\...(要求当前目录为空)

$ git clone https://github.com/user/repo.git path/to/dir
# 结果:C:\projects\path\to\dir\...(dir 目录必须为空)


二、在 Git 仓库中记录变更

工作目录下的每个文件都处于两种状态之一:

  • 已跟踪(tracked):上一次快照中包含的文件;
    • 又可分为:已修改;未修改;已暂存;
  • 未跟踪(untracked):除已跟踪外的所有文件,即 不在上一次快照中,也不在暂存区中的文件。

(一)查看当前文件状态

检查文件状态使用 git status 命令。

Bash
# 克隆仓库后立即使用 git status 命令:
$ git status
On branch master
Your branch is up-to-date with 'origin/main'.

nothing to commit, working tree clean

如果向项目中添加一个 README 文件,再使用命令。Git 不会主动添加新文件到下一次的提交范围,所以该文件会处于 未跟踪 状态:

Bash
# 新建 README.md 文件并写入内容
$ echo 'hello, world' > README.md
$ git status
On branch master

No commits yet

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

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

(二)跟踪新文件

使用 git add <file/path> 命令让 Git 跟踪新文件:

  • 如果参数为目录,则递归跟踪目录下的所有文件。
Bash
$ git add README.md
$ git status
On branch master

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
        new file:   README.md

(三)暂存已修改的文件

git add 是多功能命令,其核心操作是把内容写入暂存区,所以既可用来跟踪新文件,也可用来暂存文件。

Bash
# 添加一些内容到 README.md 末尾
$ echo "Welcome to salmon-isle.com!" >> README.md
$ git status
On branch master

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
        new file:   README.md

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   README.md

$ git add README.md
$ git status
On branch master

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
        new file:   README.md

为什么第一次的 git status 中 README.md 同时出现在了已暂存和未暂存列表中?

  • 暂存文件时,Git 保存该文件在 git add 时的样子;
  • 如果现在执行 git commit,则会提交该文件上次 git add 时的版本,而不是当前工作目录中的版本;
  • 所以,若暂存区中文件发生修改,需再执行一次 git add;

(四)显示更简洁的状态信息

执行 git status -s 或 git status --short 显示更简洁的状态信息:

Bash
$ git status -s
 M README
MM Rakefile
A  lib/git.rb
M  lib/simplegit.rb
?? LICENSE.txt
字母含义
Mmodified,已修改
Aadded,新增并已暂存
Ddeleted,已删除
Rrenamed,重命名
Ccopied,复制
Uupdated but unmerged,冲突未解决
??untracked,未跟踪
!!ignored,被忽略

(五)忽略文件

如果不希望某类文件被 Git 自动添加 / 出现在 Untracked 列表中(如日志文件、构建文件),可创建 .gitignore 文件,列出带匹配文件的模式(pattern):

  • 空行 / 以 # 开头的行会被忽略;
  • 支持标准 glob 模式;
  • 正斜杠(/)开头的模式,禁止递归匹配。
  • 正斜杠(/)结束的模式,表示目录。
  • 感叹号(!)开头的模式,表示取反。
Bash
*.a            # 忽略所有 .a 文件
!lib.a         # 但跟踪 lib.a,即使上面忽略了 .a 文件
/TODO          # 只忽略当前目录下的 TODO 文件,而不是 subdir/TODO
build/         # 忽略任何名为 build 的目录中的所有文件
doc/*.txt      # 忽略 doc/notes.txt,但不忽略 doc/server/arch.txt
doc/**/*.pdf   # 忽略 doc/ 目录及其所有子目录中的所有 .pdf 文件

参考资料:

glob (programming) – Wikipedia
https://en.wikipedia.org/wiki/Glob_(programming)

GitHub 官方 .gitignore 模版库,涵盖了百余种不同项目和语言
https://github.com/github/gitignore