Rev 3557: (jam) Implement _walkdirs_win32, in file:///home/pqm/archives/thelove/bzr/%2Btrunk/
Canonical.com Patch Queue Manager
pqm at pqm.ubuntu.com
Thu Jul 17 14:27:23 BST 2008
At file:///home/pqm/archives/thelove/bzr/%2Btrunk/
------------------------------------------------------------
revno: 3557
revision-id:pqm at pqm.ubuntu.com-20080717132712-1zbt1asfsuslh1v9
parent: pqm at pqm.ubuntu.com-20080717095800-b6c3hdb60qazu5am
parent: john at arbash-meinel.com-20080717125830-tvrs36uf3x223elx
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Thu 2008-07-17 14:27:12 +0100
message:
(jam) Implement _walkdirs_win32,
going directly to Win32 apis improves status performance 2-6x
added:
bzrlib/_walkdirs_win32.h _walkdirs_win32.h-20080716220454-kweh3tgxez5dvw2l-1
bzrlib/_walkdirs_win32.pyx _walkdirs_win32.pyx-20080716220454-kweh3tgxez5dvw2l-2
bzrlib/tests/test__walkdirs_win32.py test__walkdirs_win32-20080716220454-kweh3tgxez5dvw2l-3
modified:
.bzrignore bzrignore-20050311232317-81f7b71efa2db11a
NEWS NEWS-20050323055033-4e00b5db738777ff
bzrlib/osutils.py osutils.py-20050309040759-eeaff12fbf77ac86
bzrlib/tests/__init__.py selftest.py-20050531073622-8d0e3c8845c97a64
bzrlib/tests/test_osutils.py test_osutils.py-20051201224856-e48ee24c12182989
setup.py setup.py-20050314065409-02f8a0a6e3f9bc70
------------------------------------------------------------
revno: 3504.4.15
revision-id:john at arbash-meinel.com-20080717125830-tvrs36uf3x223elx
parent: john at arbash-meinel.com-20080717125511-rjpil183ctky8l84
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: win32_find_files
timestamp: Thu 2008-07-17 07:58:30 -0500
message:
Update NEWS with the performance improvements, and the 1.6b3 release
modified:
NEWS NEWS-20050323055033-4e00b5db738777ff
------------------------------------------------------------
revno: 3504.4.14
revision-id:john at arbash-meinel.com-20080717125511-rjpil183ctky8l84
parent: john at arbash-meinel.com-20080717122119-alnqlevrp4n3td2b
parent: pqm at pqm.ubuntu.com-20080717095800-b6c3hdb60qazu5am
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: win32_find_files
timestamp: Thu 2008-07-17 07:55:11 -0500
message:
Merge bzr.dev 3556
removed:
bzrlib/store/revision/__init__.py __init__.py-20060303014707-305238f06ae20dae
bzrlib/store/revision/knit.py knit.py-20060303020652-de5fa299e941a3c7
bzrlib/store/revision/text.py text.py-20060303020652-e49155f0da4d14ab
bzrlib/tests/interversionedfile_implementations/ interversionedfile_implementations-20060301230427-f1f3ca8ddd5ff482
bzrlib/tests/interversionedfile_implementations/__init__.py __init__.py-20060302012326-981af525594d02ed
bzrlib/tests/interversionedfile_implementations/test_join.py test_join.py-20060302012326-9b5e9b0f0a03fedc
bzrlib/tests/revisionstore_implementations/ revisionstore_implementations-20060303020702-1d2e36b63cef2706
bzrlib/tests/revisionstore_implementations/__init__.py __init__.py-20060303020702-976c4186a0f99edb
bzrlib/tests/revisionstore_implementations/test_all.py test_all.py-20060303020702-9b2d4c1d75407f31
bzrlib/tests/test_escaped_store.py test_escaped_store.py-20060216023929-6bcb9a067344959f
added:
bzrlib/help_topics/en/patterns.txt patterns.txt-20080625070357-wx8qm46a19ejwfns-1
bzrlib/help_topics/en/rules.txt rules.txt-20080516063844-ghr5l6pvvrhiycun-1
bzrlib/push.py push.py-20080606021927-5fe39050e8xne9un-1
bzrlib/rules.py properties.py-20080506032617-9k06uqalkf09ck0z-1
bzrlib/tests/branch_implementations/test_stacking.py test_stacking.py-20080214020755-msjlkb7urobwly0f-1
bzrlib/tests/repository_implementations/test_add_fallback_repository.py test_add_fallback_re-20080215040003-8w9n4ck9uqdxj18m-1
bzrlib/tests/test_rules.py test_properties.py-20080506033501-3p9kmuob25dho8xl-1
bzrlib/tests/tree_implementations/test_iter_search_rules.py test_iter_search_rul-20080528065532-1ml1ttb12az20cxf-1
contrib/bash/bzrbashprompt.sh bzrbashprompt.sh-20080414112733-b78chl4ubylc6775-1
doc/en/user-guide/stacked.txt stacked.txt-20080711023247-4uh9oovoka0sze8b-1
tools/win32/run_script.py run_script.py-20080717003927-k6itvarbtnwk44o9-1
modified:
Makefile Makefile-20050805140406-d96e3498bb61c5bb
NEWS NEWS-20050323055033-4e00b5db738777ff
bzr bzr.py-20050313053754-5485f144c7006fa6
bzrlib/annotate.py annotate.py-20050922133147-7c60541d2614f022
bzrlib/branch.py branch.py-20050309040759-e4baf4e0d046576e
bzrlib/builtins.py builtins.py-20050830033751-fc01482b9ca23183
bzrlib/bundle/serializer/v4.py v10.py-20070611062757-5ggj7k18s9dej0fr-1
bzrlib/bzrdir.py bzrdir.py-20060131065624-156dfea39c4387cb
bzrlib/check.py check.py-20050309040759-f3a679400c06bcc1
bzrlib/commands.py bzr.py-20050309040720-d10f4714595cf8c3
bzrlib/config.py config.py-20051011043216-070c74f4e9e338e8
bzrlib/directory_service.py directory_service.py-20080305221044-vr2mkvlsk8jypa2y-1
bzrlib/errors.py errors.py-20050309040759-20512168c4e14fbd
bzrlib/fetch.py fetch.py-20050818234941-26fea6105696365d
bzrlib/globbing.py glob.py-20061113075651-q63o2v35fm2ydk9x-1
bzrlib/graph.py graph_walker.py-20070525030359-y852guab65d4wtn0-1
bzrlib/help_topics/__init__.py help_topics.py-20060920210027-rnim90q9e0bwxvy4-1
bzrlib/help_topics/en/hooks.txt hooks.txt-20070830033044-xxu2rced13f72dka-1
bzrlib/ignores.py ignores.py-20060712153832-2von9l0t7p43ixsv-1
bzrlib/index.py index.py-20070712131115-lolkarso50vjr64s-1
bzrlib/info.py info.py-20050323235939-6bbfe7d9700b0b9b
bzrlib/inventory.py inventory.py-20050309040759-6648b84ca2005b37
bzrlib/knit.py knit.py-20051212171256-f056ac8f0fbe1bd9
bzrlib/log.py log.py-20050505065812-c40ce11702fe5fb1
bzrlib/mail_client.py mail_client.py-20070809192806-vuxt3t19srtpjpdn-1
bzrlib/memorytree.py memorytree.py-20060906023413-4wlkalbdpsxi2r4y-1
bzrlib/merge.py merge.py-20050513021216-953b65a438527106
bzrlib/multiparent.py __init__.py-20070410133617-n1jdhcc1n1mibarp-1
bzrlib/osutils.py osutils.py-20050309040759-eeaff12fbf77ac86
bzrlib/reconcile.py reweave_inventory.py-20051108164726-1e5e0934febac06e
bzrlib/remote.py remote.py-20060720103555-yeeg2x51vn0rbtdp-1
bzrlib/repofmt/knitrepo.py knitrepo.py-20070206081537-pyy4a00xdas0j4pf-1
bzrlib/repofmt/pack_repo.py pack_repo.py-20070813041115-gjv5ma7ktfqwsjgn-1
bzrlib/repofmt/weaverepo.py presplitout.py-20070125045333-wfav3tsh73oxu3zk-1
bzrlib/repository.py rev_storage.py-20051111201905-119e9401e46257e3
bzrlib/revisiontree.py revisiontree.py-20060724012533-bg8xyryhxd0o0i0h-1
bzrlib/smart/branch.py branch.py-20061124031907-mzh3pla28r83r97f-1
bzrlib/smart/medium.py medium.py-20061103051856-rgu2huy59fkz902q-1
bzrlib/smart/repository.py repository.py-20061128022038-vr5wy5bubyb8xttk-1
bzrlib/smart/request.py request.py-20061108095550-gunadhxmzkdjfeek-1
bzrlib/smart/server.py server.py-20061110062051-chzu10y32vx8gvur-1
bzrlib/store/__init__.py store.py-20050309040759-164dc5173d6406c2
bzrlib/store/text.py text.py-20050928201105-c26468dcb5d9b18b
bzrlib/store/versioned/__init__.py weavestore.py-20050907094258-88262e0434babab9
bzrlib/symbol_versioning.py symbol_versioning.py-20060105104851-9ecf8af605d15a80
bzrlib/tests/__init__.py selftest.py-20050531073622-8d0e3c8845c97a64
bzrlib/tests/blackbox/test_branch.py test_branch.py-20060524161337-noms9gmcwqqrfi8y-1
bzrlib/tests/blackbox/test_check.py test_check.py-20071024054728-mn44rt3z5hnqcbke-1
bzrlib/tests/blackbox/test_info.py test_info.py-20060215045507-bbdd2d34efab9e0a
bzrlib/tests/blackbox/test_locale.py test_lang.py-20060824204205-80v50j25qkuop7yn-1
bzrlib/tests/blackbox/test_log.py test_log.py-20060112090212-78f6ea560c868e24
bzrlib/tests/blackbox/test_push.py test_push.py-20060329002750-929af230d5d22663
bzrlib/tests/branch_implementations/__init__.py __init__.py-20060123013057-b12a52c3f361daf4
bzrlib/tests/branch_implementations/test_branch.py testbranch.py-20050711070244-121d632bc37d7253
bzrlib/tests/branch_implementations/test_hooks.py test_hooks.py-20070129154855-blhpwxmvjs07waei-1
bzrlib/tests/bzrdir_implementations/__init__.py __init__.py-20060131065642-34c39b54f42dd048
bzrlib/tests/bzrdir_implementations/test_bzrdir.py test_bzrdir.py-20060131065642-0ebeca5e30e30866
bzrlib/tests/commands/test_push.py test_push.py-20070525122003-gc1ob0ea0nueoqgj-1
bzrlib/tests/ftp_server.py ftpserver.py-20071019102346-61jbvdkrr70igauv-1
bzrlib/tests/interrepository_implementations/test_fetch.py test_fetch.py-20080425213627-j60cjh782ufm83ry-1
bzrlib/tests/interrepository_implementations/test_interrepository.py test_interrepository.py-20060220061411-1ec13fa99e5e3eee
bzrlib/tests/per_repository_reference/test_add_inventory.py test_add_inventory.p-20080220025549-nnm2s80it1lvcwnc-3
bzrlib/tests/repository_implementations/__init__.py __init__.py-20060131092037-9564957a7d4a841b
bzrlib/tests/repository_implementations/helpers.py helpers.py-20070924032407-m460yl9j5gu5ju85-2
bzrlib/tests/repository_implementations/test_check.py test_check.py-20070824124512-38g4d135gcqxo4zb-1
bzrlib/tests/repository_implementations/test_check_reconcile.py test_broken.py-20070928125406-62236394w0jpbpd6-2
bzrlib/tests/repository_implementations/test_commit_builder.py test_commit_builder.py-20060606110838-76e3ra5slucqus81-1
bzrlib/tests/repository_implementations/test_fetch.py test_fetch.py-20070814052151-5cxha9slx4c93uog-1
bzrlib/tests/repository_implementations/test_reconcile.py test_reconcile.py-20060223022332-572ef70a3288e369
bzrlib/tests/repository_implementations/test_repository.py test_repository.py-20060131092128-ad07f494f5c9d26c
bzrlib/tests/repository_implementations/test_statistics.py test_statistics.py-20070203082432-6738e8fl0mm7ikre-1
bzrlib/tests/test_branch.py test_branch.py-20060116013032-97819aa07b8ab3b5
bzrlib/tests/test_bundle.py test.py-20050630184834-092aa401ab9f039c
bzrlib/tests/test_bzrdir.py test_bzrdir.py-20060131065654-deba40eef51cf220
bzrlib/tests/test_config.py testconfig.py-20051011041908-742d0c15d8d8c8eb
bzrlib/tests/test_directory_service.py test_directory_servi-20080305221044-vr2mkvlsk8jypa2y-2
bzrlib/tests/test_errors.py test_errors.py-20060210110251-41aba2deddf936a8
bzrlib/tests/test_fetch.py testfetch.py-20050825090644-f73e07e7dfb1765a
bzrlib/tests/test_globbing.py test_glob.py-20061113075651-q63o2v35fm2ydk9x-2
bzrlib/tests/test_graph.py test_graph_walker.py-20070525030405-enq4r60hhi9xrujc-1
bzrlib/tests/test_http_response.py test_http_response.py-20060628233143-950b2a482a32505d
bzrlib/tests/test_ignores.py test_ignores.py-20060712172354-vqq9ln0t8di27v53-1
bzrlib/tests/test_knit.py test_knit.py-20051212171302-95d4c00dd5f11f2b
bzrlib/tests/test_log.py testlog.py-20050728115707-1a514809d7d49309
bzrlib/tests/test_merge.py testmerge.py-20050905070950-c1b5aa49ff911024
bzrlib/tests/test_merge_core.py test_merge_core.py-20050824132511-eb99b23a0eec641b
bzrlib/tests/test_remote.py test_remote.py-20060720103555-yeeg2x51vn0rbtdp-2
bzrlib/tests/test_repository.py test_repository.py-20060131075918-65c555b881612f4d
bzrlib/tests/test_selftest.py test_selftest.py-20051202044319-c110a115d8c0456a
bzrlib/tests/test_smart.py test_smart.py-20061122024551-ol0l0o0oofsu9b3t-2
bzrlib/tests/test_store.py teststore.py-20050826022702-f6caadb647395769
bzrlib/tests/test_transform.py test_transaction.py-20060105172520-b3ffb3946550e6c4
bzrlib/tests/test_transport.py testtransport.py-20050718175618-e5cdb99f4555ddce
bzrlib/tests/test_tsort.py testtsort.py-20051025073946-27da871c394d5be4
bzrlib/tests/test_upgrade.py test_upgrade.py-20051004040251-555fe1d2bae1bc71
bzrlib/tests/test_urlutils.py test_urlutils.py-20060502192900-46b1f9579987cf9c
bzrlib/tests/test_versionedfile.py test_versionedfile.py-20060222045249-db45c9ed14a1c2e5
bzrlib/tests/test_weave.py testknit.py-20050627023648-9833cc5562ffb785
bzrlib/tests/tree_implementations/__init__.py __init__.py-20060717075546-420s7b0bj9hzeowi-2
bzrlib/tests/tree_implementations/test_inv.py test_inv.py-20070312023226-0cdvk5uwhutis9vg-1
bzrlib/tests/tree_implementations/test_tree.py test_tree.py-20061215160206-usu7lwcj8aq2n3br-1
bzrlib/tests/workingtree_implementations/__init__.py __init__.py-20060203003124-b2aa5aca21a8bfad
bzrlib/tests/workingtree_implementations/test_workingtree.py test_workingtree.py-20060203003124-817757d3e31444fb
bzrlib/timestamp.py timestamp.py-20070306142322-ttbb9oulf3jotljd-1
bzrlib/trace.py trace.py-20050309040759-c8ed824bdcd4748a
bzrlib/transform.py transform.py-20060105172343-dd99e54394d91687
bzrlib/transport/__init__.py transport.py-20050711165921-4978aa7ce1285ad5
bzrlib/transport/ftp.py ftp.py-20051116161804-58dc9506548c2a53
bzrlib/transport/http/response.py _response.py-20060613154423-a2ci7hd4iw5c7fnt-1
bzrlib/transport/local.py local_transport.py-20050711165921-9b1f142bfe480c24
bzrlib/transport/remote.py ssh.py-20060608202016-c25gvf1ob7ypbus6-1
bzrlib/transport/trace.py trace.py-20070828055009-7kt0bbc4t4b92apz-1
bzrlib/tree.py tree.py-20050309040759-9d5f2496be663e77
bzrlib/tsort.py tsort.py-20051025073946-7808f6aaf7d07208
bzrlib/urlutils.py urlutils.py-20060502195429-e8a161ecf8fac004
bzrlib/versionedfile.py versionedfile.py-20060222045106-5039c71ee3b65490
bzrlib/weave.py knit.py-20050627021749-759c29984154256b
bzrlib/weave_commands.py weave_commands.py-20060320231507-8e9f300bffc1aa19
bzrlib/workingtree.py workingtree.py-20050511021032-29b6ec0a681e02e3
bzrlib/workingtree_4.py workingtree_4.py-20070208044105-5fgpc5j3ljlh5q6c-1
doc/developers/HACKING.txt HACKING-20050805200004-2a5dc975d870f78c
doc/en/user-guide/browsing_history.txt browsing_history.txt-20071121073725-0corxykv5irjal00-2
doc/en/user-guide/configuring_bazaar.txt configuring_bazaar.t-20071128000722-ncxiua259xwbdbg7-1
doc/en/user-guide/index.txt index.txt-20060622101119-tgwtdci8z769bjb9-2
doc/en/user-guide/organizing_branches.txt organizing_branches.-20071123154453-dk2mjhrg1vpjm5w2-3
setup.py setup.py-20050314065409-02f8a0a6e3f9bc70
tools/rst2html.py rst2html.py-20060817120932-gn177u8v0008txhu-1
------------------------------------------------------------
revno: 3504.4.13
revision-id:john at arbash-meinel.com-20080717122119-alnqlevrp4n3td2b
parent: john at arbash-meinel.com-20080717044957-xokssio0q76zy0q3
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: win32_find_files
timestamp: Thu 2008-07-17 07:21:19 -0500
message:
Clean up according to review comments.
modified:
bzrlib/_walkdirs_win32.pyx _walkdirs_win32.pyx-20080716220454-kweh3tgxez5dvw2l-2
bzrlib/osutils.py osutils.py-20050309040759-eeaff12fbf77ac86
bzrlib/tests/test_osutils.py test_osutils.py-20051201224856-e48ee24c12182989
------------------------------------------------------------
revno: 3504.4.12
revision-id:john at arbash-meinel.com-20080717044957-xokssio0q76zy0q3
parent: john at arbash-meinel.com-20080717043518-c1ncnoygo3ppew2f
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: win32_find_files
timestamp: Wed 2008-07-16 23:49:57 -0500
message:
A couple small cleanups, make test_osutils more correct
modified:
bzrlib/_walkdirs_win32.pyx _walkdirs_win32.pyx-20080716220454-kweh3tgxez5dvw2l-2
bzrlib/osutils.py osutils.py-20050309040759-eeaff12fbf77ac86
bzrlib/tests/test_osutils.py test_osutils.py-20051201224856-e48ee24c12182989
------------------------------------------------------------
revno: 3504.4.11
revision-id:john at arbash-meinel.com-20080717043518-c1ncnoygo3ppew2f
parent: john at arbash-meinel.com-20080717042644-rt8ofayxp8849t3s
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: win32_find_files
timestamp: Wed 2008-07-16 23:35:18 -0500
message:
A bit more reorganizing.
modified:
bzrlib/_walkdirs_win32.pyx _walkdirs_win32.pyx-20080716220454-kweh3tgxez5dvw2l-2
------------------------------------------------------------
revno: 3504.4.10
revision-id:john at arbash-meinel.com-20080717042644-rt8ofayxp8849t3s
parent: john at arbash-meinel.com-20080717040502-ql39j194cvqoy68o
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: win32_find_files
timestamp: Wed 2008-07-16 23:26:44 -0500
message:
Move the helpers to be standalone, rather than members
modified:
bzrlib/_walkdirs_win32.pyx _walkdirs_win32.pyx-20080716220454-kweh3tgxez5dvw2l-2
------------------------------------------------------------
revno: 3504.4.9
revision-id:john at arbash-meinel.com-20080717040502-ql39j194cvqoy68o
parent: john at arbash-meinel.com-20080717034613-3cqwmu9mfshqwyet
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: win32_find_files
timestamp: Wed 2008-07-16 23:05:02 -0500
message:
Switch to using a cdef object with readonly attributes.
modified:
bzrlib/_walkdirs_win32.pyx _walkdirs_win32.pyx-20080716220454-kweh3tgxez5dvw2l-2
------------------------------------------------------------
revno: 3504.4.8
revision-id:john at arbash-meinel.com-20080717034613-3cqwmu9mfshqwyet
parent: john at arbash-meinel.com-20080717024305-1odvs9kc7vqd3dum
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: win32_find_files
timestamp: Wed 2008-07-16 22:46:13 -0500
message:
Some code cleanups.
Remove extra comments.
Use 64 bit integer math when possible.
Use PyList_Append rather than foo.append()
Use PyUnicode_AsUTF8String rather than codecs.encode()
Make sure to raise an exception if the target directory doesn't exist.
Seems to have made a significant performance impact.
modified:
.bzrignore bzrignore-20050311232317-81f7b71efa2db11a
bzrlib/_walkdirs_win32.h _walkdirs_win32.h-20080716220454-kweh3tgxez5dvw2l-1
bzrlib/_walkdirs_win32.pyx _walkdirs_win32.pyx-20080716220454-kweh3tgxez5dvw2l-2
bzrlib/tests/test__walkdirs_win32.py test__walkdirs_win32-20080716220454-kweh3tgxez5dvw2l-3
------------------------------------------------------------
revno: 3504.4.7
revision-id:john at arbash-meinel.com-20080717024305-1odvs9kc7vqd3dum
parent: john at arbash-meinel.com-20080717023713-832g08rsq7emxh8f
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: win32_find_files
timestamp: Wed 2008-07-16 21:43:05 -0500
message:
Update the comment
modified:
bzrlib/_walkdirs_win32.pyx _walkdirs_win32.pyx-20080716220454-kweh3tgxez5dvw2l-2
------------------------------------------------------------
revno: 3504.4.6
revision-id:john at arbash-meinel.com-20080717023713-832g08rsq7emxh8f
parent: john at arbash-meinel.com-20080717022133-hcd78dqy2qn60drx
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: win32_find_files
timestamp: Wed 2008-07-16 21:37:13 -0500
message:
Start exposing the times on the stat, this now seems to be a complete walkdirs implementation.
modified:
bzrlib/_walkdirs_win32.pyx _walkdirs_win32.pyx-20080716220454-kweh3tgxez5dvw2l-2
bzrlib/tests/test_osutils.py test_osutils.py-20051201224856-e48ee24c12182989
------------------------------------------------------------
revno: 3504.4.5
revision-id:john at arbash-meinel.com-20080717022133-hcd78dqy2qn60drx
parent: john at arbash-meinel.com-20080716232929-pcyg06005uxpveav
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: win32_find_files
timestamp: Wed 2008-07-16 21:21:33 -0500
message:
Add tests to ensure that you can skip subdirs, start exposing the function.
modified:
bzrlib/osutils.py osutils.py-20050309040759-eeaff12fbf77ac86
bzrlib/tests/test__walkdirs_win32.py test__walkdirs_win32-20080716220454-kweh3tgxez5dvw2l-3
bzrlib/tests/test_osutils.py test_osutils.py-20051201224856-e48ee24c12182989
------------------------------------------------------------
revno: 3504.4.4
revision-id:john at arbash-meinel.com-20080716232929-pcyg06005uxpveav
parent: john at arbash-meinel.com-20080716220622-m6zsz00j08co7l5g
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: win32_find_files
timestamp: Wed 2008-07-16 18:29:29 -0500
message:
We have walkdirs basically working, only without timestamps
modified:
bzrlib/_walkdirs_win32.pyx _walkdirs_win32.pyx-20080716220454-kweh3tgxez5dvw2l-2
bzrlib/osutils.py osutils.py-20050309040759-eeaff12fbf77ac86
bzrlib/tests/test__walkdirs_win32.py test__walkdirs_win32-20080716220454-kweh3tgxez5dvw2l-3
------------------------------------------------------------
revno: 3504.4.3
revision-id:john at arbash-meinel.com-20080716220622-m6zsz00j08co7l5g
parent: john at arbash-meinel.com-20080626211800-mb234d9wpgxklotf
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: win32_find_files
timestamp: Wed 2008-07-16 17:06:22 -0500
message:
Start working on an extension specifically for win32,
This will wrap the win32 FindFile code into nice objects for higher levels.
Mostly, I'm cribbing the code from other places like posixmodule.c
I'm doing it in Pyrex, though, so I get a couple conveniences, like
not having to watch all of my allocations, etc.
I might *want* to do that for performance before all is said and done,
but for now, get it working.
ATM, it just iterates, but doesn't actually work out any data.
added:
bzrlib/_walkdirs_win32.h _walkdirs_win32.h-20080716220454-kweh3tgxez5dvw2l-1
bzrlib/_walkdirs_win32.pyx _walkdirs_win32.pyx-20080716220454-kweh3tgxez5dvw2l-2
bzrlib/tests/test__walkdirs_win32.py test__walkdirs_win32-20080716220454-kweh3tgxez5dvw2l-3
modified:
.bzrignore bzrignore-20050311232317-81f7b71efa2db11a
bzrlib/osutils.py osutils.py-20050309040759-eeaff12fbf77ac86
bzrlib/tests/__init__.py selftest.py-20050531073622-8d0e3c8845c97a64
setup.py setup.py-20050314065409-02f8a0a6e3f9bc70
------------------------------------------------------------
revno: 3504.4.2
revision-id:john at arbash-meinel.com-20080626211800-mb234d9wpgxklotf
parent: john at arbash-meinel.com-20080626164622-s0dpqlxzdybnmcb8
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: win32_find_files
timestamp: Thu 2008-06-26 16:18:00 -0500
message:
Add a test case that shows the mtime is not being returned correctly.
modified:
bzrlib/tests/test_osutils.py test_osutils.py-20051201224856-e48ee24c12182989
------------------------------------------------------------
revno: 3504.4.1
revision-id:john at arbash-meinel.com-20080626164622-s0dpqlxzdybnmcb8
parent: pqm at pqm.ubuntu.com-20080619070027-3xv1vy81m3ix2oup
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: win32_find_files
timestamp: Thu 2008-06-26 11:46:22 -0500
message:
Write an alternative 'walkdirs' implementation that uses win32 apis.
Basically, calling nt.lstat() lots of times is really slow, when we can get the
results right away from the FindFiles api.
In my tests with ~9000 entries, it changes 'bzr status' from 4+s => 1.2s
modified:
bzrlib/osutils.py osutils.py-20050309040759-eeaff12fbf77ac86
bzrlib/tests/test_osutils.py test_osutils.py-20051201224856-e48ee24c12182989
=== added file 'bzrlib/_walkdirs_win32.h'
--- a/bzrlib/_walkdirs_win32.h 1970-01-01 00:00:00 +0000
+++ b/bzrlib/_walkdirs_win32.h 2008-07-17 03:46:13 +0000
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2007 Canonical Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* Header includes, etc for _walkdirs_win32
+ * Pyrex doesn't support #define, and defining WIN32_LEAN_AND_MEAN makes
+ * importing windows.h a lot less painful.
+ */
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
=== added file 'bzrlib/_walkdirs_win32.pyx'
--- a/bzrlib/_walkdirs_win32.pyx 1970-01-01 00:00:00 +0000
+++ b/bzrlib/_walkdirs_win32.pyx 2008-07-17 12:21:19 +0000
@@ -0,0 +1,283 @@
+# Copyright (C) 2008 Canonical Ltd
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+"""Helper functions for Walkdirs on win32."""
+
+
+cdef extern from "_walkdirs_win32.h":
+ cdef struct _HANDLE:
+ pass
+ ctypedef _HANDLE *HANDLE
+ ctypedef unsigned long DWORD
+ ctypedef long long __int64
+ ctypedef unsigned short WCHAR
+ cdef struct _FILETIME:
+ DWORD dwHighDateTime
+ DWORD dwLowDateTime
+ ctypedef _FILETIME FILETIME
+
+ cdef struct _WIN32_FIND_DATAW:
+ DWORD dwFileAttributes
+ FILETIME ftCreationTime
+ FILETIME ftLastAccessTime
+ FILETIME ftLastWriteTime
+ DWORD nFileSizeHigh
+ DWORD nFileSizeLow
+ # Some reserved stuff here
+ WCHAR cFileName[260] # MAX_PATH
+ WCHAR cAlternateFilename[14]
+
+ # We have to use the typedef trick, otherwise pyrex uses:
+ # struct WIN32_FIND_DATAW
+ # which fails due to 'incomplete type'
+ ctypedef _WIN32_FIND_DATAW WIN32_FIND_DATAW
+
+ cdef HANDLE INVALID_HANDLE_VALUE
+ cdef HANDLE FindFirstFileW(WCHAR *path, WIN32_FIND_DATAW *data)
+ cdef int FindNextFileW(HANDLE search, WIN32_FIND_DATAW *data)
+ cdef int FindClose(HANDLE search)
+
+ cdef DWORD FILE_ATTRIBUTE_READONLY
+ cdef DWORD FILE_ATTRIBUTE_DIRECTORY
+ cdef int ERROR_NO_MORE_FILES
+
+ cdef int GetLastError()
+
+ # Wide character functions
+ DWORD wcslen(WCHAR *)
+
+
+cdef extern from "Python.h":
+ WCHAR *PyUnicode_AS_UNICODE(object)
+ Py_ssize_t PyUnicode_GET_SIZE(object)
+ object PyUnicode_FromUnicode(WCHAR *, Py_ssize_t)
+ int PyList_Append(object, object) except -1
+ object PyUnicode_AsUTF8String(object)
+
+
+import operator
+import stat
+
+from bzrlib import osutils
+
+
+cdef class _Win32Stat:
+ """Represent a 'stat' result generated from WIN32_FIND_DATA"""
+
+ cdef readonly int st_mode
+ cdef readonly double st_ctime
+ cdef readonly double st_mtime
+ cdef readonly double st_atime
+ cdef readonly __int64 st_size
+
+ # os.stat always returns 0, so we hard code it here
+ cdef readonly int st_dev
+ cdef readonly int st_ino
+
+ def __repr__(self):
+ """Repr is the same as a Stat object.
+
+ (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)
+ """
+ return repr((self.st_mode, 0, 0, 0, 0, 0, self.st_size, self.st_atime,
+ self.st_mtime, self.st_ctime))
+
+
+cdef object _get_name(WIN32_FIND_DATAW *data):
+ """Extract the Unicode name for this file/dir."""
+ return PyUnicode_FromUnicode(data.cFileName,
+ wcslen(data.cFileName))
+
+
+cdef int _get_mode_bits(WIN32_FIND_DATAW *data):
+ cdef int mode_bits
+
+ mode_bits = 0100666 # writeable file, the most common
+ if data.dwFileAttributes & FILE_ATTRIBUTE_READONLY == FILE_ATTRIBUTE_READONLY:
+ mode_bits ^= 0222 # remove the write bits
+ if data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY == FILE_ATTRIBUTE_DIRECTORY:
+ # Remove the FILE bit, set the DIR bit, and set the EXEC bits
+ mode_bits ^= 0140111
+ return mode_bits
+
+
+cdef __int64 _get_size(WIN32_FIND_DATAW *data):
+ # Pyrex casts a DWORD into a PyLong anyway, so it is safe to do << 32
+ # on a DWORD
+ return ((<__int64>data.nFileSizeHigh) << 32) + data.nFileSizeLow
+
+
+cdef double _ftime_to_timestamp(FILETIME *ft):
+ """Convert from a FILETIME struct into a floating point timestamp.
+
+ The fields of a FILETIME structure are the hi and lo part
+ of a 64-bit value expressed in 100 nanosecond units.
+ 1e7 is one second in such units; 1e-7 the inverse.
+ 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
+ It also uses the epoch 1601-01-01 rather than 1970-01-01
+ (taken from posixmodule.c)
+ """
+ cdef __int64 val
+ # NB: This gives slightly different results versus casting to a 64-bit
+ # integer and doing integer math before casting into a floating
+ # point number. But the difference is in the sub millisecond range,
+ # which doesn't seem critical here.
+ # secs between epochs: 11,644,473,600
+ val = ((<__int64>ft.dwHighDateTime) << 32) + ft.dwLowDateTime
+ return (val * 1.0e-7) - 11644473600.0
+
+
+cdef int _should_skip(WIN32_FIND_DATAW *data):
+ """Is this '.' or '..' so we should skip it?"""
+ if (data.cFileName[0] != c'.'):
+ return 0
+ if data.cFileName[1] == c'\0':
+ return 1
+ if data.cFileName[1] == c'.' and data.cFileName[2] == c'\0':
+ return 1
+ return 0
+
+
+cdef class Win32Finder:
+ """A class which encapsulates the search of files in a given directory"""
+
+ cdef object _top
+ cdef object _prefix
+
+ cdef object _directory_kind
+ cdef object _file_kind
+
+ cdef object _pending
+ cdef object _last_dirblock
+
+ def __init__(self, top, prefix=""):
+ self._top = top
+ self._prefix = prefix
+
+ self._directory_kind = osutils._directory_kind
+ self._file_kind = osutils._formats[stat.S_IFREG]
+
+ self._pending = [(osutils.safe_utf8(prefix), osutils.safe_unicode(top))]
+ self._last_dirblock = None
+
+ def __iter__(self):
+ return self
+
+ cdef object _get_kind(self, WIN32_FIND_DATAW *data):
+ if data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY:
+ return self._directory_kind
+ return self._file_kind
+
+ cdef _Win32Stat _get_stat_value(self, WIN32_FIND_DATAW *data):
+ """Get the filename and the stat information."""
+ cdef _Win32Stat statvalue
+
+ statvalue = _Win32Stat()
+ statvalue.st_mode = _get_mode_bits(data)
+ statvalue.st_ctime = _ftime_to_timestamp(&data.ftCreationTime)
+ statvalue.st_mtime = _ftime_to_timestamp(&data.ftLastWriteTime)
+ statvalue.st_atime = _ftime_to_timestamp(&data.ftLastAccessTime)
+ statvalue.st_size = _get_size(data)
+ statvalue.st_ino = 0
+ statvalue.st_dev = 0
+ return statvalue
+
+ def _get_files_in(self, directory, relprefix):
+ cdef WIN32_FIND_DATAW search_data
+ cdef HANDLE hFindFile
+ cdef int last_err
+ cdef WCHAR *query
+ cdef int result
+
+ top_star = directory + '*'
+
+ dirblock = []
+
+ query = PyUnicode_AS_UNICODE(top_star)
+ hFindFile = FindFirstFileW(query, &search_data)
+ if hFindFile == INVALID_HANDLE_VALUE:
+ # Raise an exception? This path doesn't seem to exist
+ raise WindowsError(GetLastError(), top_star)
+
+ try:
+ result = 1
+ while result:
+ # Skip '.' and '..'
+ if _should_skip(&search_data):
+ result = FindNextFileW(hFindFile, &search_data)
+ continue
+ name_unicode = _get_name(&search_data)
+ name_utf8 = PyUnicode_AsUTF8String(name_unicode)
+ relpath = relprefix + name_utf8
+ abspath = directory + name_unicode
+ PyList_Append(dirblock,
+ (relpath, name_utf8,
+ self._get_kind(&search_data),
+ self._get_stat_value(&search_data),
+ abspath))
+
+ result = FindNextFileW(hFindFile, &search_data)
+ # FindNextFileW sets GetLastError() == ERROR_NO_MORE_FILES when it
+ # actually finishes. If we have anything else, then we have a
+ # genuine problem
+ last_err = GetLastError()
+ if last_err != ERROR_NO_MORE_FILES:
+ raise WindowsError(last_err)
+ finally:
+ result = FindClose(hFindFile)
+ if result == 0:
+ last_err = GetLastError()
+ pass
+ return dirblock
+
+ cdef _update_pending(self):
+ """If we had a result before, add the subdirs to pending."""
+ if self._last_dirblock is not None:
+ # push the entries left in the dirblock onto the pending queue
+ # we do this here, because we allow the user to modified the
+ # queue before the next iteration
+ for d in reversed(self._last_dirblock):
+ if d[2] == self._directory_kind:
+ self._pending.append((d[0], d[-1]))
+ self._last_dirblock = None
+
+ def __next__(self):
+ self._update_pending()
+ if not self._pending:
+ raise StopIteration()
+ relroot, top = self._pending.pop()
+ # NB: At the moment Pyrex doesn't support Unicode literals, which means
+ # that all of these string literals are going to be upcasted to Unicode
+ # at runtime... :(
+ # Maybe we could use unicode(x) during __init__?
+ if relroot:
+ relprefix = relroot + '/'
+ else:
+ relprefix = ''
+ top_slash = top + '/'
+
+ dirblock = self._get_files_in(top_slash, relprefix)
+ dirblock.sort(key=operator.itemgetter(1))
+ self._last_dirblock = dirblock
+ return (relroot, top), dirblock
+
+
+def _walkdirs_utf8_win32_find_file(top, prefix=""):
+ """Implement a version of walkdirs_utf8 for win32.
+
+ This uses the find files api to both list the files and to stat them.
+ """
+ return Win32Finder(top, prefix=prefix)
=== added file 'bzrlib/tests/test__walkdirs_win32.py'
--- a/bzrlib/tests/test__walkdirs_win32.py 1970-01-01 00:00:00 +0000
+++ b/bzrlib/tests/test__walkdirs_win32.py 2008-07-17 03:46:13 +0000
@@ -0,0 +1,122 @@
+# Copyright (C) 2008 Canonical Ltd
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+"""Tests for the win32 walkdir extension."""
+
+import errno
+
+from bzrlib import tests
+
+
+class _WalkdirsWin32Feature(tests.Feature):
+
+ def _probe(self):
+ try:
+ import bzrlib._walkdirs_win32
+ except ImportError:
+ return False
+ else:
+ return True
+
+ def feature_name(self):
+ return 'bzrlib._walkdirs_win32'
+
+WalkdirsWin32Feature = _WalkdirsWin32Feature()
+
+
+class TestWin32Finder(tests.TestCaseInTempDir):
+
+ _test_needs_features = [WalkdirsWin32Feature]
+
+ def setUp(self):
+ super(TestWin32Finder, self).setUp()
+ from bzrlib._walkdirs_win32 import (
+ _walkdirs_utf8_win32_find_file
+ )
+ self.walkdirs_utf8 = _walkdirs_utf8_win32_find_file
+
+ def _remove_stat_from_dirblock(self, dirblock):
+ return [info[:3] + info[4:] for info in dirblock]
+
+ def assertWalkdirs(self, expected, top, prefix=''):
+ finder = self.walkdirs_utf8(top, prefix=prefix)
+ result = []
+ for dirname, dirblock in finder:
+ result.append((dirname, self._remove_stat_from_dirblock(dirblock)))
+ self.assertEqual(expected, result)
+
+ def test_empty_directory(self):
+ self.assertWalkdirs([(('', u'.'), [])], u'.')
+
+ def test_file_in_dir(self):
+ self.build_tree(['foo'])
+ self.assertWalkdirs([
+ (('', u'.'), [('foo', 'foo', 'file', u'./foo')])
+ ], u'.')
+
+ def test_subdir(self):
+ self.build_tree(['foo', 'bar/', 'bar/baz'])
+ self.assertWalkdirs([
+ (('', u'.'), [('bar', 'bar', 'directory', u'./bar'),
+ ('foo', 'foo', 'file', u'./foo'),
+ ]),
+ (('bar', u'./bar'), [('bar/baz', 'baz', 'file', u'./bar/baz')]),
+ ], '.')
+ self.assertWalkdirs([
+ (('xxx', u'.'), [('xxx/bar', 'bar', 'directory', u'./bar'),
+ ('xxx/foo', 'foo', 'file', u'./foo'),
+ ]),
+ (('xxx/bar', u'./bar'), [('xxx/bar/baz', 'baz', 'file', u'./bar/baz')]),
+ ], '.', prefix='xxx')
+ self.assertWalkdirs([
+ (('', u'bar'), [('baz', 'baz', 'file', u'bar/baz')]),
+ ], 'bar')
+
+ def test_skip_subdir(self):
+ self.build_tree(['a/', 'b/', 'c/', 'a/aa', 'b/bb', 'c/cc'])
+ base_dirblock = [('a', 'a', 'directory', u'./a'),
+ ('b', 'b', 'directory', u'./b'),
+ ('c', 'c', 'directory', u'./c'),
+ ]
+ self.assertWalkdirs([
+ (('', u'.'), base_dirblock),
+ (('a', u'./a'), [('a/aa', 'aa', 'file', u'./a/aa')]),
+ (('b', u'./b'), [('b/bb', 'bb', 'file', u'./b/bb')]),
+ (('c', u'./c'), [('c/cc', 'cc', 'file', u'./c/cc')]),
+ ], '.')
+
+ walker = self.walkdirs_utf8('.')
+ dir_info, first_dirblock = walker.next()
+ self.assertEqual(('', u'.'), dir_info)
+ self.assertEqual(base_dirblock,
+ self._remove_stat_from_dirblock(first_dirblock))
+ # Now, remove 'b' and it should be skipped on the next round
+ del first_dirblock[1]
+ dir_info, second_dirblock = walker.next()
+ second_dirblock = self._remove_stat_from_dirblock(second_dirblock)
+ self.assertEqual(('a', u'./a'), dir_info)
+ self.assertEqual([('a/aa', 'aa', 'file', u'./a/aa')], second_dirblock)
+ dir_info, third_dirblock = walker.next()
+ third_dirblock = self._remove_stat_from_dirblock(third_dirblock)
+ self.assertEqual(('c', u'./c'), dir_info)
+ self.assertEqual([('c/cc', 'cc', 'file', u'./c/cc')], third_dirblock)
+
+ def test_missing_dir(self):
+ e = self.assertRaises(WindowsError, list,
+ self.walkdirs_utf8(u'no_such_dir'))
+ self.assertEqual(errno.ENOENT, e.errno)
+ self.assertEqual(3, e.winerror)
+ self.assertEqual((3, u'no_such_dir/*'), e.args)
=== modified file '.bzrignore'
--- a/.bzrignore 2008-02-18 21:17:42 +0000
+++ b/.bzrignore 2008-07-17 03:46:13 +0000
@@ -40,6 +40,7 @@
doc/developers/performance.png
bzrlib/_dirstate_helpers_c.c
bzrlib/_knit_load_data_c.c
+bzrlib/_walkdirs_win32.c
doc/en/release-notes/NEWS.txt
doc/en/developer-guide/HACKING.txt
doc/en/user-reference/bzr_man.txt
=== modified file 'NEWS'
--- a/NEWS 2008-07-17 09:58:00 +0000
+++ b/NEWS 2008-07-17 12:58:30 +0000
@@ -10,6 +10,39 @@
FEATURES:
+
+ IMPROVEMENTS:
+
+ * Implemented a custom ``walkdirs_utf8`` implementation for win32.
+ This uses a pyrex extension to get direct access to the
+ ``FindFirstFileW`` style apis, rather than using ``listdir`` +
+ ``lstat``. Shows a very strong improvement in commands like
+ ``status`` and ``diff`` which have to iterate the working tree.
+ Anywhere from 2x-6x faster depending on the size of the tree (bigger
+ trees, bigger benefit.) (John Arbash Meinel)
+
+
+ BUG FIXES:
+
+
+ DOCUMENTATION:
+
+
+ TESTING:
+
+
+ API CHANGES:
+
+
+ INTERNALS:
+
+
+
+bzr 1.6beta3 2008-07-17
+-----------------------
+
+ FEATURES:
+
* New ``pre_change_branch_tip`` hook that is called before the
branch tip is moved, while the branch is write-locked. See the User
Reference for signature details. (Andrew Bennetts)
=== modified file 'bzrlib/osutils.py'
--- a/bzrlib/osutils.py 2008-06-26 17:18:55 +0000
+++ b/bzrlib/osutils.py 2008-07-17 12:55:11 +0000
@@ -53,6 +53,7 @@
)
""")
+
import bzrlib
from bzrlib import symbol_versioning
from bzrlib.symbol_versioning import (
@@ -1193,8 +1194,14 @@
pass to os functions to affect the file in question. (such as os.lstat)
"""
fs_encoding = _fs_enc.upper()
- if (sys.platform == 'win32' or
- fs_encoding not in ('UTF-8', 'US-ASCII', 'ANSI_X3.4-1968')): # ascii
+ if sys.platform == 'win32':
+ try:
+ from bzrlib._walkdirs_win32 import _walkdirs_utf8_win32_find_file
+ except ImportError:
+ return _walkdirs_unicode_to_utf8(top, prefix=prefix)
+ else:
+ return _walkdirs_utf8_win32_find_file(top, prefix=prefix)
+ if fs_encoding not in ('UTF-8', 'US-ASCII', 'ANSI_X3.4-1968'): # ascii
return _walkdirs_unicode_to_utf8(top, prefix=prefix)
else:
return _walkdirs_fs_utf8(top, prefix=prefix)
=== modified file 'bzrlib/tests/__init__.py'
--- a/bzrlib/tests/__init__.py 2008-07-14 07:47:45 +0000
+++ b/bzrlib/tests/__init__.py 2008-07-17 12:55:11 +0000
@@ -2796,6 +2796,7 @@
'bzrlib.tests.test_versionedfile',
'bzrlib.tests.test_version',
'bzrlib.tests.test_version_info',
+ 'bzrlib.tests.test__walkdirs_win32',
'bzrlib.tests.test_weave',
'bzrlib.tests.test_whitebox',
'bzrlib.tests.test_win32utils',
=== modified file 'bzrlib/tests/test_osutils.py'
--- a/bzrlib/tests/test_osutils.py 2008-06-11 03:56:46 +0000
+++ b/bzrlib/tests/test_osutils.py 2008-07-17 12:21:19 +0000
@@ -16,16 +16,19 @@
"""Tests for the osutils wrapper."""
+from cStringIO import StringIO
import errno
import os
import socket
import stat
import sys
+import time
import bzrlib
from bzrlib import (
errors,
osutils,
+ tests,
win32utils,
)
from bzrlib.errors import BzrBadParameterNotUnicode, InvalidURL
@@ -46,7 +49,8 @@
from bzrlib.tests.file_utils import (
FakeReadFile,
)
-from cStringIO import StringIO
+from bzrlib.tests.test__walkdirs_win32 import WalkdirsWin32Feature
+
class TestOSUtils(TestCaseInTempDir):
@@ -974,6 +978,99 @@
self._filter_out_stat(result)
self.assertEqual(expected_dirblocks, result)
+ def test__walkdirs_utf_win32_find_file(self):
+ self.requireFeature(WalkdirsWin32Feature)
+ self.requireFeature(tests.UnicodeFilenameFeature)
+ from bzrlib._walkdirs_win32 import _walkdirs_utf8_win32_find_file
+ name0u = u'0file-\xb6'
+ name1u = u'1dir-\u062c\u0648'
+ name2u = u'2file-\u0633'
+ tree = [
+ name0u,
+ name1u + '/',
+ name1u + '/' + name0u,
+ name1u + '/' + name1u + '/',
+ name2u,
+ ]
+ self.build_tree(tree)
+ name0 = name0u.encode('utf8')
+ name1 = name1u.encode('utf8')
+ name2 = name2u.encode('utf8')
+
+ # All of the abspaths should be in unicode, all of the relative paths
+ # should be in utf8
+ expected_dirblocks = [
+ (('', '.'),
+ [(name0, name0, 'file', './' + name0u),
+ (name1, name1, 'directory', './' + name1u),
+ (name2, name2, 'file', './' + name2u),
+ ]
+ ),
+ ((name1, './' + name1u),
+ [(name1 + '/' + name0, name0, 'file', './' + name1u
+ + '/' + name0u),
+ (name1 + '/' + name1, name1, 'directory', './' + name1u
+ + '/' + name1u),
+ ]
+ ),
+ ((name1 + '/' + name1, './' + name1u + '/' + name1u),
+ [
+ ]
+ ),
+ ]
+ result = list(_walkdirs_utf8_win32_find_file(u'.'))
+ self._filter_out_stat(result)
+ self.assertEqual(expected_dirblocks, result)
+
+ def assertStatIsCorrect(self, path, win32stat):
+ os_stat = os.stat(path)
+ self.assertEqual(os_stat.st_size, win32stat.st_size)
+ self.assertAlmostEqual(os_stat.st_mtime, win32stat.st_mtime, places=4)
+ self.assertAlmostEqual(os_stat.st_ctime, win32stat.st_ctime, places=4)
+ self.assertAlmostEqual(os_stat.st_atime, win32stat.st_atime, places=4)
+ self.assertEqual(os_stat.st_dev, win32stat.st_dev)
+ self.assertEqual(os_stat.st_ino, win32stat.st_ino)
+ self.assertEqual(os_stat.st_mode, win32stat.st_mode)
+
+ def test__walkdirs_utf_win32_find_file_stat_file(self):
+ """make sure our Stat values are valid"""
+ self.requireFeature(WalkdirsWin32Feature)
+ self.requireFeature(tests.UnicodeFilenameFeature)
+ from bzrlib._walkdirs_win32 import _walkdirs_utf8_win32_find_file
+ name0u = u'0file-\xb6'
+ name0 = name0u.encode('utf8')
+ self.build_tree([name0u])
+ # I hate to sleep() here, but I'm trying to make the ctime different
+ # from the mtime
+ time.sleep(2)
+ f = open(name0u, 'ab')
+ try:
+ f.write('just a small update')
+ finally:
+ f.close()
+
+ result = list(_walkdirs_utf8_win32_find_file(u'.'))
+ entry = result[0][1][0]
+ self.assertEqual((name0, name0, 'file'), entry[:3])
+ self.assertEqual(u'./' + name0u, entry[4])
+ self.assertStatIsCorrect(entry[4], entry[3])
+ self.assertNotEqual(entry[3].st_mtime, entry[3].st_ctime)
+
+ def test__walkdirs_utf_win32_find_file_stat_directory(self):
+ """make sure our Stat values are valid"""
+ self.requireFeature(WalkdirsWin32Feature)
+ self.requireFeature(tests.UnicodeFilenameFeature)
+ from bzrlib._walkdirs_win32 import _walkdirs_utf8_win32_find_file
+ name0u = u'0dir-\u062c\u0648'
+ name0 = name0u.encode('utf8')
+ self.build_tree([name0u + '/'])
+
+ result = list(_walkdirs_utf8_win32_find_file(u'.'))
+ entry = result[0][1][0]
+ self.assertEqual((name0, name0, 'directory'), entry[:3])
+ self.assertEqual(u'./' + name0u, entry[4])
+ self.assertStatIsCorrect(entry[4], entry[3])
+
def assertPathCompare(self, path_less, path_greater):
"""check that path_less and path_greater compare correctly."""
self.assertEqual(0, osutils.compare_paths_prefix_order(
=== modified file 'setup.py'
--- a/setup.py 2008-07-02 16:52:12 +0000
+++ b/setup.py 2008-07-17 12:55:11 +0000
@@ -226,6 +226,8 @@
add_pyrex_extension('bzrlib._dirstate_helpers_c')
add_pyrex_extension('bzrlib._knit_load_data_c')
+if sys.platform == 'win32':
+ add_pyrex_extension('bzrlib._walkdirs_win32')
ext_modules.append(Extension('bzrlib._patiencediff_c', ['bzrlib/_patiencediff_c.c']))
More information about the bazaar-commits
mailing list