1.对当前的操作创建一个Tag(专业术语叫里程碑,也叫打标签),里程碑也是一个引用.存放在.git/refs/tags目录下.
bluceshang@bluceshang:~/gittemp$git tag -m "Say bye-bye " old_practice
-m是tag说明,最后面是标签名称,名称可以自己定义,这样就打了一个里程碑,可以进行查看刚才打的tag.
bluceshang@bluceshang:~/gittemp$ git tag
old_practice
在.git/refs/tags目录下就有了一个old_practice的文件,存放的是一个引用.
bluceshang@bluceshang:~/gittemp$ git rev-parse .git/refs/tags/old_practice
.git/refs/tags/old_practice
2.删除命令
rm删除的只是本地文件,而对暂存区与版本库没有影响
bluceshang@bluceshang:~/gittemp$ rm readme.txt
bluceshang@bluceshang:~/gittemp$ git status -s
D readme.txt
恢复刚才删除的文件用checkout 命令恢复
bluceshang@bluceshang:~/gittemp$ git checkout -- readme.txt
bluceshang@bluceshang:~/gittemp$ ls
a detached-commit.txt new-commmit.txt readme.txt welcome.txt
发现readme.txt文件又回来了,如果要删除暂存区文件,用git rm
bluceshang@bluceshang:~/gittemp$ git rm readme.txt
rm 'readme.txt'
bluceshang@bluceshang:~/gittemp$ git status -s
D readme.txt
bluceshang@bluceshang:~/gittemp$ git ls-files
a/b/c/hello.txt
detached-commit.txt
new-commmit.txt
welcome.txt
readme.txt文件不见了.
恢复刚才删除的文件
bluceshang@bluceshang:~/gittemp$ git checkout HEAD readme.txt
如果文件从工作区/暂存区/版本库都删除了怎么办?没关系,从历史记录中可以很简单的找回.
bluceshang@bluceshang:~/gittemp$ git rm readme.txt
rm 'readme.txt'
bluceshang@bluceshang:~/gittemp$ git commit -m "delete readme file"
[master 530dca8] delete readme file
1 file changed, 2 deletions(-)
delete mode 100644 readme.txt
bluceshang@bluceshang:~/gittemp$ git checkout HEAD~1 -- readme.txt
bluceshang@bluceshang:~/gittemp$ git status -s
A readme.txt
git cat-file -p HEAD~1 :readme.txt >readme.txt
git show HEAD~1:readme.txt>readme.txt
git checkout HEAD~1 -- readme.txt
上面本条命令都是从历史中恢复文件.
注:通过再次添加的方式恢复被删除文件是最自然的方法.其它版本制件器如svn这样操作会有严重的副作用,文件变更历史被人为地割裂,而且还会千百万服务器存储空间的浪费.Git通过添加文件反复删除文件没有副作用,因为在Git版本中相同的内容的文件保存在一个blob中,即便是内容不的blob对象通过对象打包也会进行存储优化.
移动文件 修改文件名称,Git的改名操作相当于git rm与git add两条操作.
bluceshang@bluceshang:~/gittemp$ git mv new-commmit.txt new_commmit.txt
bluceshang@bluceshang:~/gittemp$ git status -s
R new-commmit.txt -> new_commmit.txt
bluceshang@bluceshang:~/gittemp$ git commit -m "改名测试"
[master 01dce67] 改名测试
1 file changed, 0 insertions(+), 0 deletions(-)
rename new-commmit.txt => new_commmit.txt (100%)
前面有一个tag,现在查看一下版本号 ,3表示tag后的第三个版本,后面是提交Id
bluceshang@bluceshang:~/gittemp$ git describe
old_practice-3-g01dce67
bluceshang@bluceshang:~/gittemp$ git log --oneline --decorate -4
01dce67 (HEAD, master) 改名测试
bec1459 restore file:readme.txt
530dca8 delete readme file
84f0e65 (tag: old_practice) last commit.
选择性提交,参数-i是选择提交文件.
bluceshang@bluceshang:~/gittemp/src$ git add -i
staged unstaged path
*** Commands ***
1: status 2: update 3: revert 4: add untracked
5: patch 6: diff 7: quit 8: help
What now> 4
1: src/Makefile
2: src/hello
3: src/main.c
4: src/main.o
5: src/version.h
6: src/version.h.in
Add untracked>>
added 3 paths
*** Commands ***
1: status 2: update 3: revert 4: add untracked
5: patch 6: diff 7: quit 8: help
What now> q
Bye.
文件忽略,有的本地临时文件不想提交,用.gitignore,添加gitingore后,发现不需要的临时文件没有了.
bluceshang@bluceshang:~/gittemp/src$ cat >.gitignore<<EOF
> hello
> *.o
> *.h
> EOF
bluceshang@bluceshang:~/gittemp/src$ git add .gitignore
bluceshang@bluceshang:~/gittemp/src$ git commit -m "ignore object files."
[master 7c2a528] ignore object files.
1 file changed, 3 insertions(+)
create mode 100644 src/.gitignore
bluceshang@bluceshang:~/gittemp/src$ git status -s
上面忽略了所有.h的文件,如果添加了.h文件,则查看不了其文件状态,必须要加--ignored,如果要添加则用-f
bluceshang@bluceshang:~/gittemp/src$ touch hello.h
bluceshang@bluceshang:~/gittemp/src$ git status -s
bluceshang@bluceshang:~/gittemp/src$ git status --ignored -s
!! hello
!! hello.h
!! main.o
!! version.h
bluceshang@bluceshang:~/gittemp/src$ git add -f hello.h
bluceshang@bluceshang:~/gittemp/src$ git commit -m "add hello.h"
[master 3a92e79] add hello.h
0 files changed
create mode 100644 src/hello.h
文件hello.h加入版本库之后,就不再受.gitignore影响了.
注:刚才用的是共享式忽略,即使用此工程的所有人都会忽略这些文件,还有独享式的忽略,独享式的忽略是在.git目录下的一个文件.git/info/exclude来设置文件忽略.另一种 是全局设置,通过git配置变量core.excludesfile指定一个忽略文件.
注:忽略语法
- 忽略文件中的空行或以#号开始的行会被忽略
- 可以使用通配符,*代表任意多字符,?代表一个字符[abc]代表可选字符范
- 如果名称的最前面是一个路径分隔符(/)表明要忽略文件在此目录下,而非子目录的文件.
- 如果名称的最后面是一个路径分隔符(/),青蛙要忽略的是整下目录,同名的文件不忽略,否则同名的文件和目录都忽略.
- 通过在名称前面添加一个!,代表不忽略
bluceshang@bluceshang:~/gittemp$ git rev-parse --symbolic --branches
branch_1.0
master
2.显示里程碑
hello_1.0
old_practice
3.显示定义的所有引用
bluceshang@bluceshang:~/gittemp$ git rev-parse --symbolic --glob=refs/*
refs/heads/branch_1.0
refs/heads/master
refs/tags/hello_1.0
refs/tags/old_practice
4.可以同时显示多个表达式的SHA1值
bluceshang@bluceshang:~/gittemp$ git rev-parse master HEAD
b83f4cb6466d830c718b378c783e4fc1d24fb7b2
b83f4cb6466d830c718b378c783e4fc1d24fb7b2
5.显示里程碑hello_1.0对应的目录树,以下2种方法
bluceshang@bluceshang:~/gittemp$ git rev-parse hello_1.0^{tree} hello_1.0:
a31d51ad9474433200090195d4d0252f2cab0436
a31d51ad9474433200090195d4d0252f2cab0436
6.查看树里面的文件
bluceshang@bluceshang:~/gittemp$ git rev-parse hello_1.0^{tree}:welcome.txt hello_1.0:welcome.txt
6f8949d155c24a1232f0c90e66a043a37239e30e
6f8949d155c24a1232f0c90e66a043a37239e30e
7.暂存区里的文件和HEAD中的文件相同
bluceshang@bluceshang:~/gittemp$ git rev-parse :welcome.txt HEAD:welcome.txt
6f8949d155c24a1232f0c90e66a043a37239e30e
6f8949d155c24a1232f0c90e66a043a37239e30e
8一个提交ID实际上可以代表一个版本列表,含义是该版本开始的所有历史提交
bluceshang@bluceshang:~/gittemp/gitdemo-commit-tree$ git rev-list --oneline A
8199323 Commit A: merge B with C.
0cd7f2e commit C.
776c5c9 Commit B: merge D with E and F
beb30ca Commit F: merge I with J
212efce Commit D: merge G with H
634836c commit I.
3252fcc commit J.
83be369 commit E.
2ab52ad commit H.
e80aa74 commit G.
9.在一个版本前面加上符号(^)含义是取反,即排除这个版本及其历史提交
bluceshang@bluceshang:~/gittemp/gitdemo-commit-tree$ git rev-list --oneline ^G D
212efce Commit D: merge G with H
2ab52ad commit H.
和上面等价的".."表示法,使用2个点点连接两个版本如G..D,就相当于^G D.
bluceshang@bluceshang:~/gittemp/gitdemo-commit-tree$ git rev-list --oneline G..D
212efce Commit D: merge G with H
2ab52ad commit H.
10.某提交的历史提交,自身除外,用语法r1^@
bluceshang@bluceshang:~/gittemp/gitdemo-commit-tree$ git rev-list --oneline B^@
beb30ca Commit F: merge I with J
212efce Commit D: merge G with H
634836c commit I.
3252fcc commit J.
83be369 commit E.
2ab52ad commit H.
e80aa74 commit G.
11.显示日志范围
bluceshang@bluceshang:~/gittemp/gitdemo-commit-tree$ git log --oneline D
212efce Commit D: merge G with H
2ab52ad commit H.
e80aa74 commit G.
12.显示最近的几条日志
bluceshang@bluceshang:~/gittemp/gitdemo-commit-tree$ git log -3 --oneline
6652a0d Add Images for git treeview.
8199323 Commit A: merge B with C.
0cd7f2e commit C.
13比较命令DIff
- 比较里程碑B和里程碑A,用命令:git diff B A
- 比较工作区和里程碑用A,用命令:git diff A
- 比较暂存区和里程碑A,用命令:git diff --cached A
- 比较工作区与暂存区,用命令:git diff
- 比较暂存区与HEAD,用命令:git diff --cached
- 比较工作区与HEAD,用命令:git diff HEAD
14 git blame
bluceshang@bluceshang:~/gittemp/gitdemo-commit-tree$ git blame README
^e80aa74 (Jiang Xin 2010-12-09 14:00:33 +0800 1) DEMO program for git-scm-book.
^e80aa74 (Jiang Xin 2010-12-09 14:00:33 +0800 2)
^e80aa74 (Jiang Xin 2010-12-09 14:00:33 +0800 3) Changes
^e80aa74 (Jiang Xin 2010-12-09 14:00:33 +0800 4) =======
^e80aa74 (Jiang Xin 2010-12-09 14:00:33 +0800 5)
81993234 (Jiang Xin 2010-12-09 14:30:15 +0800 6) * create node A.
0cd7f2ea (Jiang Xin 2010-12-09 14:29:09 +0800 7) * create node C.
776c5c9d (Jiang Xin 2010-12-09 14:27:31 +0800 8) * create node B.
beb30ca7 (Jiang Xin 2010-12-09 14:11:01 +0800 9) * create node F.
^3252fcc (Jiang Xin 2010-12-09 14:00:33 +0800 10) * create node J.
^634836c (Jiang Xin 2010-12-09 14:00:33 +0800 11) * create node I.
^83be369 (Jiang Xin 2010-12-09 14:00:33 +0800 12) * create node E.
212efce1 (Jiang Xin 2010-12-09 14:06:34 +0800 13) * create node D.
^2ab52ad (Jiang Xin 2010-12-09 14:00:33 +0800 14) * create node H.
^e80aa74 (Jiang Xin 2010-12-09 14:00:33 +0800 15) * create node G.
^e80aa74 (Jiang Xin 2010-12-09 14:00:33 +0800 16) * initialized.