Git基础知识总结
一、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 <file>..." to unstage) # 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 <dihaifeng@126.com> #Date: Mon Mar 20 14:43:57 2017 +0800 # add function count #commit e82db64408cde94ff6e5adf6967e55f029e23775 #Author: dihaifeng <dihaifeng@126.com> #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 <dihaifeng@126.com> 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 <file>..."的方式取消暂存。
相关命令详解:
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 <dihaifeng@126.com> # Date: Mon Mar 20 17:17:36 2017 +0800 # # my test # # commit ac0ea8f6cc42d4336c228a135c4a2fdc3962d8b1 # Author: dihaifeng <dihaifeng@126.com> # 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<tab><tab> commit config |