Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Model Center   Code  
»áÔ±   
   
 
     
   
 ¶©ÔÄ
  ¾èÖú
Subversion API ʹÓüò½é
 
  4101  次浏览      29
 2018-1-29
 
±à¼­ÍƼö:

±¾ÎÄÀ´×ÔдÀֵIJ©¿Í£¬±¾ÎÄÖ÷Òª´ÓʹÓô¦Àí°æ±¾¿â½éÉÜÁËʹÓÃSubversion¿âAPI¿ª·¢Ó¦Óá£

ʹÓà API

ʹÓÃSubversion¿âAPI¿ª·¢Ó¦Óÿ´ÆðÀ´Ï൱µÄÖ±½Ó£¬ËùÓеĹ«¹²Í·Îļþ·ÅÔÚÔ´ÎļþµÄsubversion/includeĿ¼£¬´ÓÔ´´úÂë±àÒëºÍ°²×°Subversion±¾Éí£¬ÐèÒªÕâЩͷÎļþ¿½±´µ½ÏµÍ³Î»Öá£ÕâЩͷÎļþ°üÀ¨ÁËËùÓÐÓû§ºÍSubversion¿â¿ÉÒÔ·ÃÎʵŦÄܺÍÀàÐÍ¡£Subversion¿ª·¢ÕßÉçÇø×ÐϸµÄÈ·±£ËùÓеĹ«¹²APIÓÐÍêºÃµÄÎĵµ¡ªÖ±½ÓÒýÓÃÍ·ÎļþµÄÎĵµ¡£

ÄãÊ×ÏÈÓ¦¸Ã×¢ÒâSubversionµÄÊý¾ÝÀàÐͺͷ½·¨ÊÇÃüÃû¿Õ¼ä±£»¤µÄ£¬Ã¿Ò»¸ö¹«¹²Subversion¶ÔÏóÃûÒÔsvn_¿ªÍ·£¬È»ºó½ô¸úÒ»¸öÕâ¸ö¶ÔÏó¶¨Òå(Èçwc¡¢clientºÍfsµÈµÈ)ËùÔڵĿâµÄ¼ò¶Ì±àÂ룬ȻºóÊÇÒ»¸öÏ»®Ïß(_)ºÍºóÃæµÄ¶ÔÏóÃû³Æ¡£°ë¹«¿ªµÄ·½·¨(¿âʹÓ㬵«Êǵ«¿âÖ®Íâ´úÂë²»¿ÉÒÔʹÓò¢ÇÒÖ»¿ÉÒÔÔÚ¿â×Ô¼ºµÄĿ¼¿´µ½)ÓëÕâ¸öÃüÃûģʽ²»Í¬£¬²¢²»ÊÇ¿â´úÂëÖ®ºó½ô¸úÒ»¸öÏ»®Ïߣ¬ËûÃÇÊÇÓÃÁ½¸öÏ»®Ïß(__)¡£¸ø¶¨Ô´ÎļþµÄ˽Óз½·¨Ã»ÓÐÌØÊâǰ׺£¬Ê¹ÓÃstaticÉùÃ÷¡£µ±È»£¬Ò»¸ö±àÒëÆ÷²»»á¹ØÐÄÃüÃûϰ¹ß£¬Ö»ÊÇÓÃÀ´Çø·Ö¸ø¶¨·½·¨»òÊý¾ÝÀàÐ͵ÄÓ¦Ó÷¶Î§¡£

¹ØÓÚSubversionµÄAPI±à³ÌµÄÁíÒ»¸öºÃµÄ×ÊÔ´ÊÇhackingÖ¸ÄÏ£¬¿ÉÒÔÔÚhttp://subversion.tigris.org/hacking.htmlÕÒµ½£¬Õâ¸öÎĵµ°üº¬ÁËÓÐÓõÄÐÅÏ¢£¬Í¬Ê±Âú×ãSubversion±¾ÉíµÄ¿ª·¢Õߺͽ«Subversion×÷ΪµÚÈý·½¿âµÄ¿ª·¢Õß¡£[50]

Apache ¿ÉÒÆÖ²ÔËÐпâ

°éËæSubversion×Ô¼ºµÄÊý¾ÝÀàÐÍ£¬Äã»á¿´µ½Ðí¶àapr¿ªÍ·µÄÊý¾ÝÀàÐÍÒýÓáªÀ´×ÔApache¿ÉÒÆÖ²ÔËÐпâ(APR)µÄ¶ÔÏó¡£APRÊÇApache¿ÉÒÆÖ²ÔËÐп⣬Դ×ÔΪÁË·þÎñÆ÷´úÂëµÄ¶àƽ̨ÐÔ£¬³¢ÊÔ½«²»Í¬µÄ²Ù×÷ÏµÍ³ÌØ¶¨×Ö½ÚÓë²Ù×÷ϵͳÎ޹شúÂë¸ôÀë¡£½á¹û¾ÍÌṩÁËÒ»¸ö»ù´¡APIµÄ¿â£¬Ö»ÓÐһЩÊʶÈÇø±ð¡ª»òÕßÊǹ㷺µÄ¡ªÀ´×Ô¸÷¸ö²Ù×÷ϵͳ¡£Apache HTTP·þÎñÆ÷ºÜÃ÷ÏÔÊÇAPR¿âµÄµÚÒ»¸öÓû§£¬Subversion¿ª·¢ÕßÁ¢¿Ì·¢ÏÖÁËʹÓÃAPR¿âµÄ¼ÛÖµ¡£Òâζ×ÅSubversionûÓвÙ×÷ÏµÍ³ÌØ¶¨µÄ´úÂ룬ҲÒâζ×ÅSubversion¿Í»§¶Ë¿ÉÒÔÔÚServer´æÔ򵀮½Ì¨±àÒëºÍÔËÐС£µ±Ç°Õâ¸öÁбí°üÀ¨£¬¸÷ÖÖÀàÐ͵ÄUnix¡¢Win32¡¢OS/2ºÍMac OS X¡£

³ýÁËÌṩÁË¿çÆ½Ì¨Ò»ÖµÄϵͳµ÷Ó㬠[51]APR¸øSubversion¶Ô¶àÖÖÊý¾ÝÀàÐÍÓпìËٵķÃÎÊ£¬È綯̬Êý×éºÍ¹þÏ£±í¡£SubversionÔÚ´úÂëÖй㷺ʹÓÃÕâЩÀàÐÍ£¬µ«ÊÇSubversionµÄAPIÔ­ÐÍÖÐ×î³£¼ûµÄAPRÀàÐÍÊÇapr_pool_t¡ªAPRÄÚ´æ³Ø£¬SubversionʹÓÃÄÚ²¿»º³å³ØÓÃÀ´½øÐÐÄÚ´æ·ÖÅä(³ý·ÇÍⲿ¿âÔÚAPI´«µÝ²ÎÊýʱÐèÒªÒ»¸ö²»Í¬µÄÄÚ´æ¹ÜÀíģʽ)£¬ [52]¶øÇÒÒ»¸öÈËÈç¹ûÕë¶ÔSubversionµÄAPI±àÂë²»ÐèÒª×öͬÑùµÄÊÂÇ飬ËûÃÇ¿ÉÒÔÔÚÐèҪʱ¸øAPIÌṩ»º³å³Ø£¬ÕâÒâζ×ÅSubversionµÄAPIʹÓÃÕßÒ²±ØÐëÁ´½Óµ½APR£¬±ØÐëµ÷ÓÃapr_initialize()À´³õʼ»¯APR×Óϵͳ£¬¶øÇÒÔÚʹÓÃSubversion APIʱ±ØÐë´´½¨ºÍ¹ÜÀí³Ø£¬Í¨³£ÊÇʹÓÃsvn_pool_create()¡¢svn_pool_clear()ºÍsvn_pool_destroy()¡£

ʹÓÃÄÚ´æ³Ø±à³Ì

¼¸ºõÿһ¸öʹÓùýCÓïÑԵĿª·¢ÕßÔø¾­¸Ð̾ÁîÈËηËõµÄÄÚ´æ¹ÜÀí£¬·ÖÅä×ã¹»µÄÄڴ棬²¢ÇÒ×·×ÙÄÚ´æµÄ·ÖÅ䣬ÔÚ²»ÐèҪʱÊÍ·ÅÄڴ桪Õâ¸öÈÎÎñ»á·Ç³£¸´ÔÓ¡£µ±È»£¬Èç¹ûûÓÐÕýÈ·µØ×öµ½ÕâÒ»µã»áµ¼Ö³ÌÐò»Ùµô×Ô¼º£¬»òÕ߸ü¼ÓÑÏÖØÒ»µã£¬°ÑµçÄÔ¸ã̱¡£

ÁíÒ»·½Ãæ¸ß¼¶ÓïÑÔʹ¿ª·¢ÕßÍêÈ«°ÚÍÑÁËÄÚ´æ¹ÜÀí£¬[53]JavaºÍPythonÖ®ÀàµÄÓïÑÔʹÓÃÀ¬»øÊÕ¼¯Ô­Àí£¬ÔÚÐèÒªµÄʱºò·ÖÅä¶ÔÏóÄڴ棬ÔÚ²»Ê¹ÓÃʱ½øÐÐÇåÀí¡£

APRÌṩÁËÒ»ÖÖ½Ð×ö³Ø»ù´¡µÄÖеȵÄÄÚ´æ¹ÜÀí·½·¨£¬ÔÊÐí¿ª·¢ÕßÒÔÒ»ÖֵͷֱæÂʵķ½Ê½¿ØÖÆÄڴ桪ÿ¿é(»ò³Ø¡°pool¡±)µÄÄڴ棬¶ø²»ÊÇÿ¸ö¶ÔÏó¡£²»ÊÇʹÓÃmalloc()ºÍÆäËû°´ÕÕ¶ÔÏó·ÖÅäÄÚ´æµÄ·½Ê½£¬ÄãÒªÇóAPR´ÓÄÚ´æ´´½¨Ò»¶ÎÄÚ´æ³Ø£¬µ±Äã½áÊøÊ¹ÓÃÔÚ³ØÖд´½¨µÄ¶ÔÏó£¬ÄãÏú»Ù³Ø£¬¿ÉÒÔÓÐЧµØÈ¡ÏûÆäÖеĶÔÏóÏûºÄµÄÄڴ档ͨ¹ý³Ø£¬Äã²»ÐèÒª¸ú×Ùÿ¸ö¶ÔÏóµÄÄÚ´æÊÍ·Å£¬ÄãµÄ³ÌÐòÖ»ÐèÒª¸ú×ÙÕâЩ¶ÔÏ󣬽«¶ÔÏó·ÖÅäµ½³ØÖУ¬¶ø³ØµÄÉúÃüÖÜÆÚ(³ØµÄ´´½¨ºÍɾ³ýÖ®¼äµÄʱ¼ä)Âú×ãËùÓжÔÏóµÄÐèÒª¡£

URL ºÍ·¾¶ÐèÇó

ÒòΪ·Ö²¼Ê½°æ±¾¿ØÖƲÙ×÷ÊÇSubversion´æÔÚµÄÖØµã£¬ÓÐÒâÒåÀ´¹Ø×¢Ò»Ï¹ú¼Ê»¯(i18n)Ö§³Ö¡£±Ï¾¹£¬µ±¡°·Ö²¼Ê½¡±»òÐíÒâζ×Å¡°ºá¿ç°ì¹«ÊÒ¡±£¬ËüÒ²Òâζ×Å¡°ºá¿çÈ«Çò¡±¡£ÎªÁ˸üÈÝÒ×Ò»µã£¬SubversionµÄËùÓй«¹²½Ó¿ÚÖ»½ÓÊÜ·¾¶²ÎÊý,ÕâЩ²ÎÊýÊÇ´«Í³µÄ£¬Ê¹ÓÃUTF-8±àÂë¡£ÕâÒâζ×Å£¬¾Ù¸öÀý×Ó£¬ÈκÎеÄʹÓÃlibsvn_client½Ó¿Ú¿Í»§¶Ë¿â£¬ÔÚ°ÑÕâЩ²ÎÊý´«µÝ¸øSubversion¿âǰ£¬ÐèÒªÊ×ÏȽ«Â·¾¶´Ó±¾µØ´úÂëת»¯ÎªUTF-8´úÂ룬Ȼºó½«Subversion´«µÝ»ØÀ´µÄ·¾¶×ª»»Îª±¾µØ´úÂ룬ºÜÐÒÔË£¬SubversionÌṩÁËÒ»×éÈκγÌÐò¿ÉÒÔʹÓõÄת»¯·½·¨(¼ûsubversion/include/svn_utf.h)¡£

ͬÑù£¬SubversionµÄAPIÐèÒªËùÓеÄURL²ÎÊýÊÇÕýÈ·µÄURI±àÂ룬ËùÒÔ£¬ÎÒÃDz»»á´«µÝfile:///home/username/My File.txt×÷ΪMy File.txtµÄURL£¬¶øÒª´«µÝfile:///home/username/My%20File.txt¡£ÔٴΣ¬SubversionÌṩÁËһЩÄã¿ÉÒÔʹÓõÄÖúÊÖ·½·¨¡ªsvn_path_uri_encode()ºÍsvn_path_uri_decode()£¬·Ö±ðÓÃÀ´URIµÄ±àÂëºÍ½âÂë¡£

ʹÓà C ºÍ C++ ÒÔÍâµÄÓïÑÔ

³ýCÓïÑÔÒÔÍ⣬Èç¹ûÄã¶ÔʹÓÃÆäËûÓïÑÔ½áºÏSubversion¿â¸ÐÐËȤ¡ªÈçPython½Å±¾»òÊÇJavaÓ¦ÓáªSubversionͨ¹ý¼òµ¥°ü¹üÉú³ÉÆ÷(SWIG)ÌṩÁË×î³õµÄÖ§³Ö¡£SubversionµÄSWIG°ó¶¨Î»ÓÚsubversion/bindings/swig£¬²¢ÇÒÂýÂýµÄ×ßÏò³ÉÊì½øÈë¿ÉÓÃ״̬¡£Õâ¸ö°ó¶¨ÔÊÐíÄãÖ±½Óµ÷ÓÃSubversionµÄAPI·½·¨£¬Ê¹Óðü¹üÆ÷»á°Ñ½Å±¾Êý¾ÝÀàÐÍת»¯ÎªSubversionÐèÒªµÄCÓïÑÔ¿âÀàÐÍ¡£

·Ç³£²»ÐÒ£¬SubversionµÄÓïÑÔ°ó¶¨È±·¦¶ÔºËÐÄSubversionÄ£¿éµÄ¹Ø×¢£¬µ«ÊÇ£¬»¨Á˺ܶàÁ¦Æø´¦Àí´´½¨Õë¶ÔPython¡¢PerlºÍRubyµÄ¹¦Äܰ󶨣¬ÔÚÒ»¶¨³Ì¶ÈÉÏ£¬ÔÚÕâЩ½Ó¿ÚÉϵŤ×÷Á¿¿ÉÒÔÔÚÆäËûÓïÑÔµÄSWIG(°üÀ¨C#¡¢Guile¡¢Java¡¢MzScheme¡¢OCaml¡¢PHP¡¢TclµÈµÈ)½Ó¿ÚÉϵõ½ÖØÓá£È»¶ø£¬ÎªÁËÍê³É¸´ÔÓµÄAPI£¬Ò»Ð©SWIG½Ó¿ÚÈÔÈ»ÐèÒª¶îÍâµÄ±à³Ì¹¤×÷£¬¹ØÓÚSWIG±¾ÉíµÄ¸ü¶àÐÅÏ¢¿ÉÒÔ¿´ÏîÄ¿µÄÍøÕ¾http://www.swig.org/¡£

SubversionÒ²ÓÐJavaµÄÓïÑ԰󶨣¬JavaJL°ó¶¨(λÓÚSubversionԴĿ¼Ê÷µÄsubversion/bindings/java)²»ÊÇ»ùÓÚSWIGµÄ£¬¶øÊÇjavahºÍÊÖдJNIµÄ»ìºÏ£¬JavaHL¼¸ºõ¸²¸ÇSubversion¿Í»§¶ËµÄAPI£¬Ä¿±êÊÇ×÷ΪJava»ù´¡µÄSubversion¿Í»§¶ËºÍ¼¯³ÉIDEµÄʵÏÖ¡£

SubversionµÄÓïÑÔ°ó¶¨È±·¦SubversionºËÐÄÄ£¿éµÄ¹Ø×¢£¬µ«ÊÇͨ³£¿ÉÒÔ×÷Ϊһ¸ö²úÆ·ÐÅÀµ¡£´óÁ¿½Å±¾¡¢Ó¦Óá¢SubversionµÄGUI¿Í»§¶ËºÍÆäËûµÚÈý·½¹¤¾ßÏÖÔÚÒѾ­³É¹¦µØÔËÓÃÁËSubversionÓïÑÔ°ó¶¨À´Íê³ÉSubversionµÄ¼¯³É¡£

ÕâÀïʹÓÃÆäËüÓïÑԵķ½·¨À´ÓëSubversion½»»¥Ã»ÓÐÈκÎÒâÒ壺Subversion¿ª·¢ÉçÇøÃ»ÓÐÌṩÆäËûµÄ°ó¶¨£¬Äã¿ÉÒÔÔÚSubversionÏîÄ¿Á´½ÓÒ³Àï(http://subversion.tigris.org/links.html)ÕÒµ½ÆäËû°ó¶¨µÄÁ´½Ó£¬µ«ÊÇÓÐһЩÁ÷Ðеİó¶¨ÎÒ¾õµÃÓ¦¸ÃÌØ±ðÁôÒâ¡£Ê×ÏÈÊÇPythonµÄÁ÷Ðа󶨣¬Barry ScottµÄPySVN(http://pysvn.tigris.org/)¡£PySVN¹Ä´µËüÃÇÌṩÁ˸ü¶àPythonÑùʽµÄ½Ó¿Ú£¬¶ø²»ÏñSubversion×Ô¼ºµÄPython°ó¶¨µÄCÑùʽ½Ó¿Ú¡£¶ÔÓÚÏ£ÍûѰÇóSubversion´¿JavaʵÏÖµÄÈË£¬¿ÉÒÔ¿´¿´SVNKit(http://svnkit.com/)£¬Ò²¾ÍÊÇ´ÓͷʹÓÃJava±àдµÄSubversion¡£Äã±ØÐëҪСÐÄ£¬SVNKitûÓвÉÓÃSubversionµÄºËÐĿ⣬ÆäÐÐΪ·½Ê½Ã»ÓÐÈ·±£ÓëSubversionÆ¥Åä¡£

´úÂëÑùÀý

Àý 8.1 ¡°Ê¹Óð汾¿â²ã¡±°üº¬ÁËÒ»¶ÎC´úÂë(C±àд)ÃèÊöÁËÎÒÃÇÌÖÂ۵ĸÅÄËüʹÓÃÁ˰汾¿âºÍÎļþϵͳ½Ó¿Ú(¿ÉÒÔͨ¹ý·½·¨Ãûsvn_repos_ºÍsvn_fs_·Ö±æ)´´½¨ÁËÒ»¸öÌí¼ÓĿ¼µÄÐÞ¶©°æ±¾¡£Äã¿ÉÒÔ¿´µ½APR¿âµÄʹÓã¬ÎªÁËÄÚ´æ·ÖÅä¶ø´«µÝ£¬ÕâЩ´úÂëÒ²½Ò¿ªÁËһЩ¹ØÓÚSubversion´íÎó´¦ÀíµÄ»ÞɬÊÂʵ¡ªËùÓеÄSubversion´íÎó±ØÐëÐèÒªÃ÷È·µÄ´¦ÀíÒÔ·ÀÖ¹ÄÚ´æÐ¹Â¶(ÔÚijЩÇé¿öÏ£¬Ó¦ÓÃʧ°Ü)¡£

Àý 8.1. ʹÓð汾¿â²ã

#define INT_ERR(expr) \ do { \
svn_error_t *__temperr = (expr); \
if (__temperr) \
{ \
svn_error_clear(__temperr); \
return 1; \
} \
return 0; \
} while (0)
static int
make_new_directory(const char *repos_path,
const char *new_directory,
apr_pool_t *pool)
{
svn_error_t *err;
svn_repos_t *repos;
svn_fs_t *fs;
svn_revnum_t youngest_rev;
svn_fs_txn_t *txn; svn_fs_root_t *txn_root;
const char *conflict_str;
INT_ERR(svn_repos_open(&repos, repos_path, pool));
fs = svn_repos_fs(repos);
INT_ERR(svn_fs_youngest_rev(&youngest_rev, fs, pool));
INT_ERR(svn_fs_begin_txn(&txn, fs, youngest_rev, pool));
INT_ERR(svn_fs_txn_root(&txn_root, txn, pool));
INT_ERR(svn_fs_make_dir(txn_root, new_directory, pool));
err = svn_repos_fs_commit_txn(&conflict_str, repos,
&youngest_rev, txn, pool);
if (! err)
{
printf("Directory '%s' was successfully added as new revision "
"'%ld'.\n", new_directory, youngest_rev);
}
else if (err->apr_err == SVN_ERR_FS_CONFLICT)
{
printf("A conflict occurred at path '%s' while attempting "
"to add directory '%s' to the repository at '%s'.\n",
conflict_str, new_directory, repos_path);
}
else
{
printf("An error occurred while attempting to add directory '%s' "
"to the repository at '%s'.\n",
new_directory, repos_path);
}
INT_ERR(err);
}

Çë×¢ÒâÔÚÀý 8.1 ¡°Ê¹Óð汾¿â²ã¡±ÖУ¬´úÂë¿ÉÒԷdz£ÈÝÒ×ʹÓÃsvn_fs_commit_txn()Ìá½»ÊÂÎñ¡£µ«ÊÇÎļþϵͳµÄAPI¶Ô°æ±¾¿â¿âµÄ¹³×ÓÒ»ÎÞËùÖª£¬Èç¹ûÄãÏ£ÍûÄãµÄSubversion°æ±¾¿âÔÚÿ´ÎÌá½»Ò»¸öÊÂÎñʱ×Ô¶¯Ö´ÐÐһЩ·ÇSubversionµÄÈÎÎñ(ÀýÈ磬¸ø¿ª·¢ÕßÓʼþ×é·¢ËÍÒ»¸öÃèÊöÊÂÎñÐ޸ĵÄÓʼþ)£¬ÄãÐèҪʹÓÃlibsvn_repos°ü¹üµÄ¹¦Äܰ汾¡ªÕâ¸ö¹¦ÄÜ»áʵ¼ÊÉÏÊ×ÏÈÔËÐÐÒ»¸öÈç¹û´æÔÚµÄpre-commit¹³×ӽű¾£¬È»ºóÌá½»ÊÂÎñ£¬×îºó»áÔËÐÐÒ»¸öpost-commit¹³×ӽű¾¡£¹³×ÓÌṩÁËÒ»ÖÖÌØ±ðµÄ±¨¸æ»úÖÆ£¬²»ÊÇÕæµÄÊôÓÚºËÐÄÎļþϵͳ¿â±¾Éí¡£(¹ØÓÚSubversion°æ±¾¿â¹³×ӵĸü¶àÐÅÏ¢£¬¼û¡°ÊµÏÖ°æ±¾¿â¹³×Ó¡±Ò»½Ú¡£)

ÏÖÔÚÎÒÃÇת»»Ò»ÏÂÓïÑÔ£¬Àý 8.2 ¡°Ê¹Óà Python ´¦Àí°æ±¾¿â²ã¡±Ê¹ÓÃSubversion SWIGµÄPython°ó¶¨ÊµÏÖÁË´Ó°æ±¾¿âÈ¡µÃ×îеİ汾£¬²¢ÇÒ´òÓ¡ÁËÈ¡³öʱ·ÃÎʵÄĿ¼¡£

Àý 8.2. ʹÓà Python ´¦Àí°æ±¾¿â²ã

#!/usr/bin/python """Crawl a repository, printing versioned object path names."""
import sys
import os.path
import svn.fs, svn.core, svn.repos
def crawl_filesystem_dir(root, directory):
"""Recursively crawl DIRECTORY under ROOT in the filesystem, and return
a list of all the paths at or below DIRECTORY."""

# Print the name of this path.
print directory + "/"

# Get the directory entries for DIRECTORY.
entries = svn.fs.svn_fs_dir_entries(root, directory)

# Loop over the entries.
names = entries.keys()
for name in names:
# Calculate the entry's full path.
full_path = directory + '/' + name

# If the entry is a directory, recurse. The recursion will return
# a list with the entry and all its children, which we will add to
# our running list of paths.
if svn.fs.svn_fs_is_dir(root, full_path):
crawl_filesystem_dir(root, full_path)
else:
# Else it's a file, so print its path here.
print full_path

def crawl_youngest(repos_path):
"""Open the repository at REPOS_PATH, and recursively crawl its
youngest revision."""

# Open the repository at REPOS_PATH, and get a reference to its
# versioning filesystem.
repos_obj = svn.repos.svn_repos_open(repos_path)
fs_obj = svn.repos.svn_repos_fs(repos_obj)

# Query the current youngest revision.
youngest_rev = svn.fs.svn_fs_youngest_rev(fs_obj)

# Open a root object representing the youngest (HEAD) revision.
root_obj = svn.fs.svn_fs_revision_root(fs_obj, youngest_rev)

# Do the recursive crawl.
crawl_filesystem_dir(root_obj, "")

if __name__ == "__main__":
# Check for sane usage.
if len(sys.argv) != 2:
sys.stderr.write("Usage: %s REPOS_PATH\n"
% (os.path.basename(sys.argv[0])))
sys.exit(1)

# Canonicalize the repository path.
repos_path = svn.core.svn_path_canonicalize(sys.argv[1])

# Do the real work.
crawl_youngest(repos_path)

ͬÑùµÄC³ÌÐòÐèÒª´¦ÀíAPRÄÚ´æ³ØÏµÍ³£¬µ«ÊÇPython×Ô¼º´¦ÀíÄڴ棬SubversionµÄPython°ó¶¨Ò²×ñÑ­ÕâÖÖϰ¹ß¡£ÔÚCÓïÑÔÖУ¬Îª±íʾ·¾¶ºÍÌõÄ¿µÄhashÐèÒª´¦Àí×Ô¶¨ÒåµÄÊý¾ÝÀàÐÍ(ÀýÈçAPRÌṩµÄ¿â)£¬µ«ÊÇPythonÓÐhash(½Ð×ö¡°dictionaries¡±)£¬²¢ÇÒÊÇÄÚÖÃÊý¾ÝÀàÐÍ£¬¶øÇÒ»¹ÌṩÁËһϵÁвÙ×÷ÕâЩÀàÐ͵ĺ¯Êý£¬ËùÒÔSWIG(ͨ¹ýSubversionµÄÓïÑ԰󶨲ãµÄ×Ô¶¨Òå°ïÖú)ҪСÐĵĽ«ÕâЩ×Ô¶¨ÒåÊý¾ÝÀàÐÍÓ³É䵽Ŀ±êÓïÑÔµÄÊý¾ÝÀàÐÍ£¬ÕâΪĿ±êÓïÑÔµÄÓû§ÌṩÁËÒ»¸ö¸ü¼ÓÖ±¹ÛµÄ½Ó¿Ú¡£

SubversionµÄPython°ó¶¨Ò²¿ÉÒÔÓÃÀ´½øÐй¤×÷¿½±´µÄ²Ù×÷£¬ÔÚ±¾ÕÂÇ°ÃæµÄС½ÚÖУ¬ÎÒÃÇÌáµ½¹ýlibsvn_client½Ó¿Ú£¬Ëü´æÔÚµÄÄ¿µÄ¾ÍÊǼò»¯±àдSubversion¿Í»§¶ËµÄÄѶȣ¬Àý 8.3 ¡°Ò»¸öPython״̬ÅÀ³æ¡±ÊÇÒ»¸öÀý×Ó£¬½²µÄÊÇÈçºÎʹÓÃSWIG°ó¶¨´´½¨Ò»¸öÀ©Õ¹°æ±¾µÄsvn statusÃüÁî¡£

Àý 8.3. Ò»¸öPython״̬ÅÀ³æ

#!/usr/bin/env python
"""Crawl a working copy directory, printing status information."""
import sys
import os.path
import getopt
import svn.core, svn.client, svn.wc
def generate_status_code(status):
"""Translate a status value into a single-character status code,
using the same logic as the Subversion command-line client."""
code_map = { svn.wc.svn_wc_status_none : ' ',
svn.wc.svn_wc_status_normal : ' ',
svn.wc.svn_wc_status_added : 'A',
svn.wc.svn_wc_status_missing : '!',
svn.wc.svn_wc_status_incomplete : '!',
svn.wc.svn_wc_status_deleted : 'D',
svn.wc.svn_wc_status_replaced : 'R',
svn.wc.svn_wc_status_modified : 'M',
svn.wc.svn_wc_status_merged : 'G',
svn.wc.svn_wc_status_conflicted : 'C',
svn.wc.svn_wc_status_obstructed : '~',
svn.wc.svn_wc_status_ignored : 'I',
svn.wc.svn_wc_status_external : 'X',
svn.wc.svn_wc_status_unversioned : '?',
} return code_map.get(status, '?')
def do_status(wc_path, verbose):
# Calculate the length of the input working copy path.
wc_path_len = len(wc_path)
# Build a client context baton.
ctx = svn.client.svn_client_ctx_t()
def _status_callback(path, status, root_path_len=wc_path_len):
"""A callback function for svn_client_status."""
# Print the path, minus the bit that overlaps with the root of
# the status crawl
text_status = generate_status_code(status.text_status)
prop_status = generate_status_code(status.prop_status)
print '%s%s %s' % (text_status, prop_status, path[wc_path_len + 1:])

# Do the status crawl, using _status_callback() as our callback function.
svn.client.svn_client_status(wc_path, None, _status_callback,
1, verbose, 0, 0, ctx)
def usage_and_exit(errorcode):
"""Print usage message, and exit with ERRORCODE."""
stream = errorcode and sys.stderr or sys.stdout
stream.write("""Usage: %s OPTIONS WC-PATH
Options:
--help, -h : Show this usage message
--verbose, -v : Show all statuses, even uninteresting ones
""" % (os.path.basename(sys.argv[0])))
sys.exit(errorcode)
if __name__ == '__main__':
# Parse command-line options.
try:
opts, args = getopt.getopt(sys.argv[1:], "hv", ["help", "verbose"])
except getopt.GetoptError:
usage_and_exit(1)
verbose = 0
for opt, arg in opts:
if opt in ("-h", "--help"):
usage_and_exit(0)
if opt in ("-v", "--verbose"):
verbose = 1
if len(args) != 1:
usage_and_exit(2)
# Canonicalize the repository path.
wc_path = svn.core.svn_path_canonicalize(args[0])
# Do the real work.
try:
do_status(wc_path, verbose)
except svn.core.SubversionException, e:
sys.stderr.write("Error (%d): %s\n" % (e[1], e[0]))
sys.exit(1)

¾ÍÏñÀý 8.2 ¡°Ê¹Óà Python ´¦Àí°æ±¾¿â²ã¡±ÖеÄÀý×Ó£¬Õâ¸ö³ÌÐòÊdzØ×ÔÓɵ쬶øÇÒ×îÖØÒªµÄÊÇʹÓÃPythonµÄÊý¾ÝÀàÐÍ¡£svn_client_ctx_t()ÊÇÆÛÆ­£¬ÒòΪSubversionµÄAPIûÓÐÕâ¸ö·½·¨¡ªÕâ½ö½öÊÇSWIG×Ô¶¯ÓïÑÔÉú³ÉÖеÄÒ»µãÎÊÌâ(ÕâÊǶÔÓ¦¸´ÔÓC½á¹¹µÄÒ»ÖÖ¹¤³§·½·¨)¡£Ò²ÐèҪעÒâ´«µÝ¸ø³ÌÐòµÄ·¾¶(Ïó×îºóÒ»¸ö)ÊÇͨ¹ý svn_path_canonicalize()Ö´Ðеģ¬ÒòΪҪ·ÀÖ¹´¥·¢Subversionµ×²ãC¿âµÄ¶ÏÑÔ£¬Ò²¾ÍÊÇ·ÀÖ¹µ¼Ö³ÌÐòÁ¢¿ÌËæÒâÍ˳ö¡£

   
4101 ´Îä¯ÀÀ       29
Ïà¹ØÎÄÕÂ

ÿÈÕ¹¹½¨½â¾ö·½°¸
ÈçºÎÖÆ¶¨ÓÐЧµÄÅäÖùÜÀíÁ÷³Ì
ÅäÖùÜÀíÖ÷Òª»î¶¯¼°ÊµÏÖ·½·¨
¹¹½¨¹ÜÀíÈëÃÅ
Ïà¹ØÎĵµ

ÅäÖùÜÀíÁ÷³Ì
ÅäÖùÜÀí°×ƤÊé
CM09_CÅäÖùÜÀí±ê×¼
ʹÓÃSVN½øÐа汾¿ØÖÆ
Ïà¹Ø¿Î³Ì

ÅäÖùÜÀíʵ¼ù
ÅäÖùÜÀí·½·¨¡¢¹¤¾ßÓëÓ¦ÓÃ
¶à²ã´Î¼¯³ÉÅäÖùÜÀí
²úÆ··¢²¼¹ÜÀí