一、Git文件的三种状态:
已提交(committed):该文件已经被安全地保存在本地数据库中(git add 文件名)
已修改(modified):修改了某个文件,但没有提交保存(git status 查看当前状态)
已暂存(staged):已修改的文件放在下次提交时要保存的清单中(只要在 “Changes to be committed” 这行下面的,就说明是已暂存状态)
二、Git忽略某些文件(.gitignore):
一般我们总会有些文件纳入Git的管理,也不希望它们总出现在未跟踪文件列表里。通常都是写自动生成的文件,比如日志文件或者在编译过程中创建的临时文件等。
我们可以创建一个名为.gitignore的文件,列出要忽略的文件模式。例如:
1
2
3
4
|
cat
.gitignore
*.[oa]
*~
*.log
|
第一行告诉Git忽略所有以.o或者.a结尾的文件。一般这类对象文件和存档文件都是编译过程中出现的,我们用不着跟踪它们的版本。第二行告诉Git忽略所有以波浪线(~)结尾的文件。此外,你可能还需要忽略log,tmp或者pid目录,以及自动生成 文档等等。要养成一开始就设置好.gitignore文件的习惯,以免将来误提交这类无用文件。
文件.gitignore的格式规范如下:
所有空行或者以注释符号#开头的行会被Git忽略;
可以使用标准的glob模式匹配;
匹配模式最后跟反斜线(/)说明要忽略的是目录;
要忽略指定模式以外的文件或者目录,可以在模式上感叹号(!)取反;
所谓的glob模式是指shell所使用的简化了的正则表达式。星号(*)匹配零个或多个任意字符;[abc]匹配任何一个在方括号中的字符;问号(?)只匹配一个字符;如果字符方括号中使用短划线分割两个字符,表示所有在这两个字符范围的都可以匹配(如[0-9])。例如:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
#此为注释-将被Git忽略
#忽略所有.a结尾的文件
*.a
#但lib.a除外
!lib.a
#仅仅忽略项目根目录下的TODO文件,不包括subdir/TODO
/TODO
#忽略build/目录下的所有文件
build/
#会忽略 doc/notes.txt 但不包括doc/server/arch.txt
doc/*.txt
|
三、提交更新(git diff、git commit、git rm 、git mv)
3.1 查看暂存和未暂存的更新
实际上git status 的显示比较简单,仅仅是列出了修改过的文件,如果查看具体修改了什么地方,可以用git diff命令。git diff命令比较的是工作目录中当前文件和暂存区域快照之间的差异,也就是修改之后还没有暂存起来的变化内容。
1
2
3
4
5
6
7
8
9
10
11
|
$ git
diff
#只显示没有存入暂存区的文件
diff
--git a
/tongji
.py b
/tongji
.py
index 600e54e..a81a715 100644
--- a
/tongji
.py
+++ b
/tongji
.py
@@ -7,5 +7,3 @@ def monitor():
def
sum
(*args,**wargs):
pass
-def count():
- pass
|
若要看已经暂存起来的文件和上次提交时的快照之间的差异,可以使用git diff --cached 命令。(Git 1.6.1及更高版本还允许使用 git diff --staged,效果是相同的)。例如:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
$ git
diff
--staged
diff
--git a
/README
.md b
/README
.md
index 699a957..0721fbd 100644
--- a
/README
.md
+++ b
/README
.md
@@ -1,4 +1,13 @@
## /usr/bin/env python3
-
## -*- coding=utf-8 -*-
+
#上线:
+ 制定上线部署规范
+ 编译环境,是否可以使用静态库
+ 打包规范
+ 部署规范
+ 统一代码部署目录规范
+ 命名规范
+ 服务上下游拓扑图
+ 重启服务通知运维,将服务设置为维护时间
+ 开发设计时运维参与
|
3.2 更新
现在的暂存区已经准备妥当可以提交了,请一定要确认还有什么修改过的或新建的文件还没有git add过,否则提交的时候不会记录这些还没暂存起来的变化。
所以,每次提交前,先用git status 看下,是不是都已经暂存起来了,然后可以用git commit -m 提交说明 的方式,在一行命令中提交更新:
1
2
3
4
|
git commit -m
"update README"
[master]: created 463dw4f:
"update README"
2 files changed, 3 insertions(+), 0 deletions(-)
create mode 100644 README
|
可以看到,提交完它会告诉当前在那个分支(master)提交的,本次提交的完整SHA-1校验和是什么,以及本次提交中,有多少文件修订过,多少行添加和删除过。提交时记录是放在暂存区域的快照,任何还未暂存的仍然保持已修改状态,可以在下次提交时纳入版本管理。每一次运行提交操作,都是项目作一次快照,以后可以回到这个状态,或者进行比较。
3.3 跳过使用暂存区域
尽管使用暂存区域的方式可以精心准备要提交的细节,但有时候这么做略显繁琐。Git提供了一个跳过使用暂存区域的方式,只要在提交的时候,给git commit 加上-a选项,Git就会自动把所有已经跟踪过的文件暂存起来一并提交,从而跳过git add步骤:
1
|
git commit -a -m
"add function count"
#省略git add命令
|
3.4 移除文件
要从Git中移除某个文件,就必须要从已跟踪文件清单中移除( 确切地说,是从暂存区域移除),然后提交。可以用git rm命令完成此项工作,并连带从工作目录中删除指定的文件,这样以后就不会出现在未跟踪文件清单中了。
1
2
3
4
5
6
7
8
9
10
|
rm
test
git status
#查看文件在未跟踪的清单中
#Changes not staged for commit:
#deleted: test
#然后再运行git rm记录此次移除文件的操作:
git
rm
test
rm
'test'
git status
#此时查看已经不在清单中
|
最后提交的时候,该文件就不再纳入版本管理了。如果删除之前修改过并且已经放到暂存区的话,则必须要用强制删除选项-f(即:force的首字母),已防误删除文件后丢失修改的内容。另外一种情况,如果我们想把文件从Git仓库中删除(亦即从暂存区域删除),但仍然希望保留在当前工作目录中。换句话说,仅是从跟踪清单中删除。例如一些大型日志文件或者一堆.a编译文件,不小心纳入仓库中,要移除但不删除文件,以便稍后在.gitgnore文件中补上,用--cached选项即可:
1
2
3
4
5
6
7
|
git
rm
--cached readme.txt
#仅删除暂存区域文件,工作目录文件不会删除
#支持glob模式
git
rm
log/\*.log
#删除所有log/目录下扩展名为.log的文件
#递归删除
git
rm
\*~
#递归删除当前目录及其子目录中所有~结尾的文件
|
3.5 移动文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
$ git
mv
tongji.py count.py
$ git status
#On branch master
#Your branch is ahead of 'origin/master' by 2 commits.
#Changes to be committed:
# (use "git reset HEAD
# renamed: tongji.py -> count.py
#其实,运行git mv就相当于运行了下面三条命令:
$
mv
tongji,py count.py
$git
rm
tongji.py
$git add count.py
#切记:在执行批处理改名时,要记得在提交前删除老的文件名,在添加新的文件名
|
四、查看提交历史(git log)
在提交了若干更新之后,又或者克隆了某个项目,想回顾提交历史,可以使用git log 命令查看,具体输出如下:
1
2
3
4
5
6
7
8
9
10
11
12
|
$ git log
#查看提交历史
#commit 9f8d743ef00af3906654ca35be9eaa8cfa73e383
#Author: dihaifeng
#Date: Mon Mar 20 14:43:57 2017 +0800
# add function count
#commit e82db64408cde94ff6e5adf6967e55f029e23775
#Author: dihaifeng
#Date: Mon Mar 20 14:25:51 2017 +0800
# files update
|
默认不用任何参数的话,git log 会按提交时间列出所有的更新,最近的更新排在最上面。git log有许多选项可以帮助你搜寻感兴趣的提交,我们常用-p选项展开显示每次提交的内容差异,用-2则显示最近的两次更新:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
$ git log -p -1
#显示最近一次提交的内容差异
commit 9f8d743ef00af3906654ca35be9eaa8cfa73e383
Author: dihaifeng
Date: Mon Mar 20 14:43:57 2017 +0800
add
function
count
diff
--git a
/tongji
.py b
/tongji
.py
index a81a715..600e54e 100644
--- a
/tongji
.py
+++ b
/tongji
.py
@@ -7,3 +7,5 @@ def monitor():
def
sum
(*args,**wargs):
pass
+def count():
+ pass
|
在做代码审查,或者要快速浏览其他协作者提交的更新都作了那些改动时,就可以用这个选项。此外,还有许多摘要选项可以用,例如
--stat :仅显示简要的增改行数统计。
--pretty:
--pretty=oneline:将每个提交放在一行显示,还有short、full、fuller可以用,展示的信息或多或少有些不同。
1
2
|
#git log --pretty=oneline -1
#9f8d743ef00af3906654ca35be9eaa8cfa73e383 add function count
|
--pretty=format:可以定制要显示的记录格式,这样的输出便于后期编程提取分析
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
28
29
30
31
32
33
34
35
|
#$ git log --pretty=format:"%H - %cn" -1
#9f8d743ef00af3906654ca35be9eaa8cfa73e383 - dihaifeng
#常用的格式占位符写法及其代表的意义:
# 选项 说明 # %H 提交对象(commit)的完整哈希字串
# %h 提交对象的简短哈希字串
# %T 树对象(tree)的完整哈希字串
# %t 树对象的简短哈希字串
# %P 父对象(parent)的完整哈希字串
# %p 父对象的简短哈希字串
# %an 作者(author)的名字
# %ae 作者的电子邮件地址
# %ad 作者修订日期(可以用 -date= 选项定制格式)
# %ar 作者修订日期,按多久以前的方式显示
# %cn 提交者(committer)的名字
# %ce 提交者的电子邮件地址
# %cd 提交日期
# %cr 提交日期,按多久以前的方式显示
# %s 提交说明
|
git log 命令的具体选项如下:
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
28
29
|
#选项 说明
# -p 按补丁格式显示每个更新之间的差异。
# --stat 显示每次更新的文件修改统计信息。
# --shortstat 只显示 --stat 中最后的行数修改添加移除统计。
# --name-only 仅在提交信息后显示已修改的文件清单。
# --name-status 显示新增、修改、删除的文件清单。
# --abbrev-commit 仅显示 SHA-1 的前几个字符,而非所有的 40 个字符。
# --relative-date 使用较短的相对时间显示(比如,“2 weeks ago”)。
# --graph 显示 ASCII 图形表示的分支合并历史。
# --pretty 使用其他格式显示历史提交信息。可用的选项包括 oneline,short,full,fuller 和 format(后跟指定格式)。
# -(n) 仅显示最近的 n 条提交
# --since, --after 仅显示指定时间之后的提交。
# --until, --before 仅显示指定时间之前的提交。
# --author 仅显示指定作者相关的提交。
# --committer 仅显示指定提交者相关的提交。
|
五、撤销操作(git reset )、远程仓库(git remote、git fetch、git push)
任何时候,都有可能需要撤销刚才所做的某些操作。接下来,学习几个撤销操作相关的命令,切记有些撤销操作是不可逆的,所有请务必谨慎操作。可以通过git commit --amend 命令 ,相当于有机会重新提交说明就在“Changes to be comitted”下面,括号中有提示,可以使用git reset HEAD
相关命令详解:
1
2
3
4
5
6
7
8
9
10
11
|
# git reset HEAD count.py #从暂存区域撤销回工作目录
#git remote -v #查看当前远程库
#git remote add pb git://github.com/paulboone/ticgit.git #pb指对应的仓库地址
#git fetch pb #抓取所有Paul有的,但本地仓库没有的信息
#git push orrigin master #推送数据到远程仓库
#git remote show origin #查看远程仓库信息
|
六、打标签
Git可以对某一时间点上的版本打上标签,人们在发布某个版本的时候,经常这么做。下面具体了解一下如何列出所有标签,如果新建标签,以及不同类型标签之间的差别。
6.1 列显已有的标签
列出现有标签的命令非常简单,直接运行git tag 即可:
1
2
|
# git tag #显示所有标签
v1.0
|
我们可以用特定的搜索模式列出符合条件的标签,如果只对1.4.2系列版本感兴趣,可以运行下面的命令:
1
|
# git tag -l 'v1.4.2.*' #列出v1.4.2下面系列的版本
|
6.2 新建标签
Git使用的标签有两种类型:轻量级的(lightweight)和含备注的(annotated)。
含附注的标签:创建一个含附注类型的标签非常简单,用-a指定标签的名字即可;
轻量级标签:实际就是一个保存着对应提交对象的校验和信息文件.要创建这样的标签,一个-a,-s ,-m都不用,直接给出标签名字即可:如 git tag v1.2-lw
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
|
# git tag -a v1.1 -m "my test" #打含附注的标签
# git show v1.1 #查看相应标签的版本信息
# tag v1.1
# Tagger: dihaifeng
# Date: Mon Mar 20 17:17:36 2017 +0800
#
# my test
#
# commit ac0ea8f6cc42d4336c228a135c4a2fdc3962d8b1
# Author: dihaifeng
# Date: Mon Mar 20 16:44:03 2017 +0800
#
# test
#
# diff --git a/count.py b/count.py
# index 600e54e..a81a715 100644
# --- a/count.py
# +++ b/count.py
# @@ -7,5 +7,3 @@ def monitor():
# def sum(*args,**wargs):
# pass
#
# -def count():
# - pass
|
如果有自己的私钥,还可以用GPG来签署标签,只需要把之前的-a 改为-s 即可。
七、分享标签
默认情况下,git push并不会把标签传送到远端服务器上,只有通过显示命令才能分享标签到远端仓库。其命令格式如同推送分支,运行git push origin [tagname]即可:
1
2
3
4
5
6
|
git push origin v1.0
#将标签推送到远程仓库
#如果要一次推送所有本地新增的标签上QQ,可以使用 --tags
git push origin --tags
# 这样其他人克隆共享仓库或拉取数据同步后,也会看到这些标签
|
八、使用技巧
8.1 自动补全:
如果你用的是 Bash shell,可以试试看 Git 提供的自动补全脚本。下载 Git 的源代码,进入 contrib/completion
目录,会看到一个 git-completion.bash
文件。将此文件复制到你自己的用户主目录中(译注:按照下面的示例,还应改名加上点:cp git-completion.bash ~/.git-completion.bash
),并把下面一行内容添加到你的 .bashrc
文件中:
1
|
source
~/.git-completion.
bash
|
可以为系统上所有用户都设置默认使用此脚本。Mac 上将此脚本复制到 /opt/local/etc/bash_completion.d
目录中,Linux 上则复制 /etc/bash_completion.d/
目录中。这两处目录中的脚本,都会在 Bash 启动时自动加载。如果在 Windows 上安装了 msysGit,默认使用的 Git Bash 就已经配好了这个自动补全脚本,可以直接使用。在输入 Git 命令的时候可以敲两次跳格键(Tab),就会看到列出所有匹配的可用命令建议:
1
2
|
git co
commit config
|