Git 学习笔记

Introduction to Git for Data Science Course 学习笔记 ~

一、基本工作流程

本章介绍了什么是版本控制以及为什么要使用它,并介绍了常见 Git 工作流程中最常见的步骤。

1. 什么是版本控制(version control)

一个版本控制系统是管理在项目中的文件和目录的更改的工具。

2. Git 在哪里存储信息

一个 Git 项目包括两个部分:文件和目录以及项目历史记录,这两者合称为一个仓库(repository)。
Git 将所有项目历史记录保存在根目录中名为 .git 的文件中。

3. 检查仓库的状态

运行 git status 命令,显示自上次保存更改以来已修改的文件列表。

4. 我怎么知道改变了什么

Git 有一个暂存区域(staging area)保存着将要提交的更改的文件。git status 显示哪些文件位于暂存区域以及哪些文件已经被更改但还未被放进暂存区域。为了比较当前文件和最后一次保存的文件,可以使用 git diff filename。使用 git diff 显示仓库中所有更改的文件,使用 git diff directory 显示指定目录下所有更改的文件。

5. diff 是什么

一个 diff 是两个文件之间差异的显示格式。Git 显示 diff 类似:

1
2
3
4
5
6
7
8
9
diff --git a/report.txt b/report.txt
index e713b17..4c0742a 100644
--- a/report.txt
+++ b/report.txt
@@ -1,4 +1,4 @@
-# Seasonal Dental Surgeries 2017-18
+# Seasonal Dental Surgeries (2017) 2017-18

TODO: write executive summary.

6. 保存更改的第一步

向 Git 仓库提交更改包含两步:

  1. 添加一个或多个文件到暂存区域。
  2. 提交暂存区域的所有东西。

添加一个文件到暂存区域,使用 git add filename

7. 如何知道将要发生什么

比较文件状态和暂存区域的状态,使用 git diff -r HEAD-r 表示与特定版本比较,HEAD 表示最近的提交。可以使用 git diff -r HEAD path/to/file 指定单个文件。

8. 提交更改

在暂存区域提交所有更改,使用 git commit 。当提交更改时,Git 要求输入一个日志信息(log message),使用 git commit -m "some message in quotes"。如果需要更改日志信息,使用 git commit --amend -m "new message"

9. 查看仓库历史记录

使用 git log 查看项目的历史记录,首先会显示最近的历史记录,类似:

1
2
3
4
5
commit 0430705487381195993bac9c21512ccfb511056d
Author: Rep Loop <repl@datacamp.com>
Date: Wed Sep 20 13:42:26 2017 +0000

Added year to report title.

commit 行显示唯一的提交的 ID,是一个哈希值(hash)。

10. 查看特定文件的历史记录

使用 git log pathpath 是特定的文件或目录。文件的日志显示对该文件的更改,目录的日志显示在该目录中添加或删除文件的时间。

11. 编写更好的日志信息

编写单行日志信息 git commot -m "message" 非常适合进行小的更改。使用 git commit ,不带 -m "message" , Git 会启动一个文本编辑器,可以编写更好信息,模版如下:

1
2
3
4
5
6
7
8
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch master
# Your branch is up-to-date with 'origin/master'.
#
# Changes to be committed:
# modified: skynet.R
#

# 是注释。

二、仓库

本章深入探讨了 Git 如何存储信息以及如何探索仓库的历史记录。

1. Git 如何存储信息

Git 使用三级结构:

  1. commit 包括作者等元数据,提交的日志信息,提交时间等。
  2. 每个提交有一个 tree, 它发生在提交时跟踪仓库中的名称和位置。
  3. 对于 tree 中列出的每个文件都有一个 blob,包含提交发生时文件内容的压缩快照。如果在该提交中没有更改,tree 链接到上一次提交的 blob。这样有助于快速执行常见操作并最大限度地减少存储空间。

2. 哈希是什么

每次提交到仓库都有一个称为哈希的唯一标识符(因为它是通过称为哈希函数的伪随机数生成器运行更改而生成的)。这个散列通常写成40个字符的十六进制字符串 7c35a3ce607a14953f070f0f83b5d74c2296ef93 ,但大多数情况下,只需要给 Git 前6或8个字符。

哈希使 Git 能够在仓库之间有效地共享数据。如果两个文件相同,则它们的哈希值保证相同。同样,如果两个提交包含相同的文件并具有相同的祖先,则它们的哈希值也是相同的。因此,通过比较哈希而不是比较整个文件,Git 可以告诉需要保存哪些信息。

3. 查看特定的提交

要查看特定提交的详细信息,使用 git show 带有提交哈希的前几个字符的命令。例如,该命令 git show 0da2f7 产生:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
commit 0da2f7ad11664ca9ed933c1ccd1f3cd24d481e42
Author: Rep Loop <repl@datacamp.com>
Date: Wed Sep 5 15:39:18 2018 +0000

Added year to report title.

diff --git a/report.txt b/report.txt
index e713b17..4c0742a 100644
--- a/report.txt
+++ b/report.txt
@@ -1,4 +1,4 @@
-# Seasonal Dental Surgeries 2017-18
+# Seasonal Dental Surgeries (2017) 2017-18

TODO: write executive summary.

4. Git 相对路径的等价形式

哈希就像一个绝对路径:它标识一个特定的提交。识别提交的另一种方法是使用相对路径的等价物。

HEAD 特殊标签总是指最近的提交。然后标签 HEAD~1 引用它之前的提交,同时 HEAD~2 引用之前的提交,依此类推。

5. 查看谁更改了文件

git annotate file 显示谁对文件的每一行进行了最后一次更改以及何时进行。每行结果包括5项:

  1. 哈希值的前八位
  2. 作者
  3. 提交时间
  4. 更改的行号
  5. 更改内容

6. 如何查看两次提交之间的变化

带有提交 ID 的 git show ID 显示一个特定提交的更改。查看两个提交之间的更改,使用 git diff ID1..ID2

7. 添加新文件到暂存区域

Git 默认不跟踪文件,它会等到使用 git add 之后开始关注之前至少使用过一次的文件。git status 始终显示仓库中尚未被跟踪的文件。

8. 使 Git 忽略某些文件

数据分析通常会生成你不想保存的临时或中间文件。你可以告诉 Git 停止关注你不关心的文件,方法是在仓库的根目录中创建一个文件 .gitignore 并存储一个通配符模式列表,指定你不希望 Git 关注的文件。

9. 删除不需要的文件

Git 可以删除不需要的文件。使用 git clean -n 显示存储库中的文件列表,使用 git clean -f 删除这些文件。 git clean 仅适用于未跟踪的文件。

10. 查看 Git 的设置

使用 git config --list 带上下面三个选项之一查看:

  • --system :此计算机上每个用户的设置
  • --global :每个项目的设置
  • --local :一个特定性项目的设置

以上优先级从低到高。

11. 更改 Git 的设置

通常需要设置两项个人信息:姓名和电子邮件。这些会在每次提交更改时记录在日志中。更改特定计算机上所有项目的配置值:

1
2
git config --global user.name itroger
git config --global user.email itroger@outlook.com

三、撤销

由于 Git 会保存对文件所做的所有更改,因此可以使用它来撤消这些更改。本章展示了几种方法。

1. 有选择地提交更改

不必将最近所做的所有更改一次性放入暂存区域。例如,假设你要添加一个功能 analysis.R ,并发现一个错误 cleanup.R 。修复后,想保存你的工作。由于更改 cleanup.R 与正在进行的 analysis.R 工作没有直接关系,因此应该将工作保存在两个单独的提交中。

添加单个文件到暂存区域使用 git add path/to/file

如果需要撤销添加则使用 git reset HEAD

2. 重新保存到暂存区域

人们在使用桌面文本编辑器时,每隔几分钟就会经常保存他们的工作。同样,通常定期使用 git add 将文件的最新更改保存到暂存区域。当更改是实验性的并且你可能想要撤消它们而不会使仓库的历史记录混乱时,这尤其有用。

3. 撤销对未保存到暂存区域文件的更改

使用 git checkout -- filename

4. 撤销对暂存文件的更改

使用 git reset 撤销文件的 git add 操作。通过结合 git resetgit checkout 可以撤销对暂存文件的更改。

1
2
git reset HEAD path/to/file
git checkout -- path/to/file

5. 恢复旧版本的文件

使用 git checkout 撤销自上次提交以来所做的更改。此命令还可用于返回文件的历史记录,并从提交中恢复该文件的旧版本。还原旧版本的语法有两个参数:标识要还原版本的哈希值和文件名。

6. 撤销所有的更改

使用 git reset HEAD path/to/file 撤销对单个文件的更改。撤销对多个文件的更改,一种方式是 git reset HEAD data 这将撤销 data 目录下所有文件的更改。另一种方式,直接使用 git reset 将撤销所有的更改。同样使用 git checkout -- data 将恢复 data 目录下的所有文件。也可以使用 git checkout -- . 恢复所有的文件。

四、分支

分支(branch)是 Git 最强大的功能之一,因为它允许你同时处理多个事务而不会羁绊自己。本章介绍如何创建和管理分支。

1. 什么是分支

Git 受欢迎的原因之一是支持创建分支,这使你可以拥有多个版本的工作,并允许你系统地跟踪每个版本。每个分支都是并行的,互不影响,直到将它们
合并回来。

2. 查看仓库中的分支

默认情况下,每个 Git 仓库都有一个主分支 master ,要列出仓库中的所有分支,使用 git branch 。当前所在的分支将用 * 标记。

3. 查看分支之间的差异

分支和修订是紧密相连的,对后者起作用的命令通常适用于前者。例如,git diff revision-1..revision-2 显示仓库的两个版本之间的差异一样, git diff branch-1..branch-2 也显示了两个分支之间的差异。

4. 切换分支

使用 git checkout hash 将仓库状态切换到该哈希值。还可以使用 git checkout branch 切换到该分支。

5. 创建分支

  • 使用 git branch branch-name 创建一个分支
  • 使用 git checkout -b branch-name 创建一个分支并切换到该分支

6. 合并两个分支

使用 git merge source destination 合并两个分支,Git 会自动打开一个编辑器,以便为合并编写日志信息,可以保留其默认信息或填写更多信息。

7. 什么是冲突

有时两个分支的更改会相互冲突:例如,bug 修复触及同一行代码。

8. 合并两个冲突分支

在合并期间发生冲突时,Git 会提示存在的问题,在合并后运行 git status 会显示哪些文件存在冲突,需要解决 both modified: filename 的冲突。

五、合作

本章介绍了 Git 的另一个最大特点:如何在仓库之间共享更改以进行大规模协作。

1. 创建一个新的仓库

使用 git init project-name 创建一个新的仓库。

2. 将现有项目转换为 Git 仓库

  • 在项目的根目录运行 git init
  • 在任何地方运行 git init /path/to/project

3. 创建现有仓库的副本

克隆一个仓库,运行 git clone URL

4. 克隆仓库的来源

  • 使用 git remote 显示来源的名称
  • 使用 git remote -v 显示来源的名称和 URL

5. 定义远程

  • 添加远程:git remote add remote-name URL
  • 删除远程:git remote rm remote-name

6. 从远程仓库拉取更改

Git 会跟踪远程仓库,以便可以从这些仓库中拉取更改并将更改推送到仓库。
拉取请求,运行 git pull remote branch 可以从远程 remote 仓库中拉取所有文件到本地 branch 仓库。

7. 在未保存的更改中拉取更改

正如 Git 阻止你在未保存的工作时切换分支一样,它也会阻止你从远程仓库中拉取更改,这样做可能会覆盖你在本地完成的操作。修复很简单:提交本地更改或还原它们,然后尝试再次提取。

8. 推送更改到远程仓库

在本地进行的更改推送到远程仓库,运行 git push remote-name branch-name

9. 推送冲突

为了防止这种情况发生,Git 不允许你将更改推送到远程存储库,除非您你将远程存储库的内容合并到你自己的工作中。

-------------本文结束 感谢您的阅读-------------
您的支持将鼓励我继续创作!