理解git常用命令原理

今天想了解git blame 是从怎样获取文件中每行的owner的?要深入了解git command 还是很有必要了解git 的工作原理的。今后将git 常用命令的工作原理相关的东东整理在这里:

SHA:所有用来表示项目历史信息的文件,是通过一个40个字符的(40-digit)“对象名”来索引的。

SHA-1是一种加密哈希函数(cryptographic hash function),另外两种SHA(secure hash algorithm)算法是SHA-0和SHA-2。SHA-1将文件中的内容通过其hash算法生成一个160bit的报文摘要,即40个十六进制数字(每个十六进制数字占4位)。它几乎可以保证,如果两个文件的SHA-1值是相同的,那么它们确是完全相同的内容(类似于生活中的指纹识别);不过也不是绝对的安全可靠,最新资料显示,理论上对其进行哈希碰撞(hash collision,不同的两块数据有相同的hash值)的攻击可以在2^51(2的51次方)左右的次数内实现。(BTW,国内也有对密码攻击研究深入的学者,我就看到wikipedia上经常提到山东大学的王小云[Wang Xiaoyun]教授,有兴趣研究密码破译攻击的,可以google其论文来读读。)由于SHA-1不是足够的安全,现在美国的很多政府部门都开始不采用SHA-1而采用SHA-2(256/224/512/384等多种长度的输出报文摘要,目前还没有发现其hash碰撞的存在)。SHA-1主要有两种用途,一个是加密,一个是数据完整性校验。

这样做的好处是:

Git只要比较对象名,就可以很快的判断两个对象是否相同;

Git还可以通过检查对象名内容的SHA1的哈希值和“对象名”是否相同,来判断对象内容是否正确。

git 划分三个区域:

(1)working directory:

(2)staging area:

(3)git repository:

git 每个object包括三个部分:类型,大小和内容,四类对象:

(1)blob: 用于表示一个文件,存储文件数据

(2)tree:用于表示一个目录,管理一些“tree”或是“blob”

(3)commit:指向一个“tree”,用来标记项目某个特定时间点的状态。它包括一些关于时间点的元数据,如时间戳,最近一次提交的作者,指向上一次提交(commit)的指针等等。

(4)tag:用来标记某一次提交(commit)的方法

与“增量文件系统”(Delta Storage System)不同,Git会把每次提交的文件内容(snapshot)都记录下来。

所有这些对象都会以文件形式保存在.git/objects目录,一个对象对一个文件

我在【working directory】新建一个文件 file1,git add到【staging area】,然后git commit -m "add file1"提交到【git repository】

git log
commit a7c9f0464fc6d198d4e51c9752da4a58b8a34f3a
Author: XXXX <[email protected]>
Date:   Fri Jul 3 13:35:33 2015 +0800

    add file1
find .git/objects -type f
./ba/8d37db42d65db009cc08924df452c8a9257079
./4a/fbbf134a8f2653b578727fe102097f6ec5f883
./a7/c9f0464fc6d198d4e51c9752da4a58b8a34f3a
git 用SHA-1的钱两个数字来分目录存储对象,因此上述三个对象是
ba8d37db42d65db009cc08924df452c8a9257079 #blob
4afbbf134a8f2653b578727fe102097f6ec5f883 #tree
a7c9f0464fc6d198d4e51c9752da4a58b8a34f3a #commit
git cat-file -t <SHA1> #查看对象type
git cat-file -p <SHA1> #查看对象内容
git cat-file -t a7c9f0464fc6d198d4e51c9752da4a58b8a34f3a
commit

$git cat-file -p a7c9f0464fc6d198d4e51c9752da4a58b8a34f3a                                                                                  
tree 4afbbf134a8f2653b578727fe102097f6ec5f883
author LLL <[email protected]> 1435901733 +0800
committer LLL <[email protected]> 1435901733 +0800

add file1
SHA1相关命令:

二. 如何查看对象的SHA1值

  1.  查看文件的SHA1值,用命令
    git hash-object file
  2. 查看SHA1值对应的对象的内容,也可用命令
    git show <SHA1>
  3. 查看commits,可用命令
    git log --pretty=oneline

    这会给出commit的历史记录。每行行首显示了每次提交的SHA1值。然后用

    git show <SHA1>

    显示commit的内容。

  4. 查看每次commit指向的tree,用命令(如对commit 5ca6fc)
    git rev-parse 5ca6fc^{tree}

    会显示5ca6fc指向的tree的SHA1。如果想进一步查看tree的内容,用命力

    git show 5ca6fc^{tree}

    或者

    git cat-file -p 5ca6fc^{tree}

    后者输出形如

    100644 blob 76018072e09c5d31c8c6e3113b8aa0fe625195ca    file1
    100644 blob 5716ca5987cbf97d6bb54920bea6adde242d87e6    file2
    100644 blob 10e2d16377371e6436ba3779e62381fdaf8fcfbf    file3
    040000 tree edf40c2308b255c4aebc34aa9cce134131778a14    src

    可以看出,这个tree包含三个blob和一个子tree。

  5. 查看tag,可用
    git tag

    列出所有的tag。对于某个tag “v1”,用命令

    git rev-parse v1

    查看tag的SHA1值。

Git 创建branch,目前HEAD在master上:


#在本地新建branch
git branch <new branch>
#切换到新branch
git checkout <new branch>
#以上两句相当于下面一句
#git checkout -b <new branch>
#git merge



功能如下:
理解git常用命令原理


REPO manifest XML

Android使用repo来管理多个git项目。它需要一个manifest  XML文件来指示这些git项目的属性。

repo manifest XML可以包含下面的元素。

  • manifest: 最顶层的XML元素。
  • remote元素: 设置远程git服务器的属性,包括下面的属性
    • name: 远程git服务器的名字,直接用于git fetch, git remote 等操作
    • alias: 远程git服务器的别名,如果指定了,则会覆盖name的设定。在一个manifest中,
      name不能重名,但alias可以重名。
    • fetch: 所有projects的git URL 前缀
    • review: 指定Gerrit的服务器名,用于repo upload操作。如果没有指定,则repo upload没有效果。

Example:

<remote fetch="ssh://git.example.com" name="test"review="gerrit.example.com"/>

 

  • default元素:设定所有projects的默认属性值,如果在project元素里没有指定一个属性,则使用default元素的属性值。
    • remote: 之前定义的某一个remote元素中name属性值,用于指定使用哪一个远程git服务器。
    • revision: git分支的名字,例如master或者refs/heads/master
    • sync_j: 在repo sync中默认并行的数目。
    • sync_c: 如果设置为true,则只同步指定的分支(revision 属性指定),而不是所有的ref内容。
    • sync_s: 如果设置为true,则会同步git的子项目

Example:

<default remote="main" revision="platform/main"/>

 

  • manifest-server元素: 只能有一个该元素。它的url属性用于指定manifest服务的URL,通常是一个XML RPC 服务。
    它要支持一下RPC方法:
    • GetApprovedManifest(branch, target): 返回一个manifest用于指示所有projects的分支和编译目标。
          target参数来自环境变量TARGET_PRODUCT和TARGET_BUILD_VARIANT,组成$TARGET_PRODUCT-$TARGET_BUILD_VARIANT。
    • GetManifest(tag):  返回指定tag的manifest

 

  • project元素:指定一个需要clone的git仓库。
    • name: 唯一的名字标识project,同时也用于生成git仓库的URL。格式如下:
            ${remote_fetch}/${project_name}.git
    • path: 可选的路径。指定git clone出来的代码存放在本地的子目录。如果没有指定,则以name作为子目录名。
    • remote: 指定之前在某个remote元素中的name。
    • revision: 指定需要获取的git提交点,可以是master, refs/heads/master, tag或者SHA-1值。
    • groups: 列出project所属的组,以空格或者逗号分隔多个组名。所有的project都自动属于"all"组。每一个project自动属于
      name:'name' 和path:'path'组。例如<project name="monkeys" path="barrel-of"/>,它自动属于default, name:monkeys, and path:barrel-of组。如果一个project属于notdefault组,则,repo sync时不会下载。
    • sync_c: 如果设置为true,则只同步指定的分支(revision 属性指定),而不是所有的ref内容。
    • sync_s: 如果设置为true,则会同步git的子项目。
    • upstream: 在哪个git分支可以找到一个SHA1。用于同步revision锁定的manifest(-c 模式)。该模式可以避免同步整个ref空间。
    • annotation: 可以有多个annotation,格式为name-value pair。在repo forall 命令中这些值会导入到环境变量中。
    • remove-project: 从内部的manifest表中删除指定的project。经常用于本地的manifest文件,用户可以替换一个project的定义。

Example:

             <project groups="aosp" path="device/driver/armv7" revision="600aab270ce712b62b268055737cabcded59bf04"/>

 

  • include: 通过name属性可以引入另外一个manifest文件(路径相对与manifest repository's root)。

 

本地manifest

本地的manifest文件存放在$(TOP_DIR)/.repo/local_manifest/*.xml。$TOP_DIR/.repo/local_manifests/local_manifest.xml
如果存在,会被最先装入。然后是以字母顺序的$TOP_DIR/.repo/local_manifests/*.xml文件。这些manifest会在repo sync
之前被处理。以便repo下载和管理额外的project。

 

Example:

  $ ls .repo/local_manifests

  local_manifest.xml

  another_local_manifest.xml

 

  $ cat.repo/local_manifests/local_manifest.xml

  <?xml version="1.0"encoding="UTF-8"?>

  <manifest>

    <project path="manifest"

             name="tools/manifest"/>

    <projectpath="platform-manifest"

             name="platform/manifest"/>

  </manifest>

自:http://blog.csdn.net/hansel/article/details/9798189

你可能感兴趣的:(理解git常用命令原理)