你会用git吗?

发表于 2017-03-01 | 标签: git

关于教程

事实上关于 git 的教程,网络上铺天盖地,可是我为什么还写下本篇教程呢,其实我这篇教程的定位是,简洁明了。

关于 git 命令行工具

git 有很多可视化操作工具,做得都很好,但是本教程采用命令行的操作客户端。原因很简单 命令行容易写教程。

有两个专注点,命令行操作的话,眼睛专注屏幕,双手专注键盘。等你用鼠标移动鼠标指针找菜单我已经睡着了。 命令行操作是全集,图形操作都是命令行的一个子集。 害怕命令行的同学主要是对命令行恐惧造成的,怕自己记不住那么多命令,通过学习本课,希望能克服。 格调得到一定提升。 关于内容

因为是一份课件,所以语言组织都是很白的,内容也都是按自己理解组织的,不严谨或者是错漏恳请广大的互联网朋友勿喷。

初始化一个本地仓库

为了学习的方便可以在桌面新建一个文件夹,起名为 learn-git 。打开 git 命令行客户端,把命令行的路径定位到刚刚建立的文件夹,运行以下命令即可初始化一个本地仓库。 [^_^]:more’

git init

当运行了以上命令,git 会在当前目录新建一个名为 .git 的隐藏文件夹,这个文件夹就是 git 的仓库文件夹。

查看配置、修改配置

学习一款工具的时候,首先应该认识它的配置。运行以下命令可以查看git的配置。

# 查看所有配置
git config --list
# 查看本地配置
git config --local --list
# 查看全局配置
git config --global --list
# 查看系统配置
git config --system --list

git 的配置是有三份配置文件合成的,分别是本地配置,配置文件保存在当前仓库中,全局配置,配置保存在当前 Windows 登录用户的家目录下,系统配置,配置文件保存在 git 的安装目录下的某个目录中。当有相同配置项时,本地配置的优先级较高,全局配置次之,系统配置优先级最低。

修改配置的命令如下

``` python
# 不加配置文件选项默认配置的是本地配置
git config 配置项 "配置值"
# 配置本地配置(可以不加 --local 选项,默认就是本地配置)
git config --local 配置项 "配置值"
# 配置全局配置
git config --global 配置项 "配置值"
# 配置系统配置
git config --system 配置项 "配置值"

如配置用户名的命令如下

git config --global user.name "allowing"

如果这个电脑经常是自己本人使用,可以将用户名配置成全局的,不然就把它配置成本地的。

git config --local user.name "allowing"

查看帮助

git 查看帮助很简单,如下给出的命令。需要一定的英文能力。

# 查看 git 命令的帮助
git
# 查看某个子命令的帮助
git 子命令 -h

例如查看 config 子命令的帮助

git config -h

如果运行以下命令会打开一张网页,这个网页有更详细的帮助说明

git config --help

工作区、暂存区、仓库

工作区是指当前编辑代码的文件夹,也是 .git 仓库所在的文件夹。

暂存区只是一个概念,实际上并不存在这个区。

仓库就是 .git 文件夹了,它是我们运行 git init 命令时自动创建的,默认是隐藏的,所有的历史都保存在这里。

查看状态

查看状态命令用得很频繁,命令如下

git status

git 会把文件的变化列出来,例如未跟踪的文件,已修改的文件,已删除的文件等,将会被提交的文件列表等。良好的习惯是在操作之前先查看一下状态。

跟踪文件

初始化一个仓库时,仓库是空空的,要运行以下命令,让 git 跟踪某文件。

git add 文件名

运行以上命令就把一个文件跟踪起来了,这个文件就进入了暂存区。要注意的是,git 不会跟踪一个空文件夹的。

忽略某些文件

忽略某些文件是指让 git 不跟踪这些文件。例如一些临时文件,日志文件,可以通过 composer、node、maven 拉取的第三方包等,这些文件都没有跟踪的必要,跟踪了反而会增加不少的麻烦。

git 会递归地查找项目中每个目录是否存在 “.gitignore” 文件,可以在这个文件里声明一些忽略规则,git 就会忽略这些文件了。

要注意的是,.gitignore 文件本身不能被忽略,它要被跟踪起来。

下面给出常用的忽略规则:

# 忽略 app.log 文件
app.log

# 忽略 vendor 文件夹
vendor/

# 不管 vendor 是文件还是文件夹,只要是这个名字的都忽略
vendor

# 不递归地忽略 vendor 文件夹
# 如果没有斜杠开头,子目录如果也存在 vendor 文件夹那么也会忽略,孙目录存在它的话,也会忽略
# 所以更多时候,为了保险起见,还是不要递归忽略
/vendor/

# 不忽略 .gitignore 文件
!.gitignore

# 忽略 .log 后缀的文件
*.log

# 忽略所有文件和文件夹
*

常用的规则基本就是这些,不会很多。

提交

在提交之前先配置好 user.name 和 user.email 两个配置项。配置的原则是如果这台电脑是你自己使用的就全局配置,不然就本地配置。

全局配置:

git config --global user.name "your name"
git config --global user.email "your email"

本地配置:

git config --local user.name "your name"
git config --local user.email "your email"

提交是指把暂存区的文件提交到 git 仓库,可以通过以下命令进行

git commit -m "提交说明"

提交同时也是一个名词,在 git 中一个提交就是一个历史,每个提交都有一个唯一的提交 id

修订最近的一次提交

最近的一次提交在未和远程仓库同步之前,修改起来都是很容易的,如果发现某个文件的内容有误,可以在工作区把这个文件改正,然后又不想重新做成一个单独的提交,可以把这次的修改作为一个修订,修订最近的一次提交,操作还是跟之前一样,跟踪修改,提交,只是在提交时加上 –amend 选项

git commit --amend -m "提交说明"

修订提交不会重新生成一个单独的提交记录。

文件的状态

工作目录中的文件要么是已跟踪的和未跟踪的两种状态。

跟踪的是指已经纳入到 git 的管理中了文件,通过 “git add <文件名>" 可以跟踪它。

未跟踪的是指还没有纳入到 git 的管理中的文件,例如刚刚新建的文件,运行 “git status” 就会看到提示,说你刚刚新建的文件还未跟踪,这时你可以选择是否跟踪它。

已经跟踪了的文件的状态

已经跟踪了的文件又会发生“修改”“删除”两种变化。

当提交之后,工作区是干净的,这时修改一个已经被 git 跟踪起来了的某个文件,在运行 “git status” 查看,会得到哪个文件发生了修改的提示信息,运行 “git diff” 还能看发生了哪些修改。如果删除一个已被跟踪的文件,运行 “git status” 也能看到说哪个哪个文件删除了 最后附上一张图:

查看日志

查看日志是指查看提交的记录,可以运行以下命令查看

git log

还可以显示得简洁一点,加上 –oneline 选项

git log --oneline

单行显示模式下的 提交 id 也变短了,注意这个提交 id 也是可以进行某些操作的,和长长的提交 id 具有相同的功能。

检出文件

检出文件是指从提交中拿出一个文件到工作区,例如当想放弃某个文件的修改时,就可以这样做。

git checkout 文件名

例如我改了 README.md 可是改着改着我不想改了,就可以从历史中检出这个文件覆盖到当前工作区。

git checkout README.md

以上是从最近的一次提交中检出,还可以指定一个提交 id,指定从这次提交中检出。

# 设某次提交 id 为 1e25af6
git checkout 1e25af6 README.md

提交 id 可以运行 “git log –oneline” 查看

远程仓库

远程仓库是指保存在远程计算机的仓库,这个仓库和本地仓库保持同步,那么这样子就相当于把本地仓库漫游了,去到哪就都可以访问了,还可以和世界上其他有志小伙伴分享。

远程仓库提供商有很多,其中最著名的莫过于 github 了,它是目前全球最大的代码托管平台,可惜服务器是在国外的,可能是我国的原因吧,访问速度有点慢。中国的仓库提供商比较出名的是开源中国了。本教程就以开源中国为例,讲解怎么和远程仓库交互。

注册开源中国账号

填写好注册信息注册一个账号,这个没有什么难度的。

生成本机的 ssh

在 git 的命令行工具下,运行以下命令,然后所有的提示都默认不填,一路按三次回车,生成公私钥

ssh-keygen

这样就会在用户的家目录下的 .ssh 目录下生成公私钥对。

id_rsa 私钥

id_rsa.pub 公钥

用文本编辑器打开公钥,全选里面的内容,复制到开源中国,在用户的设置里能看到对应选项的。

当把本机的公钥添加到了开源中国之后,git 命令行工具就可以和开源中国的仓库连接了。

用户的家目录在哪?家目录其实是 linux 系统的说法,我也硬生生地用到 windows 上来了。windows 中的用户家目录,一般是 “C:/Users/<用户名>",例如 "Administrator" 用户的家目录是 "C:/Users/Administrator"。windows 可能还会把 "Users" 显示成中文的 "用户",这个知道就行,它仅仅是显示成了中文而已。

新建一个远程的空白仓库

在刚刚注册好的账号,新建一个公开的空白的仓库,注意一定要空白的,不要用 README.md 初始化这个仓库。

然后把刚新建的仓库的 ssh 地址复制,添加到要同步的本地仓库。

git remote add <远程仓库名字> <远程仓库地址>

远程仓库名字随便起,一般叫 “origin” ,远程仓库地址就是刚刚复制的 ssh 地址。例如

git remote add origin git@git.oschina.net:allowing/class001-homework.git

公开的仓库是指人人都可以查看,人人都可以克隆。里面的代码也叫开源的代码,因为大家都可以克隆嘛,但是开源不代表没有原则,也是要遵循开源协议的。

私有的仓库是指个人的仓库,其他小伙伴不能查看不能克隆。

我本人的开源精神是:片段开源,系统闭源。

推送本地仓库到远程

配置好远程仓库地址之后,就可以推送本地的仓库到远程了。具体运行以下命令,首次推送应该加上 “-u” 选项,这样就会在远程仓库建立一个与推送的分支同名的关联分支,这个本地分支叫做远程分支的跟踪分支也叫上游分支。

# 首次推送加上 -u 选项
git push -u <远程仓库名> <要推送的分支名>

# 如
git push -u origin master

# 下次再推送这个分支就不用加任何选项了,甚至在当前分支下还可以直接推送
git push

跟踪分支:跟踪分支是指和远程分支具有关联关系的分支,一般保持它们两者同名。跟踪分支也叫上游分支。

更多关于分支的内容,往后会继续学到,暂时先用默认的 master 分支联系。

推送本地仓库的原则是,完成了一定的工作之后就要及时推送到远程。

认识开源中国仓库

推送了本地仓库到远程之后,再到线上查看,各个链接按钮都点击一下,认识认识它们。

拉取远程仓库的更新到本地

实际工作中,我们可能会在各台电脑推送推送代码到远程,那么其他电脑就要及时拉取远程的更新下来。

设当前 master 分支是远程仓库 origin/master 分支的跟踪分支,则可以运行以下命令拉取

git pull

如果当前 master 分支没有和远程的 origin/master 分支存在跟踪关系,那么这种关系一般是不正常的,这里我们不作介绍,因为新手难理解,老手又不会犯,而且解释起来语言难组织^_^。

克隆一个远程仓库

克隆仓库是指把线上的仓库“复制”一份到本地。

git clone <远程仓库地址>

当克隆完之后,git 会自动检出一个活动分支到当前的工作区,这个分支也已经和远程的分支建立起了跟踪关系,提交到了本地仓库的提交可以直接运行 “git push” 推送到远程仓库。

分支

分支是指一条挂载了“提交”的历史进程。如下图中,存在着 master 和 testing 两个分支。

新建分支

新建分支可以运行以下命令

git branch <分支名>
# 如新建一个 test 分支
git branch test

上面的操作是基于当前分支分叉出的分支,历史的提交也会在刚刚新建的分支出现。

基于给定提交 id 新建分支

基于给定的提交 id 新建分支。设某提交 id 为 abc123, 以下命令则可以基于这个提交 id 分叉出一条分支

git branch <分支名> <提交 id>
# 如基于 abc123 新建 test-for-commit-id 分支
git branch test-for-commit-id abc123

切换到新建的分支

git checkout <分支名>
# 如切换到 test 分支
git checkout test

切换到新建的分支之后工作区的内容也会跟着改变,工作目录的内容就是要切换到的那个分支的最后一次提交的内容。

需要注意的是,当前分支的工作进行了一半,还没完的话,不要切换分支,要把当前的工作完成了并提交了再切换,不然会自己惹麻烦的。

实际中,往往新建一个分支之后要马上切换过去的,所以有以下简便方式

git checkout -b <新分支名>
# 基于给定提交 id
git checkout -b <新分支名> <提交 id>

HEAD

在 git 中,存在一个指针叫 “HEAD”。HEAD 通常指向当前分支的最后一次提交。

当从一个分支切换到另一个分支,实际上只是将 HEAD 指针指向了这个分支的最后一次提交。例如从 master 分支切换到 test分支。

贮藏当前的工作

正如上文有提到,在当前分支进行的工作还没完,又要急需切换到其他分支进行工作,而又不想提交当前工作,因为当前工作还没完成,提交没有意义,怎么办呢,这是就可以把当前的工作现场贮藏起来。

git stash

上面的命令可以把当前分支的工作现场贮藏起来,这是查看状态,工作区就又是干净的了,这是也就可以放心切换到其他分支进行工作了。

当其他分支的工作完成之后,切回来只有又怎么重现工作现场呢,请看

git stash pop

以上命令可以重新打开被贮藏的工作现场。

提示:贮藏工作现场毕竟不是什么好事,因为我们通常会忘记曾几何时被贮藏起来了的工作。不过,实际工作中,临时地应用一下还是很频繁的,这个当掌握了 git 之后,你自然会想到怎么应用。

检出一个远程仓库的分支

运行 git branch -a 能查看到所有分支。红色的是远程分支,他们的命名都是 “remotes/<仓库名字>/<分支名字>" 的形式。 克隆完一个仓库之后,git 只是检出默认分支一般是 master,但是要检出其他远程分支就要手动检出了,注意一般检出一个远程分支同时要建立起跟踪关系的,不建立跟踪关系是没有意义的。

git checkout --track 远程主机名/分支名
# 设存在远程分支 origin/test
git checkout --track origin/test

–track 选项是建立跟踪关系的意思

合并分支

合并分支是指把另一条分支的历史提交合并到当前分支。命令如下

git merge <分支名>
# 例如当前分支是 master 分支,想把 test 分支的提交合并到当前分支
git merge test

合并过程中,如果没有冲突,就会顺利合并。如果两个分支都对某个文件做了修改,就会产生冲突,这时候 git 就会要求我们手动解决发生冲突的文件,然后重新生成一个提交。

只获取远程的内容但不合并

git pull 命令事实上相当于做了两件事:git fetch 和 git merge。

如果我们仅仅是想获取一下远程分支的内容,而不合并到它们对应的本地分支的话,可以直接运行 git fetch 命令。

# 设本地分支 php ,其远程分支为 remotes/origin/php ,当前 HEAD 在 php 上,

git fetch

# 如果远程的分支有更新,那么运行了上面的命令之后,就能看到更新日志了
git log --oneline remotes/origin/php

删除分支

已经合并了的分支,一般都可以删除了,还有不想要的又还没有合并的分支,也可以删除。

git branch -d <分支名>
# 例如删除 test 分支
git branch -d test
# 没有合并的分支,自检出之后又有了自己的提交记录,这时加 -d 选项想删除是不行的,这是 git 的保护机制
# 一定要删除可以加 -D
git branch -D test

查看本地分支和远程分支的同步信息

实践中,常常需要查看一下当前分支是否滞后于远程的关联分支,还有想知道当前分支有没有推送到了远程,可以运行如下命令查看

git branch -v
# 显示的信息更详细
git branch -vv

重置(reset)

利用重置子命令可以实现重置 HEAD 或者重置到某个提交,以下给出实际中常用的操作

# 仅仅重置 HEAD
git reset
# 放弃当前的所有修改,重置 HEAD 和工作目录
# 这个操作会重置掉当前的工作目录,使之恢复到上一次提交
git reset --hard
# 重置到上上次
git reset --hard HEAD^
# 重置到给定的提价点上
#
# 设某提交 id 为 abc123
git reset --hard abc123

结束语

git 是一款强大的工具,同时学习它也是一件不容易的事情,熟练掌握它就更难了。能用好它,那么它将会是一个好帮手,用不好就会被它牵着走。

建议新手写一个留言板,并使用它进行版本控制,在这个过程中慢慢体会它的好。最好能买一台服务器,不是共享的,是有独立操作系统的,能远程登录的,不会 linux 系统的同学可以买 windows 系统的,就好像操作自己的主机一样。

重申重申重申,git 的概念都很抽象,所以 git 的文字版学习资料也好,视频教程也好,跟着学一遍是不行的,一定要自己用 git 来正式管理一个项目,这样才能掌握它。不然,久而久之,你就会对 git 是去热情,感觉它怎么不好怎么不好,或者抱怨教程不好,视频不行,产生这些厌烦情绪。 ####最后附图一张,自己体会