您的位置:首页 > 其它

git 笔记记录(七) git基本操作

bluceshang 2013-11-25 19:33 84 查看
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]代表可选字符范
如果名称的最前面是一个路径分隔符(/)表明要忽略文件在此目录下,而非子目录的文件.
如果名称的最后面是一个路径分隔符(/),青蛙要忽略的是整下目录,同名的文件不忽略,否则同名的文件和目录都忽略.
通过在名称前面添加一个!,代表不忽略

# 这是注释行 -- 被忽略
*.a #忽略所有以.a为扩展名的文件
!lib.a #不忽略lib.a
/TODO #只忽略此目录下的TODO文件,子目录的TODO文件不忽略
build/ #忽略所有build/目录下的文件
doc/*.txt #角力文件如doc/notes.txt 但是文件doc/server/arch.txt不忽略

文件归档
压缩工具会将所有文件压缩到其中,包括忽略文件.git archive不会.
最新的提交建立归档文件
git archive -o latest.zip HEAD
只将目录src和doc建立到归档partial.tar中
git archive -o partial.tar HEAD src doc
基于里程碑v1.0建立归档,并且为归档中的文件添加目录前缀1.0
git archive --format=tar --prefix=1.0/v1.0 | gzip >foo-1.0.tar.gz

版本表示法
命令git rev-parse是Git的一个底层命令,功能非常丰富.如显示版本库的位置(--git-dir),当前工作目录的深度(--show-cdup)
1.显示分支
bluceshang@bluceshang:~/gittemp$ git rev-parse --symbolic --branches
branch_1.0
master
2.显示里程碑
bluceshang@bluceshang:~/gittemp$ git rev-parse --symbolic --tags
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.显示日志范围
命令git log的后面可以接表示版本的范围的参数,当不使用任何表示版本范围的参数时,相当于使用了默认的参数HEAD,即显示当前HEAD能够访问的所有历史提交,

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
在开发中当发现Bug并定位到具体代码时,git的文件追溯命令可以指出是谁在什么时候,以及什么版本引入的Bug 只想查看某几行,使用-L n,m参数.
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.
标签: