2个提交如何在git存储库中具有相同的文件信息?

时间:2014-09-12 00:50:46

标签: git

具体来说,https://github.com/kodekwality/mean/commit/e6f85531279a9ce8624df180603a94837b87cd64https://github.com/kodekwality/mean/commit/fda7c3dc29b35e4781964e35fee6878c6827c22c似乎具有相同的父级和ALMOST相同的文件和更改集。也许我错过了一些东西,但他们也在同一个分支中。那么同一个文件怎么可能多次added?第二次不是modified吗?

2 个答案:

答案 0 :(得分:1)

这些确实是两个不同的提交。一个独立存在。

makoto@LATLON-Epimetheus:~/mean$ git log --graph --decorate fda7c3d e6f8553
* commit fda7c3dc29b35e4781964e35fee6878c6827c22c
| Author: Amos Haviv <mail@amoshaviv.com>
| Date:   Wed May 22 17:03:50 2013 +0300
| 
|     First Commit
|    
| * commit e6f85531279a9ce8624df180603a94837b87cd64
|/  Author: Amos Haviv <mail@amoshaviv.com>
|   Date:   Wed May 22 17:03:50 2013 +0300
|   
|       First Commit
|  
* commit 58a7ebe92d0196ef96d20f16a0376c6c44777442
  Author: Amos Haviv <mail@amoshaviv.com>
  Date:   Wed May 22 17:01:43 2013 +0300

      first commit

e6f8553提交,从祖先的角度来看,在fda73cd提交之前。这种情况的可能解释是由于樱桃选择(可以保留时间戳)或补丁(看起来确实发生在日志的历史中:

makoto@LATLON-Epimetheus:~/mean$ git log --decorate --graph 58a7ebe..c46e52c86b34ff5d746feb883c703dd1a18e34ac
*   commit c46e52c86b34ff5d746feb883c703dd1a18e34ac
|\  Merge: 6ef0d73 e99faff
| | Author: Lior Kesos <lior@linnovate.net>
| | Date:   Tue Jun 18 08:13:13 2013 -0700
| | 
| |     Merge pull request #3 from shacharz/patch-1
| |     
| |     Update README.md
| |   
| * commit e99fafff2c9d4ef7544f8fffa921ce8ceab26629
|/  Author: Shachar Zohar <shacharz@gmail.com>
|   Date:   Tue Jun 18 17:25:19 2013 +0300
|   
|       Update README.md
|  
* commit 6ef0d73d6491bd0d4c1c45a0280f81304ee2b6b5
| Author: Amos Haviv <mail@amoshaviv.com>
| Date:   Sun Jun 9 15:35:39 2013 +0300
| 
|     Clearing Config File
|  
* commit b0058919f7fe7cf6aa718f09a1474b4d96c7c877
| Author: Amos Haviv <mail@amoshaviv.com>
| Date:   Sun May 26 21:18:16 2013 +0300
| 
|     Adding Angular-Strap + Datepicker
|  
* commit 39fc1dfd68d98f2dff78434e091ee66b355dca51
| Author: Amos Haviv <mail@amoshaviv.com>
| Date:   Wed May 22 17:17:09 2013 +0300
| 
|     Removing .DS_Store
|  
* commit a3daa3baf6d2d5753bba96b792c6657096beea40
| Author: Amos Haviv <mail@amoshaviv.com>
| Date:   Wed May 22 17:16:13 2013 +0300
| 
|     Removing DSSTORES
|  
* commit 4c029d093bd8503fa31206962f98208eeef04d47
| Author: Amos Haviv <mail@amoshaviv.com>
| Date:   Wed May 22 17:08:27 2013 +0300
| 
|     .DS_Store banished!
|  
* commit e6f85531279a9ce8624df180603a94837b87cd64
  Author: Amos Haviv <mail@amoshaviv.com>
  Date:   Wed May 22 17:03:50 2013 +0300

      First Commit

答案 1 :(得分:1)

在git中,你所看到的是&#34;一个变化&#34;是始终比较两个提交的结果。 (好吧,有时更多而不是两个,但一次只有两个。)这是这里发生的事情的关键。

提交本身并没有实际添加&#34;一个文件,或者&#34;删除&#34;一个文件,或者真的,根本不对文件进行任何更改。这看起来很奇怪(git是版本化系统,不是吗?)直到你意识到git实际上是一个文件系统,并添加了一堆版本控制支持它。每次提交只存储一堆文件, 1 以及允许git 从前一版本中派生更改的项: 2 父提交ID。 (另外,还有作者,提交者,一些时间戳和提交消息。)

所以,当git说某些提交时,我们会调用这个&#34;提交C1&#34; - &#34;添加一个文件&#34;,它通过比较 C1到它的父级。如果父提交缺少文件a.txt而C1具有a.txt,则git声称C1&#34;添加a.txt&#34;。

如果某个其他提交C2有a.txt,并且提交C2的父级缺少a.txt,那么git clais C2也会&#34;添加a.txt&#34;

如果C1的父级与C2的父级是相同的提交,那么很明显单亲的两次都缺少相同的文件。

绘制提交图的一部分可能会有所帮助:

                  C1 - ...
                /
... - o - o - P
                \
                  C2 - ...

C1和C2都与同一父P进行比较,因此如果C1&#34;添加a.txt&#34;,P必须缺少a.txt;因此,如果C2 具有 a.txt,则C2必须同时添加a.txt

即使历史记录稍后合并,也是如此,因此只有一个分支包含C1C2

                  C1
                /    \
... - o - o - P        M - o - ...
                \    /
                  C2

(这里合并提交M有两个父提交;如果你检查提交M并询问&#34;更改&#34; git将为每个父提供一个差异,或者称为&#34;组合&#34;差异在哪里它成对地看C1-vs-M和C2-vs-M,但是然后将这两个差异合并在一起。)


1 更准确地说,提交有一个&#34;树&#34;。树包含额外的树(子树)和/或各种文件(&#34; blob&#34;,在git-internals-speak中)。

2 更准确地说,提交具有零个或多个父提交。大多数提交只有一个。合并提交有两个或更多,root提交(通常只是初始提交)没有。