9.6
´«ÊäÐÒé
Git ¿ÉÒÔÒÔÁ½ÖÖÖ÷ÒªµÄ·½Ê½¿çÔ½Á½¸ö²Ö¿â´«ÊäÊý¾Ý£º»ùÓÚHTTPÐÒéÖ®ÉÏ£¬ºÍ
file://, ssh://, ºÍgit:// µÈÖÇÄÜ´«ÊäÐÒé¡£ÕâÒ»½Ú´øÄã¿ìËÙä¯ÀÀÕâÁ½ÖÖÖ÷ÒªµÄÐÒé²Ù×÷¹ý³Ì¡£
ÑÆÐÒé
Git »ùÓÚHTTPÖ®ÉÏ´«Êäͨ³£±»³ÆÎªÑÆÐÒ飬ÕâÊÇÒòΪËüÔÚ·þÎñ¶Ë²»ÐèÒªÓÐÕë¶Ô
Git ÌØÓеĴúÂë¡£Õâ¸ö»ñÈ¡¹ý³Ì½ö½öÊÇһϵÁÐGETÇëÇ󣬿ͻ§¶Ë¿ÉÒÔ¼Ù¶¨·þÎñ¶ËµÄGit²Ö¿âÖеIJ¼¾Ö¡£ÈÃÎÒÃÇÒÔ
simplegit ¿âÀ´¿´¿´http-fetch µÄ¹ý³Ì£º
$ git clone http://github.com/schacon/simplegit-progit.git |
Ëü×öµÄµÚ1¼þÊÂÇé¾ÍÊÇ»ñÈ¡ info/refs Îļþ¡£Õâ¸öÎļþÊÇÔÚ·þÎñ¶ËÔËÐÐÁË
update-server-info ËùÉú³ÉµÄ£¬ÕâÒ²½âÊÍÁËΪʲôÔÚ·þÎñ¶ËÒªÏëʹÓÃHTTP´«Ê䣬±ØÐëÒª¿ªÆôpost-receive
¹³×Ó£º
=> GET info/refs ca82a6dff817ec66f44342007202690a93763949 refs/heads/master |
ÏÖÔÚÄãÓÐÒ»¸öÔ¶¶ËÒýÓúÍSHAÖµµÄÁÐ±í¡£ÏÂÒ»²½ÊÇѰÕÒHEADÒýÓã¬ÕâÑùÄã¾ÍÖªµÀÁËÔÚÍê³Éºó£¬Ê²Ã´Ó¦¸Ã±»¼ì³öµ½¹¤×÷Ŀ¼£º
=> GET HEAD ref: refs/heads/master |
Õâ˵Ã÷ÔÚÍê³É»ñÈ¡ºó£¬ÐèÒª¼ì³ö master ·ÖÖ§¡£ Õâʱ£¬ÒѾ¿ÉÒÔ¿ªÊ¼ÂþÓβÙ×÷ÁË¡£ÒòΪÄãµÄÆðµãÊÇÔÚ
info/refs ÎļþÖÐËùÌáµ½µÄca82a6 commit ¶ÔÏó£¬ÄãµÄ¿ªÊ¼²Ù×÷¾ÍÊÇ»ñÈ¡Ëü£º
=> GET objects/ca/82a6dff817ec66f44342007202690a93763949 (179 bytes of binary data) |
È»ºóÄãÈ¡»ØÁËÕâ¸ö¶ÔÏó £ ÕâÔÚ·þÎñ¶ËÊÇÒ»¸öËÉÉ¢¸ñʽµÄ¶ÔÏó£¬ÄãʹÓõÄÊǾ²Ì¬µÄ
HTTP GET ÇëÇó»ñÈ¡µÄ¡£¿ÉÒÔʹÓà zlib ½âѹËõËü£¬È¥³ýÆäÍ·²¿£¬²é¿´ËüµÄ commmit ÄÚÈÝ£º
$ git cat-file -p ca82a6dff817ec66f44342007202690a93763949 tree cfda3bf379e4f8dba8717dee55aab78aef7f4daf parent 085bb3bcb608 |
ÕâÑù£¬¾ÍµÃµ½ÁËÁ½¸öÐèÒª½øÒ»²½»ñÈ¡µÄ¶ÔÏó £ cfda3b ÊÇÕâ¸ö commit
¶ÔÏóËù¶ÔÓ¦µÄ tree ¶ÔÏó£¬ºÍ 085bb3 ÊÇËüµÄ¸¸¶ÔÏó£»
=> GET objects/08/5bb3bcb608e1e8451d4b2432f8ecbe6306e7e7 (179 bytes of data) |
ÕâÑù¾ÍÈ¡µÃÁËÕâËüµÄÏÂÒ»²½ commit ¶ÔÏó£¬ÔÙץȡ tree ¶ÔÏó£º
=> GET objects/cf/da3bf379e4f8dba8717dee55aab78aef7f4daf (404 - Not Found) |
Oops - ¿´ÆðÀ´Õâ¸ö tree ¶ÔÏóÔÚ·þÎñ¶Ë²¢²»ÒÔËÉÉ¢¸ñʽ¶ÔÏó´æÔÚ£¬ËùÒԵõ½ÁË404ÏìÓ¦£¬´ú±íÔÚHTTP·þÎñ¶ËûÓÐÕÒµ½¸Ã¶ÔÏó¡£ÕâÓкü¸¸öÔÒò
£ Õâ¸ö¶ÔÏó¿ÉÄÜÔÚÌæ´ú²Ö¿âÀïÃæ£¬»òÕßÔÚ´ò°üÎļþÀïÃæ£¬ Git »áÊ×Ïȼì²éÈκÎÁгöµÄÌæ´ú²Ö¿â£º
=> GET objects/info/http-alternates (empty file) |
Èç¹ûÕâ·µ»ØÁ˼¸¸öÌæ´ú²Ö¿âÁÐ±í£¬ÄÇôËü»áÈ¥ÄÇЩµØ·½¼ì²éËÉÉ¢¸ñʽ¶ÔÏóºÍÎļþ
£ ÕâÊÇÒ»ÖÖÔÚÈí¼þ·Ö²æÖ®¼ä¹²Ïí¶ÔÏóÒÔ½ÚÊ¡´ÅÅ̵ĺ÷½·¨¡£È»¶ø£¬ÔÚÕâ¸öÀý×ÓÖУ¬Ã»ÓÐÌæ´ú²Ö¿â¡£ËùÒÔÄãËùÐèÒªµÄ¶ÔÏó¿Ï¶¨ÔÚij¸ö´ò°üÎļþÖС£Òª¼ì²é·þÎñ¶ËÓÐÄÄЩ´ò°ü¸ñʽÎļþ£¬ÄãÐèÒª»ñÈ¡objects/info/packs
Îļþ£¬ÕâÀïÃæ°üº¬Óдò°üÎļþÁÐ±í£¨Êǵģ¬ËüÒ²ÊDZ» update-server-info ËùÉú³ÉµÄ£©£»
=> GET objects/info/packs P pack-816a9b2334da9953e530f27bcac22082a9f5b835.pack |
ÕâÀï·þÎñ¶ËÖ»ÓÐÒ»¸ö´ò°üÎļþ£¬ËùÒÔÄãÒªµÄ¶ÔÏóÏÔÈ»¾ÍÔÚÀïÃæ¡£µ«ÊÇÄã¿ÉÒÔÏȼì²éËüµÄË÷ÒýÎļþÒÔÈ·ÈÏ¡£ÕâÔÚ·þÎñ¶ËÓжà¸ö´ò°üÎļþʱҲºÜÓÐÓã¬ÒòΪÕâÑù¾Í¿ÉÒÔÏȼì²éÄãËùÐèÒªµÄ¶ÔÏó¿Õ¼äÊÇÔÚÄÄÒ»¸ö´ò°üÎļþÀïÃæÁË£º
=> GET objects/pack/pack-816a9b2334da9953e530f27bcac22082a9f5b835.idx (4k of binary data) |
ÏÖÔÚÄãÓÐÁËÕâ¸ö´ò°üÎļþµÄË÷Òý£¬Äã¿ÉÒÔ¿´¿´ÄãÒªµÄ¶ÔÏóÊÇ·ñÔÚÀïÃæ £ ÒòΪË÷ÒýÎļþÁгöÁËÕâ¸ö´ò°üÎļþËù°üº¬µÄËùÓжÔÏóµÄSHAÖµ£¬ºÍ¸Ã¶ÔÏó´æÔÚÓÚ´ò°üÎļþÖÐµÄÆ«ÒÆÁ¿£¬ËùÒÔÄãÖ»ÐèÒª¼òµ¥µØ»ñÈ¡Õû¸ö´ò°üÎļþ£º
=> GET objects/pack/pack-816a9b2334da9953e530f27bcac22082a9f5b835.pack (13k of binary data) |
ÏÖÔÚÄãÒ²ÓÐÁËÕâ¸ö tree ¶ÔÏó£¬Äã¿ÉÒÔ¼ÌÐøÔÚ commit ¶ÔÏóÉÏÂþÓΡ£ËüÃÇÈ«²¿¶¼ÔÚÕâ¸öÄãÒѾÏÂÔØµ½µÄ´ò°üÎļþÀïÃæ£¬ËùÒÔÄã²»ÓüÌÐøÏò·þÎñ¶ËÇëÇó¸ü¶àÏÂÔØÁË¡£
ÔÚÕâÍê³ÉÖ®ºó£¬ÓÉÓÚÏÂÔØ¿ªÊ¼Ê±ÒÑ̽Ã÷HEADÒýÓÃÊÇÖ¸Ïòmaster ·ÖÖ§£¬ Git »á½«Ëü¼ì³öµ½¹¤×÷Ŀ¼¡£
Õû¸ö¹ý³Ì¿´ÆðÀ´¾ÍÏñÕâÑù£º
$ git clone http://github.com/schacon/simplegit-progit.git Initialized empty Git repository in /private/tmp/simplegit-progit |
ÖÇÄÜÐÒé
Õâ¸öHTTP·½·¨ÊǺܼòµ¥µ«Ð§Âʲ»ÊǺܸߡ£Ê¹ÓÃÖÇÄÜÐÒéÊÇ´«ËÍÊý¾ÝµÄ¸ü³£Óõķ½·¨¡£ÕâЩÐÒéÔÚÔ¶¶Ë¶¼ÓÐGitÖÇÄÜÐͽø³ÌÔÚ·þÎñ
£ Ëü¿ÉÒÔ¶Á³ö±¾µØÊý¾Ý²¢¼ÆËã³ö¿Í»§¶ËËùÐèÒªµÄ£¬²¢Éú³ÉºÏÊʵÄÊý¾Ý¸øËü£¬ÕâÓÐÁ½Àà´«ÊäÊý¾ÝµÄ½ø³Ì£ºÒ»¶ÔÓÃÓÚÉÏ´«Êý¾ÝºÍÒ»¶ÔÓÃÓÚÏÂÔØ¡£
ÉÏ´«Êý¾Ý
ΪÁËÉÏ´«Êý¾ÝÖÁÔ¶¶Ë£¬ Git ʹÓà send-pack ºÍ receive-pack
½ø³Ì¡£Õâ¸ö send-pack ½ø³ÌÔËÐÐÔÚ¿Í»§¶ËÉÏ£¬ËüÁ¬½ÓÖÁÔ¶¶ËÔËÐÐµÄ receive-pack ½ø³Ì¡£
¾ÙÀýÀ´Ëµ£¬ÄãÔÚÄãµÄÏîÄ¿ÉÏÔËÐÐÁË git push origin master,
²¢ÇÒ origin ±»¶¨ÒåΪһ¸öʹÓÃSSHÐÒéµÄURL¡£ Git »áʹÓÃsend-pack ½ø³Ì£¬Ëü»áÆô¶¯Ò»¸ö»ùÓÚSSHµÄÁ¬½Óµ½·þÎñÆ÷¡£Ëü³¢ÊÔÏñÕâÑù͸¹ýSSHÔÚ·þÎñ¶ËÔËÐÐÃüÁ
$ ssh -x git@github.com "git-receive-pack 'schacon/simplegit-progit.git'" 005bca82a6dff817ec66f4437202690a93763949 refs/head |
ÕâÀïµÄ git-receive-pack ÃüÁî»áÁ¢¼´¶ÔËüËùÓµÓеÄÿһ¸öÒýÓÃÏìÓ¦Ò»ÐÐ
£ ÔÚÕâ¸öÀý×ÓÖУ¬Ö»ÓÐ master ·ÖÖ§ºÍËüµÄSHAÖµ¡£ÕâÀïµÚ1ÐÐÒ²°üº¬ÁË·þÎñ¶ËµÄÄÜÁ¦ÁÐ±í£¨ÕâÀïÊÇreport-status
ºÍ delete-refs£©¡£
ÿһÐÐÒÔ4×Ö½ÚµÄÊ®Áù½øÖÆ¿ªÊ¼£¬ÓÃÓÚÖ¸¶¨ÕûÐеij¤¶È¡£Äã¿´µ½µÚ1ÐÐÒÔ005b¿ªÊ¼£¬ÕâÔÚÊ®Áù½øÖÆÖбíʾ91£¬Òâζ×ŵÚ1ÐÐÓÐ91×Ö½Ú³¤¡£ÏÂÒ»ÐÐÒÔ003eÆðʼ£¬±íʾÓÐ62×Ö½Ú³¤£¬ËùÒÔÐèÒª¶ÁʣϵÄ62×Ö½Ú¡£ÔÙÏÂÒ»ÐÐÊÇ0000¿ªÊ¼£¬±íʾ·þÎñÆ÷ÒÑÍê³ÉÁËÒýÓÃÁбí¹ý³Ì¡£
ÏÖÔÚËüÖªµÀÁË·þÎñ¶ËµÄ״̬£¬ÄãµÄ send-pack ½ø³Ì»áÅжÏÄÄЩ commit
ÊÇËüËùÓµÓе«·þÎñ¶ËûÓеġ£Õë¶Ôÿ¸öÒýÓã¬Õâ´ÎÍÆËͶ¼»á¸æË߶Զ˵Äreceive-pack Õâ¸öÐÅÏ¢¡£¾ÙÀý˵£¬Èç¹ûÄãÔÚ¸üÐÂ
master ·ÖÖ§£¬²¢ÇÒÔö¼Ó experiment ·ÖÖ§£¬Õâ¸ösend-pack ½«»áÊÇÏñÕâÑù£º
0085ca82a6dff817ec66f44342007202690a93763949 15027957951b64cf874c3557a0f3547bd83b3ff6 refs/heads/master report-status 00670000 |
ÕâÀïµÄÈ«¡¯0¡¯µÄSHA-1Öµ±íʾ֮ǰûÓйýÕâ¸ö¶ÔÏó £ ÒòΪÄãÊÇÔÚÌí¼ÓеÄ
experiment ÒýÓá£Èç¹ûÄãÔÚɾ³ýÒ»¸öÒýÓã¬Äã»á¿´µ½Ïà·´µÄ£º ¾ÍÊÇÓÒ±ßÊÇÈ«¡¯0¡¯¡£
Git Õë¶Ôÿ¸öÒýÓ÷¢ËÍÕâÑùÒ»ÐÐÐÅÏ¢£¬¾ÍÊǾɵÄSHAÖµ£¬ÐµÄSHAÖµ£¬ºÍ½«Òª¸üеÄÒýÓõÄÃû³Æ¡£µÚ1Ðл¹»á°üº¬Óпͻ§¶ËµÄÄÜÁ¦¡£ÏÂÒ»²½£¬¿Í»§¶Ë»á·¢ËÍÒ»¸öËùÓÐÄÇЩ·þÎñ¶ËËùûÓеĶÔÏóµÄÒ»¸ö´ò°üÎļþ¡£×îºó£¬·þÎñ¶ËÒԳɹ¦(»òÕßʧ°Ü)À´ÏìÓ¦£º
ÏÂÔØÊý¾Ý
µ±ÄãÔÚÏÂÔØÊý¾Ýʱ£¬ fetch-pack ºÍ upload-pack ½ø³Ì¾ÍÆð×÷ÓÃÁË¡£¿Í»§¶ËÆô¶¯
fetch-pack ½ø³Ì£¬Á¬½ÓÖÁÔ¶¶ËµÄ upload-pack ½ø³Ì£¬ÒÔÐÉ̺óÐøÊý¾Ý´«Êä¹ý³Ì¡£
ÔÚÔ¶¶Ë²Ö¿âÓв»Í¬µÄ·½Ê½Æô¶¯ upload-pack ½ø³Ì¡£Äã¿ÉÒÔʹÓÃÓë
receive-pack ÏàͬµÄ͸¹ýSSH¹ÜµÀµÄ·½Ê½£¬Ò²¿ÉÒÔͨ¹ý Git ºǫ́À´Æô¶¯Õâ¸ö½ø³Ì£¬ËüĬÈϼàÌýÔÚ9418ºÅ¶Ë¿ÚÉÏ¡£ÕâÀïfetch-pack
½ø³ÌÔÚÁ¬½ÓºóÏñÕâÑùÏòºǫ́·¢ËÍÊý¾Ý£º
003fgit-upload-pack schacon/simplegit-progit.git\0host=myserver.com\0 |
ËüÒ²ÊÇÒÔ4×Ö½ÚÖ¸¶¨ºóÐø×Ö½Ú³¤¶ÈµÄ·½Ê½¿ªÊ¼£¬È»ºóÊÇÒªÔËÐеÄÃüÁºÍÒ»¸ö¿Õ×Ö½Ú£¬È»ºóÊÇ·þÎñ¶ËµÄÖ÷»úÃû£¬ÔÙ¸úËæÒ»¸ö×îºóµÄ¿Õ×Ö½Ú¡£
Git ºǫ́½ø³Ì»á¼ì²éÕâ¸öÃüÁîÊÇ·ñ¿ÉÒÔÔËÐУ¬ÒÔ¼°ÄǸö²Ö¿âÊÇ·ñ´æÔÚ£¬ÒÔ¼°ÊÇ·ñ¾ßÓй«¿ªÈ¨ÏÞ¡£Èç¹ûËùÓмì²é¶¼Í¨¹ýÁË£¬Ëü»áÆô¶¯Õâ¸öupload-pack
½ø³Ì²¢½«¿Í»§¶ËµÄÇëÇóÒÆ½»¸øËü¡£
Èç¹ûÄã͸¹ýSSHʹÓûñÈ¡¹¦ÄÜ£¬ fetch-pack »áÏñÕâÑùÔËÐУº
$ ssh -x git@github.com "git-upload-pack 'schacon/simplegit-progit.git'" |
²»¹ÜÄÄÖÖ·½Ê½£¬ÔÚ fetch-pack Á¬½ÓÖ®ºó£¬ upload-pack
¶¼»áÒÔÕâÖÖÐÎʽ·µ»Ø£º
0088ca82a6dff817ec66f44342007202690a93763949 HEAD\0multi_ack thin-pack
\ side-band side-band-64k ofs-delta shallow no-progre |
ÕâÓë receive-pack ÏìÓ¦ºÜÀàËÆ£¬µ«ÊÇÕâÀïÖ¸µÄÄÜÁ¦ÊDz»Í¬µÄ¡£¶øÇÒËü»¹»áÖ¸³öHEADÒýÓã¬Èÿͻ§¶Ë¿ÉÒÔ¼ì²éÊÇ·ñÊÇÒ»·Ý¿Ë¡¡£
ÔÚÕâÀ fetch-pack ½ø³Ì¼ì²éËü×Ô¼ºËùÓµÓеĶÔÏóºÍËùÓÐËüÐèÒªµÄ¶ÔÏó£¬Í¨¹ý·¢ËÍ
¡°want¡± ºÍËùÐè¶ÔÏóµÄSHAÖµ£¬·¢ËÍ ¡°have¡± ºÍËùÓÐËüÒÑÓµÓеĶÔÏóµÄSHAÖµ¡£ÔÚÁбíÍê³Éʱ£¬ÔÙ·¢ËÍ
¡°done¡± ֪ͨupload-pack ½ø³Ì¿ªÊ¼·¢ËÍËùÐè¶ÔÏóµÄ´ò°üÎļþ¡£Õâ¸ö¹ý³Ì¿´ÆðÀ´ÏñÕâÑù£º
0054want ca82a6dff817ec66f44342007202690a93763949 ofs-delta
0032have 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7 0000 0009done |
ÕâÊÇ´«ÊäÐÒéµÄÒ»¸öºÜ»ù´¡µÄÀý×Ó£¬ÔÚ¸ü¸´ÔÓµÄÀý×ÓÖУ¬¿Í»§¶Ë¿ÉÄÜ»áÖ§³Ö multi_ack
»òÕß side-band ÄÜÁ¦£»µ«ÊÇÕâ¸öÀý×ÓÖÐչʾÁËÖÇÄÜÐÒéµÄ»ù±¾½»»¥¹ý³Ì¡£
9.7 ά»¤¼°Êý¾Ý»Ö¸´
Äãʱ²»Ê±µÄÐèÒª½øÐÐһЩÇåÀí¹¤×÷ ©¤©¤ Èç¼õСһ¸ö²Ö¿âµÄ´óС£¬ÇåÀíµ¼ÈëµÄ¿â£¬»òÊǻָ´¶ªÊ§µÄÊý¾Ý¡£±¾½Ú½«ÃèÊöÕâÀàʹÓó¡¾°¡£
ά»¤
Git »á²»¶¨Ê±µØ×Ô¶¯ÔËÐгÆÎª ¡°auto gc¡± µÄÃüÁî¡£´ó²¿·ÖÇé¿öϸÃÃüÁîʲô¶¼²»´¦Àí¡£²»¹ýÒªÊÇ´æÔÚÌ«¶àËÉÉ¢¶ÔÏó
(loose object, ²»ÔÚ packfile ÖеĶÔÏó) »ò packfile£¬Git »á½øÐе÷ÓÃgit
gc ÃüÁî¡£ gc Ö¸À¬»øÊÕ¼¯ (garbage collect)£¬´ËÃüÁî»á×öºÜ¶à¹¤×÷£ºÊÕ¼¯ËùÓÐËÉÉ¢¶ÔÏó²¢½«ËüÃÇ´æÈë
packfile£¬ºÏ²¢ÕâЩ packfile ½øÒ»¸ö´óµÄ packfile£¬È»ºó½«²»±»ÈκΠcommit
ÒýÓò¢ÇÒÒÑ´æÔÚÒ»¶Îʱ¼ä (ÊýÔÂ) µÄ¶ÔÏóɾ³ý¡£
¿ÉÒÔÊÖ¹¤ÔËÐÐ auto gc ÃüÁ
ÔÙ´ÎÇ¿µ÷£¬Õâ¸öÃüÁîÒ»°ãʲô¶¼²»¸É¡£Èç¹ûÓÐ 7,000 ¸ö×óÓÒµÄËÉÉ¢¶ÔÏó»òÊÇ
50 ¸öÒÔÉ쵀 packfile£¬Git ²Å»áÕæÕýµ÷Óà gc ÃüÁî¡£¿ÉÄÜͨ¹ýÐÞ¸ÄÅäÖÃÖеÄgc.auto
ºÍ gc.autopacklimit À´µ÷ÕûÕâÁ½¸öãÐÖµ¡£
gc »¹»á½«ËùÓÐÒýÓà (references) ²¢ÈëÒ»¸öµ¥¶ÀÎļþ¡£¼ÙÉè²Ö¿âÖаüº¬ÒÔÏ·ÖÖ§ºÍ±êÇ©£º
$ find .git/refs -type f .git/refs/heads/experiment .git/refs/heads/master .git/refs/tags/v1.0 .git/refs/tags/v1.1 |
ÕâʱÈç¹ûÔËÐÐ git gc, refs ϵÄËùÓÐÎļþ¶¼»áÏûʧ¡£Git »á½«ÕâЩÎļþŲµ½
.git/packed-refs ÎļþÖÐÈ¥ÒÔÌá¸ßЧÂÊ£¬¸ÃÎļþÊÇÕâ¸öÑù×ӵģº
$ cat .git/packed-refs # pack-refs with: peeled cac0cab538b970a37ea1e769cbbde608743bc96d refs/heads/experiment ab1afef80fac8 |
µ±¸üÐÂÒ»¸öÒýÓÃʱ£¬Git ²»»áÐÞ¸ÄÕâ¸öÎļþ£¬¶øÊÇÔÚ refs/heads
ÏÂдÈëÒ»¸öÐÂÎļþ¡£µ±²éÕÒÒ»¸öÒýÓÃµÄ SHA ʱ£¬Git Ê×ÏÈÔÚrefs Ŀ¼Ï²éÕÒ£¬Èç¹ûδÕÒµ½Ôòµ½ packed-refs
ÎļþÖÐÈ¥²éÕÒ¡£Òò´ËÈç¹ûÔÚ refs Ŀ¼ÏÂÕÒ²»µ½Ò»¸öÒýÓ㬸ÃÒýÓÿÉÄÜ´æµ½packed-refs ÎļþÖÐÈ¥ÁË¡£
ÇëÁôÒâÎļþ×îºóÒÔ ^ ¿ªÍ·µÄÄÇÒ»ÐС£Õâ±íʾ¸ÃÐÐÉÏÒ»ÐеÄÄǸö±êÇ©ÊÇÒ»¸ö annotated
±êÇ©£¬¶ø¸ÃÐÐÕýÊÇÄǸö±êÇ©ËùÖ¸ÏòµÄ commit ¡£
Êý¾Ý»Ö¸´
ÔÚʹÓà Git µÄ¹ý³ÌÖУ¬ÓÐʱ»á²»Ð¡ÐĶªÊ§ commit ÐÅÏ¢¡£ÕâÒ»°ã³öÏÖÔÚÒÔÏÂÇé¿öÏ£ºÇ¿ÖÆÉ¾³ýÁËÒ»¸ö·ÖÖ§¶øºóÓÖÏëÖØÐÂʹÓÃÕâ¸ö·ÖÖ§£¬hard-reset
ÁËÒ»¸ö·ÖÖ§´Ó¶ø¶ªÆúÁË·ÖÖ§µÄ²¿·Ö commit¡£Èç¹ûÕâÕæµÄ·¢ÉúÁË£¬ÓÐʲô°ì·¨°Ñ¶ªÊ§µÄ commit ÕÒ»ØÀ´ÄØ£¿
ÏÂÃæµÄʾÀýÑÝʾÁË¶Ô test ²Ö¿âÖ÷·ÖÖ§½øÐÐ hard-reset µ½Ò»¸öÀϰ汾µÄ
commit µÄ²Ù×÷£¬È»ºó»Ö¸´¶ªÊ§µÄ commit ¡£Ê×ÏȲ鿴һϵ±Ç°µÄ²Ö¿â״̬£º
$ git log --pretty=oneline ab1afef80fac8e34258ff41fc1b867c702daa24b
modified repo a bit 484a59275031909e19aadb7c92262719cfcd |
½Ó׎« master ·ÖÖ§ÒÆ»ØÖÁÖмäµÄÒ»¸ö commit£º
$ git reset --hard 1a410efbd13591db07496601ebc7a059dd55cfe9 HEAD
is now at 1a410ef third commit $ git log --pretty=oneline 1a4 |
ÕâÑù¾Í¶ªÆúÁË×îеÄÁ½¸ö commit ©¤©¤ °üº¬ÕâÁ½¸ö commit µÄ·ÖÖ§²»´æÔÚÁË¡£ÏÖÔÚÒª×öµÄÊÇÕÒ³ö×îеÄÄǸö
commit µÄ SHA£¬È»ºóÌí¼ÓÒ»¸öÖ¸ËüËüµÄ·ÖÖ§¡£¹Ø¼üÔÚÓÚÕÒ³ö×îÐ嵀 commit µÄ SHA ©¤©¤
Äã²»´ó¿ÉÄܼÇסÁËÕâ¸ö SHA£¬Êǰɣ¿
ͨ³£×î¿ì½ÝµÄ°ì·¨ÊÇʹÓà git reflog ¹¤¾ß¡£µ±Äã (ÔÚÒ»¸ö²Ö¿âÏÂ)
¹¤×÷ʱ£¬Git »áÔÚÄãÿ´ÎÐÞ¸ÄÁË HEAD ʱÇÄÇĵؽ«¸Ä¶¯¼Ç¼ÏÂÀ´¡£µ±ÄãÌá½»»òÐ޸ķÖ֧ʱ£¬reflog
¾Í»á¸üС£git update-ref ÃüÁîÒ²¿ÉÒÔ¸üРreflog£¬ÕâÊÇÔÚ±¾ÕÂÇ°ÃæµÄ ¡°Git References¡±
²¿·ÖÎÒÃÇʹÓøÃÃüÁî¶ø²»ÊÇÊÖ¹¤½« SHA ֵдÈë ref ÎļþµÄÀíÓÉ¡£ÈκÎʱ¼äÔËÐÐgit reflog ÃüÁî¿ÉÒԲ鿴µ±Ç°µÄ״̬£º
$ git reflog 1a410ef HEAD@{0}: 1a410efbd13591db07496601ebc7a059dd55cfe9:
updating HEAD ab1afef HEAD@{1}: ab1afef80fac8e34258f |
¿ÉÒÔ¿´µ½ÎÒÃÇÇ©³öµÄÁ½¸ö commit £¬µ«Ã»Óиü¶àµÄÏà¹ØÐÅÏ¢¡£ÔËÐÐ git
log -g »áÊä³ö reflog µÄÕý³£ÈÕÖ¾£¬´Ó¶øÏÔʾ¸ü¶àÓÐÓÃÐÅÏ¢£º
$ git log -g commit 1a410efbd13591db07496601ebc7a059dd55cfe9 Reflog:
HEAD@{0} (Scott Chacon ) Reflog message: updating HEAD Au |
¿´ÆðÀ´Åª¶ªÁ赀 commit Êǵ×ÏÂÄǸö£¬ÕâÑùÔÚÄǸö commit ÉÏ´´½¨Ò»¸öзÖÖ§¾ÍÄܰÑËü»Ö¸´¹ýÀ´¡£±È·½Ëµ£¬¿ÉÒÔÔÚÄǸö
commit (ab1afef) ÉÏ´´½¨Ò»¸öÃûΪrecover-branch µÄ·ÖÖ§£º
$ git branch recover-branch ab1afef $ git log
--pretty=oneline recover-branch ab1afef80fac8e34258ff41fc1b867c702daa24b modif |
¿á£¡ÕâÑùÓÐÁËÒ»¸ö¸úÔÀ´ master Ò»ÑùµÄ recover-branch
·ÖÖ§£¬×îеÄÁ½¸ö commit ÓÖÕÒ»ØÀ´ÁË¡£½Ó×Å£¬¼ÙÉèÒýÆð commit ¶ªÊ§µÄÔÒò²¢Ã»ÓмǼÔÚ reflog
ÖÐ ©¤©¤ ¿ÉÒÔͨ¹ýɾ³ýrecover-branch ºÍ reflog À´Ä£ÄâÕâÖÖÇé¿ö¡£ÕâÑù×îеÄÁ½¸ö commit
²»»á±»Èκζ«Î÷ÒýÓõ½£º
$ git branch -D recover-branch $ rm -Rf .git/logs/ |
ÒòΪ reflog Êý¾ÝÊDZ£´æÔÚ .git/logs/ Ŀ¼Ïµģ¬ÕâÑù¾ÍûÓÐ
reflog ÁË¡£ÏÖÔÚÒªÔõÑù»Ö¸´ commit ÄØ£¿°ì·¨Ö®Ò»ÊÇʹÓÃgit fsck ¹¤¾ß£¬¸Ã¹¤¾ß»á¼ì²é²Ö¿âµÄÊý¾ÝÍêÕûÐÔ¡£Èç¹ûÖ¸¶¨
--ful Ñ¡Ï¸ÃÃüÁîÏÔʾËùÓÐδ±»ÆäËû¶ÔÏóÒýÓà (Ö¸Ïò) µÄËùÓжÔÏó£º
$ git fsck --full dangling blob d670460b4b4aece5915caf5c68d12f560a9fe3e4
dangling commit ab1afef80fac8e34258ff41fc1b867c702da |
±¾ÀýÖУ¬¿ÉÒÔ´Ó dangling commit ÕÒµ½¶ªÊ§Á赀 commit¡£ÓÃÏàͬµÄ·½·¨¾Í¿ÉÒÔ»Ö¸´Ëü£¬¼´´´½¨Ò»¸öÖ¸Ïò¸Ã
SHA µÄ·ÖÖ§¡£
ÒÆ³ý¶ÔÏó
Git ÓÐÐí¶à¹ýÈËÖ®´¦£¬²»¹ýÓÐÒ»¸ö¹¦ÄÜÓÐʱȴ»á´øÀ´ÎÊÌ⣺git clone
»á½«°üº¬Ã¿Ò»¸öÎļþµÄËùÓÐÀúÊ·°æ±¾µÄÕû¸öÏîÄ¿ÏÂÔØÏÂÀ´¡£Èç¹ûÏîÄ¿°üº¬µÄ½ö½öÊÇÔ´´úÂëµÄ»°ÕⲢûÓÐʲô»µ´¦£¬±Ï¾¹
Git ¿ÉÒԷdz£¸ßЧµØÑ¹Ëõ´ËÀàÊý¾Ý¡£²»¹ýÈç¹ûÓÐÈËÔÚij¸öʱ¿ÌÍùÏîÄ¿ÖÐÌí¼ÓÁËÒ»¸ö·Ç³£´óµÄÎļþ£¬ÄÇÃǼ´±ãËûÔÚºóÀ´µÄÌá½»Öн«´ËÎļþɾµôÁË£¬ËùÓеÄÇ©³ö¶¼»áÏÂÔØÕâ¸ö
´óÎļþ¡£ÒòΪÀúÊ·¼Ç¼ÖÐÒýÓÃÁËÕâ¸öÎļþ£¬Ëü»áÒ»Ö±´æÔÚ×Å¡£
µ±Ä㽫 Subversion »ò Perforce ²Ö¿âת»»µ¼ÈëÖÁ Git
ʱÕâ»á³ÉΪһ¸öºÜÑÏÖØµÄÎÊÌâ¡£ÔÚ´ËÀàϵͳÖУ¬(Ç©³öʱ) ²»»áÏÂÔØÕû¸ö²Ö¿âÀúÊ·£¬ËùÒÔÕâÖÖÇéÐβ»´ó»áÓв»Á¼ºó¹û¡£Èç¹ûÄã´ÓÆäËûϵͳµ¼ÈëÁËÒ»¸ö²Ö¿â£¬»òÊÇ·¢¾õÒ»¸ö²Ö¿âµÄ³ß´çÔ¶³¬³öÔ¤¼Æ£¬¿ÉÒÔÓÃÏÂÃæµÄ·½·¨ÕÒµ½²¢ÒƳý
´ó (³ß´ç) ¶ÔÏó¡£
¾¯¸æ£º´Ë·½·¨»áÆÆ»µÌá½»ÀúÊ·¡£ÎªÁËÒÆ³ý¶ÔÒ»¸ö´óÎļþµÄÒýÓ㬴Ó×îÔç°üº¬¸ÃÒýÓõÄ
tree ¶ÔÏó¿ªÊ¼Ö®ºóµÄËùÓÐ commit ¶ÔÏó¶¼»á±»ÖØÐ´¡£Èç¹ûÔÚ¸Õµ¼ÈëÒ»¸ö²Ö¿â²¢ÔÚÆäËûÈËÔÚ´Ë»ù´¡ÉÏ¿ªÊ¼¹¤×÷֮ǰÕâô×ö£¬ÄÇûÓÐʲôÎÊÌâ
©¤©¤ ·ñÔòÄã²»µÃ²»Í¨ÖªËùÓÐÐ×÷Õß (¹±Ï×Õß) È¥ÑܺÏÄãÐÂÐÞ¸ÄµÄ commit ¡£
ΪÁËÑÝʾÕâµã£¬Íù test ²Ö¿âÖмÓÈëÒ»¸ö´óÎļþ£¬È»ºóÔÚÏ´ÎÌύʱ½«Ëüɾ³ý£¬½Ó×ÅÕÒµ½²¢½«Õâ¸öÎļþ´Ó²Ö¿âÖÐÓÀ¾Ãɾ³ý¡£Ê×ÏÈ£¬¼ÓÒ»¸ö´óÎļþ½øÈ¥£º
$ curl http://kernel.org/pub/software/scm/git/git-1.6.3.1.tar.bz2 >
git.tbz2 $ git add git.tbz2 $ git commit -am 'added git ta |
ร¬Äã²¢²»ÏëÍùÏîÄ¿ÖмӽøÒ»¸öÕâô´óµÄ tar °ü¡£×îºó»¹ÊÇÈ¥µôËü£º
$ git rm git.tbz2 rm 'git.tbz2' $ git commit -m 'oops
- removed large tarball' [master da3f30d] oops - removed large tarball |
¶Ô²Ö¿â½øÐÐ gc ²Ù×÷£¬²¢²é¿´Õ¼ÓÃÁ˿ռ䣺
$ git gc Counting objects: 21, done. Delta compression using
2 threads. Compressing objects: 100% (16/16), done. Writing obj |
¿ÉÒÔÔËÐÐ count-objects ÒԲ鿴ʹÓÃÁ˶àÉٿռ䣺
$ git count-objects -v count: 4 size: 16 in-pack: 21 packs: 1 size-pack: 2016 prune-packable: 0 garbage: 0 |
size-pack ÊÇÒÔǧ×Ö½ÚΪµ¥Î»±íʾµÄ packfiles µÄ´óС£¬Òò´ËÒѾʹÓÃÁË
2MB ¡£¶øÔÚÕâ´ÎÌύ֮ǰ½öÓÃÁË 2K ×óÓÒ ©¤©¤ ÏÔÈ»ÔÚÕâ´ÎÌύʱɾ³ýÎļþ²¢Ã»ÓÐÕæÕý½«Æä´ÓÀúÊ·¼Ç¼ÖÐɾ³ý¡£Ã¿µ±ÓÐÈ˸´ÖÆÕâ¸ö²Ö¿âȥȡµÃÕâ¸öСÏîĿʱ£¬¶¼²»µÃ²»¸´ÖÆËùÓÐ
2MB Êý¾Ý£¬¶øÕâ½ö½öÒòΪÄãÔø¾²»Ð¡ÐļÓÁ˸ö´óÎļþ¡£µ±ÎÒÃÇÀ´½â¾öÕâ¸öÎÊÌâ¡£
Ê×ÏÈÒªÕÒ³öÕâ¸öÎļþ¡£ÔÚ±¾ÀýÖУ¬ÄãÖªµÀÊÇÄĸöÎļþ¡£¼ÙÉèÄã²¢²»ÖªµÀÕâÒ»µã£¬ÒªÈçºÎÕÒ³öÄĸö
(Щ) ÎļþÕ¼ÓÃÁËÕâô¶àµÄ¿Õ¼ä£¿Èç¹ûÔËÐÐ git gc£¬ËùÓжÔÏó»á´æÈëÒ»¸ö packfile Îļþ£»ÔËÐÐÁíÒ»¸öµ×²ãÃüÁîgit
verify-pack ÒÔʶ±ð³ö´ó¶ÔÏ󣬶ÔÊä³öµÄµÚÈýÁÐÐÅÏ¢¼´Îļþ´óС½øÐÐÅÅÐò£¬»¹¿ÉÒÔ½«Êä³ö¶¨Ïòµ½ tail
ÃüÁÒòΪÄãÖ»¹ØÐÄÅÅÔÚ×îºóµÄÄǼ¸¸ö×î´óµÄÎļþ£º
$ git verify-pack -v .git/objects/pack/pack-3f8c0...bb.idx |
sort -k 3 -n | tail -3 e3f094f522629ae358806b17daf78246c27c007b |
×îµ×ÏÂÄǸö¾ÍÊÇÄǸö´óÎļþ£º2MB ¡£Òª²é¿´Õâµ½µ×ÊÇÄĸöÎļþ£¬¿ÉÒÔʹÓõÚ
7 ÕÂÖÐÒѾ¼òµ¥Ê¹ÓùýµÄ rev-list ÃüÁî¡£Èô¸ø rev-list ÃüÁî´«Èë --objects
Ñ¡ÏËü»áÁгöËùÓÐ commit SHA Öµ£¬blob SHA Öµ¼°ÏàÓ¦µÄÎļþ·¾¶¡£¿ÉÒÔÕâÑù²é¿´ blob
µÄÎļþÃû£º
$ git rev-list --objects --all | grep 7a9eb2fb 7a9eb2fba2b1811321254ac360970fc169ba2330 git.tbz2 |
½ÓÏÂÀ´Òª½«¸ÃÎļþ´ÓÀúÊ·¼Ç¼µÄËùÓÐ tree ÖÐÒÆ³ý¡£ºÜÈÝÒ×ÕÒ³öÄÄЩ commit
ÐÞ¸ÄÁËÕâ¸öÎļþ£º
$ git log --pretty=oneline -- git.tbz2 da3f30d019005479c99eb4c3406225613985a1db
oops - removed large tarball 6df764092f3e7c8 |
±ØÐëÖØÐ´´Ó 6df76 ¿ªÊ¼µÄËùÓÐ commit ²ÅÄܽ«Îļþ´Ó Git
ÀúÊ·ÖÐÍêÈ«ÒÆ³ý¡£Õâô×öÐèÒªÓõ½µÚ 6 ÕÂÖÐÓùýµÄ filter-branch ÃüÁ
$ git filter-branch --index-filter \ 'git rm --cached --ignore-unmatch git.tbz2'
-- 6df7640^.. Rewrite 6df764092f3e7c8f5f94cb |
--index-filter Ñ¡ÏîÀàËÆÓÚµÚ 6 ÕÂÖÐʹÓÃµÄ --tree-filter
Ñ¡Ïµ«ÕâÀï²»ÊÇ´«ÈëÒ»¸öÃüÁîÈ¥Ð޸ĴÅÅÌÉÏÇ©³öµÄÎļþ£¬¶øÊÇÐÞ¸ÄÔÝ´æÇøÓò»òË÷Òý¡£²»ÄÜÓÃrm file ÃüÁîÀ´É¾³ýÒ»¸öÌØ¶¨Îļþ£¬¶øÊDZØÐëÓÃ
git rm --cached À´É¾³ýËü ©¤©¤ ¼´´ÓË÷Òý¶ø²»ÊÇ´ÅÅÌɾ³ýËü¡£ÕâÑù×öÊdzöÓÚËÙ¶È¿¼ÂÇ ©¤©¤ ÓÉÓÚ
Git ÔÚÔËÐÐÄãµÄ filter ֮ǰÎÞÐ轫ËùÓа汾ǩ³öµ½´ÅÅÌÉÏ£¬Õâ¸ö²Ù×÷»á¿ìµÃ¶à¡£Ò²¿ÉÒÔÓÃ--tree-filter
À´Íê³ÉÏàͬµÄ²Ù×÷¡£git rm µÄ --ignore-unmatch Ñ¡ÏîÖ¸¶¨µ±ÄãÊÔͼɾ³ýµÄÄÚÈݲ¢²»´æÔÚʱ²»ÏÔʾ´íÎó¡£×îºó£¬ÒòΪÄãÇå³þÎÊÌâÊÇ´ÓÄĸö
commit ¿ªÊ¼µÄ£¬Ê¹ÓÃfilter-branch ÖØÐ´×Ô 6df7640 Õâ¸ö commit ¿ªÊ¼µÄËùÓÐÀúÊ·¼Ç¼¡£²»Õâô×öµÄ»°»áÖØÐ´ËùÓÐÀúÊ·¼Ç¼£¬»¨·Ñ²»±ØÒªµÄ¸ü¶àʱ¼ä¡£
ÏÖÔÚÀúÊ·¼Ç¼ÖÐÒѾ²»°üº¬¶ÔÄǸöÎļþµÄÒýÓÃÁË¡£²»¹ý reflog ÒÔ¼°ÔËÐÐ
filter-branch ʱ Git Íù .git/refs/original Ìí¼ÓµÄһЩ refs
ÖÐÈÔÓжÔËüµÄÒýÓã¬Òò´ËÐèÒª½«ÕâЩÒýÓÃɾ³ý²¢¶Ô²Ö¿â½øÐÐ repack ²Ù×÷¡£ÔÚ½øÐÐ repack ǰÐèÒª½«ËùÓжÔÕâЩ
commits µÄÒýÓÃÈ¥³ý£º
$ rm -Rf .git/refs/original $ rm -Rf .git/logs/ $ git gc
Counting objects: 19, done. Delta compression using 2 threads. Compr |
¿´Ò»Ï½ÚÊ¡Á˶àÉٿռ䡣
$ git count-objects -v count: 8 size: 2040 in-pack: 19 packs: 1 size-pack: 7 prune-packable: 0 garbage: 0 |
repack ºó²Ö¿âµÄ´óС¼õСµ½ÁË 7K £¬Ô¶Ð¡ÓÚ֮ǰµÄ 2MB ¡£´Ó
size Öµ¿ÉÒÔ¿´³ö´óÎļþ¶ÔÏó»¹ÔÚËÉÉ¢¶ÔÏóÖУ¬Æäʵ²¢Ã»ÓÐÏûʧ£¬²»¹ýÕâûÓйØÏµ£¬ÖØÒªµÄÊÇÔÚÔÙ½øÐÐÍÆËÍ»ò¸´ÖÆ£¬Õâ¸ö¶ÔÏó²»»áÔÙ´«ËͳöÈ¥¡£Èç¹ûÕæµÄÒªÍêÈ«°ÑÕâ¸ö¶ÔÏóɾ³ý£¬¿ÉÒÔÔËÐÐgit
prune --expire ÃüÁî¡£
9.8 ×ܽá
ÏÖÔÚÄãÓ¦¸Ã¶Ô Git ¿ÉÒÔ×÷ʲôÏ൱Á˽âÁË£¬²¢ÇÒÔÚÒ»¶¨³Ì¶ÈÉÏÒ²ÖªµÀÁË Git
ÊÇÈçºÎʵÏֵġ£±¾Õ¸²¸ÇÁËÐí¶à plumbing ÃüÁî ©¤©¤ ÕâЩÃüÁî±È½Ïµ×²ã£¬ÇÒ±ÈÄãÔÚ±¾ÊéÆäËû²¿·Öѧµ½µÄ
porcelain ÃüÁîÒªÀ´µÃ¼òµ¥¡£´Óµ×²ãÁ˽â Git µÄ¹¤×÷ÔÀí¿ÉÒÔ°ïÖúÄã¸üºÃµØÀí½âΪºÎ Git ʵÏÖÁËĿǰµÄÕâЩ¹¦ÄÜ£¬Ò²Ê¹ÄãÄܹ»Õë¶ÔÄãµÄ¹¤×÷Á÷д³ö×Ô¼ºµÄ¹¤¾ßºÍ½Å±¾¡£
Git ×÷ΪһÌ× content-addressable µÄÎļþϵͳ£¬ÊÇÒ»¸ö·Ç³£Ç¿´óµÄ¹¤¾ß£¬¶ø²»½ö½öÖ»ÊÇÒ»¸ö
VCS ¹©ÈËʹÓá£Ï£Íû½èÖúÓÚÄãÐÂѧµ½µÄ Git ÄÚ²¿ÔÀíµÄ֪ʶ£¬Äã¿ÉÒÔʵÏÖ×Ô¼ºµÄÓÐȤµÄÓ¦Ó㬲¢ÒÔ¸ü¸ß¼¶±ãÀûµÄ·½Ê½Ê¹ÓÃ
Git¡£
|