Git简介

Author Avatar
A Man Has No Name 3月 12, 2017
  • 在其它设备中阅读本文章

简单介绍一下GIT, 用作培训,不用点进来看了

GIT 和 SVN

SVN

我一开始用的是svn,那就先从svn说起,svn就是典型的集中式是管理,也就是所有操作必须与代码服务器通信。总体来说还是比较好用的,因为比起上一代CVS,它可以创建分支,虽然它的分支是真的把整个目录拷出来一份(比较挫), 而且离开网络什么也干不了, 当你在紧急情况下,diff文件的时候,网络却以几b的速度。。。。。。

https://git-scm.com/book/en/v2/images/distributed.png

GIT

GIT起源与维护Linux核心库维护工作, 被认为是分布式的版本管理工具,每一个客户端都会有一份完整的版本记录(所以目录会比较大),所有的操作都会是在本地进行, 你的每次提交,它都会在本地做一次快照,只是存储本次修改的数据。他的特点基本如下

  • GIT关注的是数据,svn关注的是文件,比如svn,举个例子,你在git和svn中创建一个空文件夹试试上传代码。
  • GIT几乎所有的操作都是在本地
  • 简单分支创建,切换
  • 离线操作,缓存本地的提交,git会保留你所有的提交记录,然后在联网之后,与其他伙伴合并代码
  • 先进的存储模式。

三种状态

这是正题,git有三种状态

  • Committed, 已经安全提交到了版本库
  • Modified, 文件已经修改了,但是未提交
  • Staged, 对那些需要提交到版本库的Modified的文件,做标记,等待提交操作

所以.git文件就是当前项目的版本数据库,它包含了,这个项目的一切信息。

别名

我一般会给git常用命令设置别名

1
2
3
4
$ git config --global alias.co checkout
$ git config --global alias.br branch
$ git config --global alias.ci commit
$ git config --global alias.st status

这样

  • git checkout == git co
  • git branch == git br
  • git commit == git ci
  • git status = git st

常用命令

推荐大家使用Source Tree,很好用

  • 首先设置自己
    1
    2
    $ git config --global user.name "John Doe"
    $ git config --global user.email johndoe@example.com

clone 代码

1
2
3
$ git clone git@github.com:php-ai/php-ml.git
# 如果你只想要最新的代码,当前的网络又特别慢的时候,你可以指定要下载哪几次提交的代码(尤其在公司的时候下载github代码)
$ git clone git@github.com:php-ai/php-ml.git --depth 1 //可以试试,有惊喜

设置自己编辑器, 默认是vim

1
2
3
4
$ git config --global core.editor atom
# 设置忽略大小写引起的改动那么
# 默认是false
$ git config --global core.ignorecase true

查看配置文件

1
2
3
4
5
6
7
$ 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状态, git status

1
2
3
$ git status
On branch master # 目前在master分支上
nothing to commit, working directory clean # 这个目录是干净的
创建新文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$ echo 'test git' > test_git.txt
$ git status
On branch master
Initial commit
Untracked files: # 当前这些文件状态是Untracked
(use "git add <file>..." to include in what will be committed) # 推荐你进行这些操作
test_git.txt # 这些文件没有被版本追踪
nothing added to commit but untracked files present (use "git add" to track)
$ git add test_git.txt # 如果是多个文件git add * , 把这些文件放在Staged中
$ git status
On branch master
Initial commit
Changes to be committed: # Staged状态,
(use "git rm --cached <file>..." to unstage)
new file: test_git.txt # 这个文件暂存
$ git commit -m "这是要写理由"
  • 简洁的输出, git status -s
    • 新添加的未跟踪文件前面有 ?? 标记,
    • 新添加到暂存区中的文件前面有 A 标记,
    • 修改过的文件前面有 M 标记
      1
      2
      3
      $ git status -s #推荐使用这个命令,比较简洁
      M test_git.txt # 说明这个文件修改过了
      ?? test.md # 这个文件是没有被追踪的

忽略文件, .gitignore

  • # 和 空行,都会被忽略
  • 支持正则匹配
  • 匹配模式以(/)开始,以(/)结束
  • 要忽略制定模式意外的文件, 加(!)
  • 匹配任意目录d/**/d1, 可以匹配d/d2/d1, d/d2/d3/d1等, 一个*,匹配任何文件;.没有其他意义
    1
    2
    3
    4
    5
    6
    # 忽略当前目录里面的文件 TEST
    /TEST
    # 这个才是忽略TEST目录以及下面的文件
    TEST/
    # 忽略test目录所有后缀是.pyc的文件
    test/**/*.pyc
  • diff 文件,暂存区,是只还没有commit的文件
    • git diff, 如果要对比未放入暂存区的文件,直接输入
    • git diff –staged, 如果要对比已经进入暂存区文件

提交文件 git commit

1
2
$ git commit # 提交文件
$ git commit -a -m '此处输入理由' # 这个可以直接跳过暂存区进行暂存

暂存修改,提交代码

如果,本地有没修改玩的代码,但是这个时候又需要合并别的人代码,那么这个时候就需要

1
2
$ git stash
$ git pull origin master

当把别人的代码合并了之后,需要把之前的暂存代码拉出来这个时候

1
2
$ git stash pop # 把最近一次的暂存文件拿出来
$ git stash

当我们觉得刚才输入的 -m 写的不好,我们可以进行后悔重新写
1
$ git commit --amend -m '这次写的炫酷的理由'

删除文件

  • git rm
    1
    2
    3
    4
    5
    $ git rm a.t # 删除a.t,真的就没有这个文件了
    $ git status -s # 查看状态
    D a.t
    $ git rm a.t --cached # 只是删除了缓存区内的文件,但是并不会删除文件

查看历史

git log
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
commit ef80dd6875bfea55723a280caa9f5ad5ecc87a74
Author: t <t@playcrab.com>
Date: Sun Mar 12 19:46:09 2017 +0800
asdasd
commit 5c9e8df22d8b3d46833619caffd56655e9a0c6ed
Author: t <t@playcrab.com>
Date: Sun Mar 12 19:42:37 2017 +0800
dd
commit 60202107a4292ff2fb375f64099b841f7bb639ac
Author: t <t@playcrab.com>
Date: Sun Mar 12 19:39:28 2017 +0800
git log -p -2

查看版本差异,-p 后面的数字,表示最近几个版本的差异,比如-2,代表最近两个版本差异

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
commit 52c661dcca23764c0ed24d32215ab7ca961af31d
Author: t <t@playcrab.com>
Date: Sun Mar 12 19:46:09 2017 +0800
asdasd
diff --git a/a.t b/a.t
deleted file mode 100644
index 5d308e1..0000000
--- a/a.t
+++ /dev/null
@@ -1 +0,0 @@
-aaaa
commit 5c9e8df22d8b3d46833619caffd56655e9a0c6ed
Author: t <t@playcrab.com>
Date: Sun Mar 12 19:42:37 2017 +0800
dd
diff --git a/a.t b/a.t
index 304f1bb..5d308e1 100644
--- a/a.t
+++ b/a.t
@@ -1 +1 @@
-adas
+aaaa

git log –stat

这个是简单的统计信息,比如有此次更新有多少修改,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
commit 23a4d911feb212e50d5f5d32f802b460c2ca01c8
Author: t <t@playcrab.com>
Date: Sun Mar 12 20:10:28 2017 +0800
ttttttt
a.t | 2 ++
1 file changed, 2 insertions(+)
commit 52c661dcca23764c0ed24d32215ab7ca961af31d
Author: t <t@playcrab.com>
Date: Sun Mar 12 19:46:09 2017 +0800
asdasd
a.t | 1 -
1 file changed, 1 deletion(-)
commit 5c9e8df22d8b3d46833619caffd56655e9a0c6ed
Author: t <t@playcrab.com>
Date: Sun Mar 12 19:42:37 2017 +0800
dd
a.t | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
git log –pretty

美化日志输出:

  • oneline, 简化为1行输出

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    d3373c97e1bd4fceb0687d2e289998bccda514f1 Fix old reference to _sheetIndex in HTML Writer
    1c8c2379ccf5ab9dd7cb46be965821d22173bcf4 Fix to Radar and Scatter chart examples
    900325d0c809bc9cc4263fe67881d7627bb0b7f3 Minor updates to composer
    e487f5c11a4b62376015d1e7da27420be0932275 Fix for multiple worksheets, all with merge cells, in HTML Writer
    fcc5c6585574054bd2dce530d5fb3f5da745bc49 Fix to 01simple.php example after mis-commit
    650d2d099c293794cbaa9f41c332cf90078a4428 Merge branch 'develop' into 1.8
    b2029564e5fe1f7e8a154defe20604666c7192a3 Fix for XML settings, together with unit tests
    b0ce48fd92e15a874b8246d645072ad817b68114 Merge pull request #895 from psirus0588/patch-1
    772e66f74a2162574d6fa128b26381a6299d084e Update 01-Getting-Started.md
    8af620f97b8b1c8a677d90b3d7203fa562050db1 GH-879 Bug in file PHPExcel/Reader/CSV.php Code logic identifying a defined separator when no separator is explicitly defined Case-insensitive check when separator is explicitly defined
  • shor, full, fuller 这三个可以试试,有惊喜

  • format, 可以自定义输出显示内容
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    $ git log --pretty=%h\ \ %s //只显示简短commit号和提交信息
    d3373c9 Fix old reference to _sheetIndex in HTML Writer
    1c8c237 Fix to Radar and Scatter chart examples
    900325d Minor updates to composer
    e487f5c Fix for multiple worksheets, all with merge cells, in HTML Writer
    fcc5c65 Fix to 01simple.php example after mis-commit
    650d2d0 Merge branch 'develop' into 1.8
    b202956 Fix for XML settings, together with unit tests
    b0ce48f Merge pull request #895 from psirus0588/patch-1
    772e66f Update 01-Getting-Started.md
    8af620f GH-879 Bug in file PHPExcel/Reader/CSV.php Code logic identifying a defined separator when no separator is explicitly defined Case-insensitive check when separator is explicitly defined
    c4782b6 General: (sim642) Pull Request 489 - Implement actual timezone adjustment into PHPExcel_Shared_Date::PHPToExcel
    a1dee8f Bugfix: (vitalyrepin) Pull Request 869 - c:max and c:min elements shall NOT be inside c:orientation elements

以下表格,摘自的是官网内容

选项 说明
%H 提交对象(commit)的完整哈希字串
%h 提交对象的简短哈希字串
%an 作者(author)的名字
%s 提交说明
%cr 提交日期,按多久以前的方式显示

常用的选项

选项 说明
-p 按补丁格式显示每个更新之间的差异。
–stat 显示每次更新的文件修改统计信息。
–shortstat 只显示 –stat 中最后的行数修改添加移除统计。
–name-only 仅在提交信息后显示已修改的文件清单。
–name-status 显示新增、修改、删除的文件清单。
–relative-date 使用较短的相对时间显示(比如,“2 weeks ago”)。
–graph 显示 ASCII 图形表示的分支合并历史。这个很好用
–pretty 使用其他格式显示历史提交信息。可用的选项包括 oneline,short,full,fuller 和 format(后跟指定格式)。
git log 其他一些好用的方法
  • git log –since=2017-03-10 –after=2017-03-11, 从2017-03-10开始之后的到2017-03-11日之前提交显示
  • git log –until=2017-03-10,–before=2017-03-09, 在2017-03-09之后到2017-03-10之前的提交, 由于本人英语没过六级,所以更牛逼的语法,我也不会写
  • git log –author=MarkBaker, 查询MarkBaker提交的记录显示
  • git log –grep=test,显示包含test的提交
  • git log -Stest, 显示包含删除,或者新增的包含test的文件

GIT数据恢复 (危险,一般别用,后果自负)

  • 当你不小心删除了一个分支之后
  • 先让我们认为造几个删除分支的情况

    • git reset –soft HEAD~2 和 git reset –hard HEAD~2 区别是soft 只是向下走两个指针,hard却会删除那两个提交
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      $ git log --oneline# 查看分支
      b0ce48f Merge pull request #895 from psirus0588/patch-1
      772e66f Update 01-Getting-Started.md
      8af620f GH-879 Bug in file PHPExcel/Reader/CSV.php Code logic identifying a defined separator when no separator is explicitly defined Case-insensitive check when separator is explicitly defined
      c4782b6 General: (sim642) Pull Request 489 - Implement actual timezone adjustment into PHPExcel_Shared_Date::PHPToExcel
      a1dee8f Bugfix: (vitalyrepin) Pull Request 869 - c:max and c:min elements shall NOT be inside c:orientation elements
      $ git reset --hard HEAD^^ #(注意HEAD^^,它表示,向前三个版本删掉)
      $ git log --oneline
      c4782b6 General: (sim642) Pull Request 489 - Implement actual timezone adjustment into PHPExcel_Shared_Date::PHPToExcel
      a1dee8f Bugfix: (vitalyrepin) Pull Request 869 - c:max and c:min elements shall NOT be inside c:orientation elements
      1a23757 Merge pull request #869 from vitalyrepin/1.8
      4491898 Bug fix: c:max and c:min elements must not be inside c:orientation elements. They shall be inside c:scaling elements. Otherwise they are ignored by Excel and Libreoffice
      $ git reset --hard HEAD~2 # (注意,这个,标示前两个版本删除)
  • 然后,让我们发现删除错了, 需要恢复文件的时候, 我建议你自己新建一个分支,用来做恢复使用

  1. 切记不要在当前分支恢复
  2. 切记不要在当前分支恢复
  3. 切记不要在当前分支恢复
  • 接下来,我们进行恢复操作

  • 如果我们要恢复之前删除,可以使用命令git reflog 工具,它忠实的记录我们每次操作的日志,如果你发现你的操作这里也没有,那么就说明,你可以放弃了恢复了。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    $ git reflog
    c4782b6 HEAD@{0}: reset: moving to HEAD^^ # 这是之前的操作
    # 如果想看详细的自己操作记录
    $ git log -g
    commit c4782b660619be139a64d96a545f6a422ca74c20
    Reflog: HEAD@{0} (t <t@playcrab.com>)
    Reflog message: reset: moving to HEAD^^
    Author: MarkBaker <mark@lange.demon.co.uk>
    Date: Thu Mar 31 23:50:44 2016 +0100
    General: (sim642) Pull Request 489 - Implement actual timezone adjustment into PHPExcel_Shared_Date::PHPToExcel
    # 我们开始恢复到一个新分支(recover)中
    $ git branch recover c4782b660619be139a64d96a545f6a422ca74c20
  • git fsck –full, 终极大招,如果实在找不到,那么就执行这个

GIT最牛技能,分支

  • 我们使用的git分支模型, 请参考GitFlow
  • git checkout -b work 新建一个分支, 并且切换到分支work
    分支的合并 merge –no-ff
    TODO

  • git branch -d work 删除分支work
    TODO

  • git clone –bare 下载纯净代码

  • GIT 变基….
    TODO

其他

.git

1
2
3
4
5
6
7
8
9
10
11
12
COMMIT_EDITMSG
HEAD # 重要,指向当前所在的分支
ORIG_HEAD
branches/
config # 可以覆盖全局的git config --global
description # 没啥用
hooks/ # 文件提供了回调函数, 比如自定义,提交之前做什么,提交之后做什么,更新之后做什么
index # 当前暂存区的信息
info/
logs/
objects/ # 重要,存储所有数据内容
refs/ # 重要,存储各分支,tag当前指向的引用

查看提交信息

1
$ git cat-file -p 1c8c2379ccf5ab9dd7cb46be965821d22173bcf4

git add -i # 交互式的提交方式,这个很哔,使用起来,比一般的GUI工具要牛哔

git 调试代码

git blame

  • 我要分析文件 Classes/PHPExcel/Shared/Date.php 第80 到 85行到底什么时候添加的代码,为毛写的这么挫(举例而已,人家写的很好)
    1
    2
    3
    4
    5
    6
    7
    8
    $ git blame -C -L 84,90:Classes/PHPExcel/Shared/Date.php
    f7296f58 (MarkBaker 2015-05-13 00:40:55 +0100 84) public static function setExcelCalendar($baseDate)
    f7296f58 (MarkBaker 2015-05-13 00:40:55 +0100 85) {
    f7296f58 (MarkBaker 2015-05-13 00:40:55 +0100 86) if (($baseDate == self::CALENDAR_WINDOWS_1900) ||
    f7296f58 (MarkBaker 2015-05-13 00:40:55 +0100 87) ($baseDate == self::CALENDAR_MAC_1904)) {
    f7296f58 (MarkBaker 2015-05-13 00:40:55 +0100 88) self::$excelBaseDate = $baseDate;
    f7296f58 (MarkBaker 2015-05-13 00:40:55 +0100 89) return true;
    f7296f58 (MarkBaker 2015-05-13 00:40:55 +0100 90) }

git bisect

  • 我们要查找一个bug,但是不知道bug出在哪里,这个时候,我们可以告诉git哪一个版本的时候还是正常的,到哪一个版本之后就错误了
1
2
3
4
5
6
7
8
9
$ git bisect start # 我们要开始查找错误了
$ git bisect bad # 从这里开始就错误了
$ git bisect good f94dcb9852debe2f1068b828f4c27c7fddc92c7b # 这个版本的时候还是好的
Bisecting: 44 revisions left to test after this (roughly 6 steps)
[e7c7a6eb53e05daec307fa380bdf84bdb35f9363] Merge branch '1.8' of https://github.com/PHPOffice/PHPExcel into 1.8
$ git bisect bad # 如果你这个时候,还是不行,那么它就会继续查找
$ git bisect bad # 这次会继续尝试
$ git bisect good # 直到找到问题的根源,输入good标示, 这样查找结束
$ git bisect reset # 一定要记住,reset回原始状态,否则你就会停留在一个奇怪的提交树