软件工程 实验一 Git版本管理

 

实验目的:

1)了解分布式分布式版本控制系统的核心机理;

2)   熟练掌握git的基本指令和分支管理指令;

实验内容:

1)安装git

2)初始配置git ,git init git status指令

3)掌握git log ,git add ,git diff 指令

4) 掌握git tag git branch,git commit 指令

5)掌握git revert 指令

实验记录:

1)实验内容以及结果的截图:

2)实验过程中发生的问题与解决。

4.1.4 从头创建仓库

  在进行 Git 仓库的创建之前我们首先需要进行的就是项目目录的创建,

创建项目目录

  在我的F盘下创建一个叫做 se2020-git-course 的目录,在该目录中再创建另一个叫做 new-git-project 的目录并使用 cd 命令移到 new-git-project 目录下。代码如下图:

创建仓库

  在对 Git 仓库进行 commit 或执行任何其他操作之前都需要一个实际存在的仓库。要使用 Git 新建一个仓库,我们将使用 git init 命令来完成仓库的创建。代码如下图:

克隆现有仓库

  首先需要验证终端所在的位置。在克隆任何内容之前都需要确保命令行工具已定位于正确的目录下。克隆项目会新建一个目录,并将克隆的 Git 仓库放在其中。问题是无法创建嵌套的 Git 仓库。因此,确保终端的当前工作目录没有位于 Git 仓库中。在 Git 上进行克隆的方法是调用我们将在终端上运行的命令 git clone,然后传入要克隆的 Git 仓库的路径(通常是 URL)。代码及运行结果如下图:

查看克隆后仓库的状态

  git status 是了解 Git 的核心所在。它将告诉我们 Git 正在考虑什么,以及 Git 所看到的我们仓库的状态因此可利用 git status 命令来随时查看当前仓库的状态。代码及运行结果如下图:

*git statu命令拓展

  git status 命令将显示很多信息,具体取决于你的文件状态、工作目录和仓库。但是你不需要过于关心这些内容…只需运行 git status,它将显示你需要知道的信息。

输出结果告诉了我们几条信息:

  • On branch master – 这部分告诉我们 Git 位于 master 分支上,(也就是默认分支)。

  • Your branch is up-to-date with 'origin/master'. – 因为我们使用 git clone 从另一台计算机上复制了此仓库,因此这部分告诉我们项目是否与所复制的仓库保持同步状态。我们不会在其他计算机上处理该项目,因此这一行可以忽略。

  • nothing to commit, working directory clean – 表示没有任何待定的更改。

  可以将这一输出结果看作“休息状态(resting state)”。代码及运行结果如下图:

  上图是在已经具有 commit 的仓库中运行 git status 之后的状态。我们切换到一个空目录中运行 git status 命令。在结果中出现清晰明了的 "No commits yet"(尚未有任何提交)。代码及运行结果如下图:

4.1.5 git log

git log命令

   git log 命令用于显示仓库中所有 commit 的信息。默认情况下该命令会显示仓库中每个 commit 的:SHA、作者、日期、消息等。代码及运行结果如图:

git log --oneline命令

  我们可以使用 git log --oneline 命令以不同的格式风格来代替 git log 的输出,相比较而言 git log --oneline的输出结果更为简短并且可以节省大量空间。

  git log --oneline命令的显示格式通常为:

  • 每行显示一个 commit

  • 显示 commit 的 SHA 的前 7 个字符

  • 显示 commit 的消息

·  git log --oneline 命令的代码及运行结果如下图:

git log --stat命令

   git log --stat命令可以用来显示 commit 中更改的文件以及添加或删除的行数。(stat 是“统计信息 statistics”的简称)

   git log --stat命令的显示格式通常为:

  • 显示被修改的文件

  • 显示添加/删除的行数

  • 显示一个摘要,其中包含修改/删除的总文件数和总行数

  git log --stat 命令的代码及运行结果如下图:

查看更改 

git log -p 命令

  git log -p 命令是一个可用来显示对文件作出实际更改的命令。( -p 是 --patch 的简写)。

  git log -p 命令通常会向默认的输出中添加以下信息:

  • 显示被修改的文件

  • 显示添加/删除的行所在的位置

  • 显示做出的实际更改

  代码及运行结果如下图:

git show 命令

  通过以上的各个命令的实验过程会发现,上面的命令在执行结束之后需要在补丁(修改)输出中不断向下滚动,以便找到正确的 commit 并查看其信息。能够显示特定 commit 的详情,而不用关心仓库中的所有其他内容。git show 命令通常将 SHA 作为最后一个参数提供给命令。(例如:git log -p fdf5493)git show 命令的输出和 git log -p 命令的完全一样。因此默认情况下,git show 也会显示:commit、作者、日期、commit 消息、补丁信息。代码及运行结果如下图:

 4.1.6 git add& git commit&git diff

准备工作

  首先在new-git-project目录下创建一个叫做 index.html 的文件,并添加一些起始代码之后分别建立 js 和css 文件夹,并在文件下分别建立 app.js 和 app.css 文件,文件内容可为空。准备工作完成之后利用 git status 命令查看长裤状态。代码及运行结果如下图:

git add 命令

   若想要将文件提交到仓库中,首先需要将这些文件从工作目录移到暂存区。可以利用 git add 命令来完成相关操作。在终端上运行 git add 命令将 index.html 添加到暂存区中,代码及运行结果如下图:

  与添加index.html相同,我们将目录下的其他文件利用 git add 命令也一同放入到暂存区中。完成之后利用 git status 命令查看当前仓库状态。代码及运行结果如下图:

git commit 命令

  使用 git commit 命令将暂存区中的文件进行提交。代码及运行结果如下图:

   完成代码的提交之后利用 git status 命令再次查看仓库状态。代码及运行结果如下图:

 使用 -m 选项绕过编辑器

  先使用 git add 命令将文件移到暂存区,并使用 git status 验证文件是否位于暂存区,使用 git commit 命令提交 commit,并添加提交说明 Add header to blog。代码及运行结果如下图:

   使用 git log 命令和 git log --stas 命令检查刚刚提交的 commit。代码及运行结果如下图:

 git diff

  通过使用 git status 命令我们可以知道哪些文件被更改了可是不会显示到底是什么样的更改,像这种情况我们通常可以使用 git diff 命令。git diff 命令用来查看那些已被加入但是尚未提交的更改。该命令的显示格式通常为:

  • 已经修改的文件

  • 添加/删除的行所在的位置

  • 执行的实际更改

  代码及运行结果如下图:

 git ignore 命令

  在我们的项目目录中如果有其他文件并且我们并不想将其提交到仓库中这是如果再使用 git add .命令来添加所有文件就会非常不方便。遇到这种想将某个文件保留在项目的目录结构中并且确保它不会意外地提交到项目当中,可以使用名称特殊的文件 .gitignore (文件名开头的点,很重要!)。我们将希望忽略的文件(例如:project.docx)写出到  .gitignore 中。当面对许多文件需要忽略的情况时可以另外使用通配符来配合完成。通俗的说,git ignore 命令的功能就是告诉 git 不应跟踪哪些文件。代码及运行结果如下图:

4.1.7 标签、分支

git  tag命令(标签)

  git tag 命令用来标记特定的 commit ,在添加新的 commit 时标签不会移动。下面我们从宏观层面了解下 git 标签在仓库中的作用。首先查看项目使用 git log 的效果,代码及运行结果如下图:

  注意上图所显示的结果(只需注意 SHA 和 commit 消息)我们将使用 git tag 命令与仓库的标签进行交互。在终端输入:git tag -a v1.0。该条命令将打开代码编辑器,并等待用户为标签输入信息。我们输入"Ready for content"作为tag。代码及运行结果如下图:

 *上面采用的命令带有 -a 打开编辑器为一个带注释的标签。我们也可以不适用 -a 此时它将创建一个轻量级的标签。建议使用前者即带注释的标签。

  验证标签:保存并退出编辑器后,终端界面上什么也不会显示。我们只需要往项目中输入 git tag 命令就可以知道我们添加了的所有标签。代码及运行结果如下图:

   查看标签:使用 git log 命令查看标签位于仓库的哪个位置。下图中的输出结果显示的 tag: v1.0 这就是标签!标签与 commit 相绑定。因此,该标签与 commit 的 SHA 位于同一行。代码及运行结果如下图:

  删除标签:如果我们将标签消息中的某个字打错了或标签名称打错了(输入 v0.1,而不是 v1.0)最简单的方法是删除这个标签并重新创建。可以通过输入 git tag -d 命令来删除 这个错误的标签名(例如:git tag -d v1.0)。代码及运行结果如下图:

 *向以前的 commit 中添加标签:git tag -a 命令给一般直接向最近的 commit 添加标签,但如果用户提供了 SHA,命令则向具体的 commit 添加标签。以 SHA 为 574dff7 为例,代码及运行结果如下图:

 git branch标签(分支)

   git 中的分支非常灵活,能够实现一些很强大的功能。而git branch 命令则是用来与 git 的分支进行交互的。通常包括:列出仓库中的所有分支名称、创建新的分支、删除分支。如果我们只输入 git branch 命令,终端将列出仓库中的所有分支。代码及运行结果如下图:

   创建分支:我们只需要使用 git branch 命令并提供要创建分支对应的名称。但是同时需要注意的是新创建的分支它不是当前系统分支。提示符显示的才是当前分支master。要使用新创建的 sidebar 分支,我们需要使用 git checkout 命令手动的切换到该分支。以创建 sidebar 的分支为例,代码及运行结果 如下图:

*对于 git checkout 命令请务必了解该命令的工作方式。运行该命令执行时首先:从工作目录中删除 git 跟踪的所有文件和目录(git 跟踪的文件存储在仓库中,因此什么也不会丢失)。之后:再转到仓库中并提取分支指向的 commit 所对应的所有文件和目录。由于命令的执行方式,因此此命令将删除 master 分支中的 commit 引用的所有文件,它会将这些文件替换为 sidebar 分支中的 commit 引用的文件。

  仔细的观察可以发现当执行完 git checkout 命令之后提示符会开始显示 sidebar。我们可以使用 git log --oneline 命令来清晰的观察提示符中的有关分支的有用信息。特殊指示符"HEAD"具有一个指向 sidebar 分支的箭头。它指向 sidebar 是因为 sidebar 分支是当前分支,现在提交的任何 commit 将添加到 sidebar 分支。代码及运行结果 如下图:

   活跃分支:提示符通常显示活跃分支。但这是我们对提示符进行的特殊自定义,如果你使用的是不同的计算机,我们可以通过最快速的 git branch 命令的方式来判断活跃分支。(活跃分支名称旁边会显示一个星号)代码及运行结果如下图:

   删除分支:如果我们不再需要某个分支时我们可以使用 git branch -d 命令来完成。但时 git 中对分支的删除有很严格的限制,只有满足了这些限制删除操作才能完成。如果某个

  • 将要删除的分支上有任何其他分支上都没有包含的 commit(也就是这个 commit 是将要被删除的分支所独有的),git 不会删除该分支。
  • 如果我们创建了 sidebar 分支并向其添加了 commit 然后尝试使用 git branch -d 命令删除该分支。git 不会让你删除该分支,因为我们无法删除当前所在的分支。
  • 如果我们切换到 master 分支并尝试删除 sidebar 分支,git 也不会让你删除,因为 sidebar 分支上的新 commit 会丢失!如果要强制删除则需要使用大写的 -D ,即 git branch -D 。代码及运行结果如下图:

 高效分支

  基础操作:我们首先需要在当前目录的基础上进行四步操作,分别为:删除 前面建好的 siderbar 分支、所有文件暂存并提交到仓库、切换到master分支、运行git status, 确认出现  working tree clean 或 working directory clearn。代码及运行结果如下图:

   分支实战:通过上面的基础操作之后,现在我们的左右代码都位于 master 分支上了。现在我们使用分支来完成一下各项更改:

  • 在 master 分支上向页面添加默认颜色:首先想 css 文件夹下的 app.css 文件中加入设置背景色的代码然后保存文件并将该文件添加到暂存区再将其 commit 到仓库。 commit 的内容写为:Set background color for page ,最后通过git log --oneline 命令来检查 commit 记录。代码及运行结果如下图:

  • 创建一个 sidebar 分支为页面创建侧栏:假定我们并不确定是否喜欢新的背景色。因此我们要将 sidebar 分支放在设置页面颜色的 commit 之前。以确保我们更容易的更改操作。根据上图中 git log --oneline 命令执行的结果来看,我们将 sidebar 分支设置哎 SHA 为 574dff7 上(即运行 git branch sidebar 574dff7)。之后运行 git checkout 命令切换到新的 sidebar 分支上再运行 git log --oneline。代码及运行结果如下图:

  • 在 master 分支上更改页面的标题:我们将 <aside> 内容添加到 <main> 元素旁边,作为 <div class = "container"> 元素的子级。在 <aside> 标签中添加 This a message ! 所有操作完毕之后我们可以 commit 任何更改。代码及运行结果如下图:

  *特别提醒:千万不要更改 CSS 文件。否则会出现“合并冲突”(merge conflict)。

  • 在 master 分支上更改页面的标题:使用 git branch master 命令切换到 master 分支上。需要特别注意的是,由于所有代码都妥善地保存在 sidebar 分支上故当切换到 master 分支时新的侧栏的相关 HTML 已经不在了!我们将 index.html 中的<H>标题从之前的"Expedition"改为"Adventure"。保存 index.html 文件并进行 commit 以将此更改添加到仓库中(将 commit 消息设为"Improve site heading for SEO"),提交用git log --oneline 命令检查仓库。代码及运行结果如下图:

  •  同时查看所有分支:到目前为止我们已经在三个不同的分支上进行了多项更改。我们知道可以使用 git log 命令来查看分支的各种信息但是去只能局限于当前的分支。这里我们可以使用 git log 的几个新的选项。--graph 选项将条目和行添加到输出的最左侧,显示了实际的分支。--all选项会显示仓库中的所有分支。

    运行此命令将显示仓库中的所有分支和 commit。代码及运行结果如下图:

合并

  当你在主题分支上做出更改后,如果觉得不想要该分支上的更改,则可以删掉该分支,或者你决定要保留更改,则可以将该分支上的更改与其他分支上的更改进行合并。git 可以自动将不同分支上的更改合并到一起。这种分支和合并功能正是 git 的强大之处!你可以在分支上做出小的或大的更改,然后使用 git 合并这些更改。发生合并时,git 将:查看将合并的分支、查看分支的历史记录并寻找两个分支的 commit 历史记录中都有的单个 commit、将单个分支上更改的代码行合并到一起、提交一个 commit 来记录合并操作。代码及运行结果如下图:

commit 合并冲突

  大部分情况下,git 将能够成功地合并分支。但是,有时候 git 无法完全自动地进行合并。合并失败时,就称为合并冲突。大部分情况下,git 将能够成功地合并分支。但是,有时候 git 无法完全自动地进行合并。合并失败时,就称为合并冲突。代码及运行结果如下图:

合并冲突小结

  当相同的行在要合并的不同分支上做出了更改时,就会出现合并冲突。git 将在合并途中暂停,并告诉你存在冲突,以及哪些文件存在冲突。要解决文件中的冲突需要:找到并删掉存在合并冲突指示符的所有行、决定保留哪些行、保存文件、暂存文件、提交 commit。代码及运行结果如下图:

*解决合并冲突

  git 使用合并冲突指示符来告诉我们两个不同分支上的哪些行导致了合并冲突,以及原始行是什么。要想解决合并冲突,我们需要:选择保留哪些行以及删掉所有带指示符的行。

git commit --amend命令

  上面的合并冲突中通过将标题设为Advanture Quest解决了该冲突。现在可以通过 git commit --amensd 命令将标题更改为 Quests & Crusades来解决冲突。代码及运行结果如下图:

 

 git revert 命令

  当我们创建了一个包含一些更改的 commit,我们可以使用 git revert 命令来还原它。代码及运行结果如下图:

 

 相关 commit 引用

  我们可以使用 SHA、标签、分支和特殊的 SEAD 指针引用 commit。有时候这些并不足够,你可能需要引用相对于另一个 commit 的 commit。我们可以使用特殊的“祖先引用”字符来告诉 git 这些相对引用。这些字符为:^ 表示 父commit 、~ 表示第一个父 commit。两者区别主要体现在通过合并而创建的 commit 中。合并 commit 具有两个父级。对于合并 commit,^ 引用用来表示第一个父 commit,而 ^2 表示第二个父 commit。第一个父 commit 是当你运行 git merge 时所处的分支,而第二个父 commit 是被合并的分支。一下是我自己运行 git log --oneline --graph --all 命令的结果:

git reset 命令

  我们通常使用 git reset 命令用来重置(清除)commit。主要包括:将 HEAD 和当前分支指针移到目标 commit、清除 commit、将 commit 的更改移到暂存区、取消暂存 commit 的更改。git 根据所使用选项来判断是清除、暂存之前 commit 的更改,还是取消暂存之前 commit 的更改。这些选项包括:使用 --hard 选项清除 commit、使用 --soft 选项将 commit 的更改移至暂存区、使用 --mixed选项取消暂存已被 commit 的更改。

  git reset -mixed 命令执行后结果如下图:

备份分支

  注意,使用git reset 命令将清除当前分支上的 commit。因此,如果你想跟着操作接下来出现的所有重置操作,需要在当前 commit 上创建一个分支,以便用作备份。

在进行任何重置操作之前,我通常会在最近的 commit 上创建一个 backup 分支,因此如果出现错误,我可以返回这些 commit。

实验总结与体会:

  整个实验围绕 gIt 的各种命令的实际应用背景展开,通过在一个个实例中去深刻理解命令的用途及含义。这种需求推动知识的学习方法让我在解决一个又一个实际问题中既获得了成就感也学会了各种命令。但是这次的实验是验证型实验整体没有太高的难度但是需要花一定的时间去完成每一个分模块,特别是当自己运行的结果与自己预期的不同时需要花费大量的时间去查找错误原因。所以从整个实验过程来看,虽然实验结束了但是各种知识点也仅仅的有所了解,只有通过课后的进一步巩固强化才能更好的吸收和消化实验的真个内容。

思考题:

  Q:总结分布式版本控制系统的核心机理

  分布式版本控制系统是一种有效、高速地处理从很小到非常大的项目版本管理系统。与它相对的是集中式版本控制系统。在分布式版本控制系统中客户端并不像集中式版本控制系统那样提取最新版本的文件快照,而是把代码仓库完整地镜像下来。这样的核心机理就轻松的解决了集中式版本控制系统中容易出现的也是很致命的中央服务器单点故障。分布式版本控制系统没有所谓的"中央服务器",每个人的电脑上都是一个完整的版本库。通常分布式版本控制系统有一台"伪中央服务器",但是这个服务器的作用仅仅是用来方便"交换"大家的修改,没有它大家仍然可以正常工作。

posted @ 2020-02-19 16:18  薄言襭之  阅读(575)  评论(2编辑  收藏  举报