±à¼ÍƼö: |
±¾ÎÄÀ´×ÔдÀֵ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¿âµÄ¶ÏÑÔ£¬Ò²¾ÍÊÇ·ÀÖ¹µ¼Ö³ÌÐòÁ¢¿ÌËæÒâÍ˳ö¡£
|