从源代码编译时为什么有这么多相同的git可执行文件?

时间:2011-08-02 02:56:22

标签: c git

git                       
git-add                   
git-annotate              
git-apply                 
git-archive               
git-bisect--helper        
git-blame                 
git-branch                
git-bundle                
git-cat-file              
git-check-attr            
git-checkout              
git-checkout-index        
git-check-ref-format      
git-cherry                
git-cherry-pick           
git-clean                 
git-clone                 
git-commit                
git-commit-tree           
git-config                
git-count-objects         
git-describe              
git-diff                  
git-diff-files            
git-diff-index            
git-diff-tree             
git-fast-export           
git-fetch                 
git-fetch-pack            
git-fmt-merge-msg         
git-for-each-ref          
git-format-patch          
git-fsck                  
git-fsck-objects          
git-gc                    
git-get-tar-commit-id     
git-grep                  
git-hash-object           
git-help                  
git-index-pack            
git-init                  
git-init-db               
git-log                   
git-ls-files              
git-ls-remote             
git-ls-tree               
git-mailinfo              
git-mailsplit             
git-merge                 
git-merge-base            
git-merge-file            
git-merge-index           
git-merge-ours            
git-merge-recursive       
git-merge-subtree         
git-merge-tree            
git-mktag                 
git-mktree                
git-mv                    
git-name-rev              
git-notes                 
git-pack-objects          
git-pack-redundant        
git-pack-refs             
git-patch-id              
git-peek-remote           
git-prune                 
git-prune-packed          
git-push                  
git-read-tree             
git-receive-pack          
git-reflog                
git-remote                
git-remote-ext            
git-remote-fd             
git-replace               
git-repo-config           
git-rerere                
git-reset                 
git-revert                
git-rev-list              
git-rev-parse             
git-rm                    
git-send-pack             
git-shortlog              
git-show                  
git-show-branch           
git-show-ref              
git-stage                 
git-status                
git-stripspace            
git-symbolic-ref          
git-tag                   
git-tar-tree              
git-unpack-file           
git-unpack-objects        
git-update-index          
git-update-ref            
git-update-server-info    
git-upload-archive        
git-var                   
git-verify-pack           
git-verify-tag            
git-whatchanged           
git-write-tree            

所有这些目标的大小相同:4951925,其内容相同。为什么?

[root@ git-1.7.6]$ ls -il /usr/bin/git*
17823222 lrwxrwxrwx 1 root root 22 2011-01-24 11:43 /usr/bin/git -> /usr/local/git/bin/git
17823223 lrwxrwxrwx 1 root root 32 2011-01-24 11:43 /usr/bin/git-cvsserver -> /usr/local/git/bin/git-cvsserver
17823224 lrwxrwxrwx 1 root root 23 2011-01-24 11:43 /usr/bin/gitk -> /usr/local/git/bin/gitk
17823225 lrwxrwxrwx 1 root root 35 2011-01-24 11:43 /usr/bin/git-receive-pack -> /usr/local/git/bin/git-receive-pack
17823226 lrwxrwxrwx 1 root root 28 2011-01-24 11:43 /usr/bin/git-shell -> /usr/local/git/bin/git-shell
17823227 lrwxrwxrwx 1 root root 37 2011-01-24 11:43 /usr/bin/git-upload-archive -> /usr/local/git/bin/git-upload-archive
17823228 lrwxrwxrwx 1 root root 34 2011-01-24 11:43 /usr/bin/git-upload-pack -> /usr/local/git/bin/git-upload-pack



[root@ git-1.7.6]$ ls -li /usr/local/git/bin/git*
126612251 -rwxr-xr-x 107 root root 4686039 2011-01-24 11:42 /usr/local/git/bin/git
126614976 -rwxr-xr-x   2 root root  120960 2011-01-24 11:42 /usr/local/git/bin/git-cvsserver
126614978 -rwxr-xr-x   1 root root  321995 2011-01-24 11:42 /usr/local/git/bin/gitk
126612251 -rwxr-xr-x 107 root root 4686039 2011-01-24 11:42 /usr/local/git/bin/git-receive-pack
126612255 -rwxr-xr-x   2 root root 1952607 2011-01-24 11:42 /usr/local/git/bin/git-shell
126612251 -rwxr-xr-x 107 root root 4686039 2011-01-24 11:42 /usr/local/git/bin/git-upload-archive
126612252 -rwxr-xr-x   2 root root 2001993 2011-01-24 11:42 /usr/local/git/bin/git-upload-pack

2 个答案:

答案 0 :(得分:2)

我认为这是为了向后兼容,因为在早期版本的git中,每个git子命令都是一个单独的可执行文件(例如git-commit而不是git commit

在以后的版本中,他们将它们作为实际的子命令,唯一真正的可执行文件是git。其他可能只是git可执行文件的链接。

答案 1 :(得分:1)

因为唯一真实的命令是git。其余的要么象征性地与git本身相关联,要么(更有可能)它们都是硬连接的。

当两个文件硬连接在一起时,它们引用磁盘上的一个副本,尽管名称不同。文件名只是指向磁盘上特定inode的指针,这就是Linux / Unix跟踪存储位置的方式。

您可以通过执行以下操作进行验证:

$ ls -il /usr/bin/git*

如果它们在第一列中共享相同的数字,那么它们都引用相同的inode。权限之后的数字是指向该单个inode的硬链接数。在该计数达到零之前,该可执行文件(或任何硬链接文件)的实际磁盘空间不会被释放(对它的所有引用都会消失)。

(顺便说一下......如果它们符号链接,你会看到类似git-annotate -> git的内容,这意味着git-annotate的名称引用名称git,然后将其解析为inode包含(指向)可执行文件的数据)

Git本身就是一个程序,它知道如何根据它的调用方式做很多事情。您可以调用git annotategit-annotate,它们将由一个git二进制文件解释,以执行注释操作。

这样做的原因只是为了您的方便,git本身并不需要任何东西,因为您始终可以使用其git<space>command形式的调用。