一、概述

1.1 关于 Git

https://git-scm.com/

Git is a free and open source distributed version control system designed to
handle everything from small to very large projects with speed and efficiency.

Git是一个免费开源分布式版本控制系统,被设计成快速高效地管理或大或小的项目。

1.2 关于 Github

https://github.com

GitHub is a web-based Git or version control repository and Internet hosting
service. It offers all of the distributed version control and source code
management (SCM) functionality of Git as well as adding its own features. It
provides access control and several collaboration features such as bug
tracking, feature requests, task management, and wikis for every project.
From Wikipedia

1.3 Github 与 Git 的区别

Github 是基于 Git 进行开发的。类似地,开源项目 Gitlab 也是基于 Git 进行开发。
你可以将 Gitlab 安装在你的某个网络中的某台 PC 上,以该台 PC 搭建起一个代码管理平台。
这样,Github、Gitlab 就很好理解了。

与此同时还有:
Gitlab(局域网部署)
Bitbucket(免费账号不限 private 项目个数)
Coding(对国内开发者来说可能有墙内优势)

1.4 Github的一些功能

  • Git 的基本功能,版本控制
  • Repository,仓库
  • Fork,授权拷贝
  • Pull Request,推送请求
  • 社交属性:
    • 针对特定个仓库(Repository)的 Watch、Star、Issue、Wiki ;
    • 针对具体用户的 Follow/Followed,基于 Git 历史的数据统计。

1.5 由Github衍生出来的项目

git-flow ——一个成功的 Git 分支模型
介绍:A successful Git branching model
翻译:http://www.juvenxu.com/2010/11/28/a-successful-git-branching-
model/

工具:nvie/gitflow
GitHubgit-flow 备忘清单

作者:天猪(刘勇)
链接:https://www.zhihu.com/question/20070065/answer/16021641
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

二、版本控制

2.1 版本控制概念

版本控制是一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统。

2.2 版本控制系统

2.2.1 本地版本控制系统

用复制整个项目目录的方式来保存不同的版本,或许还会改名加上备份时间以示区别。
https://git-scm.com/book/en/v2/images/local.png
唯一的好处就是简单,但是特别容易犯错。

2.2.2 集中化的版本控制系统

让在不同系统上的开发者协同工作.
https://git-scm.com/book/en/v2/images/centralized.png
这类系统,诸如 CVS、Subversion 以及 Perforce
等,都有一个单一的集中管理的服务器,保存所有文件的修订版本,而协同工作的人们都通过客户端连到这台服务器,取出最新的文件或者提交更新。

2.2.3 分布式版本控制系统

https://git-scm.com/book/en/v2/images/distributed.png
在这类系统中,像 Git、Mercurial、Bazaar 以及 Darcs 等,客户端并不只提取最新版本的文件快照,而是把代码仓库完整地镜像下来。

三、Git 基础

3.1 Git 历史

衍生自 Linux的开发过程。

3.2 Git 基础

3.2.1 Git 工具的特性

直接记录快照,而非差异比较

近乎所有操作都是本地执行
Git 是分布式版本控制,在 Git 中的绝大多数操作都只需要访问本地文件和资源,一般不需要来自网络上其它计算机的信息。
如果你习惯于所有操作都有网络延时开销的集中式版本控制系统,Git 在这方面会让你感到速度之神赐给了 Git 超凡的能量。
因为你在本地磁盘上就有项目的完整历史,所以大部分操作看起来瞬间完成。

如果你想查看当前版本与一个月前的版本之间引入的修改,Git
会查找到一个月前的文件做一次本地的差异计算,而不是由远程服务器处理或从远程服务器拉回旧版本文件再来本地处理。

Git 保证完整性
Git 中所有数据在存储前都计算校验和,然后以校验和来引用。 这意味着不可能在 Git 不知情时更改任何文件内容或目录内容。 这个功能建构在 Git
底层,是构成 Git 哲学不可或缺的部分。 若你在传送过程中丢失信息或损坏文件,Git 就能发现。

Git 用以计算校验和的机制叫做 SHA-1 散列(hash,哈希)。 这是一个由 40 个十六进制字符(0-9 和 a-f)组成字符串,基于 Git
中文件的内容或目录结构计算出来。 SHA-1 哈希看起来是这样:
24b9da6552252987aa493b52f8696cd6d3b00373

Git 一般只添加数据
你执行的 Git 操作,几乎只往 Git 数据库中增加数据。 很难让 Git 执行任何不可逆操作,或者让它以任何方式清除数据。

3.2.2 三种状态

Git 有三种状态,你的文件可能处于其中之一:

  • 已提交(committed),表示数据已经安全的保存在本地数据库中。
  • 已修改(modified),表示修改了文件,但还没保存到数据库中。
  • 已暂存(staged),表示对一个已修改文件的当前版本做了标记,使之包含在下次提交的快照中。

由此引入 Git 项目的三个工作区域的概念:Git 仓库、工作目录以及暂存区域。
https://git-scm.com/book/en/v2/images/areas.png

3.2.3 Git 的安装与配置

安装过程较为简单,不赘述。本文重点介绍 Git 的配置。
Git 自带一个 git config 的工具来帮助设置控制 Git 外观和行为的配置变量。 这些变量存储在三个不同的位置:

  • /etc/gitconfig 文件: 包含系统上每一个用户及他们仓库的通用配置。 如果使用带有 --system 选项的 git config 时,它会从此文件读写配置变量。
  • ~/.gitconfig~/.config/git/config 文件:只针对当前用户。 可以传递 --global 选项让 Git 读写此文件。
  • 当前使用仓库的 Git 目录中的 config 文件(就是 .git/config):针对该仓库。

每一个级别覆盖上一级别的配置,所以 .git/config 的配置变量会覆盖 /etc/gitconfig 中的配置变量。

在 Windows 系统中,Git 会查找 $HOME 目录下(一般情况下是 C:\Users\$USER)的 .gitconfig 文件。
Git 同样也会寻找 /etc/gitconfig 文件,但只限于 MSys 的根目录下,即安装 Git 时所选的目标位置。

用户信息
$ git config --global user.name "John Doe" $ git config --global user.email johndoe@example.com
再次强调,如果使用了 --global 选项,那么该命令只需要运行一次,因为之后无论你在该系统上做任何事情, Git 都会使用那些信息。
当你想针对特定项目使用不同的用户名称与邮件地址时,可以在那个项目目录下运行没有 --global 选项的命令来配置。

设置文本文本编辑器
默认使用 Vim
git config --global core.editor emacs

检查配置信息
如果想要检查你的配置,可以使用 git config --list 命令来列出所有 Git 当时能找到的配置。
$ git config --list user.name=John Doe user.email=johndoe@example.com color.status=auto color.branch=auto color.interactive=auto color.diff=auto ...
你可能会看到重复的变量名,因为 Git 会从不同的文件中读取同一个配置(例如:/etc/gitconfig~/.gitconfig)。
这种情况下,Git 会使用它找到的每一个变量的最后一个配置。
你可以通过输入 git config <key>: 来检查 Git 的某一项配置:
git config user.name

3.3 Git 详细知识

3.3.1 获取 Git 仓库

两种方式在本地建立仓库。
一种是,在现有项目会目录下导入所有文件到 Git;另一种是从服务器将已有的 Git 仓库克隆到本地。

在现有目录中初始化仓库
git init # 创建一个名为 .git 的子目录,该目录中含有初始化的 Git 仓库中所有的必须文件,这些文件时 Git 仓库的骨干。 git add *.c # 实现对文件的追踪 git add LICENSE git commit -m 'initial project version'

克隆已有的仓库
git clone [url] [本地仓库名称,可选]
当你执行 git clone 命令的时候,默认配置下远程 Git 仓库中的每一个文件的每一个版本都将被拉取下来。
事实上,如果你的服务器的磁盘坏掉了,你通常可以使用任何一个克隆下来的用户端来重建服务器上的仓库(虽然可能会丢失某些服务器端的挂钩设置,但是所有版本的数据仍在)。

GIT服务器的四种协议

3.3.2 记录每次更新到仓库

工作目录中的每个文件两种状态:

  • 已跟踪:指那些被纳入了版本控制的文件,在上一次快照中有它们的记录,在工作一段时间后,它们的状态可能处于未修改,已修改或已放入暂存区。
  • 未跟踪:工作目录中除已跟踪文件以外的所有其它文件都属于未跟踪文件,它们既不存在于上次快照的记录中,也没有放入暂存区。 初次克隆某个仓库的时候,工作目录中的所有文件都属于已跟踪文件,并处于未修改状态。
    文件的状态变化周期:
    https://git-scm.com/book/en/v2/images/lifecycle.png

检查当前文件状态
git status

跟踪新文件
git add [文件名]
暂存已修改文件
git add:这是个多功能命令:可以用它开始跟踪新文件,或者把已跟踪的文件放到暂存区,还能用于合并时把有冲突的文件标记为已解决状态等。将这个命令理解为“添加内容到下一次提交中”而不是“将一个文件添加到项目中”要更加合适。
状态简览
运行 git status -s/git status -short ,状态报告输出如下:
$ git status -s M README MM Rakefile # 你可能注意到了 M 有两个可以出现的位置,出现在右边的 M 表示该文件被修改了但是还没放入暂存区,出现在靠左边的 M 表示该文件被修改了并放入了暂存区。 A lib/git.rb # 新添加到暂存区中的文件前面有 A 标记 M lib/simplegit.rb ?? LICENSE.txt # 新添加的未跟踪文件前面有 ?? 标记
忽略文件
在这种情况下,我们可以创建一个名为 .gitignore 的文件,列出要忽略的文件模式。
文件 .gitignore 的格式规范如下:

  • 所有空行或者以 开头的行都会被 Git 忽略。
  • 可以使用标准的 glob 模式匹配。
  • 匹配模式可以以(/)开头防止递归。
  • 匹配模式可以以(/)结尾指定目录。
  • 要忽略指定模式以外的文件或目录,可以在模式前加上惊叹号(!)取反。

所谓的 glob 模式是指 shell 所使用的简化了的正则表达式。 星号(*)匹配零个或多个任意字符;[abc]
匹配任何一个列在方括号中的字符(这个例子要么匹配一个 a,要么匹配一个 b,要么匹配一个
c);问号(?)只匹配一个任意字符;如果在方括号中使用短划线分隔两个字符,表示所有在这两个字符范围内的都可以匹配(比如 [0-9] 表示匹配所有 0
到 9 的数字)。 使用两个星号(*) 表示匹配任意中间目录,比如 a/**/z 可以匹配 a/z, a/b/za/b/c/z等。
提供示例:https://github.com/github/gitignore

查看已暂存和未暂存的修改
如果 git status 命令的输出对于你来说过于模糊,你想知道具体修改了什么地方,可以用 git diff 命令。 稍后我们会详细介绍 git diff,你可能通常会用它来回答这两个问题:当前做的哪些更新还没有暂存? 有哪些更新已经暂存起来准备好了下次提交? 尽管 git status
已经通过在相应栏下列出文件名的方式回答了这个问题,git diff 将通过文件补丁的格式显示具体哪些行发生了改变。

此命令比较的是工作目录中当前文件和暂存区域快照之间的差异, 也就是修改之后还没有暂存起来的变化内容。

若要查看已暂存的将要添加到下次提交里的内容,可以用 git diff --cached 命令。(Git 1.6.1 及更高版本还允许使用 git diff --staged,效果是相同的,但更好记些。)

请注意,git diff 本身只显示尚未暂存的改动,而不是自上次提交以来所做的所有改动。 所以有时候你一下子暂存了所有更新过的文件后,运行 git diff 后却什么也没有,就是这个原因。

提交更新
git commit [comment,可选]

跳过使用暂存区域
git commit -a -m ‘added new benchmarks’

移除文件
要从 Git 中移除某个文件,就必须要从已跟踪文件清单中移除(确切地说,是从暂存区域移除),然后提交。 可以用 git rm
命令完成此项工作,并连带从工作目录中删除指定的文件,这样以后就不会出现在未跟踪文件清单中了。

如果删除之前修改过并且已经放到暂存区域的话,则必须要用强制删除选项 -f(译注:即 force 的首字母)。
这是一种安全特性,用于防止误删还没有添加到快照的数据,这样的数据不能被 Git 恢复。

git rm --cached README从暂存区域删除,同时,此处文件支持使用 glob 模式

移动文件
git mv file_from file_to
相当于
mv file_from file_to git rm file_from git add file_to

3.3.3 查看提交历史

git log 有许多选项可以帮助你搜寻你所要找的提交, 接下来我们介绍些最常用的。
git log -p -2:一个常用的选项是 -p,用来显示每次提交的内容差异。 你也可以加上 -2 来仅显示最近两次提交
如果你想看到每次提交的简略的统计信息,你可以使用 --stat 选项

另外一个常用的选项是 --pretty。 这个选项可以指定使用不同于默认格式的方式展示提交历史。 这个选项有一些内建的子选项供你使用。 比如用
oneline 将每个提交放在一行显示,查看的提交数很大时非常有用。 另外还有 shortfullfuller
可以用,展示的信息或多或少有些不同,请自己动手实践一下看看效果如何。

格式化:git log --pretty=format:"%h - %an, %ar : %s"

限制输出长度

3.3.4 撤消操作

git commit --amend修改上次 commit 的内容(如上次commit的内容已经 push ,则无法修改,只能产生新的 commit
),将自上次 commit 后发生的修改附加到上次 commit 上,并可做相关编辑。

取消暂存文件
git reset HEAD <file>... 来取消暂存.
此时,有三种参数:

  • --hard,比较危险
  • --soft
  • --mixed,默认方式

撤消对文件的修改
参见资料

二、学习使用 Git 工具

2.1 学习资料汇总

三、知乎上关于Github的问题

四、Github的一些用法

如何高效利用GitHub?(http://www.yangzhiping.com/tech/github.html)
借助于 GitStats
,我们能很好地统计自己的每个项目的工作量,从而看到工作进展。