使用git微命令深入理解git工作机制

来源:互联网 发布:安卓好用的看书软件 编辑:程序博客网 时间:2024/05/18 16:54
 首先,这篇不是真正意义上的翻译,所以大家在看的时候不要找对应的英文文章对应着看。这篇文章之所以归类为翻译,是因为最开始有一篇英文文章让我对Git内部机制有了清楚的认识,它可以说是我git的启蒙老师吧。然后很久过去后,自己也有了很多的git项目实践,觉得有必要从自己的理解角度(微命令和常用命令对应分析)来整理下自己的理解,于是有了这篇博文。
        git是一种管理数据的工具,一种支持快速索引查找数据并管理数据变化的工具。它为数据添加一个头封装为对象块(本文称为git对象)然后保存为文件,并根据数据生成一个SHA值,然后以该值作为文件名称的依据,SHA值的前2位是文件的目录名字,后面的值为文件名,这样就能很容易根据SHA查找到数据。同时由于SHA的唯一性,一旦文件内容改变,其对应的SHA就会变化,因而很适合文件变化管理。
git总共有四类对象:

         blob对象

              该对象是真正的数据对象,它的内容是各种文件的数据内容,比如git项目里的文件数据。需要注意的是blob对象只是保存数据,并不保存数据的额外信息,比如文件名,文件大小。

         tree对象:

                该对象是一种管理对象,它是用来管理对象的对象,其内容指出了该tree包含哪些子对象,tree可以递归的,也就说tree可以包含其他的tree。Tree对象就像Linux文件系统里的目录一样,目录本身是一种文件,只不过目录文件的内容是目录下的文件信息,目录下还有子目录。

         commit对象:

                commit对象是真正直接呈现给git使用者的,它就是我们经常说到的git项目历史记录,我们经常用的git show xxx,git log xxx,git check xxx等命令后面接的数字就是commit对象的名字,也就是commit对象对应的SHA值。commit对象必须有一个tree对象,它本身并不和数据有直接联系,git工具通过它的tree对象找到该commit对应的数据,同时和tree对象一样,它可以有自己的父亲commit,这样就形成了git历史单向链表。

         tag 对象:

                tag对象其实就是上面三种对象的一种别名表达方式。从上面的描述我们可知,git对象的名字是SHA值,就是一堆没有规律的长串的字符,用户自然不容易记也记不住。因此git提出了tag对象这样一种对象,它允许用户以他们容易识别的名字来标示上面的任一对象。

        有了这些基本概念,我们通过使用git 微命令来详细的认识下这些对象的形式,生成及使用。git微命令是相对

我们平时用的git commit, git addd等命令而言的,微命令做的事情少,可以很清晰看到每一个步骤。


创建新的git项目


       我们执行git init后,系统会自动帮我们创建一个隐藏目录.git,具体内容如下:

[python] view plain copy print?
  1. itleaks@Itleaks:/tmp/test$ git init .  
  2. Initialized empty Git repository in /tmp/test/.git/  
  3. itleaks@Itleaks:/tmp/test$ tree . -al  
  4. .  
  5. └── .git  
  6.     ├── branches  
  7.     ├── config  
  8.     ├── description  
  9.     ├── HEAD  
  10.     ├── hooks  
  11.     │   ├── applypatch-msg.sample  
  12.     │   ├── commit-msg.sample  
  13.     │   ├── post-update.sample  
  14.     │   ├── pre-applypatch.sample  
  15.     │   ├── pre-commit.sample  
  16.     │   ├── prepare-commit-msg.sample  
  17.     │   ├── pre-push.sample  
  18.     │   ├── pre-rebase.sample  
  19.     │   └── update.sample  
  20.     ├── info  
  21.     │   └── exclude  
  22.     ├── objects  
  23.     │   ├── info  
  24.     │   └── pack  
  25.     └── refs  
  26.         ├── heads  
  27.         └── tags  

       上面的.git/objects是最重要的目录,它就是用来保存上面提到的四种对象文件的目录。


生成Blob对象


       git生成blob对象是使用githash-object来生成,具体操作如下:

[python] view plain copy print?
  1. itleaks@Itleaks:/tmp/test$ echo "itleaks test">test.txt  
  2. itleaks@Itleaks:/tmp/test$ git hash-object -w test.txt  
  3. be976caf33466b3a9fbc04260139a992e5664b9c  
  4.   
  5. itleaks@Itleaks:/tmp/test$ tree . -al  
  6. .  
  7. ├── .git  
  8. │   ├── branches  
  9. │   ├── config  
  10. │   ├── description  
  11. │   ├── HEAD  
  12. │   ├── hooks  
  13. │   │   ├── applypatch-msg.sample  
  14. │   │   ├── commit-msg.sample  
  15. │   │   ├── post-update.sample  
  16. │   │   ├── pre-applypatch.sample  
  17. │   │   ├── pre-commit.sample  
  18. │   │   ├── prepare-commit-msg.sample  
  19. │   │   ├── pre-push.sample  
  20. │   │   ├── pre-rebase.sample  
  21. │   │   └── update.sample  
  22. │   ├── info  
  23. │   │   └── exclude  
  24. │   ├── objects  
  25. │   │   ├── be  
  26. │   │   │   └── 976caf33466b3a9fbc04260139a992e5664b9c  
  27. │   │   ├── info  
  28. │   │   └── pack  
  29. │   └── refs  
  30. │       ├── heads  
  31. │       └── tags  
  32. └── test.txt  
  33. itleaks@Itleaks:/tmp/test$ find .git/objects/ -type f  
  34. .git/objects/be/976caf33466b3a9fbc04260139a992e5664b9c  

       从上面可以看出,当我们使用hash-object–w生成一个对象后,git会在.git/objects下生一个文件be/ 976caf33466b3a9fbc04260139a992e5664b9c,这个就是SHA值。有了这个对象的SHA值后,我们可以通过gitcat-file命令来查看该对象的原始数据。

 

[python] view plain copy print?
  1. //查看对象类型  
  2. itleaks@Itleaks:/tmp/test$ git cat-file -t be976caf33466b3a9fbc04260139a992e5664b9c  
  3. blob  
  4. //查看对象内容  
  5. itleaks@Itleaks:/tmp/test$ git cat-file -p be976caf33466b3a9fbc04260139a992e5664b9c  
  6. itleaks test  
        此时对应的数据对象图如下:

        到这里,你可能会问,test.txt这个名字的信息保存在哪呢?其实前面已经提到了,blob对象只存数据(上面的字符串” itleaks test”),并不保存其他额外信息。那这个名字什么时候保存的呢?保存咋哪里呢?这个就是由下面要提到的tree 对象来维护的。


生成Tree对象


       上面的操作过后,系统已经存在一个blob对象了。我们可以将该对象添加到一个tree对象里,在添加到tree对象前,必须将该blob对象封装成一个tree 对象的item数据块, 并将该item数据块写到cache里。item数据块的格式是blob对象SHA值+数据文件名字(test.txt)+文件模式(100644)。这一个过程由git update-index完成

[python] view plain copy print?
  1. itleaks@Itleaks:/tmp/test$ git update-index --add --cacheinfo 100644 \  
  2. > be976caf33466b3a9fbc04260139a992e5664b9c test.txt  
  3. //到此,终于出现了前面提到的test.txt,这里才是我们在git里看到的文件名  
  4. //其实这里的文件名也可以填其他名字,git系统并不认识操作系统中的文件名,只  
  5. //知道这里的文件名,然后其他用户通过git clone 该git项目时,该blob对象对应的数据  
  6. //文件会命名为这里指定的名称  
  7. itleaks@Itleaks:/tmp/test$ git ls-files  
  8. test.txt  
  9. //ls-files可以查看cache里的所有blob对象描述  
  10. itleaks@Itleaks:/tmp/test$ find .git/objects/ -type f  
  11. .git/objects/be/976caf33466b3a9fbc04260139a992e5664b9c  
  12. //update-index执行后,并不会增加object  

        如果有多个数据,可以重复执行上面的命令,将多个blob对象添加到cache中。然后当用户执行git write-tree的时候,就会生成一个tree对象,并将cache里的所有blob对象的描述数据添加到tree对象的文件里,具体命令如下:

[python] view plain copy print?
  1. itleaks@Itleaks:/tmp/test$ git write-tree  
  2. 941220dc97574b7dba7b22fdb21333c7227c9603  
  3.   
  4. itleaks@Itleaks:/tmp/test$ find .git/objects/ -type f  
  5. .git/objects/be/976caf33466b3a9fbc04260139a992e5664b9c  
  6. .git/objects/94/1220dc97574b7dba7b22fdb21333c7227c9603  
  7. //新增了一个object文件  
  8. itleaks@Itleaks:/tmp/test$ git cat-file -t 941220dc97574b7dba7b22fdb21333c7227c9603  
  9. tree  
  10. itleaks@Itleaks:/tmp/test$ git cat-file -p 941220dc97574b7dba7b22fdb21333c7227c9603  
  11. 100644 blob be976caf33466b3a9fbc04260139a992e5664b9c    test.txt  
  12. //tree对象的内容是描述其管理的blob对象的指向信息  

        此时对应的数据对象图如下:

 

       到此为止,所有的对象都是相对底层的数据对象,git用户一般是不会直接使用的。然后就该commit对象露面了。


生成commit对象


        其实commit对象,你可以理解成tree对象的扩展,它是用来描述一个tree对象的额外信息的。它相当于是tree对象为用户预留出来的接口,用户通过生成一个commit对象,就可以给一个tree对象打标签,比如用户姓名,描述,时间。具体生成过程如下:

[python] view plain copy print?
  1. itleaks@Itleaks:/tmp/test$ echo 'initial version' | git commit-tree 941220dc97574b7dba  
  2. f7bde89df6b5d8ea3fa3ccae0e3d53e8a5aa25d2  
  3. //上面的941220dc97574b7dba就是tree对象的SHA值  
  4. itleaks@Itleaks:/tmp/test$ find .git/objects/ -type f  
  5. .git/objects/f7/bde89df6b5d8ea3fa3ccae0e3d53e8a5aa25d2  
  6. .git/objects/be/976caf33466b3a9fbc04260139a992e5664b9c  
  7. .git/objects/94/1220dc97574b7dba7b22fdb21333c7227c9603  
  8. //commit也是一个对象  
  9. itleaks@Itleaks:/tmp/test$ git cat-file -t f7bde89df6b5d8ea3fa3ccae0e3d53e8a5aa25d2  
  10. commit  
  11. itleaks@Itleaks:/tmp/test$ git cat-file -p f7bde89df6b5d8ea3fa3ccae0e3d53e8a5aa25d2  
  12. tree 941220dc97574b7dba7b22fdb21333c7227c9603  
  13. author itleaks <itleaks@126.com1403052327 +0800  
  14. committer itleaks <itleaks@126.com1403052327 +0800  
  15.   
  16. initial version  
  17. //commit对象的内容指出了它描述的是哪个tree  

         此时对应的数据对象图如下:

 

         Commit生成后,用户就熟悉了,用户通过常用的git show命令就可以很直接的查看这个commit

        

[python] view plain copy print?
  1. itleaks@Itleaks:/tmp/test$ git show f7bde89df6b5d8ea3fa3ccae0e3d53e8a5aa25d2  
  2. commit f7bde89df6b5d8ea3fa3ccae0e3d53e8a5aa25d2  
  3. Author: itleaks <itleaks@126.com>  
  4. Date:   Wed Jun 18 08:45:27 2014 +0800  
  5.   
  6.     initial version  
  7.   
  8. diff --git a/test.txt b/test.txt  
  9. new file mode 100644  
  10. index 0000000..be976ca  
  11. --- /dev/null  
  12. +++ b/test.txt  
  13. @@ -0,0 +1 @@  
  14. +itleaks test  

          那执行git log呢?

[python] view plain copy print?
  1. itleaks@Itleaks:/tmp/test$ git log  
  2. fatal: bad default revision 'HEAD'  
  3. itleaks@Itleaks:/tmp/test$ cat .git/HEAD   
  4. ref: refs/heads/master  
  5. itleaks@Itleaks:/tmp/test $ tree .git/refs/heads/  
  6. .git/refs/heads/  
  7.   
  8. 0 directories, 0 files  

          系统会提示bad HEAD,这是因为refs/heads/maste文件不存在。这个就是下面我要讲的git referrence对象。

 

Ref对象


         从名字可以看出来,它就是一个引用,它就是commit对象的别名,它直接以字符串的形式保存一个commit对象的名字,这样用户直接根据ref对象的名字就可以直接找到对应的commit对象,而不用记住一长串SHA字符串。另外,这里的ref对象就是我们常说说到git branch,一个branch对应一个refs/heads/xx文件。

        

[python] view plain copy print?
  1. itleaks@Itleaks:/tmp/test$ echo "f7bde89df6b5d8ea3fa3ccae0e3d53e8a5aa25d2"   
  2. > .git/refs/heads/master  
  3. itleaks@Itleaks:/tmp/test$ find .git/objects/ -type f  
  4. .git/objects/f7/bde89df6b5d8ea3fa3ccae0e3d53e8a5aa25d2  
  5. .git/objects/be/976caf33466b3a9fbc04260139a992e5664b9c  
  6. .git/objects/94/1220dc97574b7dba7b22fdb21333c7227c9603  
  7. //生成ref并没有新增object  
  8. itleaks@Itleaks:/tmp/test$ find .git/refs/ -type f  
  9. .git/refs/heads/master  
  10. //执行上面的命令生成一个master ref对象后,用户不再需要使用git show SHA值,而是  
  11. //直接使用git show name就可以查看commit对象的详细信息  
  12. itleaks@Itleaks:/tmp/test$ git show master  
  13. commit f7bde89df6b5d8ea3fa3ccae0e3d53e8a5aa25d2  
  14. Author: itleaks <itleaks@126.com>  
  15. Date:   Wed Jun 18 08:45:27 2014 +0800  
  16.   
  17.     initial version  
  18.   
  19. diff --git a/test.txt b/test.txt  
  20. new file mode 100644  
  21. index 0000000..be976ca  
  22. --- /dev/null  
  23. +++ b/test.txt  
  24. @@ -0,0 +1 @@  
  25. +itleaks test  

         refs/heads/master生成后,用户终于可以使用gitlog查看了

[python] view plain copy print?
  1. itleaks@Itleaks:/tmp/test$ git log  
  2. commit f7bde89df6b5d8ea3fa3ccae0e3d53e8a5aa25d2  
  3. Author: itleaks <itleaks@126.com>  
  4. Date:   Wed Jun 18 08:45:27 2014 +0800  
  5.   
  6.     initial version  

         此时对应的数据对象图如下:

 

微git操作对应的git常用命令


         到此,大家估计也看累了吧,但是如果我告诉你上面这么长的操作,用户其实通过如下两条命令可以实现一样的效果,你会不会惊讶啊!

        

[python] view plain copy print?
  1. git add test.txt  
  2. git commit -sm “initial version”  

         我们也来看下这两条操作对应的.git内容变化过程

[python] view plain copy print?
  1. itleaks@Itleaks:/tmp/test$ echo "itleaks test">test.txt  
  2. itleaks@Itleaks :/tmp/test$ git add test.txt   
  3. itleaks@Itleaks:/tmp/test$ find .git/objects/ -type f  
  4. .git/objects/be/976caf33466b3a9fbc04260139a992e5664b9c  
  5. itleaks@Itleaks:/tmp/test$ git cat-file -t be976caf33466b3a9fbc04260139a992e5664b9c  
  6. blob  
  7. itleaks@Itleaks:/tmp/test$ git ls-files  
  8. test.txt  

        从上面可以看出,git add命令会为我们创建blob对象,并且自动将该blob对象添加到cache中。更不可思议的是,生成的对象名字be976caf33466b3a9fbc04260139a992e5664b9c和上面的一模一样,为啥,这是由SHA签名生成机制相关---只要数据一致,其产生的SHA一定一样。

[python] view plain copy print?
  1. itleaks@Itleaks:/tmp/test$ git commit -sm "initial version"  
  2. [master (root-commit) 12ca076] initial version  
  3.  1 file changed, 1 insertion(+)  
  4.  create mode 100644 test.txt  
  5. itleaks@Itleaks:/tmp/test$ find .git/objects/ -type f  
  6. .git/objects/12/ca0768b1a7c1f5f8547617af78e13d7263aaba  
  7. .git/objects/be/976caf33466b3a9fbc04260139a992e5664b9c  
  8. .git/objects/94/1220dc97574b7dba7b22fdb21333c7227c9603  
  9.   
  10. itleaks@Itleaks:/tmp/test$ git cat-file -p 12ca0768b1a7c1f5f8547617af78e13d7263aaba  
  11. tree 941220dc97574b7dba7b22fdb21333c7227c9603  
  12. author itleaks <itleaks@126.com1403098727 +0800  
  13. committer itleaks <itleaks@126.com1403098727 +0800  
  14.   
  15. initial version  
  16.   
  17. Signed-off-by: itleaks <itleaks@126.com>  
  18. itleaks@Itleaks:/tmp/test$ git cat-file -p 941220dc97574b7dba7b22fdb21333c7227c9603  
  19. 100644 blob be976caf33466b3a9fbc04260139a992e5664b9c    test.txt  

         从上面可以看出commit这条命令生成了两个对象:tree对象和commit对象.大家注意没,只有commit对象的SHA值和我们上面不一样,另外两个对象是一样的,为什么?那是因为commit对象的内容中包含时间,两次commit对象生成的时间不一样意味着其内容就不一样,进而其SHA自然不一样。

 

commit链形成


         上面的操作,只生成一个blob对象, 一个tree对象,一个commit对象,还没法看到commit链的形成过程。因此,为了生成链,我们还需要生成另外一个commit对象。接着实验。

         新增文件,并重复上面的操作的。

[python] view plain copy print?
  1. itleaks@Itleaks:/tmp/test$ echo "second file">2.txt  
  2. itleaks@Itleaks:/tmp/test$ git hash-object -w 2.txt  
  3. 1c59427adc4b205a270d8f810310394962e79a8b  
  4. itleaks@Itleaks:/tmp/test$ find .git/objects/ -type f  
  5. .git/objects/f7/bde89df6b5d8ea3fa3ccae0e3d53e8a5aa25d2  
  6. .git/objects/1c/59427adc4b205a270d8f810310394962e79a8b  
  7. .git/objects/be/976caf33466b3a9fbc04260139a992e5664b9c  
  8. .git/objects/94/1220dc97574b7dba7b22fdb21333c7227c9603  
  9. itleaks@Itleaks:/tmp/test$ git cat-file -t 1c59427adc4b205a270d8f810310394962e79a8b  
  10. blob  
  11. itleaks@Itleaks:/tmp/test$ git cat-file -p 1c59427adc4b205a270d8f810310394962e79a8b  
  12. second file  
  13.   
  14. itleaks@Itleaks:/tmp/test$ git ls-files  
  15. test.txt  
  16. //原来的cache还在,因此只需添加新的blob对象到cache中去  
  17. itleaks@Itleaks:/tmp/test$ git update-index --add 2.txt  
  18. itleaks@Itleaks:/tmp/test$ git ls-files  
  19. 2.txt  
  20. test.txt  
  21.   
  22. itleaks@Itleaks:/tmp/test$ git write-tree  
  23. 931fdc25cbc3e0afa6e34cf275693ade0daf2c73  
  24. itleaks@Itleaks:/tmp/test$ find .git/objects/ -type f  
  25. .git/objects/f7/bde89df6b5d8ea3fa3ccae0e3d53e8a5aa25d2  
  26. .git/objects/1c/59427adc4b205a270d8f810310394962e79a8b  
  27. .git/objects/93/1fdc25cbc3e0afa6e34cf275693ade0daf2c73  
  28. .git/objects/be/976caf33466b3a9fbc04260139a992e5664b9c  
  29. .git/objects/94/1220dc97574b7dba7b22fdb21333c7227c9603  
  30. itleaks@Itleaks:/tmp/test$ git cat-file -t 931fdc25cbc3e0afa6e34cf275693ade0daf2c73  
  31. tree  
  32. itleaks@Itleaks:/tmp/test$ git cat-file -p 931fdc25cbc3e0afa6e34cf275693ade0daf2c73  
  33. 100644 blob 1c59427adc4b205a270d8f810310394962e79a8b    2.txt  
  34. 100644 blob be976caf33466b3a9fbc04260139a992e5664b9c    test.txt  
  35. //这里可以看出,这个新增的tree对象指向了两个blob对象  

        接下来就是commit链形成的重点了,在生成commit对象时,有一个-p参数,这个参数用来指示新生成的commit对象的父亲commit的。下面就来看看带这个参数和没带这个参数的生成的commit对象的差别

         不带-p参数时

 

[python] view plain copy print?
  1. itleaks@Itleaks:/tmp/test$ echo "second commit"|git commit-tree 931fdc25cbc  
  2. 2969683f04d3a32af0d6abf97f170190163b72e3  
  3.   
  4. itleaks@Itleaks:/tmp/ test $ git cat-file -p 2969683f0  
  5. tree 931fdc25cbc3e0afa6e34cf275693ade0daf2c73  
  6. author itleaks <itleaks@126.com1403055500 +0800  
  7. committer itleaks <itleaks@126.com1403055500 +0800  
  8.   
  9. second commit  
  10.   
  11. itleaks@Itleaks:/tmp/test$ git show 2969683f04d3a  
  12. commit 2969683f04d3a32af0d6abf97f170190163b72e3  
  13. Author: itleaks <itleaks@126.com>  
  14. Date:   Wed Jun 18 09:38:20 2014 +0800  
  15.   
  16.     second commit  
  17.   
  18. diff --git a/2.txt b/2.txt  
  19. new file mode 100644  
  20. index 0000000..1c59427  
  21. --- /dev/null  
  22. +++ b/2.txt  
  23. @@ -0,0 +1 @@  
  24. +second file  
  25. diff --git a/test.txt b/test.txt  
  26. new file mode 100644  
  27. index 0000000..be976ca  
  28. --- /dev/null  
  29. +++ b/test.txt  
  30. @@ -0,0 +1 @@  
  31. +itleaks test  
  32.   
  33. itleaks@Itleaks:/tmp/test$ git log 2969683f04d3a  
  34. commit 2969683f04d3a32af0d6abf97f170190163b72e3  
  35. Author: itleaks <itleaks@126.com>  
  36. Date:   Wed Jun 18 09:38:20 2014 +0800  
  37.   
  38.     second commit  
  39. //没带-p参数时,这个新的commit相当于这次commit一下子增加了两个文件  
  40.   
  41. itleaks@Itleaks:/tmp/test$ git log 2969683f04d3a  
  42. commit 2969683f04d3a32af0d6abf97f170190163b72e3  
  43. Author: itleaks <itleaks@126.com>  
  44. Date:   Wed Jun 18 09:38:20 2014 +0800  
  45.   
  46.     second commit  
  47. //这里只有一条commit记录  

         带-p参数时

 

[python] view plain copy print?
  1. itleaks@Itleaks:/tmp/test$ echo "second commit2"|git commit-tree 931fdc25cbc -p f7bde89df6b5d8ea3f  
  2. c29d97b2a89c18bdc68f0812749c76fdadd477cf  
  3.   
  4. itleaks@Itleaks:/tmp/test$ git cat-file -p c29d97b2a89c1  
  5. tree 931fdc25cbc3e0afa6e34cf275693ade0daf2c73  
  6. parent f7bde89df6b5d8ea3fa3ccae0e3d53e8a5aa25d2  
  7. author itleaks <itleaks@126.com1403055858 +0800  
  8. committer itleaks <itleaks@126.com1403055858 +0800  
  9.   
  10. second commit2  
  11.   
  12. itleaks@Itleaks:/tmp/test$ git show c29d97  
  13. commit c29d97b2a89c18bdc68f0812749c76fdadd477cf  
  14. Author: itleaks <itleaks@126.com>  
  15. Date:   Wed Jun 18 09:44:18 2014 +0800  
  16.   
  17.     second commit2  
  18.   
  19. diff --git a/2.txt b/2.txt  
  20. new file mode 100644  
  21. index 0000000..1c59427  
  22. --- /dev/null  
  23. +++ b/2.txt  
  24. @@ -0,0 +1 @@  
  25. +second file  
  26. //带了-p参数的commit,显示出来的修改只是增加了2.txt文件  
  27.   
  28. itleaks@Itleaks:/tmp/test$ git log c29d97  
  29. commit c29d97b2a89c18bdc68f0812749c76fdadd477cf  
  30. Author: itleaks <itleaks@126.com>  
  31. Date:   Wed Jun 18 09:44:18 2014 +0800  
  32.   
  33.     second commit2  
  34.   
  35. commit f7bde89df6b5d8ea3fa3ccae0e3d53e8a5aa25d2  
  36. Author: itleaks <itleaks@126.com>  
  37. Date:   Wed Jun 18 08:45:27 2014 +0800  
  38.   
  39.     initial version  
  40. //这里,可以看到”second commit2"前面的commit是” initial version”,这就是commit链  

         此次操作后对象图如下:

 

Branch更新


         上面新增了两个commit对象后,系统并不会自动更新branch的信息,需要用户主动更新,通过update-ref及尅实现,具体实现如下:

[python] view plain copy print?
  1. itleaks@Itleaks:/tmp/test$ git show master  
  2. commit f7bde89df6b5d8ea3fa3ccae0e3d53e8a5aa25d2  
  3. Author: itleaks <itleaks@126.com>  
  4. Date:   Wed Jun 18 08:45:27 2014 +0800  
  5.   
  6.     initial version  
  7.   
  8. diff --git a/test.txt b/test.txt  
  9. new file mode 100644  
  10. index 0000000..be976ca  
  11. --- /dev/null  
  12. +++ b/test.txt  
  13. @@ -0,0 +1 @@  
  14. +itleaks test  
  15.   
  16. //brach master还没有更新,接下来更新  
  17. itleaks@Itleaks:/tmp/test$ git update-ref refs/heads/master c29d97  
  18. itleaks@Itleaks:/tmp/test$ git log  
  19. commit c29d97b2a89c18bdc68f0812749c76fdadd477cf  
  20. Author: itleaks <itleaks@126.com>  
  21. Date:   Wed Jun 18 09:44:18 2014 +0800  
  22.   
  23.     second commit2  
  24.   
  25. commit f7bde89df6b5d8ea3fa3ccae0e3d53e8a5aa25d2  
  26. Author: itleaks <itleaks@126.com>  
  27. Date:   Wed Jun 18 08:45:27 2014 +0800  
  28.   
  29.     initial version  
  30. //看到我们上面添加的” second commit2” commit了  

         此次操作后对象图如下:

 

        

 附录:

启蒙git机制英文网站:http://git-scm.com/book/en/Git-Internals-Git-Objects


/********************************

* 本文来自博客  “爱踢门”

* 转载请标明出处:http://blog.csdn.net/itleaks

******************************************/

原创粉丝点击