Git实战(实验楼)学习笔记 实验2 基本用法(下)

一、实验介绍

 

本节实验为 Git 入门第二个实验,继续练习最常用的 Git 命令。

知识点

  • 对比差异

  • 分布式的工作流程

  • Git 标签

实验环境

实验环境为 Ubuntu Linux 命令行环境,需要了解基本的 Linux 操作,如果没有使用过 Linux 的同学,推荐先学习 Linux 基础入门 前三个实验。

实验准备

在进行该实验之前,可以先 clone 一个练习项目 gitproject :

Git实战(实验楼)学习笔记 实验2 基本用法(下)

本节中的实验操作都是在该项目中完成。

 

 

二、比较内容

 

下面将学习如何比较提交,分支等内容。

 

2.1 比较提交 git diff

现在我们对项目做些修改:

Git实战(实验楼)学习笔记 实验2 基本用法(下)

使用 git status 查看当前修改的状态:

Git实战(实验楼)学习笔记 实验2 基本用法(下)

可以看到一个文件修改了,另外一个文件添加了。如何查看修改的文件内容呢,那就需要使用 git diff 命令。git diff 命令的作用是比较修改的或提交的文件内容。

Git实战(实验楼)学习笔记 实验2 基本用法(下)

上面的命令执行后需要使用 q 退出。命令输出当前工作目录中修改的内容,并不包含新加文件,请注意这些内容还没有添加到本地缓存区。

将修改内容添加到本地缓存区,通配符可以把当前目录下所有修改的新增的文件都自动添加:

Git实战(实验楼)学习笔记 实验2 基本用法(下)

再执行 git diff 会发现没有任何内容输出,说明当前目录的修改都被添加到了缓存区,如何查看缓存区内与上次提交之间的差别呢?需要使用 --cached 参数:

Git实战(实验楼)学习笔记 实验2 基本用法(下)

可以看到输出中已经包含了新加文件的内容,因为 file1 已经添加到了缓存区。

最后我们提交代码:

Git实战(实验楼)学习笔记 实验2 基本用法(下)

Git实战(实验楼)学习笔记 实验2 基本用法(下)

提交后 git diff 与 git diff --cached 都不会有任何输出了。

 

 

2.2 比较分支

可以用 git diff 来比较项目中任意两个分支的差异。

我们首先创建一个新的分支 test,并在该分支上提交一些修改:

Git实战(实验楼)学习笔记 实验2 基本用法(下)

然后,我们查看 test 分支和 master 之间的差别:

Git实战(实验楼)学习笔记 实验2 基本用法(下)

git diff 是一个难以置信的有用的工具,可以找出你项目上任意两个提交点间的差异。可以使用 git help diff 详细查看其他参数和功能。

 

2.3 更多的比较选项

如果你要查看当前的工作目录与另外一个分支的差别,你可以用下面的命令执行:

Git实战(实验楼)学习笔记 实验2 基本用法(下)

Git实战(实验楼)学习笔记 实验2 基本用法(下)

你也以加上路径限定符,来只比较某一个文件或目录:

Git实战(实验楼)学习笔记 实验2 基本用法(下)

Git实战(实验楼)学习笔记 实验2 基本用法(下)

上面这条命令会显示你当前工作目录下的 file1 与 test 分支之间的差别。

--stat 参数可以统计一下有哪些文件被改动,有多少行被改动:

Git实战(实验楼)学习笔记 实验2 基本用法(下)

Git实战(实验楼)学习笔记 实验2 基本用法(下)

 

 

三、分布式的工作流程

 

下面我们学习 Git 的分布式工作流程。

 

3.1分布式的工作流程

你目前的项目在 /home/shiyanlou/gitproject 目录下,这是我们的 Git 仓库(repository),另一个用户也想与你协作开发。他的工作目录在这台机器上,如何让他提交代码到你的 Git 仓库呢?

首先,我们假设另一个用户也用 shiyanlou 用户登录,只是工作在不同的目录下开发代码,实际工作中不太可能发生,大部分情况都是多个用户,这个假设只是为了让实验简化。

该用户需要从 Git 仓库进行克隆:

Git实战(实验楼)学习笔记 实验2 基本用法(下)

这就建了一个新的 "myrepo" 的目录,这个目录里包含了一份gitproject仓库的克隆。这份克隆和原始的项目一模一样,并且拥有原始项目的历史记录。

在 myrepo 做了一些修改并且提交:

Git实战(实验楼)学习笔记 实验2 基本用法(下)

myrepo 修改完成后,如果我们想合并这份修改到 gitproject 的 git 仓库该如何做呢?

可以在仓库 /home/shiyanlou/gitproject 中把myrepo的修改给拉 (pull)下来。执行下面几条命令:

Git实战(实验楼)学习笔记 实验2 基本用法(下)

这就把 myrepo 的主分支合并到了 gitproject 的当前分支里了。

如果 gitproject 在 myrepo 修改文件内容的同时也做了修改的话,可能需要手工去修复冲突。

如果你要经常操作远程分支(remote branch),你可以定义它们的缩写:

Git实战(实验楼)学习笔记 实验2 基本用法(下)

git pull 命令等同于执行两个操作: 先使用 git fetch 从远程分支抓取最新的分支修改信息,然后使用 git merge 把修改合并进当前的分支。

gitproject 里可以用 git fetch 来执行 git pull 前半部分的工作, 但是这条命令并不会把抓下来的修改合并到当前分支里:

Git实战(实验楼)学习笔记 实验2 基本用法(下)

获取后,我们可以通过 git log 查看远程分支做的所有修改,由于我们已经合并了所有修改,所以不会有任何输出:

Git实战(实验楼)学习笔记 实验2 基本用法(下)

当检查完修改后,gitproject 可以把修改合并到它的主分支中:

Git实战(实验楼)学习笔记 实验2 基本用法(下)

如果我们在 myrepo 目录下执行 git pull 会发生什么呢?

myrepo 会从克隆的位置拉取代码并更新本地仓库,就是把 gitproject 上的修改同步到本地:

Git实战(实验楼)学习笔记 实验2 基本用法(下)

因为 myrepo 是从 gitproject 仓库克隆的,那么他就不需要指定 gitproject 仓库的地 址。因为 Git 把 gitproject 仓库的地址存储到 myrepo 的配置文件中,这个地址就是在 git pull 时默认使用的远程仓库

Git实战(实验楼)学习笔记 实验2 基本用法(下)

如果 myrepo 和 gitproject 在不同的主机上,可以通过 ssh 协议来执行 clone 和pull 操作:

Git实战(实验楼)学习笔记 实验2 基本用法(下)

这个命令会提示你输入 shiyanlou 用户的密码,用户密码随机,可以点击实验操作界面右侧工具栏的 SSH直连 按钮查看。

Git实战(实验楼)学习笔记 实验2 基本用法(下)

 

3.2 公共git仓库

开发过程中,通常大家都会使用一个公共的仓库,并 clone 到自己的开发环境中,完成一个阶段的代码后可以告诉目标仓库的维护者来 pull 自己的代码。

如果你和维护者都在同一台机器上有帐号,那么你们可以互相从对 方的仓库目录里直接拉所作的修改,git 命令里的仓库地址也可以是本地的某个目录名:

Git实战(实验楼)学习笔记 实验2 基本用法(下)

也可以是一个ssh地址:

Git实战(实验楼)学习笔记 实验2 基本用法(下)

 

3.3 将修改推到一个公共仓库

通过 http 或是 git 协议,其它维护者可以通过远程访问的方式抓取(fetch)你最近的修改,但是他们没有写权限。如何将本地私有仓库的最近修改主动上传到公共仓库中呢?

最简单的办法就是用 git push 命令,推送本地的修改到远程 Git 仓库,执行下面的命令:

Git实战(实验楼)学习笔记 实验2 基本用法(下)

或者

Git实战(实验楼)学习笔记 实验2 基本用法(下)

git push 命令的目地仓库可以是 ssh 或 http/https 协议访问。

 

3.4 当推送代码失败时怎么办

如果推送(push)结果不是快速向前 fast forward,可能会报像下面一样的错误:

Git实战(实验楼)学习笔记 实验2 基本用法(下)

这种情况通常是因为没有使用 git pull 获取远端仓库的最新更新,在本地修改的同时,远端仓库已经变化了(其他协作者提交了代码),此时应该先使用 git pull 合并最新的修改后再执行 git push:

Git实战(实验楼)学习笔记 实验2 基本用法(下)

 

 

四、git标签

 

4.1 轻量级标签

我们可以用 git tag 不带任何参数创建一个标签(tag)指定某个提交(commit):

Git实战(实验楼)学习笔记 实验2 基本用法(下)

这样,我们可以用stable-1 作为提交 8c315325 的代称。

前面这样创建的是一个“轻量级标签”。

如果你想为一个tag添加注释,或是为它添加一个签名, 那么我们就需要创建一个 "标签对象"。

标签对象

git tag 中使用 -a, -s 或是 -u三个参数中任意一个,都会创建一个标签对象,并且需要一个标签消息(tag message)来为 tag 添加注释。 如果没有 -m 或是 -F 这些参数,命令执行时会启动一个编辑器来让用户输入标签消息。

当这样的一条命令执行后,一个新的对象被添加到 Git 对象库中,并且标签引用就指向了一个标签对象,而不是指向一个提交,这就是与轻量级标签的区别。

下面是一个创建标签对象的例子:

Git实战(实验楼)学习笔记 实验2 基本用法(下)

 

4.2 签名的标签

签名标签可以让提交和标签更加完整可信。如果你配有GPG key,那么你就很容易创建签名的标签。首先你要在你的 .git/config 或 ~/.gitconfig 里配好key。

下面是示例:

Git实战(实验楼)学习笔记 实验2 基本用法(下)

你也可以用命令行来配置:

Git实战(实验楼)学习笔记 实验2 基本用法(下)

现在你可以在创建标签的时候使用 -s 参数来创建“签名的标签”:

Git实战(实验楼)学习笔记 实验2 基本用法(下)

如果没有在配置文件中配 GPG key,你可以用 -u 参数直接指定。

Git实战(实验楼)学习笔记 实验2 基本用法(下)

 

 

五、小结

 

本节学习了下面知识点:

  • git diff

  • 分布式的工作流程

  • git tag

课后练习

使用 [GitHub](https://github.com) 账号,创建自己的仓库并练习一遍本节所讲的内容。

对于初学者,如果不想深入 git 强大的高级功能的话,学完这个实验就可以开始上手开发了,后续实验内容用到的比较少,并且理解难度大。如果仍然感兴趣,建议使用一段时间 Git 后再仔细学习后续实验,会有更好的收获。