Git-基本概念

Git Object

  • git object,git 对象,用于存放信息,而且具备必定的结构.linux

  • 每个 git object 都被 40 位的 SHA1 值惟一索引.便可以经过 40 位 SHA1 值来访问对应的 git object.git

不一样类型的 git object

  • commit object,用于保存一个提交相关的信息,如提交者,提交时间,提交的说明...,commit object 的结构如:shell

$ git cat-file -p master   # 显示 master 引用的提交对象的内容.
tree b9335367560fcbb14669227c427d3020cb10362c  # 该提交对象对应的 tree object.
parent 11176be04831f5cd8c8947b4b0eaa182595ad069 # 该 commit object 的父提交对象
author WangXiaoWei <1258941862@qq.com> 1401371236 +0800 # 提交做者
committer WangXiaoWei <1258941862@qq.com> 1401428713 +0800 # 提交者

新增 protect 子命令 # 提交的注释信息.

  • tag object,标签对象,保存着标签相关信息,结构如:函数

$ git cat-file -t afa17d1
tag         # afa17d1 指向着一个 tag object.
$ git cat-file -p afa17d1
object 836dc9e3fbbab0c30aa6e664417225f5c1fb1c39 # 该 tag object 引用的 git object 的 SHA1 值.
type commit     # 用于代表上述 object 的类型,是一个 commit object.
tag v3.8-rc7    # 该 tag object 的名称. 
tagger Linus Torvalds <torvalds@linux-foundation.org> 1360358456 +1100 
# 建立该 tag object 的做者以及时间.

Linux 3.8-rc7   # 该 tag object 的注释.

  • blob object,文件对象,保存着一个文件的完整内容.如:测试

$ git cat-file -t  6f109854c5d4
blob  # 代表 6f109854c5d4 指向着一个 blob object
$ git cat-file -p  6f109854c5d4  # 显示 blob object 的内容,就是文件内容.
/**
 * @file .
 * Created on: 2014年5月28日 下午3:20:44 Author: WangXiaoWei
 * 包含了 main.cc 函数中可能会使用到的函数原型.
 */

#ifndef MMAP_MAIN_H_
#define MMAP_MAIN_H_

int parse_cmdline(char *cmdline,char **argv,int argv_len);
int get_show_args(int argc,char **argv,int *off,int *len);
int get_unmap_args(int argc,char **argv,int *off,int *len);
int get_modify_args(int argc,char **argv,int *off,char **str);
int get_protect_args(int argc,char **argv,int *off,int *len,int *prot);
int str2int(const char *str,int *output);
char* prot2str(int prot,char *buf);

#endif /* MMAP_MAIN_H_ */

  • tree object,目录树信息,保存着在该目录下子目录,与文件的信息.其结构以下:spa

    • 对于子目录,则存放着子目录名,子目录的状态信息,子目录对应的 tree object 的 SHA1 值.3d

    • 对于文件,则存放着文件名,文件的状态信息(如: 文件的最后一次修改时间...),文件对应的 blob object 的 SHA1 值指针

$ git cat-file -t 4c58c57
tree # 代表 4c58c57 指向着一个 tree object.
$ git cat-file -p 4c58c57 # 该 tree object 的内容
100644 blob 42fa0d5626a9560d74d16b2df5250b300543b67e    .gitignore  # 文件
100644 blob c596b74b29d532246b3646086c77381076ad3c15    MAINTAINERS # 文件
100644 blob 8a8440a3578e1d3b2fde55625fbc506a5d2979e4    Makefile    # 文件 
100644 blob a24ec89ba4420ad38e8848422ca5f69baa5ffe1c    README      # 文件
040000 tree f1ef1ece9e8b963629398f632f041a8e94ac536d    arch        # 子目录
040000 tree 0e2802a3add8c60f0d2f57b6662cdd2707a613d3    block       # 子目录
040000 tree 62f2007ef4f418c65b33dec22f767ae7fd5ee7e2    crypto      # 子目录

访问 git object

  • 最基本,最底层的访问方式: 经过 40 位 SHA1 值来访问 git object.code

# 经过 40 位 SHA1 值来访问其对应的 git object
$ git cat-file -t 836dc9e3fbbab0c30aa6e664417225f5c1fb1c39   # 指向的 git object 的类型.
commit
$ git cat-file -s 836dc9e3fbbab0c30aa6e664417225f5c1fb1c39   # 指向的 git object 的尺寸.
254
$ git cat-file -p 836dc9e3fbbab0c30aa6e664417225f5c1fb1c39   # 指向的 git object 的内容. 
tree 8d490c389d08035d6c1a926d9b89b3b07f0edf7d
parent 39923134885759405e64cb9491a273a2bcd356ed
author Linus Torvalds <torvalds@linux-foundation.org> 1360358439 +1100
committer Linus Torvalds <torvalds@linux-foundation.org> 1360358439 +1100

Linux 3.8-rc7

  •  采用部分的 SHA1 值,没必要将 40 位的哈希值写全.即只采用开头 n 位的哈希值(至少 4 位),如:对象

$ git cat-file -p 836dc9     # 使用开头 6 位 SHA1 值.  
tree 8d490c389d08035d6c1a926d9b89b3b07f0edf7d
parent 39923134885759405e64cb9491a273a2bcd356ed
author Linus Torvalds <torvalds@linux-foundation.org> 1360358439 +1100
committer Linus Torvalds <torvalds@linux-foundation.org> 1360358439 +1100

Linux 3.8-rc7

对于 commit object ,能够:

  • 使用 ^ 访问该 commit object 的父提交.

  • 使用 ~n 访问该 commit object 的祖先提交,如:

# master~2 等同于 master^^
$ git rev-parse master^^
68cb363a4ddc335fddf6e2ccb03e4a907ba7afbf
$ git rev-parse master~2
68cb363a4ddc335fddf6e2ccb03e4a907ba7afbf

  • 当一个 commit object 具备多个父提交时,使用 ^n 访问该 commit object 的第 n 个父提交.如:

$ git cat-file -p master # 使用 master 来访问其引用的 commit object.
tree 4c58c5747529b74502352b185515af43e26c0666
parent 77d92784b46549e00f7b99794cd566045ded62ba 
parent cf01f4eef9fe367ec0d85b38dd7214e29e376cdb
...
$ git rev-parse master^1 # 第 1 个父提交
77d92784b46549e00f7b99794cd566045ded62ba
$ git rev-parse master^2 # 第 2 个父提交
cf01f4eef9fe367ec0d85b38dd7214e29e376cdb

  • 使用 ^{tree} 来访问该 commit object 对应的 tree object.

$ git cat-file -p master
tree b9335367560fcbb14669227c427d3020cb10362c
parent 11176be04831f5cd8c8947b4b0eaa182595ad069
author WangXiaoWei <1258941862@qq.com> 1401371236 +0800
committer WangXiaoWei <1258941862@qq.com> 1401428713 +0800

新增 protect 子命令
$ git rev-parse master^{tree} 
b9335367560fcbb14669227c427d3020cb10362c

  • 使用 :path 来访问路径为 path 的 blob object/tree object,此时 path 为相对路径,相对于工做区的路径.

# lib 为相对路径,其完整路径为:~/CCProject/linux/lib
~/CCProject/linux$ git cat-file -t master:lib 
tree
# 其完整路径为: ~/CCProject/linux/crypto/cryptd.c
~/CCProject/linux$ git cat-file -t master:crypto/cryptd.c 
blob

对于 tag object,能够:

  • 使用 ^{} 来访问标签 tag 对应的 commit objec,如:

$ git cat-file -p v3.9
object c1be5a5b1b355d40e6cf79cc979eb66dafa24ad1
type commit
tag v3.9
tagger Linus Torvalds <torvalds@linux-foundation.org> 1367195769 -0700

Linux 3.9
$ git rev-parse v3.9^{} # v3.9 对应的 commit object.
c1be5a5b1b355d40e6cf79cc979eb66dafa24ad1

对于 tree object,能够:

  • 使用 :path 来访问 tree object 中 path 对应的 blob object/tree object.此时 path 为相对路径,至关于 tree object 的路径.

~/CCProject/linux$ git cat-file -p master^{tree}
040000 tree f1ef1ece9e8b963629398f632f041a8e94ac536d    arch
...
~/CCProject/linux$ ls arch/
alpha  arm    avr32     c6x   frv      ia64     m32r  metag       mips     openrisc  powerpc  score  sparc  um         x86
arc    arm64  blackfin  cris  hexagon  Kconfig  m68k  microblaze  mn10300  parisc    s390     sh     tile   unicore32  xtensa
#frv 是一个相对路径,相对于 f1ef1ece,其对应的完整路径为: ~/CCProject/linux/arch/frv.
~/CCProject/linux$ git cat-file -t f1ef1ece:frv         
tree
~/CCProject/linux$ git cat-file -t f1ef1ece:Kconfig
blob

引用

  • 引用,就是一个文件,文件内容为它引用的 git object 的 SHA1 值.

# master 是一个引用,其对应的文件: .git/refs/heads/master 
$ cat .git/refs/heads/master 
48549924cecf749cbfbf697f6ee34f06c6db26a1

  • 能够经过引用的全名来访问引用,也能够在不引发歧义下仅使用引用名,如:

$ git rev-parse refs/heads/master # master 引用的全名
48549924cecf749cbfbf697f6ee34f06c6db26a1
$ git rev-parse master            # 不引发歧义
48549924cecf749cbfbf697f6ee34f06c6db26a1
$ git tag -m"Test" master         # 建立一个名为 master 的标签
$ git rev-parse refs/tags/master  
85176002003cd5f11c349c61c9122e40c64d6578
$ git rev-parse master # 引发歧义,由于 master 既能够是 refs/heads/master,也能够是 refs/tags/master
warning: refname 'master' is ambiguous.
85176002003cd5f11c349c61c9122e40c64d6578

常见引用

  • .git/refs/ 引用空间,该目录下全部文件都是引用.

    • heads/ 该目录下全部文件都是对 commit object 的引用,又被称为分支.

    • tags/ 该目录下全部文件都是对 commit object/tag object 的引用,又被称为标签.

    • stash 该文件是对进度列表的引用(描述的不许确).

    • remotes/ 该目录下存放着对远程版本库上分支的引用.

      • 远程版本库1 该目录下存放着引用文件,都是对远程版本库1的分支的引用.

      • 远程版本库2 该目录下存放着引用文件,都是对远程版本库2的分支的引用.

      • ...

.git/refs/remotes/origin:
总用量 24
-rw-r--r-- 1 root root 32  5月  2 23:58 HEAD
-rw-r--r-- 1 root root 41  5月 30 18:41 maint   # 对远程版本库 maint 分支的引用
-rw-r--r-- 1 root root 41  5月 30 18:41 master
-rw-r--r-- 1 root root 41  5月 30 18:41 next
-rw-r--r-- 1 root root 41  5月 30 18:41 pu
-rw-r--r-- 1 root root 41  5月 30 18:41 todo

  • .git/HEAD 一个引用文件,若当前处于分离头指针的状态,则 HEAD 文件中记录着当前最后一次提交对应的提交 ID.不然指向着当前所处的分支.

$ cat .git/HEAD 
ref: refs/heads/master     # 代表当前处于 master 分支.
$ git checkout origin/next # 此时会进入分离头指针状态.
$ cat .git/HEAD 
5318336450357c9ecf6ffed2ca846e4c22dbfb7c # 代表当前处在分离头指针状态

分离头指针

  • 进入分离头指针状态,就像处在一个无名分支上,此时能够进行在常规分支下进行的操做,如:检查,测试,提交.

    • 当进入分离头指针状态时,git 会进行提示,而且此时从 git status 的输出中也能够看的出来.

  • 当使用 git checkout <branch> 切换到一个其余分支上时,在无名分支下所作的修改与提交会被丢弃.

  • 使用 git checkout -b <branch> 建立一个新的分支来追踪当前提交,如:

$ git checkout 49a5d7
Note: checking out '49a5d7'.
你正在处于分离头指针的状态.
若是你要是想建立一个新的分支来追踪提交,你可使用:
  git checkout -b new_branch_name
HEAD 目前位于 49a5d7d... 新增 protect 子命令

$ git status
HEAD detached at 49a5d7d # 代表此时处于分离头指针的状态
nothing to commit, working directory clean

$ git checkout -b Test_Branch # 建立一个新的分支来追踪提交.
切换到一个新分支 'Test_Branch'

$ git branch
* Test_Branch
  master

文件忽略

  • 文件忽略,对于 git 而言,忽略的文件就像从不存在同样!如:

$ git status
 位于分支 master
 Untracked files:
       .cproject
       .project
       Debug/  
       checksum.cc
       log
       mmap
       test.cc
       test.h
       write.cc
nothing added to commit but untracked files present (use "git add" to track)

$ kate .gitignore 
# 编辑 .gitignore 文件,输入如下内容:
# Debug/
# .*

$ git status
 位于分支 master
 Untracked files:
       # 能够看出设置为忽略的文件,没有再出现
       checksum.cc
       log
       mmap
       test.cc
       test.h
       write.cc
nothing added to commit but untracked files present (use "git add" to track)
# 被忽略的文件也不会被 add 到.
$ git add -Av  
add 'checksum.cc'
add 'log'
add 'mmap'
add 'test.cc'
add 'test.h'
add 'write.cc'

  • 当文件已经添加到暂存区后,忽略将会无效.

实现文件忽略:

  • 经过编写 .gitignore 文件.

    • 经过将 .gitignore 添加到版本库中,可让文件忽略在他人的工做区也有效,即由于 .gitignore 位于版本库中,因此当他们 git clone 版本库时,也会将 .gitignore 下载下来,因此文件忽略生效.

    • 也能够在 .gitignore 文件中忽略自身,如上.这样 .gitignore 就不会加入到版本库中,就成为了本地独享式忽略文件.

    • .gitignore 文件只对当前目录及其子目录有效.

$ git status
位于分支 master
Untracked files:
      World
      a/World
nothing added to commit but untracked files present (use "git add" to track)

$ kate .gitignore
# 输入:
# .*
# World

$ git status
位于分支 master
    # 文件 World a/World 均被忽略
nothing to commit, working directory clean

$ mv .gitignore a/
$ git status
位于分支 master
Untracked files:
    # 仅 a/World 被忽略,即 .gitignore 只对当前目录及其子目录有效
      World  
nothing added to commit but untracked files present (use "git add" to track)

  • 经过编写  .git/info/exclude 文件.

    • 只能是独享式忽略,而且仅局限在一个版本库中.

~/Gi$ cat .git/info/exclude 
.*
World

~$ git clone Gi/ Gi1
正克隆到 'Gi1'...
完成。
Checking connectivity... done

# 并无将 Gi 版本库中的 .git/info/exclude 内容下载下来 
Gi1$ cat .git/info/exclude  
git ls-files --others --exclude-from=.git/info/exclude
...

  • 经过设置 core.excludesfile 属性.

    • 只能是独享式忽略,不过能够经过 git config --system core.excludesfile 来做用于本地全部的版本库中.

.gitignore 忽略文件的编写

  • 以'#'开头的行为注释行.

  • 每行放置一个模式,知足模式的文件/目录将被忽略.可用的通配符:

    • * 表示任意多的任意字符; ? 表示任意一个字符;

  • 若是模式最后面是'/',则代表知足模式的目录,而不忽略知足模式的文件.

  • 若是模式的最前面是'!',则表示不忽略匹配该模式的文件/目录.

  • 若是模式的最前面是'/',则代表仅忽略当前目录下知足模式的文件/目录,而不忽略子目录下知足模式文件/目录.

相关文章
相关标签/搜索