²»¹ÜÄãÊÇ´ÓÇ°ÃæµÄÕ½ÚÖ±½ÓÌøµ½Á˱¾Õ£¬»¹ÊǶÁÍêÁËÆäÓà¸÷ÕÂÒ»Ö±µ½Õ⣬Äã¶¼½«ÔÚ±¾Õ¼ûʶ
Git µÄÄÚ²¿¹¤×÷ÔÀíºÍʵÏÖ·½Ê½¡£ÎÒ¸öÈË·¢ÏÖѧϰÕâЩÄÚÈݶÔÓÚÀí½â Git µÄÓô¦ºÍÇ¿´óÊǷdz£ÖØÒªµÄ£¬²»¹ýÒ²ÓÐÈËÈÏΪÕâЩÄÚÈݶÔÓÚ³õѧÕßÀ´Ëµ¿ÉÄÜÄÑÒÔÀí½âÇÒ¹ýÓÚ¸´ÔÓ¡£ÕýÒòÈç´ËÎÒ°ÑÕⲿ·ÖÄÚÈÝ·ÅÔÚ×îºóÒ»Õ£¬ÄãÔÚѧϰ¹ý³ÌÖпÉÒÔÏÈÔÄ
¶ÁÕⲿ·Ö£¬Ò²¿ÉÒÔÍíµãÔĶÁÕⲿ·Ö£¬ÕâÍêȫȡ¾öÓÚÄã×Ô¼º¡£
¼ÈÈ»ÒѾ¶Áµ½ÕâÁË£¬¾ÍÈÃÎÒÃÇ¿ªÊ¼°É¡£Ê×ÏÈҪŪÃ÷°×Ò»µã£¬´Ó¸ù±¾ÉÏÀ´½² Git ÊÇÒ»Ì×ÄÚÈÝѰַ (content-addressable)
Îļþϵͳ£¬ÔÚ´ËÖ®ÉÏÌṩÁËÒ»¸ö VCS Óû§½çÃæ¡£ÂíÉÏÄã¾Í»áѧµ½ÕâÒâζ×Åʲô¡£
ÔçÆÚµÄ Git (Ö÷ÒªÊÇ 1.5 ֮ǰ°æ±¾) µÄÓû§½çÃæÒª±ÈÏÖÔÚ¸´Ôӵö࣬ÕâÊÇÒòΪËü¸ü²àÖØÓÚ³ÉΪÎļþϵͳ¶ø²»ÊÇÒ»Ì׸ü¾«ÖµÄ
VCS ¡£×î½ü¼¸Äê¸Ä½øÁË UI ´Ó¶øÊ¹Ëü¸úÆäËûÈκÎϵͳһÑùÇåÎúÒ×Ó᣼´±ãÈç´Ë£¬»¹ÊǾ³£»áÓÐһЩ³ÂÇ»Àĵ÷Ìáµ½ÔçÆÚ
Git µÄ UI ¸´ÔÓÓÖÄÑѧ¡£
ÄÚÈÝѰַÎļþϵͳÕâÒ»²ãÏ൱¿á£¬ÔÚ±¾ÕÂÖÐÎÒ»áÏȽ²½âÕⲿ·Ö¡£ËæºóÄã»áѧµ½´«Êä»úÖÆºÍ×îÖÕҪʹÓõĸ÷ÖÖ¿â¹ÜÀíÈÎÎñ¡£
9.1 µ×²ãÃüÁî (Plumbing) ºÍ¸ß²ãÃüÁî (Porcelain)
±¾Êé½²½âÁËʹÓà checkout, branch, remote µÈ¹²Ô¼
30 ¸ö Git ÃüÁȻ¶øÓÉÓÚ Git Ò»¿ªÊ¼±»Éè¼Æ³É¹© VCS ʹÓõŤ¾ß¼¯¶ø²»ÊÇÒ»ÕûÌ×Óû§ÓѺõÄ
VCS£¬Ëü»¹°üº¬ÁËÐí¶àµ×²ãÃüÁÕâЩÃüÁîÓÃÓÚÒÔ UNIX ·ç¸ñʹÓûòÓɽű¾µ÷Óá£ÕâЩÃüÁîÒ»°ã±»³ÆÎª ¡°plumbing¡±
ÃüÁµ×²ãÃüÁ£¬ÆäËûµÄ¸üÓѺõÄÃüÁîÔò±»³ÆÎª ¡°porcelain¡± ÃüÁ¸ß²ãÃüÁ¡£
±¾Êéǰ°ËÕÂÖ÷ҪרÃÅÌÖÂ۸߲ãÃüÁî¡£±¾Õ½«Ö÷ÒªÌÖÂ۵ײãÃüÁîÒÔÀí½â Git µÄÄÚ²¿¹¤×÷»úÖÆ¡¢ÑÝʾ Git ÈçºÎ¼°ÎªºÎÒªÒÔÕâÖÖ·½Ê½¹¤×÷¡£ÕâЩÃüÁîÖ÷Òª²»ÊÇÓÃÀ´´ÓÃüÁîÐÐÊÖ¹¤Ê¹Óõ쬏ü¶àµÄÊÇÓÃÀ´ÎªÆäËû¹¤¾ßºÍ×Ô¶¨Òå½Å±¾·þÎñµÄ¡£
µ±ÄãÔÚÒ»¸öÐÂĿ¼»òÒÑÓÐĿ¼ÄÚÖ´ÐÐ git init ʱ£¬Git »á´´½¨Ò»¸ö
.git Ŀ¼£¬¼¸ºõËùÓÐ Git ´æ´¢ºÍ²Ù×÷µÄÄÚÈݶ¼Î»ÓÚ¸ÃĿ¼Ï¡£Èç¹ûÄãÒª±¸·Ý»ò¸´ÖÆÒ»¸ö¿â£¬»ù±¾ÉϽ«ÕâһĿ¼¿½±´ÖÁÆäËûµØ·½¾Í¿ÉÒÔÁË¡£±¾Õ»ù±¾É϶¼ÌÖÂÛ¸ÃĿ¼ÏµÄÄÚÈÝ¡£¸ÃĿ¼½á¹¹ÈçÏ£º
$ ls HEAD branches/ config description hooks/ index info/ objects/ refs/ |
¸ÃĿ¼ÏÂÓпÉÄÜ»¹ÓÐÆäËûÎļþ£¬µ«ÕâÊÇÒ»¸öÈ«Ð嵀 git init Éú³ÉµÄ¿â£¬ËùÒÔĬÈÏÇé¿öÏÂÕâЩ¾ÍÊÇÄãÄÜ¿´µ½µÄ½á¹¹¡£Ð°汾µÄ
Git ²»ÔÙʹÓÃbranches Ŀ¼£¬description Îļþ½ö¹© GitWeb ³ÌÐòʹÓã¬ËùÒÔ²»ÓùØÐÄÕâЩÄÚÈÝ¡£config
Îļþ°üº¬ÁËÏîÄ¿ÌØÓеÄÅäÖÃÑ¡Ïinfo Ŀ¼±£´æÁËÒ»·Ý²»Ï£ÍûÔÚ .gitignore ÎļþÖйÜÀíµÄºöÂÔģʽ
(ignored patterns) µÄÈ«¾Ö¿ÉÖ´ÐÐÎļþ¡£hooks Ŀ¼°üסÁ˵ÚÁùÕÂÏêϸ½éÉÜÁ˵Ŀͻ§¶Ë»ò·þÎñ¶Ë¹³×ӽű¾¡£
ÁíÍ⻹ÓÐËĸöÖØÒªµÄÎļþ»òĿ¼£ºHEAD ¼° index Îļþ£¬objects
¼°refs Ŀ¼¡£ÕâЩÊÇ Git µÄºËÐIJ¿·Ö¡£objects Ŀ¼´æ´¢ËùÓÐÊý¾ÝÄÚÈÝ£¬refs Ŀ¼´æ´¢Ö¸ÏòÊý¾Ý
(·ÖÖ§) µÄÌá½»¶ÔÏóµÄÖ¸Õ룬HEAD ÎļþÖ¸Ïòµ±Ç°·ÖÖ§£¬index Îļþ±£´æÁËÔÝ´æÇøÓòÐÅÏ¢¡£ÂíÉÏÄ㽫ÏêϸÁ˽â
Git ÊÇÈçºÎ²Ù×ÝÕâЩÄÚÈݵġ£
9.2 Git ¶ÔÏó
Git ÊÇÒ»Ì×ÄÚÈÝѰַÎļþϵͳ¡£ºÜ²»´í¡£²»¹ýÕâÊÇʲôÒâË¼ÄØ£¿ÕâÖÖ˵·¨µÄÒâ˼ÊÇ£¬´ÓÄÚ²¿À´¿´£¬Git
ÊǼòµ¥µÄ key-value Êý¾Ý´æ´¢¡£ËüÔÊÐí²åÈëÈÎÒâÀàÐ͵ÄÄÚÈÝ£¬²¢»á·µ»ØÒ»¸ö¼üÖµ£¬Í¨¹ý¸Ã¼üÖµ¿ÉÒÔÔÚÈκÎʱºòÔÙÈ¡³ö¸ÃÄÚÈÝ¡£¿ÉÒÔͨ¹ýµ×²ãÃüÁîhash-object
À´Ê¾·¶Õâµã£¬´«Ò»Ð©Êý¾Ý¸ø¸ÃÃüÁËü»á½«Êý¾Ý±£´æÔÚ .git Ŀ¼²¢·µ»Ø±íʾÕâЩÊý¾ÝµÄ¼üÖµ¡£Ê×Ïȳõʹ»¯Ò»¸ö
Git ²Ö¿â²¢È·ÈÏobjects Ŀ¼Êǿյģº
$ mkdir test $ cd test $ git init Initialized empty Git repository in /tmp/test/.git/ $ find .git/objects .git/objects .git/ |
Git ³õʼ»¯ÁË objects Ŀ¼£¬Í¬Ê±ÔÚ¸ÃĿ¼Ï´´½¨ÁË pack
ºÍ info ×ÓĿ¼£¬µ«ÊǸÃĿ¼ÏÂûÓÐÆäËû³£¹æÎļþ¡£ÎÒÃÇÍùÕâ¸ö Git Êý¾Ý¿âÀï´æ´¢Ò»Ð©Îı¾£º
$ echo 'test content' | git hash-object -w --stdin d670460b4b4aece5915caf5c68d12f560a9fe3e4 |
²ÎÊý -w ָʾ hash-object ÃüÁî´æ´¢ (Êý¾Ý) ¶ÔÏó£¬Èô²»Ö¸¶¨Õâ¸ö²ÎÊý¸ÃÃüÁî½ö½ö·µ»Ø¼üÖµ¡£--stdin
Ö¸¶¨´Ó±ê×¼ÊäÈëÉ豸 (stdin) À´¶ÁÈ¡ÄÚÈÝ£¬Èô²»Ö¸¶¨Õâ¸ö²ÎÊýÔòÐèÖ¸¶¨Ò»¸öÒª´æ´¢µÄÎļþµÄ·¾¶¡£¸ÃÃüÁîÊä³ö³¤¶ÈΪ
40 ¸ö×Ö·ûµÄУÑéºÍ¡£ÕâÊǸö SHA-1 ¹þÏ£Öµ©¤©¤ÆäֵΪҪ´æ´¢µÄÊý¾Ý¼ÓÉÏÄãÂíÉÏ»áÁ˽⵽µÄÒ»ÖÖÍ·ÐÅÏ¢µÄУÑéºÍ¡£ÏÖÔÚ¿ÉÒԲ鿴µ½
Git ÒѾ´æ´¢ÁËÊý¾Ý£º
$ find .git/objects -type f .git/objects/d6/70460b4b4aece5915caf5c68d12f560a9fe3e4 |
¿ÉÒÔÔÚ objects Ŀ¼Ï¿´µ½Ò»¸öÎļþ¡£Õâ±ãÊÇ Git ´æ´¢Êý¾ÝÄÚÈݵķ½Ê½©¤©¤ÎªÃ¿·ÝÄÚÈÝÉú³ÉÒ»¸öÎļþ£¬È¡µÃ¸ÃÄÚÈÝÓëÍ·ÐÅÏ¢µÄ
SHA-1 УÑéºÍ£¬´´½¨ÒÔ¸ÃУÑéºÍǰÁ½¸ö×Ö·ûΪÃû³ÆµÄ×ÓĿ¼£¬²¢ÒÔ (УÑéºÍ) ʣϠ38 ¸ö×Ö·ûΪÎļþÃüÃû
(±£´æÖÁ×ÓĿ¼ÏÂ)¡£
ͨ¹ý cat-file ÃüÁî¿ÉÒÔ½«Êý¾ÝÄÚÈÝÈ¡»Ø¡£¸ÃÃüÁîÊDz鿴 Git ¶ÔÏóµÄÈðÊ¿¾üµ¶¡£´«Èë -p ²ÎÊý¿ÉÒÔÈøÃÃüÁîÊä³öÊý¾ÝÄÚÈݵÄÀàÐÍ£º
$ git cat-file -p d670460b4b4aece5915caf5c68d12f560a9fe3e4 test content |
¿ÉÒÔÍù Git ÖÐÌí¼Ó¸ü¶àÄÚÈݲ¢È¡»ØÁË¡£Ò²¿ÉÒÔÖ±½ÓÌí¼ÓÎļþ¡£±È·½Ëµ¿ÉÒÔ¶ÔÒ»¸öÎļþ½øÐмòµ¥µÄ°æ±¾¿ØÖÆ¡£Ê×ÏÈ£¬´´½¨Ò»¸öÐÂÎļþ£¬²¢°ÑÎļþÄÚÈÝ´æ´¢µ½Êý¾Ý¿âÖУº
$ echo 'version 1' > test.txt $ git hash-object -w test.txt 83baae61804e65cc73a7201a7252750c76066a30 |
½Ó×ÅÍù¸ÃÎļþÖÐдÈëһЩÐÂÄÚÈݲ¢Ôٴα£´æ£º
$ echo 'version 2' > test.txt $ git hash-object -w test.txt 1f7a7a472abf3dd9643fd615f6da379c4acb3e3a |
Êý¾Ý¿âÖÐÒѾ½«ÎļþµÄÁ½¸öа汾Á¬Í¬Ò»¿ªÊ¼µÄÄÚÈݱ£´æÏÂÀ´ÁË£º
$ find .git/objects -type f .git/objects/1f/7a7a472abf3dd9643fd615f6da379c4acb3e3a .git/objects/83/baae61804e65cc73a7201a7252 |
ÔÙ½«Îļþ»Ö¸´µ½µÚÒ»¸ö°æ±¾£º
$ git cat-file -p 83baae61804e65cc73a7201a7252750c76066a30 > test.txt $ cat test.txt version 1 |
»ò»Ö¸´µ½µÚ¶þ¸ö°æ±¾£º
$ git cat-file -p 1f7a7a472abf3dd9643fd615f6da379c4acb3e3a > test.txt $ cat test.txt version 2 |
ÐèÒª¼ÇסµÄÊǼ¸¸ö°æ±¾µÄÎļþ SHA-1 Öµ¿ÉÄÜÓëʵ¼ÊµÄÖµ²»Í¬£¬Æä´Î£¬´æ´¢µÄ²¢²»ÊÇÎļþÃû¶ø½ö½öÊÇÎļþÄÚÈÝ¡£ÕâÖÖ¶ÔÏóÀàÐͳÆÎª
blob ¡£Í¨¹ý´«µÝ SHA-1 Öµ¸øcat-file -t ÃüÁî¿ÉÒÔÈà Git ·µ»ØÈκζÔÏóµÄÀàÐÍ£º
$ git cat-file -t 1f7a7a472abf3dd9643fd615f6da379c4acb3e3a blob |
tree (Ê÷) ¶ÔÏó
½ÓÏÂÈ¥À´¿´ tree ¶ÔÏó£¬tree ¶ÔÏó¿ÉÒÔ´æ´¢ÎļþÃû£¬Í¬Ê±Ò²ÔÊÐí´æ´¢Ò»×éÎļþ¡£Git
ÒÔÒ»ÖÖÀàËÆ UNIX Îļþϵͳµ«¸ü¼òµ¥µÄ·½Ê½À´´æ´¢ÄÚÈÝ¡£ËùÓÐÄÚÈÝÒÔ tree »ò blob ¶ÔÏó´æ´¢£¬ÆäÖÐ
tree ¶ÔÏó¶ÔÓ¦ÓÚ UNIX ÖеÄĿ¼£¬blob ¶ÔÏóÔò´óÖ¶ÔÓ¦ÓÚ inodes »òÎļþÄÚÈÝ¡£Ò»¸öµ¥¶ÀµÄ
tree ¶ÔÏó°üº¬Ò»Ìõ»ò¶àÌõ tree ¼Ç¼£¬Ã¿Ò»Ìõ¼Ç¼º¬ÓÐÒ»¸öÖ¸Ïò blob »ò×Ó tree ¶ÔÏóµÄ
SHA-1 Ö¸Õ룬²¢¸½ÓиöÔÏóµÄȨÏÞģʽ (mode)¡¢ÀàÐͺÍÎļþÃûÐÅÏ¢¡£ÒÔ simplegit ÏîĿΪÀý£¬×îеÄ
tree ¿ÉÄÜÊÇÕâ¸öÑù×Ó£º
$ git cat-file -p master^{tree} 100644 blob
a906cb2a4a904a152e80877d4088654daad0c859 README 100644 blob 8f94139338f9404f2629 |
master^{tree} ±íʾ branch ·ÖÖ§ÉÏ×îÐÂÌá½»Ö¸ÏòµÄ tree
¶ÔÏó¡£Çë×¢Òâ lib ×ÓĿ¼²¢·ÇÒ»¸ö blob ¶ÔÏ󣬶øÊÇÒ»¸öÖ¸Ïò±ðÒ»¸ö tree ¶ÔÏóµÄÖ¸Õ룺
$ git cat-file -p 99f1a6d12cb4b6f19c8655fca46c3ecf317074e0
100644 blob 47c6340d6459e05787f644c2447d2595f5d3a54b simplegit.rb |
´Ó¸ÅÄîÉÏÀ´½²£¬Git ±£´æµÄÊý¾ÝÈçͼ 9-1 Ëùʾ¡£

ͼ 9-1. Git ¶ÔÏóÄ£Ð͵ļò»¯°æ
Äã¿ÉÒÔ×Ô¼º´´½¨ tree ¡£Í¨³£ Git ¸ù¾ÝÄãµÄÔÝ´æÇøÓò»ò index
À´´´½¨²¢Ð´ÈëÒ»¸ö tree ¡£Òò´ËÒª´´½¨Ò»¸ö tree ¶ÔÏóµÄ»°Ê×ÏÈҪͨ¹ý½«Ò»Ð©ÎļþÔÝ´æ´Ó¶ø´´½¨Ò»¸ö index
¡£¿ÉÒÔʹÓà plumbing ÃüÁîupdate-index Ϊһ¸öµ¥¶ÀÎļþ ©¤©¤ test.txt ÎļþµÄµÚÒ»¸ö°æ±¾
©¤©¤ ´´½¨Ò»¸ö index ¡£Í¨¹ý¸ÃÃüÁîÈËΪµÄ½« test.txt ÎļþµÄÊ׸ö°æ±¾¼ÓÈëµ½ÁËÒ»¸öеÄÔÝ´æÇøÓòÖС£ÓÉÓÚ¸ÃÎļþÔÏȲ¢²»ÔÚÔÝ´æÇøÓòÖÐ
(ÉõÖÁ¾ÍÁ¬ÔÝ´æÇøÓòÒ²»¹Ã»±»´´½¨³öÀ´ÄØ) £¬±ØÐë´«Èë--add ²ÎÊý;ÓÉÓÚÒªÌí¼ÓµÄÎļþ²¢²»ÔÚµ±Ç°Ä¿Â¼Ï¶øÊÇÔÚÊý¾Ý¿âÖУ¬±ØÐë´«Èë
--cacheinfo ²ÎÊý¡£Í¬Ê±Ö¸¶¨ÁËÎļþģʽ£¬SHA-1 ÖµºÍÎļþÃû£º
$ git update-index --add --cacheinfo 100644 \ 83baae61804e65cc73a7201a7252750c76066a30 test.txt |
ÔÚ±¾ÀýÖУ¬Ö¸¶¨ÁËÎļþģʽΪ 100644£¬±íÃ÷ÕâÊÇÒ»¸öÆÕͨÎļþ¡£ÆäËû¿ÉÓõÄģʽÓУº100755
±íʾ¿ÉÖ´ÐÐÎļþ£¬120000 ±íʾ·ûºÅÁ´½Ó¡£ÎļþģʽÊÇ´Ó³£¹æµÄ UNIX ÎļþģʽÖвο¼À´µÄ£¬µ«ÊÇûÓÐÄÇôÁé»î
©¤©¤ ÉÏÊöÈýÖÖģʽ½ö¶Ô Git ÖеÄÎļþ (blobs) ÓÐЧ (ËäȻҲÓÐÆäËûģʽÓÃÓÚĿ¼ºÍ×ÓÄ£¿é)¡£
ÏÖÔÚ¿ÉÒÔÓà write-tree ÃüÁÔÝ´æÇøÓòµÄÄÚÈÝдµ½Ò»¸ö tree ¶ÔÏóÁË¡£ÎÞÐè -w ²ÎÊý ©¤©¤
Èç¹ûÄ¿±ê tree ²»´æÔÚ£¬µ÷ÓÃwrite-tree »á×Ô¶¯¸ù¾Ý index ״̬´´½¨Ò»¸ö tree ¶ÔÏó¡£
$ git write-tree d8329fc1cc938780ffdd9f94e0d364e0ea74f579
$ git cat-file -p d8329fc1cc938780ffdd9f94e0d364e0ea74f579 100644 |
¿ÉÒÔÕâÑùÑéÖ¤ÕâȷʵÊÇÒ»¸ö tree ¶ÔÏó£º
$ git cat-file -t d8329fc1cc938780ffdd9f94e0d364e0ea74f579 tree |
ÔÙ¸ù¾Ý test.txt µÄµÚ¶þ¸ö°æ±¾ÒÔ¼°Ò»¸öÐÂÎļþ´´½¨Ò»¸öРtree
¶ÔÏó£º
$ echo 'new file' > new.txt $ git update-index test.txt $ git update-index --add new.txt |
ÕâʱÔÝ´æÇøÓòÖаüº¬ÁË test.txt µÄа汾¼°Ò»¸öÐÂÎļþ new.txt
¡£´´½¨ (д) ¸Ã tree ¶ÔÏó (½«ÔÝ´æÇøÓò»ò index ״̬дÈëµ½Ò»¸ö tree ¶ÔÏó)£¬È»ºóÇÆÇÆËüµÄÑù×Ó£º
$ git write-tree 0155eb4229851634a0f03eb265b69f5a2d56f341
$ git cat-file -p 0155eb4229851634a0f03eb265b69f5a2d56f341 100644 |
Çë×¢Òâ¸Ã tree ¶ÔÏó°üº¬ÁËÁ½¸öÎļþ¼Ç¼£¬ÇÒ test.txt µÄ SHA
ÖµÊÇÔçÏÈÖµµÄ ¡°µÚ¶þ°æ¡± (1f7a7a)¡£À´µã¸üÓÐȤµÄ£¬Ä㽫°ÑµÚÒ»¸ö tree ¶ÔÏó×÷Ϊһ¸ö×ÓĿ¼¼Ó½ø¸Ã
tree ÖС£¿ÉÒÔÓÃread-tree ÃüÁ tree ¶ÔÏó¶Áµ½ÔÝ´æÇøÓòÖÐÈ¥¡£ÔÚÕâʱ£¬Í¨¹ý´«Ò»¸ö --prefix
²ÎÊý¸ø read-tree£¬½«Ò»¸öÒÑÓÐµÄ tree ¶ÔÏó×÷Ϊһ¸ö×Ó tree ¶Áµ½ÔÝ´æÇøÓòÖУº
$ git read-tree --prefix=bak d8329fc1cc938780ffdd9f94e0d364e0ea74f579
$ git write-tree 3c4e9cd789d88d8d89c1073707c3585e41b0e61 |
Èç¹û´Ó¸ÕдÈëµÄРtree ¶ÔÏó´´½¨Ò»¸ö¹¤×÷Ŀ¼£¬½«µÃµ½Î»ÓÚ¹¤×÷Ŀ¼¶¥¼¶µÄÁ½¸öÎļþºÍÒ»¸öÃûΪ
bak µÄ×ÓĿ¼£¬¸Ã×ÓĿ¼°üº¬ÁË test.txt ÎļþµÄµÚÒ»¸ö°æ±¾¡£¿ÉÒÔ½« Git ÓÃÀ´°üº¬ÕâЩÄÚÈݵÄÊý¾ÝÏëÏó³ÉÈçͼ
9-2 ËùʾµÄÑù×Ó¡£

ͼ 9-2. µ±Ç° Git Êý¾ÝµÄÄÚÈݽṹ
commit (Ìá½») ¶ÔÏó
ÄãÏÖÔÚÓÐÈý¸ö tree ¶ÔÏó£¬ËüÃÇÖ¸ÏòÁËÄãÒª¸ú×ÙµÄÏîÄ¿µÄ²»Í¬¿ìÕÕ£¬¿ÉÊÇÏÈǰµÄÎÊÌâÒÀÈ»´æÔÚ£º±ØÐë¼ÇÍùÈý¸ö
SHA-1 ÖµÒÔ»ñµÃÕâЩ¿ìÕÕ¡£ÄãҲûÓйØÓÚË¡¢ºÎʱÒÔ¼°ÎªºÎ±£´æÁËÕâЩ¿ìÕÕµÄÐÅÏ¢¡£commit ¶ÔÏóΪÄã±£´æÁËÕâЩ»ù±¾ÐÅÏ¢¡£
Òª´´½¨Ò»¸ö commit ¶ÔÏó£¬Ê¹Óà commit-tree ÃüÁָ¶¨Ò»¸ö tree µÄ SHA-1£¬Èç¹ûÓÐÈκÎǰ¼ÌÌá½»¶ÔÏó£¬Ò²¿ÉÒÔÖ¸¶¨¡£´ÓÄãдµÄµÚÒ»¸ö
tree ¿ªÊ¼£º
$ echo 'first commit' | git commit-tree d8329f fdf4fc3344e67ab068f836878b6c4951e3b15f3d |
ͨ¹ý cat-file ²é¿´Õâ¸öРcommit ¶ÔÏó£º
$ git cat-file -p fdf4fc3 tree d8329fc1cc938780ffdd9f94e0d364e0ea74f579
author Scott Chacon 1243040974 -0700 committer Scott |
commit ¶ÔÏóÓиñʽºÜ¼òµ¥£ºÖ¸Ã÷Á˸Ãʱ¼äµãÏîÄ¿¿ìÕյĶ¥²ãÊ÷¶ÔÏó¡¢×÷Õß/Ìá½»ÕßÐÅÏ¢£¨´Ó
Git ÉèÀí·¢µêµÄ user.name ºÍuser.emailÖлñµÃ)ÒÔ¼°µ±Ç°Ê±¼ä´Á¡¢Ò»¸ö¿ÕÐУ¬ÒÔ¼°Ìá½»×¢ÊÍÐÅÏ¢¡£
½Ó×ÅÔÙдÈëÁíÍâÁ½¸ö commit ¶ÔÏó£¬Ã¿Ò»¸ö¶¼Ö¸¶¨Æä֮ǰµÄÄǸö commit ¶ÔÏó£º
$ echo 'second commit' | git commit-tree 0155eb -p fdf4fc3 cac0cab538b970a37ea1e769cbbde608743bc96d
$ echo 'third commit' | |
ÿһ¸ö commit ¶ÔÏó¶¼Ö¸ÏòÁËÄã´´½¨µÄÊ÷¶ÔÏó¿ìÕÕ¡£³öºõÒâÁϵÄÊÇ£¬ÏÖÔÚÒѾÓÐÁËÕæÊµµÄ
Git ÀúÊ·ÁË£¬ËùÒÔÈç¹ûÔËÐÐ git log ÃüÁî²¢Ö¸¶¨×îºóÄǸö commit ¶ÔÏóµÄ SHA-1 ±ã¿ÉÒԲ鿴ÀúÊ·£º
$ git log --stat 1a410e commit 1a410efbd13591db07496601ebc7a059dd55cfe9
Author: Scott Chacon Date: Fri May 22 18:15:24 2009 |
Õæ°ô¡£Äã¸Õ¸Õͨ¹ýʹÓõͼ¶²Ù×÷¶ø²»ÊÇÄÇЩÆÕͨÃüÁî´´½¨ÁËÒ»¸ö Git ÀúÊ·¡£Õâ»ù±¾ÉϾÍÊÇÔËÐÐ
git add ºÍ git commit ÃüÁîʱ Git ½øÐеŤ×÷ ©¤©¤±£´æÐÞ¸ÄÁ˵ÄÎļþµÄ blob£¬¸üÐÂË÷Òý£¬´´½¨
tree ¶ÔÏó£¬×îºó´´½¨ commit ¶ÔÏó£¬ÕâЩ commit ¶ÔÏóÖ¸ÏòÁ˶¥²ã tree ¶ÔÏóÒÔ¼°ÏÈǰµÄ
commit ¶ÔÏó¡£ÕâÈýÀà Git ¶ÔÏó ©¤©¤ blob£¬tree ÒÔ¼° tree ©¤©¤ ¶¼¸÷×ÔÒÔÎļþµÄ·½Ê½±£´æÔÚ.git/objects
Ŀ¼Ï¡£ÒÔÏÂËùÁÐÊÇĿǰΪֹÑùÀýÖеÄËùÓжÔÏó£¬Ã¿¸ö¶ÔÏóºóÃæµÄ×¢ÊÍÀï±êÃ÷ÁËËüÃDZ£´æµÄÄÚÈÝ£º
$ find .git/objects -type f .git/objects/01/55eb4229851634a0f03eb265b69f5a2d56f341 # tree 2 .git/objects/1a/410efbd13591db07 |
Èç¹ûÄã°´ÕÕÒÔÉÏÃèÊö½øÐÐÁ˲Ù×÷£¬¿ÉÒԵõ½Èçͼ 9-3 ËùʾµÄ¶ÔÏóͼ¡£

ͼ 9-3. Git Ŀ¼ÏµÄËùÓжÔÏó
¶ÔÏó´æ´¢
֮ǰÎÒÌáµ½µ±´æ´¢Êý¾ÝÄÚÈÝʱ£¬Í¬Ê±»áÓÐÒ»¸öÎļþÍ·±»´æ´¢ÆðÀ´¡£ÎÒÃÇ»¨Ð©Ê±¼äÀ´¿´¿´
Git ÊÇÈçºÎ´æ´¢¶ÔÏóµÄ¡£Ä㽫¿´À´ÈçºÎͨ¹ý Ruby ½Å±¾ÓïÑÔ´æ´¢Ò»¸ö blob ¶ÔÏó (ÕâÀïÒÔ×Ö·û´®
¡°what is up, doc?¡± ΪÀý) ¡£Ê¹ÓÃirb ÃüÁî½øÈë Ruby ½»»¥Ê½Ä£Ê½£º
$ irb >> content = "what is up, doc?" => "what is up, doc?" |
Git ÒÔ¶ÔÏóÀàÐÍΪÆðʼÄÚÈݹ¹ÔìÒ»¸öÎļþÍ·£¬±¾ÀýÖÐÊÇÒ»¸ö blob¡£È»ºóÌí¼ÓÒ»¸ö¿Õ¸ñ£¬½Ó×ÅÊÇÊý¾ÝÄÚÈݵij¤¶È£¬×îºóÊÇÒ»¸ö¿Õ×Ö½Ú
(null byte)£º
>> header = "blob #{content.length}\0" => "blob 16\000" |
Git ½«ÎļþÍ·ÓëÔʼÊý¾ÝÄÚÈÝÆ´½ÓÆðÀ´£¬²¢¼ÆËãÆ´½ÓºóµÄÐÂÄÚÈÝµÄ SHA-1
УÑéºÍ¡£¿ÉÒÔÔÚ Ruby ÖÐʹÓà require Óï¾äµ¼Èë SHA1 digest ¿â£¬È»ºóµ÷ÓÃDigest::SHA1.hexdigest()
·½·¨¼ÆËã×Ö·û´®µÄ SHA-1 Öµ£º
>> store = header + content => "blob 16\000what is up, doc?"
>> require 'digest/sha1' => true >> sha1 = Digest::SHA1.hexdige |
Git Óà zlib ¶ÔÊý¾ÝÄÚÈݽøÐÐѹËõ£¬ÔÚ Ruby ÖпÉÒÔÓà zlib
¿âÀ´ÊµÏÖ¡£Ê×ÏÈÐèÒªµ¼Èë¸Ã¿â£¬È»ºóÓà Zlib::Deflate.deflate() ¶ÔÊý¾Ý½øÐÐѹËõ£º
>> require 'zlib' => true >> zlib_content = Zlib::Deflate.deflate(store)
=> "x\234K\312\311OR04c(\317H,Q\310,V(-\320QH\311O\ |
×îºó½«Óà zlib ѹËõºóµÄÄÚÈÝдÈë´ÅÅÌ¡£ÐèÒªÖ¸¶¨±£´æ¶ÔÏóµÄ·¾¶ (SHA-1
ÖµµÄÍ·Á½¸ö×Ö·û×÷Ϊ×ÓĿ¼Ãû³Æ£¬Ê£Óà 38 ¸ö×Ö·û×÷ΪÎļþÃû±£´æÖÁ¸Ã×ÓĿ¼ÖÐ)¡£ÔÚ Ruby ÖУ¬Èç¹û×ÓĿ¼²»´æÔÚ¿ÉÒÔÓÃFileUtils.mkdir_p()
º¯Êý´´½¨Ëü¡£½Ó×ÅÓà File.open ·½·¨´ò¿ªÎļþ£¬²¢Óà write() ·½·¨½«Ö®Ç°Ñ¹ËõµÄÄÚÈÝдÈë¸ÃÎļþ£º
>> path = '.git/objects/' + sha1[0,2] + '/' + sha1[2,38]
=> ".git/objects/bd/9dbf5aae1a3862dd1526723246b20206e5fc37"
|
Õâ¾ÍÐÐÁË ©¤©¤ ÄãÒѾ´´½¨ÁËÒ»¸öÕýÈ·µÄ blob ¶ÔÏó¡£ËùÓÐµÄ Git
¶ÔÏó¶¼ÒÔÕâÖÖ·½Ê½´æ´¢£¬Î©Ò»µÄÇø±ðÊÇÀàÐͲ»Í¬ ©¤©¤ ³ýÁË×Ö·û´® blob£¬ÎļþÍ·ÆðʼÄÚÈÝ»¹¿ÉÒÔÊÇ commit
»ò tree ¡£²»¹ýËäÈ» blob ¼¸ºõ¿ÉÒÔÊÇÈÎÒâÄÚÈÝ£¬commit ºÍ tree µÄÊý¾ÝÈ´ÊÇÓй̶¨¸ñʽµÄ¡£
9.3 Git References
Äã¿ÉÒÔÖ´ÐÐÏñ git log 1a410e ÕâÑùµÄÃüÁîÀ´²é¿´ÍêÕûµÄÀúÊ·£¬µ«ÊÇÕâÑùÄã¾ÍÒª¼ÇµÃ
1a410e ÊÇÄã×îºóÒ»´ÎÌá½»£¬ÕâÑù²ÅÄÜÔÚÌá½»ÀúÊ·ÖÐÕÒµ½ÕâЩ¶ÔÏó¡£ÄãÐèÒªÒ»¸öÎļþÀ´ÓÃÒ»¸ö¼òµ¥µÄÃû×ÖÀ´¼Ç¼ÕâЩ
SHA-1 Öµ£¬ÕâÑùÄã¾Í¿ÉÒÔÓÃÕâЩָÕë¶ø²»ÊÇÔÀ´µÄ SHA-1 ֵȥ¼ìË÷ÁË¡£
ÔÚ Git ÖУ¬ÎÒÃdzÆÖ®Îª¡°ÒýÓá±£¨references »òÕß refs£¬ÒëÕß×¢£©¡£Äã¿ÉÒÔÔÚ .git/refs
Ŀ¼ÏÂÃæÕÒµ½ÕâЩ°üº¬ SHA-1 ÖµµÄÎļþ¡£ÔÚÕâ¸öÏîÄ¿ÀÕâ¸öĿ¼»¹Ã»²»°üº¬ÈκÎÎļþ£¬µ«Êǰüº¬ÕâÑùÒ»¸ö¼òµ¥µÄ½á¹¹£º
$ find .git/refs .git/refs .git/refs/heads .git/refs/tags $ find .git/refs -type f $ |
Èç¹ûÏëÒª´´½¨Ò»¸öеÄÒýÓðïÖúÄã¼Çס×îºóÒ»´ÎÌá½»£¬¼¼ÊõÉÏÄã¿ÉÒÔÕâÑù×ö£º
$ echo "1a410efbd13591db07496601ebc7a059dd55cfe9" > .git/refs/heads/master |
ÏÖÔÚ£¬Äã¾Í¿ÉÒÔÔÚ Git ÃüÁîÖÐʹÓÃÄã¸Õ²Å´´½¨µÄÒýÓöø²»ÊÇ SHA-1
Öµ£º
$ git log --pretty=oneline master 1a410efbd13591db07496601ebc7a059dd55cfe9 third
commit cac0cab538b970a37ea1e769cbbde608743bc |
µ±È»£¬ÎÒÃDz¢²»¹ÄÀøÄãÖ±½ÓÐÞ¸ÄÕâЩÒýÓÃÎļþ¡£Èç¹ûÄãȷʵÐèÒª¸üÐÂÒ»¸öÒýÓã¬Git
ÌṩÁËÒ»¸ö°²È«µÄÃüÁî update-ref£º
$ git update-ref refs/heads/master 1a410efbd13591db07496601ebc7a059dd55cfe9 |
»ù±¾ÉÏ Git ÖеÄÒ»¸ö·ÖÖ§Æäʵ¾ÍÊÇÒ»¸öÖ¸Ïòij¸ö¹¤×÷°æ±¾Ò»Ìõ HEAD
¼Ç¼µÄÖ¸Õë»òÒýÓá£Äã¿ÉÒÔÓÃÕâÌõÃüÁî´´½¨Ò»¸öÖ¸ÏòµÚ¶þ´ÎÌá½»µÄ·ÖÖ§£º
$ git update-ref refs/heads/test cac0ca |
ÕâÑùÄãµÄ·ÖÖ§½«»áÖ»°üº¬ÄÇ´ÎÌá½»ÒÔ¼°Ö®Ç°µÄ¹¤×÷£º
$ git log --pretty=oneline test cac0cab538b970a37ea1e769cbbde608743bc96d
second commit fdf4fc3344e67ab068f836878b6c4951e3b15 |
ÏÖÔÚ£¬ÄãµÄ Git Êý¾Ý¿âÓ¦¸Ã¿´ÆðÀ´Ïñͼ 9-4 Ò»Ñù¡£

ͼ 9-4. °üº¬·ÖÖ§ÒýÓÃµÄ Git Ŀ¼¶ÔÏó
ÿµ±ÄãÖ´ÐÐ git branch (·ÖÖ§Ãû³Æ) ÕâÑùµÄÃüÁGit »ù±¾ÉϾÍÊÇÖ´ÐÐ
update-ref ÃüÁ°ÑÄãÏÖÔÚËùÔÚ·ÖÖ§ÖÐ×îºóÒ»´ÎÌá½»µÄ SHA-1 Öµ£¬Ìí¼Óµ½ÄãÒª´´½¨µÄ·ÖÖ§µÄÒýÓá£
HEAD 񈬀
ÏÖÔÚµÄÎÊÌâÊÇ£¬µ±ÄãÖ´ÐÐ git branch (·ÖÖ§Ãû³Æ) ÕâÌõÃüÁîµÄʱºò£¬Git
Ôõô֪µÀ×îºóÒ»´ÎÌá½»µÄ SHA-1 ֵĨ£¿´ð°¸¾ÍÊÇ HEAD Îļþ¡£HEAD ÎļþÊÇÒ»¸öÖ¸ÏòÄ㵱ǰËùÔÚ·ÖÖ§µÄÒýÓñêʶ·û¡£ÕâÑùµÄÒýÓñêʶ·û¡ª¡ªËü¿´ÆðÀ´²¢²»ÏñÒ»¸öÆÕͨµÄÒýÓ᪡ªÆäʵ²¢²»°üº¬
SHA-1 Öµ£¬¶øÊÇÒ»¸öÖ¸ÏòÁíÍâÒ»¸öÒýÓõÄÖ¸Õë¡£Èç¹ûÄã¿´Ò»ÏÂÕâ¸öÎļþ£¬Í¨³£Ä㽫»á¿´µ½ÕâÑùµÄÄÚÈÝ£º
$ cat .git/HEAD ref: refs/heads/master |
Èç¹ûÄãÖ´ÐÐ git checkout test£¬Git ¾Í»á¸üÐÂÕâ¸öÎļþ£¬¿´ÆðÀ´ÏñÕâÑù£º
$ cat .git/HEAD ref: refs/heads/test |
µ±ÄãÔÙÖ´ÐÐ git commit ÃüÁËü¾Í´´½¨ÁËÒ»¸ö commit ¶ÔÏ󣬰ÑÕâ¸ö
commit ¶ÔÏóµÄ¸¸¼¶ÉèÖÃΪ HEAD Ö¸ÏòµÄÒýÓÃµÄ SHA-1 Öµ¡£
ÄãÒ²¿ÉÒÔÊÖ¶¯±à¼Õâ¸öÎļþ£¬µ«ÊÇͬÑùÓÐÒ»¸ö¸ü°²È«µÄ·½·¨¿ÉÒÔÕâÑù×ö£ºsymbolic-ref¡£Äã¿ÉÒÔÓÃÏÂÃæÕâÌõÃüÁî¶ÁÈ¡
HEAD 掙朧
$ git symbolic-ref HEAD refs/heads/master |
ÄãÒ²¿ÉÒÔÉèÖà HEAD µÄÖµ£º
<!DOCTYPE HTML>$ git symbolic-ref HEAD refs/heads/test $ cat .git/HEAD ref: refs/heads/test
|
µ«ÊÇÄã²»ÄÜÉèÖÃ³É refs ÒÔÍâµÄÐÎʽ£º
$ git symbolic-ref HEAD test fatal: Refusing to point HEAD outside of refs/ |
Tags
Äã¸Õ¸ÕÒÑ¾ÖØÎ¹ýÁË Git µÄÈý¸öÖ÷Òª¶ÔÏóÀàÐÍ£¬ÏÖÔÚÕâÊǵÚËÄÖÖ¡£Tag
¶ÔÏó·Ç³£ÏñÒ»¸ö commit ¶ÔÏ󡪡ª°üº¬Ò»¸ö±êÇ©£¬Ò»×éÊý¾Ý£¬Ò»¸öÏûÏ¢ºÍÒ»¸öÖ¸Õë¡£×îÖ÷ÒªµÄÇø±ð¾ÍÊÇ Tag
¶ÔÏóÖ¸ÏòÒ»¸ö commit ¶ø²»ÊÇÒ»¸ö tree¡£Ëü¾ÍÏñÊÇÒ»¸ö·ÖÖ§ÒýÓ㬵«ÊDz»»á±ä»¯¡ª¡ªÓÀÔ¶Ö¸Ïòͬһ¸ö
commit£¬½ö½öÊÇÌṩһ¸ö¸ü¼ÓÓѺõÄÃû×Ö¡£
ÕýÈçÎÒÃÇÔÚµÚ¶þÕÂËùÌÖÂ۵ģ¬Tag ÓÐÁ½ÖÖÀàÐÍ£ºannotated ºÍ lightweight ¡£Äã¿ÉÒÔÀàËÆÏÂÃæÕâÑùµÄÃüÁÁ¢Ò»¸ö
lightweight tag£º
$ git update-ref refs/tags/v1.0 cac0cab538b970a37ea1e769cbbde608743bc96d |
Õâ¾ÍÊÇ lightweight tag µÄÈ«²¿ ¡ª¡ª Ò»¸öÓÀÔ¶²»»á·¢Éú±ä»¯µÄ·ÖÖ§¡£
annotated tag Òª¸ü¸´ÔÓÒ»µã¡£Èç¹ûÄã´´½¨Ò»¸ö annotated tag£¬Git »á´´½¨Ò»¸ö
tag ¶ÔÏó£¬È»ºóдÈëÒ»¸öÖ¸ÏòÖ¸ÏòËü¶ø²»ÊÇÖ±½ÓÖ¸Ïò commit µÄ reference¡£Äã¿ÉÒÔÕâÑù´´½¨Ò»¸ö
annotated tag£¨-a ²ÎÊý±íÃ÷ÕâÊÇÒ»¸ö annotated tag£©£º
$ git tag -a v1.1 1a410efbd13591db07496601ebc7a059dd55cfe9 -m 'test tag' |
ÕâÊÇËù´´½¨¶ÔÏóµÄ SHA-1 Öµ£º
$ cat .git/refs/tags/v1.1 9585191f37f7b0fb9444f35a9bf50de191beadc2 |
ÏÖÔÚÄã¿ÉÒÔÔËÐÐ cat-file ÃüÁî¼ì²éÕâ¸ö SHA-1 Öµ£º
$ git cat-file -p 9585191f37f7b0fb9444f35a9bf50de191beadc2 object
1a410efbd13591db07496601ebc7a059dd55cfe9 type commit tag v1. |
ÖµµÃ×¢ÒâµÄÊÇÕâ¸ö¶ÔÏóÖ¸ÏòÄãËù±ê¼ÇµÄ commit ¶ÔÏóµÄ SHA-1 Öµ¡£Í¬Ê±ÐèҪעÒâµÄÊÇËü²¢²»ÊDZØÐëÒªÖ¸ÏòÒ»¸ö
commit ¶ÔÏó£»Äã¿ÉÒÔ±ê¼ÇÈκΠGit ¶ÔÏó¡£ÀýÈ磬ÔÚ Git µÄÔ´´úÂëÀ¹ÜÀíÕßÌí¼ÓÁËÒ»¸ö GPG
¹«Ô¿£¨ÕâÊÇÒ»¸ö blob ¶ÔÏ󣩶ÔËü×öÁËÒ»¸ö±êÇ©¡£Äã¾Í¿ÉÒÔÔËÐУº
$ git cat-file blob junio-gpg-pub |
À´²é¿´ Git Ô´´úÂë²Ö¿âÖеĹ«Ô¿. Linux kernel Ò²ÓÐÒ»¸ö²»ÊÇÖ¸Ïò
commit ¶ÔÏóµÄ tag ¡ª¡ª µÚÒ»¸ö tag ÊÇÔÚµ¼ÈëÔ´´úÂëµÄʱºò´´½¨µÄ£¬ËüÖ¸Ïò³õʼ tree £¨initial
tree£¬ÒëÕß×¢£©¡£
Remotes
Ä㽫»á¿´µ½µÄµÚËÄÖÖ reference ÊÇ remote reference£¨Ô¶³ÌÒýÓã¬ÒëÕß×¢£©¡£Èç¹ûÄãÌí¼ÓÁËÒ»¸ö
remote È»ºóÍÆËÍ´úÂë¹ýÈ¥£¬Git »á°ÑÄã×îºóÒ»´ÎÍÆË͵½Õâ¸ö remote µÄÿ¸ö·ÖÖ§µÄÖµ¶¼¼Ç¼ÔÚrefs/remotes
Ŀ¼Ï¡£ÀýÈ磬Äã¿ÉÒÔÌí¼ÓÒ»¸ö½Ð×ö origin µÄ remote È»ºó°ÑÄãµÄ master ·ÖÖ§ÍÆËÍÉÏÈ¥£º
$ git remote add origin git@github.com:schacon/simplegit-progit.git
$ git push origin master Counting objects: 11, done. Com |
È»ºó²é¿´ refs/remotes/origin/master Õâ¸öÎļþ£¬Äã¾Í»á·¢ÏÖ
origin remote ÖеÄmaster ·ÖÖ§¾ÍÊÇÄã×îºóÒ»´ÎºÍ·þÎñÆ÷µÄͨÐÅ¡£
$ cat .git/refs/remotes/origin/master ca82a6dff817ec66f44342007202690a93763949 |
Remote Ó¦ÓúͷÖÖ§Ö÷񻂿±ðÔÚÓÚËûÃÇÊDz»Äܱ» check out µÄ¡£Git
°ÑËûÃǵ±×÷ÊDZê¼ÇÕâЩÁËÕâЩ·ÖÖ§ÔÚ·þÎñÆ÷ÉÏ×îºó״̬µÄÒ»ÖÖÊéÇ©¡£
9.4 Packfiles
ÎÒÃÇÔÙÀ´¿´Ò»Ï test Git ²Ö¿â¡£Ä¿Ç°ÎªÖ¹£¬ÓÐ 11 ¸ö¶ÔÏó ©¤©¤
4 ¸ö blob£¬3 ¸ö tree£¬3 ¸ö commit ÒÔ¼°Ò»¸ö tag£º
$ find .git/objects -type f .git/objects/01/55eb4229851634a0f03eb265b69f5a2d56f341
# tree 2 .git/objects/1a/410efbd13591db07 |
Git Óà zlib ѹËõÎļþÄÚÈÝ£¬Òò´ËÕâЩÎļþ²¢Ã»ÓÐÕ¼ÓÃÌ«¶à¿Õ¼ä£¬ËùÓÐÎļþ¼ÓÆðÀ´×ܹ²½öÓÃÁË
925 ×Ö½Ú¡£½ÓÏÂÈ¥Äã»áÌí¼ÓһЩ´óÎļþÒÔÑÝʾ Git µÄÒ»¸öºÜÓÐÒâ˼µÄ¹¦ÄÜ¡£½«Äã֮ǰÓõ½¹ýµÄ Grit
¿âÖÐµÄ repo.rb Îļþ¼Ó½øÈ¥ ©¤©¤ Õâ¸öÔ´´úÂëÎļþ´óСԼΪ 12K£º
$ curl http://github.com/mojombo/grit/raw/master/lib/grit/repo.rb > repo.rb
$ git add repo.rb $ git commit -m 'added repo.rb |
Èç¹û²é¿´Ò»ÏÂÉú³ÉµÄ tree£¬¿ÉÒÔ¿´µ½ repo.rb ÎļþµÄ blob
¶ÔÏóµÄ SHA-1 Öµ£º
$ git cat-file -p master^{tree} 100644 blob fa49b077972391ad58037050f2a75f74e3671e92 new.txt
100644 blob 9bc1dc421dcd51b4ac2 |
È»ºó¿ÉÒÔÓà git cat-file ÃüÁî²é¿´Õâ¸ö¶ÔÏóÓжà´ó£º
$ git cat-file -s 9bc1dc421dcd51b4ac296e3e5b6e2a99cf44391e 12898 |
ÉÔ΢ÐÞ¸ÄÒ»ÏÂЩÎļþ£¬¿´»á·¢ÉúЩʲô£º
$ echo '# testing' >> repo.rb $ git commit -am 'modified repo a bit'
[master ab1afef] modified repo a bit 1 files changed, 1 |
²é¿´Õâ¸ö commit Éú³ÉµÄ tree£¬¿ÉÒÔ¿´µ½Ò»Ð©ÓÐȤµÄ¶«Î÷£º
$ git cat-file -p master^{tree} 100644 blob fa49b077972391ad58037050f2a75f74e3671e92 new.txt
100644 blob 05408d195263d853f09d |
blob ¶ÔÏóÓë֮ǰµÄÒѾ²»Í¬ÁË¡£Õâ˵Ã÷ËäȻֻÊÇÍùÒ»¸ö 400 ÐеÄÎļþ×îºó¼ÓÈëÁËÒ»ÐÐÄÚÈÝ£¬Git
È´ÓÃÒ»¸öȫеĶÔÏóÀ´±£´æÐµÄÎļþÄÚÈÝ£º
$ git cat-file -s 05408d195263d853f09dca71d55116663690c27c 12908 |
ÄãµÄ´ÅÅÌÉÏÓÐÁËÁ½¸ö¼¸ºõÍêÈ«ÏàͬµÄ 12K µÄ¶ÔÏó¡£Èç¹û Git Ö»ÍêÕû±£´æÆäÖÐÒ»¸ö£¬²¢±£´æÁíÒ»¸ö¶ÔÏóµÄ²îÒìÄÚÈÝ£¬Æñ²»¸üºÃ£¿
ÊÂʵÉÏ Git ¿ÉÒÔÄÇÑù×ö¡£Git Íù´ÅÅ̱£´æ¶ÔÏóʱĬÈÏʹÓõĸñʽ½ÐËÉÉ¢¶ÔÏó (loose object)
¸ñʽ¡£Git ʱ²»Ê±µØ½«ÕâЩ¶ÔÏó´ò°üÖÁÒ»¸ö½Ð packfile µÄ¶þ½øÖÆÎļþÒÔ½ÚÊ¡¿Õ¼ä²¢Ìá¸ßЧÂÊ¡£µ±²Ö¿âÖÐÓÐÌ«¶àµÄËÉÉ¢¶ÔÏ󣬻òÊÇÊÖ¹¤µ÷ÓÃgit
gc ÃüÁ»òÍÆËÍÖÁÔ¶³Ì·þÎñÆ÷ʱ£¬Git ¶¼»áÕâÑù×ö¡£ÊÖ¹¤µ÷Óà git gc ÃüÁîÈà Git ½«¿âÖжÔÏó´ò°ü²¢¿´»á·¢ÉúЩʲô£º
$ git gc Counting objects: 17, done. Delta compression using 2 threads.
Compressing objects: 100% (13/13), done. Writing obj |
²é¿´Ò»Ï objects Ŀ¼£¬»á·¢Ïִ󲿷ֶÔÏó¶¼²»ÔÚÁË£¬Óë´Ëͬʱ³öÏÖÁËÁ½¸öÐÂÎļþ£º
$ find .git/objects -type f .git/objects/71/08f7ecb345ee9d0084193f147cdad4d2998293
.git/objects/d6/70460b4b4aece5915caf5c68d |
ÈÔ±£Áô×ŵö¶ÔÏóÊÇδ±»ÈκΠcommit ÒýÓÃµÄ blob ©¤©¤ ÔÚ´ËÀýÖÐÊÇÄã֮ǰ´´½¨µÄ
¡°what is up, doc?¡± ºÍ ¡°test content¡± ÕâÁ½¸öʾÀý blob¡£Äã´Óû½«ËûÃÇÌí¼ÓÖÁÈκÎ
commit£¬ËùÒÔ Git ÈÏΪËüÃÇÊÇ ¡°Ðü¿Õ¡± µÄ£¬²»»á½«ËüÃÇ´ò°ü½ø packfile ¡£
ʣϵÄÎļþÊÇд´½¨µÄ packfile ÒÔ¼°Ò»¸öË÷Òý¡£packfile
Îļþ°üº¬Á˸ղŴÓÎļþϵͳÖÐÒÆ³ýµÄËùÓжÔÏó¡£Ë÷ÒýÎļþ°üº¬ÁË packfile µÄÆ«ÒÆÐÅÏ¢£¬ÕâÑù¾Í¿ÉÒÔ¿ìËÙ¶¨Î»ÈÎÒâÒ»¸öÖ¸¶¨¶ÔÏó¡£ÓÐÒâ˼µÄÊÇÔËÐÐgc
ÃüÁîǰ´ÅÅÌÉϵĶÔÏó´óСԼΪ 12K £¬¶øÕâ¸öÐÂÉú³ÉµÄ packfile ½öΪ 6K ´óС¡£Í¨¹ý´ò°ü¶ÔÏó¼õÉÙÁËÒ»°ë´ÅÅÌʹÓÿռ䡣
Git ÊÇÈçºÎ×öµ½ÕâµãµÄ£¿Git ´ò°ü¶ÔÏóʱ£¬»á²éÕÒÃüÃû¼°³ß´çÏà½üµÄÎļþ£¬²¢Ö»±£´æÎļþ²»Í¬°æ±¾Ö®¼äµÄ²îÒìÄÚÈÝ¡£¿ÉÒԲ鿴һÏÂ
packfile £¬¹Û²ìËüÊÇÈçºÎ½ÚÊ¡¿Õ¼äµÄ¡£git verify-pack ÃüÁîÓÃÓÚÏÔʾÒÑ´ò°üµÄÄÚÈÝ£º
$ git verify-pack -v \ .git/objects/pack/pack-7a16e4488ae40c7d2bc56ea2bd43e25212a66c45.idx
0155eb4229851634a0f03eb265b69f5a2d |
Èç¹ûÄ㻹¼ÇµÃµÄ»°, 9bc1d Õâ¸ö blob ÊÇ repo.rb ÎļþµÄµÚÒ»¸ö°æ±¾£¬Õâ¸ö
blob ÒýÓÃÁË 05408 Õâ¸ö blob£¬¼´¸ÃÎļþµÄµÚ¶þ¸ö°æ±¾¡£ÃüÁîÊä³öÄÚÈݵĵÚÈýÁÐÏÔʾµÄÊǶÔÏó´óС£¬¿ÉÒÔ¿´µ½05408
Õ¼ÓÃÁË 12K ¿Õ¼ä£¬¶ø 9bc1d ½öΪ 7 ×Ö½Ú¡£·Ç³£ÓÐȤµÄÊǵڶþ¸ö°æ±¾²ÅÊÇÍêÕû±£´æÎļþÄÚÈݵĶÔÏ󣬶øµÚÒ»¸ö°æ±¾ÊÇÒÔ²îÒ췽ʽ±£´æµÄ
©¤©¤ ÕâÊÇÒòΪ´ó²¿·ÖÇé¿öÏÂÐèÒª¿ìËÙ·ÃÎÊÎļþµÄ×îа汾¡£
×îÃîµÄÊÇ¿ÉÒÔËæÊ±½øÐÐÖØÐ´ò°ü¡£Git ×Ô¶¯¶¨ÆÚ¶Ô²Ö¿â½øÐÐÖØÐ´ò°üÒÔ½ÚÊ¡¿Õ¼ä¡£µ±È»Ò²¿ÉÒÔÊÖ¹¤ÔËÐÐ
git gc ÃüÁîÀ´Õâô×ö¡£
9.5 The Refspec
Õâ±¾Êé¶Áµ½ÕâÀÄãÒѾʹÓùýһЩ¼òµ¥µÄÔ¶³Ì·ÖÖ§µ½±¾µØÒýÓõÄÓ³É䷽ʽÁË£¬ÕâÖÖÓ³Éä¿ÉÒÔ¸üΪ¸´ÔÓ¡£
¼ÙÉèÄãÏñÕâÑùÌí¼ÓÁËÒ»ÏîÔ¶³Ì²Ö¿â£º
$ git remote add origin git@github.com:schacon/simplegit-progit.git |
ËüÔÚÄãµÄ .git/config ÎļþÖÐÌí¼ÓÁËÒ»½Ú£¬Ö¸¶¨ÁËÔ¶³ÌµÄÃû³Æ (origin),
Ô¶³Ì²Ö¿âµÄURLµØÖ·£¬ºÍÓÃÓÚ»ñÈ¡²Ù×÷µÄ Refspec:
[remote "origin"] url = git@github.com:schacon/simplegit-progit.git fetch = +refs/heads/*:refs/remotes/origin/* |
Refspec µÄ¸ñʽÊÇÒ»¸ö¿ÉÑ¡µÄ + ºÅ£¬½Ó×ÅÊÇ : µÄ¸ñʽ£¬ÕâÀï ÊÇÔ¶¶ËÉϵÄÒýÓøñʽ£¬
Êǽ«Òª¼Ç¼ÔÚ±¾µØµÄÒýÓøñʽ¡£¿ÉÑ¡µÄ + ºÅ¸æËß Git ÔÚ¼´Ê¹²»ÄÜ¿ìËÙÑݽøµÄÇé¿öÏ£¬Ò²È¥Ç¿ÖƸüÐÂËü¡£
ȱʡÇé¿öÏ refspec »á±» git remote add ÃüÁîËù×Ô¶¯Éú³É£¬
Git »á»ñȡԶ¶ËÉÏ refs/heads/ ÏÂÃæµÄËùÓÐÒýÓ㬲¢½«ËüдÈëµ½±¾µØµÄrefs/remotes/origin/.
ËùÒÔ£¬Èç¹ûÔ¶¶ËÉÏÓÐÒ»¸ö master ·ÖÖ§£¬ÄãÔÚ±¾µØ¿ÉÒÔͨ¹ýÏÂÃæÕâÖÖ·½Ê½À´·ÃÎÊËüµÄÀúÊ·¼Ç¼£º
$ git log origin/master $ git log remotes/origin/master $ git log refs/remotes/origin/master |
ËüÃÇÈ«Êǵȼ۵ģ¬ÒòΪ Git °ÑËüÃǶ¼À©Õ¹³É refs/remotes/origin/master.
Èç¹ûÄãÏëÈà Git ÿ´ÎÖ»ÀȡԶ³ÌµÄ master ·ÖÖ§£¬¶ø²»ÊÇÔ¶³ÌµÄËùÓзÖÖ§£¬Äã¿ÉÒÔ°Ñ fetch
ÕâÒ»ÐÐÐ޸ijÉÕâÑù£º
fetch = +refs/heads/master:refs/remotes/origin/master |
ÕâÊÇ git fetch ²Ù×÷¶ÔÕâ¸öÔ¶¶ËµÄȱʡ refspec Öµ¡£¶øÈç¹ûÄãÖ»Ïë×öÒ»´Î¸Ã²Ù×÷£¬Ò²¿ÉÒÔÔÚÃüÁîÐÐÉÏÖ¸¶¨Õâ¸ö
refspec. Èç¿ÉÒÔÕâÑùÀȡԶ³ÌµÄmaster ·ÖÖ§µ½±¾µØµÄ origin/mymaster ·ÖÖ§£º
$ git fetch origin master:refs/remotes/origin/mymaster |
ÄãÒ²¿ÉÒÔÔÚÃüÁîÐÐÉÏÖ¸¶¨¶à¸ö refspec. ÏñÕâÑù¿ÉÒÔÒ»´Î»ñȡԶ³ÌµÄ¶à¸ö·ÖÖ§£º
$ git fetch origin master:refs/remotes/origin/mymaster \
topic:refs/remotes/origin/topic From git@github.com:schacon/simpleg |
ÔÚÕâ¸öÀý×ÓÖУ¬ master ·ÖÖ§ÒòΪ²»ÊÇÒ»¸ö¿ÉÒÔ¿ìËÙÑݽøµÄÒýÓöøÀÈ¡²Ù×÷±»¾Ü¾ø¡£Äã¿ÉÒÔÔÚ
refspec ֮ǰʹÓÃÒ»¸ö + ºÅÀ´ÖØÔØÕâÖÖÐÐΪ¡£
ÄãÒ²¿ÉÒÔÔÚÅäÖÃÎļþÖÐÖ¸¶¨¶à¸ö refspec. ÈçÄãÏëÔÚÿ´Î»ñȡʱ¶¼»ñÈ¡ master ºÍ experiment
·ÖÖ§£¬¾ÍÌí¼ÓÁ½ÐУº
[remote "origin"] url = git@github.com:schacon/simplegit-progit.git fetch
= +refs/heads/master:refs/remotes/origin/master fe |
µ«ÊÇÕâÀï²»ÄÜʹÓò¿·ÖͨÅä·û£¬ÏñÕâÑù¾ÍÊDz»ºÏ·¨µÄ£º
fetch = +refs/heads/qa*:refs/remotes/origin/qa* |
µ«ÎÞÂÛÈçºÎ£¬Äã¿ÉÒÔʹÓÃÃüÃû¿Õ¼äÀ´´ïµ½Õâ¸öÄ¿µÄ¡£ÈçÄãÓÐÒ»¸öQA×飬ËûÃÇÍÆËÍһϵÁзÖÖ§£¬ÄãÏëÿ´Î»ñÈ¡
master ·ÖÖ§ºÍQA×éµÄËùÓзÖÖ§£¬Äã¿ÉÒÔʹÓÃÕâÑùµÄÅäÖöÎÂ䣺
[remote "origin"] url = git@github.com:schacon/simplegit-progit.git fetch
= +refs/heads/master:refs/remotes/origin/master fe |
Èç¹ûÄãµÄ¹¤×÷Á÷ºÜ¸´ÔÓ£¬ÓÐQA×éÍÆË͵ķÖÖ§¡¢¿ª·¢ÈËÔ±ÍÆË͵ķÖÖ§¡¢ºÍ¼¯³ÉÈËÔ±ÍÆË͵ķÖÖ§£¬²¢ÇÒËûÃÇÔÚÔ¶³Ì·ÖÖ§ÉÏÐ×÷£¬Äã¿ÉÒÔ²ÉÓÃÕâÖÖ·½Ê½ÎªËûÃÇ´´½¨¸÷×ÔµÄÃüÃû¿Õ¼ä¡£
ÍÆËÍ Refspec
²ÉÓÃÃüÃû¿Õ¼äµÄ·½Ê½È·ÊµºÜ°ô£¬µ«QA×é³ÉÔ±µÚ1´ÎÊÇÈçºÎ½«ËûÃǵķÖÖ§ÍÆË͵½
qa/ ¿Õ¼äÀïÃæµÄÄØ£¿´ð°¸ÊÇÄã¿ÉÒÔʹÓà refspec À´ÍÆËÍ¡£
Èç¹ûQA×é³ÉÔ±Ïë°ÑËûÃÇµÄ master ·ÖÖ§ÍÆË͵½Ô¶³ÌµÄ qa/master ·ÖÖ§ÉÏ£¬¿ÉÒÔÕâÑùÔËÐУº
$ git push origin master:refs/heads/qa/master |
Èç¹ûËûÃÇÏëÈà Git ÿ´ÎÔËÐÐ git push origin ʱ¶¼ÕâÑù×Ô¶¯ÍÆËÍ£¬ËûÃÇ¿ÉÒÔÔÚÅäÖÃÎļþÖÐÌí¼Ó
push Öµ£º
[remote "origin"] url = git@github.com:schacon/simplegit-progit.git fetch
= +refs/heads/*:refs/remotes/origin/* push = refs/h |
ÕâÑù£¬¾Í»áÈà git push origin ȱʡ¾Í°Ñ±¾µØµÄ master
·ÖÖ§ÍÆË͵½Ô¶³ÌµÄ qa/master ·ÖÖ§ÉÏ¡£
ɾ³ýÒýÓÃ
ÄãÒ²¿ÉÒÔʹÓà refspec À´É¾³ýÔ¶³ÌµÄÒýÓã¬ÊÇͨ¹ýÔËÐÐÕâÑùµÄÃüÁ
ÒòΪ refspec µÄ¸ñʽÊÇ : , ͨ¹ý°Ñ ²¿·ÖÁô¿ÕµÄ·½Ê½£¬Õâ¸öÒâ˼ÊÇÊǰÑÔ¶³ÌµÄtopic
·ÖÖ§±ä³É¿Õ£¬Ò²¾ÍÊÇɾ³ýËü¡£
|