实验一 Git代码版本管理
实验目的:
1)了解分布式分布式版本控制系统的核心机理;
2)熟练掌握git的基本指令和分支管理指令;
实验内容:
1)安装git
2)初始配置git,git init statua指令
3)掌握git log,git add,git diff指令
4)掌握git tag git branch,git commit指令
5)掌握git revert指令
实验记录:
1.初次配置 Git
在开始使用 Git 之前,你需要配置 Git。在命令行工具中运行以下每行,确保所有选项都已被配置好。
# 设置你的 Git 用户名
# 设置你的 Git 邮箱
#确保 Git 输出内容带有颜色标记
# 对比显示原始状态
2.从头创建仓库
在对 Git 仓库进行 commit 或执行任何其他操作之前,需要一个实际存在的仓库。要使用 Git 新建一个仓库,我们将使用 git init 命令。
init 子命令是"initialize"(初始化)的简称,这个命令很有用
创建的过程中可能涉及如下命令
-
ls - 用来列出文件和目录
-
mkdir - 用来新建目录
-
cd - 用来更改目录
-
rm - 用来删除文件和目录
-
pwd -列出当前目录
创建项目目录
创建一个目录,叫做 se2020-git-course,在该目录中,创建另一个目录,叫做 new-git-project,使用 cd 命令移到 new-git-project
目录下可在终端上运行以下命令:
git init
可以开始使用 git init 命令了!这是最简单的命令之一。你只需在终端上运行 git init。
终端会显示 git init 命令正在运行。该命令会在当前目录下初始化生成一个空的 Git 仓库。
注意,运行 git init 之后,应该会出现一段文字:"Initialized empty Git repository in",后面提示符中出现了matser。运行 git init 命
令会初始化 Git 跟踪所有内容会用到的所有必要文件和目录。所有这些文件都存储在叫做 .git的目录下。这个 .git 目录是一个库!
Git 会将所有 commit 记录在这里,并跟踪所有内容!请勿直接修改 .git 目录下的任何文件。这是仓库的核心。如果你更改了文件
名或文件内容,Git 可能就无法跟踪你保存在仓库中的文件,你可能会丢失很多内容!可以查看这些文件,但是请勿编辑或删除这些文件。
克隆现有仓库
在 Git 上进行克隆的方法是调用我们将在终端上运行的命令 git clone,然后传入要克隆的 Git 仓库的路径(通常是 URL)。
首先需要验证终端位置,在克隆任何内容之前,确保命令行工具已定位于正确的目录下。克隆项目会新建一个目录,并将克隆的
Git 仓库放在其中。问题是无法创建嵌套的 Git 仓库。因此,确保终端的当前工作目录没有位于 Git 仓库中。如果当前工作目录没
有在 shell 的提示符中显示,输入 pwd 输出工作目录。
输入命令 git clone,然后输入你要克隆的 Git 仓库的路径。实验使用以下 URL :https://github.com/udacity/course-git-blog-project 。
完整命令是:
克隆过程中,第一行是"Cloning into 'course-git-blog-project'…"。Git 正在创建一个目录(名称与我们要克隆的项目一样),
并将仓库放在其中!其余输出结果基本都是验证信息——也就是统计远程仓库的项目数,然后压缩并接收这些项目,并解压。
如果需要换一个名称为 blog-project目录,可用
git clone https://github.com/udacity/course-git-blog-project blog-project
进入course-git-blog-project文件夹,在你喜欢的浏览器中打开 index.html 文件。可用看见已经克隆的blog网页。
判断仓库的状态
git status 是了解 Git 的核心所在。它将告诉我们 Git 正在考虑什么,以及 Git 所看到的我们仓库的状态。当你第一次使用
Git 时,你应该一直都要使用 git status 命令.你应该习惯于运行任何其他命令之后,都运行下该命令。这样可以帮助你了解
Git 的工作原理,并避免你对文件 / 仓库状态做出不正确的推论。
git log 命令
克隆course-git-blog-project 仓库后,使用命令行转到项目的目录下。
你可以看到 git status 的输出结果是:"nothing to commit, working directory clean",意味着我们可以继续并检出该项目了!
在你喜欢的代码编辑器中打开该项目。花几分钟时间看看项目,包括 CSS 和 JavaScript 文件,但是重点看一下 HTML 文件。
git log 命令用于显示仓库中所有 commit 的信息。
git log --oneline命令
-
每行显示一个 commit
-
显示 commit 的 SHA 的前 7 个字符
-
显示 commit 的消息
git log --stat
The git log 命令有一个选项可以用来显示 commit 中更改的文件以及添加或删除的行数。该选项为 --stat(stat 是“统计信息 statistics”的简称):
运行 git log --stat:
git log -p命令
git log 命令具有一个可用来显示对文件作出实际更改的选项。该选项是 --patch,可以简写为 -p:
$ git log -p
-
此命令会向默认输出中添加以下信息:
-
显示被修改的文件
-
显示添加/删除的行所在的位置
-
显示做出的实际更改
运行该命令并查看显示结果。
处理太多滚动操作
上一部分的最后几个练习需要在补丁(修改)输出中不断向下滚动,以便找到正确的 commit 并查看其信息。如果能显示
特定 commit 的详情,而不用关心仓库中的所有其他内容,是不是很棒?
实际上有两种实现方式!
-
向 git log 提供你要查看的 commit 的 SHA
-
使用新的 git show 命令
git log -p fdf5493
通过提供 SHA,git log -p 命令将从这条 commit 开始!无需滚动并逐条查阅!注意,它还会显示在所提供的 SHA 之前提
交的所有 commit 信息。
新命令 git show
git show fdf5493
上行上述示例命令将仅显示最近的 commit。通常,将 SHA 作为最后一个参数提供给命令:
git show 命令将仅显示一个 commit。因此,如果你看不到任何其他 commit,不要惊慌。它只显示一个 commit。git show
命令的输出和 git log -p 命令的完全一样。因此默认情况下,git show 会显示:
-
commit
-
作者
-
日期
-
commit 消息
-
补丁信息
3.git add& git commit&git diff
添加新文件,并使用git status 检查状态
进入到new-git-project (注意不是blog目录)
1)创建 HTML 文件
首先,创建一个叫做 index.html 的文件,并添加一些起始代码:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Blog Project</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<link rel="stylesheet" href="css/app.css">
</head>
<body>
<script src="js/app.js"></script>
</body>
</html>
2)建立 js 和css 文件夹,并在文件下分别建立 app.js 和 app.css 文件,文件内容可为空
暂存文件
在终端上运行以下命令,使用 git add 将 index.html 添加到暂存区:
运行 git add 命令没有任何输出(同样也没有错误)。如何让 git 告诉我们它执行了什么操作以及添加的 index.html 文件发
生了什么呢?git status 就可以告诉我们这些信息,在你对版本控制/命令行工具不是非常熟练的时期,要注重该命令。
暂存剩余的文件
index.html 文件已暂存。我们再暂存另外两个文件。现在我们可以运行以下命令:
$ git add css/app.css js/app.js
或者使用 git add . ( 句点指代当前目录,可以用来表示所有文件和目录(包括所有嵌套文件和目录!))。
提交 Commit
要在 git 中提交 commit,你需要使用 git commit 命令,但是先别运行这条命令。运行这条命令将会打开你在第一节课
配置的代码编辑器。
使用 -m 选项绕过编辑器
git log 命令和 git log --stas 命令检查刚刚提交的 commit。
git diff
通过使用 git status 命令我们可以知道哪些文件被更改了可是不会显示到底是什么样的更改,像这种情况我们通常可
以使用 git diff 命令。git diff 命令用来查看那些已被加入但是尚未提交的更改。该命令的显示格式通常为:
此命令会显示:
-
已经修改的文件
-
添加/删除的行所在的位置
-
执行的实际更改
gitignore
问题
假设你向项目所在目录添加了一个 Word 文档等文件,但是不希望将该文件添加到仓库中。git 会看到这个新文件,所以
在你运行 git status
时,它将显示在文件列表中。
通配符速成课程
假设你向项目中添加了 50 个图片,但是希望 git 忽略所有这些图片。这样的话,是否需要将每个文件名都列在 .gitignore
文件中呢?当然不用了,要不然太可怕了!相反,你可以采用一个叫做 通配符(英|中) 的概念。
通配符允许你使用特殊的字符来表示某些格式/字符。在 .gitignore
文件中,你可以使用:
-
空白行作为空格
-
#
- 将行标记为注释 -
*
- 与 0 个或多个字符匹配 -
?
- 与 1 个字符匹配 -
[abc]
- 与 a、b 或 c 匹配 -
**
- 与嵌套目录匹配 -a/**/z
与以下项匹配 -
a/z
-
a/b/z
-
a/b/c/z
gitignore 小结
总结下,.gitignore
文件用来告诉 git 不应跟踪的文件。该文件应该放在 .git
目录所在的目录
4.标签、分支
git tag 命令
注意所显示的结果(只需注意 SHA 和 commit 消息)
我们将使用 git tag 命令与仓库的标签进行交互,输入以下命令
上述命令将打开代码编辑器,并等待你为标签输入信息。我们输入"Ready for content"作为tag。
注意:在上述命令 (git tag -a v1.0
) 中,使用了 -a
选项。该选项告诉 git 创建一个带注释的标签。如果你没有提供该
选项(即 git tag v1.0
),那么它将创建一个轻量级标签。
建议使用带注释的标签,因为它们包含了大量的额外信息,例如:
-
标签创建者
-
标签创建日期
-
标签消息
验证标签
保存并退出编辑器后,命令行上什么也不会显示。那么如何知道已经向项目中添加了标签呢?只需输入 git tag
,命令行
会显示仓库中的所有标签。
我们已经验证了该标签位于仓库中,但是我们想知道它位于仓库的哪个位置。为此,我们需要调用一直在使用的 git log
!
删除标签
如果将标签消息中的某个字打错了,或标签名称打错了(输入 v0.1,而不是 v1.0),如何修正这个错误?最简单的方法是
删除这个标签并重新创建。
可以通过输入 -d 选项 (表示 delete 删除!)加上标签名称来删除 git 标签:
向以前的 commit 添加标签
运行 git tag -a v1.0
将为最近的 commit 添加标签。但是如果你想向仓库中很久之前的 Commit 添加标签呢?
只需提供要添加标签的 commit 的 SHA 即可!
先查询历史SHA git log --oneline,查找已经commit 的SHA
在弹出代码编辑器以便让你提供标签消息之后)此命令将向 SHA 为 eff5d50
的 commit 添加标签 v1.0
。借助这一技巧,
你可以为整个 git 仓库中的任何 commit 添加标签!很强大吧?并且只需在你已经知道的 git 标签命令中加上 commit 的 SHA 即可。
git branch 分支
理解分支的工作方式
现在该学习强大的分支功能了!git 中的分支非常灵活,使你能够实现一些很强大的功能。在详细了解一些具体的命令
之前,我们先从宏观层面了解下什么是分支以及它们的工作方式
git branch
命令
-
列出仓库中的所有分支名称
-
创建新的分支
-
删除分支
如果我们只输入 git branch
,则 git 将列出仓库中的分支:
创建分支
要创建分支,只需使用 git branch
并提供要创建的分支对应的名称。因此,如果你想创建一个叫做"sidebar"的分支,只需运行以下命令:
虽然你创建了 sidebar
分支,但是它还不是当前分支,目前提示符显示的是当前分支master。要使用该sidebar分支,你需要切换到该分支。
git checkout
命令
注意,在进行 commit 时,该 commit 将添加到当前分支上。虽然我们创建了新的 sidebar
分支,但是没有向其添加新的
commit,因为我们尚未切换到该分支。如果我们现在进行 commit 的话,该 commit 将添加到 master
分支,而不是 sidebar
分支。我们已经在演示中看到这一情况,要在分支之间进行切换,我们需要使用 git 的 checkout
命令。
请务必了解该命令的工作方式。运行该命令将:
-
从工作目录中删除 git 跟踪的所有文件和目录
-
(git 跟踪的文件存储在仓库中,因此什么也不会丢失)
-
转到仓库,并提取分支指向的 commit 所对应的所有文件和目录
因此此命令将删除 master 分支中的 commit 引用的所有文件。它会将这些文件替换为 sidebar 分支中的 commit 引用的文件。
理解这一部分十分重要,所以请务必多读几遍工作方式。
有趣的是,sidebar
和 master
都指向同一 commit,因此当你在这两个分支之间切换时,看起来什么也没变。但是提示符现在
会显示"sidebar":
提示符中的分支信息很有用,但是最清晰的查看方式是查看 git log
的输出结果。就像我们需要使用 --decorate
选项来显示
git 标签一样,我们也需要该选项来显示分支。
活跃分支
提示符将显示活跃分支。但这是我们对提示符进行的特殊自定义,如果你使用的是不同的计算机,判断活跃分支的最快速
方式是查看 git branch
命令的输出结果。活跃分支名称旁边会显示一个星号
删除分支
分支用来进行开发或对项目进行修正,不会影响到项目(因为更改是在分支上进行的)。在分支上做出更改后,你可以将该分支组合到 master
分支上(这种“分支组合过程”叫做“合并”(merge),稍后将详细讲解)
合并了分支的更改后,你可能不再需要该分支了。如果你想删除分支,可以使用 -d
选项。下面的命令包含 -d
选项,告诉 git 删掉给出的分支(这里是"sidebar"分支)。
注意,无法删除当前所在的分支。因此要删除 sidebar
分支,你需要切换到 master
分支,或者创建并切换到新的分支。
删除内容让人比较紧张。但是不用担心。
1)如果某个分支上有任何其他分支上都没有包含的 commit(也就是这个 commit 是要被删除的分支独有的),git 不会删除该分支。
2)如果你创建了 sidebar
分支,向其添加了 commit,然后尝试使用 git branch -d sidebar
删除该分支,git 不会让你删除该分支,因为你无法删除当前所在的分支。
3)如果你切换到 master
分支并尝试删除 sidebar
分支,git 也不会让你删除,因为 sidebar
分支上的新 commit 会丢失!要强制删除,你需要使用大写的 D 选项 - git branch -D sidebar
。
git branch 小结
总结下,git branch
命令用来管理 git 中的分支:
# 列出所有分支 $ git branch # 创建新的"footer-fix"分支 $ git branch footer-fix # 删除"footer-fix"分支 $ git branch -d footer-fix
此命令用来:
-
列出本地分支
-
创建新的分支
-
删除分支
高效分支
已经学会了如何创建、列出和删除分支,我们来运用下所学的知识吧!
首先,确保我们保持相同的进度,并拥有相同的起始代码。我们将在 new-git-project
项目中进行操作。该项目具有以下文件:
-
index.html
-
css/app.css
(空文件) -
js/app.js
(空文件)
为开始后面实验,执行以下操作( 具体命令自己回忆一下 ):
1) 删除 前面建好的 siderbar 分支。
2)所有文件暂存并提交到仓库
3)切换到master分支
4)运行git status, 确认出现 working tree clean 或 working directory clearn
分支实战
现在,所有代码都位于 master
分支(默认分支)上。我们通过以下操作利用分支进行工作:
-
向分支中添加内容
-
创建新的分支
-
在分支之间切换
让我们使用分支完成以下更改:
-
在 master 分支上 - 向页面添加默认颜色
-
创建一个 sidebar 分支 - 为页面创建侧栏
-
在 master 分支上 - 更改页面的标题
-
在 sidebar 分支上 - 向侧栏中添加更多内容
-
创建一个 footer 分支 - 向脚注中添加社交链接、
合并
主题分支(例如 sidebar
)的作用是让你做出不影响 master
分支的更改。当你在主题分支上做出更改后,如果觉得不想要该分支上的更改,则可以删掉该分支,或者你决定要保留更改,则可以将该分支上的更改与其他分支上的更改合并。
将分支组合到一起称为合并。
git 可以自动将不同分支上的更改合并到一起。这种分支和合并功能正是 git 的强大之处!你可以在分支上做出小的或大的更改,然后使用 git 合并这些更改。
我们来看看理论原理。注意 git 中的两种合并:普通合并和快进合并。
发生合并时,git 将:
-
查看将合并的分支
-
查看分支的历史记录并寻找两个分支的 commit 历史记录中都有的单个 commit
-
将单个分支上更改的代码行合并到一起
-
提交一个 commit 来记录合并操作
撤销更改
向 commit 中添加忘记的文件
此外,git commit --amend
使你能够包含忘记包含的文件(或文件更改)。假设你更新了整个网站的导航链接颜色。commit 了该更改,并以为完事了。但是后来发现深藏在页面上的一个特殊导航链接没有新的颜色。你可以执行新的 commit 并更新该链接的颜色,但是这样就会出现两个 commit 执行完全相同的任务(更改链接颜色)。
相反,你可以修改最后一个 commit(更新所有其他链接颜色的 commit)以包含这个忘记的链接。要包含忘记的链接,只需:
-
编辑文件
-
保存文件
-
暂存文件
-
运行
git commit --amend
你可对必要的 CSS 和/或 HTML 文件作出了更改,以便修正被遗忘的链接样式,然后保存所有被修改的文件,并使用 git add
暂存所有被修改的文件(就像要提交新的 commit 那样!),但是你也可以选择运行 git commit --amend
来更新最近的 commit,而不是创建新的 commit。
实验总结与体会:
通过本次实验z掌握git的基本指令和分支管理指令,本次实验主要是验证性实验,通过git的指令提示完成本次实验,虽然指令较多,花费时间多点,但是掌握了就觉得git还是很有趣的。
思考题:
阅读维基百科和百度百科的git词条,总结分布式分布式版本控制系统的核心机理?
答:本质上,Git是一套内容寻址(content-addressable)文件系统,而和我们直接接触的Git界面,只不过是封装在其之上的一个应用层。这个关系颇有点类似于计算机网络中应用层和下属层的关系。在Git中,那些和应用层相关的命令(也就是我们最常用的命令,如git commit、 git push等),我们称之为porcelain命令(瓷器之意,意为成品、高级命令);而和底层相关的命令(几乎不会在日常中使用,如git hash-object、git update-index等),则称之为plumbing命令(管道之意,是连接git应用界面和git底层实现的一个管道,类似于shell,底层命令)。要了解Git的底层原理,就需要了解Git是如何利用底层命令来实现高层命令的。在此之前,让我们先来看一下Git的目录结构,和各个文件在Git中的作用。