Page MenuHomestyx hydra

No OneTemporary

diff --git a/resources/sql/patches/006.repository.sql b/resources/sql/patches/006.repository.sql
index 569437c2c1..fdca9e5517 100644
--- a/resources/sql/patches/006.repository.sql
+++ b/resources/sql/patches/006.repository.sql
@@ -1,42 +1,42 @@
create table phabricator_repository.repository_commitdata (
id int unsigned not null auto_increment primary key,
commitID int unsigned not null,
authorName varchar(255) not null,
commitMessage longblob not null,
unique key (commitID),
key (authorName)
);
ALTER TABLE phabricator_worker.worker_task drop priority;
ALTER TABLE phabricator_worker.worker_task drop key leaseOwner;
ALTER TABLE phabricator_worker.worker_task drop key (leaseOwner(16));
create table phabricator_repository.repository_path (
id int unsigned not null auto_increment primary key,
- path varchar(512) not null,
+ path varchar(512) binary not null,
unique key (path)
);
create table phabricator_repository.repository_pathchange (
repositoryID int unsigned NOT NULL,
pathID int unsigned NOT NULL,
commitID int unsigned NOT NULL,
targetPathID int unsigned,
targetCommitID int unsigned,
changeType int unsigned NOT NULL,
fileType int unsigned NOT NULL,
isDirect bool NOT NULL,
commitSequence int unsigned NOT NULL,
primary key (commitID, pathID),
key (repositoryID, pathID, commitSequence)
);
create table phabricator_repository.repository_filesystem (
repositoryID int unsigned not null,
parentID int unsigned not null,
svnCommit int unsigned not null,
pathID int unsigned not null,
existed bool not null,
fileType int unsigned not null,
primary key (repositoryID, parentID, svnCommit, pathID)
);
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
index 5eef3533c0..f130884b9b 100644
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -1,628 +1,630 @@
<?php
/**
* This file is automatically generated. Use 'phutil_mapper.php' to rebuild it.
* @generated
*/
phutil_register_library_map(array(
'class' =>
array(
'Aphront400Response' => 'aphront/response/400',
'Aphront404Response' => 'aphront/response/404',
'AphrontAjaxResponse' => 'aphront/response/ajax',
'AphrontApplicationConfiguration' => 'aphront/applicationconfiguration',
'AphrontController' => 'aphront/controller',
'AphrontDatabaseConnection' => 'storage/connection/base',
'AphrontDefaultApplicationConfiguration' => 'aphront/default/configuration',
'AphrontDefaultApplicationController' => 'aphront/default/controller',
'AphrontDialogResponse' => 'aphront/response/dialog',
'AphrontDialogView' => 'view/dialog',
'AphrontErrorView' => 'view/form/error',
'AphrontException' => 'aphront/exception/base',
'AphrontFileResponse' => 'aphront/response/file',
'AphrontFormCheckboxControl' => 'view/form/control/checkbox',
'AphrontFormControl' => 'view/form/control/base',
'AphrontFormDividerControl' => 'view/form/control/divider',
'AphrontFormFileControl' => 'view/form/control/file',
'AphrontFormMarkupControl' => 'view/form/control/markup',
'AphrontFormPasswordControl' => 'view/form/control/password',
'AphrontFormRecaptchaControl' => 'view/form/control/recaptcha',
'AphrontFormSelectControl' => 'view/form/control/select',
'AphrontFormStaticControl' => 'view/form/control/static',
'AphrontFormSubmitControl' => 'view/form/control/submit',
'AphrontFormTextAreaControl' => 'view/form/control/textarea',
'AphrontFormTextControl' => 'view/form/control/text',
'AphrontFormTokenizerControl' => 'view/form/control/tokenizer',
'AphrontFormView' => 'view/form/base',
'AphrontHeadsupActionListView' => 'view/layout/headsup/actionlist',
'AphrontHeadsupActionView' => 'view/layout/headsup/action',
'AphrontMySQLDatabaseConnection' => 'storage/connection/mysql',
'AphrontNullView' => 'view/null',
'AphrontPageView' => 'view/page/base',
'AphrontPanelView' => 'view/layout/panel',
'AphrontQueryConnectionException' => 'storage/exception/connection',
'AphrontQueryConnectionLostException' => 'storage/exception/connectionlost',
'AphrontQueryCountException' => 'storage/exception/count',
'AphrontQueryDuplicateKeyException' => 'storage/exception/duplicatekey',
'AphrontQueryException' => 'storage/exception/base',
'AphrontQueryObjectMissingException' => 'storage/exception/objectmissing',
'AphrontQueryParameterException' => 'storage/exception/parameter',
'AphrontQueryRecoverableException' => 'storage/exception/recoverable',
'AphrontRedirectException' => 'aphront/exception/redirect',
'AphrontRedirectResponse' => 'aphront/response/redirect',
'AphrontRequest' => 'aphront/request',
'AphrontRequestFailureView' => 'view/page/failure',
'AphrontResponse' => 'aphront/response/base',
'AphrontSideNavView' => 'view/layout/sidenav',
'AphrontTableView' => 'view/control/table',
'AphrontURIMapper' => 'aphront/mapper',
'AphrontView' => 'view/base',
'AphrontWebpageResponse' => 'aphront/response/webpage',
'CelerityAPI' => 'infrastructure/celerity/api',
'CelerityResourceController' => 'infrastructure/celerity/controller',
'CelerityResourceMap' => 'infrastructure/celerity/map',
'CelerityStaticResourceResponse' => 'infrastructure/celerity/response',
'ConduitAPIMethod' => 'applications/conduit/method/base',
'ConduitAPIRequest' => 'applications/conduit/protocol/request',
'ConduitAPI_conduit_connect_Method' => 'applications/conduit/method/conduit/connect',
'ConduitAPI_conduit_ping_Method' => 'applications/conduit/method/conduit/ping',
'ConduitAPI_differential_creatediff_Method' => 'applications/conduit/method/differential/creatediff',
'ConduitAPI_differential_createrevision_Method' => 'applications/conduit/method/differential/createrevision',
'ConduitAPI_differential_find_Method' => 'applications/conduit/method/differential/find',
'ConduitAPI_differential_getcommitmessage_Method' => 'applications/conduit/method/differential/getcommitmessage',
'ConduitAPI_differential_getcommitpaths_Method' => 'applications/conduit/method/differential/getcommitpaths',
'ConduitAPI_differential_getdiff_Method' => 'applications/conduit/method/differential/getdiff',
'ConduitAPI_differential_markcommitted_Method' => 'applications/conduit/method/differential/markcommitted',
'ConduitAPI_differential_parsecommitmessage_Method' => 'applications/conduit/method/differential/parsecommitmessage',
'ConduitAPI_differential_setdiffproperty_Method' => 'applications/conduit/method/differential/setdiffproperty',
'ConduitAPI_differential_updaterevision_Method' => 'applications/conduit/method/differential/updaterevision',
'ConduitAPI_file_upload_Method' => 'applications/conduit/method/file/upload',
'ConduitAPI_user_find_Method' => 'applications/conduit/method/user/find',
'ConduitException' => 'applications/conduit/protocol/exception',
'DarkConsole' => 'aphront/console/api',
'DarkConsoleConfigPlugin' => 'aphront/console/plugin/config',
'DarkConsoleController' => 'aphront/console/controller',
'DarkConsoleCore' => 'aphront/console/core',
'DarkConsoleErrorLogPlugin' => 'aphront/console/plugin/errorlog',
'DarkConsoleErrorLogPluginAPI' => 'aphront/console/plugin/errorlog/api',
'DarkConsolePlugin' => 'aphront/console/plugin/base',
'DarkConsoleRequestPlugin' => 'aphront/console/plugin/request',
'DarkConsoleServicesPlugin' => 'aphront/console/plugin/services',
'DarkConsoleServicesPluginAPI' => 'aphront/console/plugin/services/api',
'DarkConsoleXHProfPlugin' => 'aphront/console/plugin/xhprof',
'DarkConsoleXHProfPluginAPI' => 'aphront/console/plugin/xhprof/api',
'DifferentialAction' => 'applications/differential/constants/action',
'DifferentialAddCommentView' => 'applications/differential/view/addcomment',
'DifferentialAttachController' => 'applications/differential/controller/attach',
'DifferentialCCWelcomeMail' => 'applications/differential/mail/ccwelcome',
'DifferentialChangeType' => 'applications/differential/constants/changetype',
'DifferentialChangeset' => 'applications/differential/storage/changeset',
'DifferentialChangesetDetailView' => 'applications/differential/view/changesetdetailview',
'DifferentialChangesetListView' => 'applications/differential/view/changesetlistview',
'DifferentialChangesetParser' => 'applications/differential/parser/changeset',
'DifferentialChangesetViewController' => 'applications/differential/controller/changesetview',
'DifferentialComment' => 'applications/differential/storage/comment',
'DifferentialCommentEditor' => 'applications/differential/editor/comment',
'DifferentialCommentMail' => 'applications/differential/mail/comment',
'DifferentialCommentPreviewController' => 'applications/differential/controller/commentpreview',
'DifferentialCommentSaveController' => 'applications/differential/controller/commentsave',
'DifferentialCommitMessage' => 'applications/differential/parser/commitmessage',
'DifferentialCommitMessageData' => 'applications/differential/data/commitmessage',
'DifferentialCommitMessageParserException' => 'applications/differential/parser/commitmessage/exception',
'DifferentialController' => 'applications/differential/controller/base',
'DifferentialDAO' => 'applications/differential/storage/base',
'DifferentialDiff' => 'applications/differential/storage/diff',
'DifferentialDiffContentMail' => 'applications/differential/mail/diffcontent',
'DifferentialDiffCreateController' => 'applications/differential/controller/diffcreate',
'DifferentialDiffProperty' => 'applications/differential/storage/diffproperty',
'DifferentialDiffTableOfContentsView' => 'applications/differential/view/difftableofcontents',
'DifferentialDiffViewController' => 'applications/differential/controller/diffview',
'DifferentialHunk' => 'applications/differential/storage/hunk',
'DifferentialInlineComment' => 'applications/differential/storage/inlinecomment',
'DifferentialInlineCommentEditController' => 'applications/differential/controller/inlinecommentedit',
'DifferentialInlineCommentPreviewController' => 'applications/differential/controller/inlinecommentpreview',
'DifferentialInlineCommentView' => 'applications/differential/view/inlinecomment',
'DifferentialLintStatus' => 'applications/differential/constants/lintstatus',
'DifferentialMail' => 'applications/differential/mail/base',
'DifferentialMarkupEngineFactory' => 'applications/differential/parser/markup',
'DifferentialNewDiffMail' => 'applications/differential/mail/newdiff',
'DifferentialReviewRequestMail' => 'applications/differential/mail/reviewrequest',
'DifferentialRevision' => 'applications/differential/storage/revision',
'DifferentialRevisionCommentListView' => 'applications/differential/view/revisioncommentlist',
'DifferentialRevisionCommentView' => 'applications/differential/view/revisioncomment',
'DifferentialRevisionControlSystem' => 'applications/differential/constants/revisioncontrolsystem',
'DifferentialRevisionDetailView' => 'applications/differential/view/revisiondetail',
'DifferentialRevisionEditController' => 'applications/differential/controller/revisionedit',
'DifferentialRevisionEditor' => 'applications/differential/editor/revision',
'DifferentialRevisionListController' => 'applications/differential/controller/revisionlist',
'DifferentialRevisionListData' => 'applications/differential/data/revisionlist',
'DifferentialRevisionStatus' => 'applications/differential/constants/revisionstatus',
'DifferentialRevisionUpdateHistoryView' => 'applications/differential/view/revisionupdatehistory',
'DifferentialRevisionViewController' => 'applications/differential/controller/revisionview',
'DifferentialSubscribeController' => 'applications/differential/controller/subscribe',
'DifferentialUnitStatus' => 'applications/differential/constants/unitstatus',
'DiffusionBrowseController' => 'applications/diffusion/controller/browse',
'DiffusionBrowseFileController' => 'applications/diffusion/controller/file',
'DiffusionBrowseQuery' => 'applications/diffusion/query/browse/base',
'DiffusionBrowseTableView' => 'applications/diffusion/view/browsetable',
'DiffusionCommitChangeTableView' => 'applications/diffusion/view/commitchangetable',
'DiffusionCommitController' => 'applications/diffusion/controller/commit',
'DiffusionController' => 'applications/diffusion/controller/base',
'DiffusionFileContent' => 'applications/diffusion/data/filecontent',
'DiffusionFileContentQuery' => 'applications/diffusion/query/filecontent/base',
'DiffusionGitBrowseQuery' => 'applications/diffusion/query/browse/git',
'DiffusionGitFileContentQuery' => 'applications/diffusion/query/filecontent/git',
'DiffusionGitHistoryQuery' => 'applications/diffusion/query/history/git',
'DiffusionGitRequest' => 'applications/diffusion/request/git',
'DiffusionHistoryController' => 'applications/diffusion/controller/history',
'DiffusionHistoryQuery' => 'applications/diffusion/query/history/base',
'DiffusionHistoryTableView' => 'applications/diffusion/view/historytable',
'DiffusionHomeController' => 'applications/diffusion/controller/home',
'DiffusionPathChange' => 'applications/diffusion/data/pathchange',
'DiffusionRepositoryPath' => 'applications/diffusion/data/repositorypath',
'DiffusionRequest' => 'applications/diffusion/request/base',
'Javelin' => 'infrastructure/javelin/api',
'LiskDAO' => 'storage/lisk/dao',
'ManiphestController' => 'applications/maniphest/controller/base',
'ManiphestDAO' => 'applications/maniphest/storage/base',
'ManiphestTask' => 'applications/maniphest/storage/task',
'ManiphestTaskDetailController' => 'applications/maniphest/controller/taskdetail',
'ManiphestTaskEditController' => 'applications/maniphest/controller/taskedit',
'ManiphestTaskListController' => 'applications/maniphest/controller/tasklist',
'ManiphestTaskListView' => 'applications/maniphest/view/tasklist',
'ManiphestTaskPriority' => 'applications/maniphest/constants/priority',
'ManiphestTaskSelectorSearchController' => 'applications/maniphest/controller/taskselectorsearch',
'ManiphestTaskStatus' => 'applications/maniphest/constants/status',
'ManiphestTaskSummaryView' => 'applications/maniphest/view/tasksummary',
'ManiphestTransaction' => 'applications/maniphest/storage/transaction',
'ManiphestTransactionDetailView' => 'applications/maniphest/view/transactiondetail',
'ManiphestTransactionEditor' => 'applications/maniphest/editor/transaction',
'ManiphestTransactionListView' => 'applications/maniphest/view/transactionlist',
'ManiphestTransactionSaveController' => 'applications/maniphest/controller/transactionsave',
'ManiphestTransactionType' => 'applications/maniphest/constants/transactiontype',
'Phabricator404Controller' => 'applications/base/controller/404',
'PhabricatorAuthController' => 'applications/auth/controller/base',
'PhabricatorConduitAPIController' => 'applications/conduit/controller/api',
'PhabricatorConduitConnectionLog' => 'applications/conduit/storage/connectionlog',
'PhabricatorConduitConsoleController' => 'applications/conduit/controller/console',
'PhabricatorConduitController' => 'applications/conduit/controller/base',
'PhabricatorConduitDAO' => 'applications/conduit/storage/base',
'PhabricatorConduitLogController' => 'applications/conduit/controller/log',
'PhabricatorConduitMethodCallLog' => 'applications/conduit/storage/methodcalllog',
'PhabricatorController' => 'applications/base/controller/base',
'PhabricatorDaemon' => 'infrastructure/daemon/base',
'PhabricatorDaemonConsoleController' => 'applications/daemon/controller/console',
'PhabricatorDaemonController' => 'applications/daemon/controller/base',
'PhabricatorDaemonTimelineConsoleController' => 'applications/daemon/controller/timeline',
'PhabricatorDaemonTimelineEventController' => 'applications/daemon/controller/timelineevent',
'PhabricatorDirectoryCategory' => 'applications/directory/storage/category',
'PhabricatorDirectoryCategoryDeleteController' => 'applications/directory/controller/categorydelete',
'PhabricatorDirectoryCategoryEditController' => 'applications/directory/controller/categoryedit',
'PhabricatorDirectoryCategoryListController' => 'applications/directory/controller/categorylist',
'PhabricatorDirectoryController' => 'applications/directory/controller/base',
'PhabricatorDirectoryDAO' => 'applications/directory/storage/base',
'PhabricatorDirectoryItem' => 'applications/directory/storage/item',
'PhabricatorDirectoryItemDeleteController' => 'applications/directory/controller/itemdelete',
'PhabricatorDirectoryItemEditController' => 'applications/directory/controller/itemedit',
'PhabricatorDirectoryItemListController' => 'applications/directory/controller/itemlist',
'PhabricatorDirectoryMainController' => 'applications/directory/controller/main',
'PhabricatorDraft' => 'applications/draft/storage/draft',
'PhabricatorDraftDAO' => 'applications/draft/storage/base',
'PhabricatorEmailLoginController' => 'applications/auth/controller/email',
'PhabricatorEmailTokenController' => 'applications/auth/controller/emailtoken',
'PhabricatorEnv' => 'infrastructure/env',
'PhabricatorFile' => 'applications/files/storage/file',
'PhabricatorFileController' => 'applications/files/controller/base',
'PhabricatorFileDAO' => 'applications/files/storage/base',
'PhabricatorFileListController' => 'applications/files/controller/list',
'PhabricatorFileStorageBlob' => 'applications/files/storage/storageblob',
'PhabricatorFileURI' => 'applications/files/uri',
'PhabricatorFileUploadController' => 'applications/files/controller/upload',
'PhabricatorFileViewController' => 'applications/files/controller/view',
'PhabricatorGoodForNothingWorker' => 'infrastructure/daemon/workers/worker/goodfornothing',
'PhabricatorHandleObjectSelectorDataView' => 'applications/phid/handle/view/selector',
'PhabricatorLiskDAO' => 'applications/base/storage/lisk',
'PhabricatorLoginController' => 'applications/auth/controller/login',
'PhabricatorLogoutController' => 'applications/auth/controller/logout',
'PhabricatorMailImplementationAdapter' => 'applications/metamta/adapter/base',
'PhabricatorMailImplementationAmazonSESAdapter' => 'applications/metamta/adapter/amazonses',
'PhabricatorMailImplementationPHPMailerLiteAdapter' => 'applications/metamta/adapter/phpmailerlite',
'PhabricatorMetaMTAController' => 'applications/metamta/controller/base',
'PhabricatorMetaMTADAO' => 'applications/metamta/storage/base',
'PhabricatorMetaMTADaemon' => 'applications/metamta/daemon/mta',
'PhabricatorMetaMTAListController' => 'applications/metamta/controller/list',
'PhabricatorMetaMTAMail' => 'applications/metamta/storage/mail',
'PhabricatorMetaMTAMailingList' => 'applications/metamta/storage/mailinglist',
'PhabricatorMetaMTAMailingListEditController' => 'applications/metamta/controller/mailinglistedit',
'PhabricatorMetaMTAMailingListsController' => 'applications/metamta/controller/mailinglists',
'PhabricatorMetaMTASendController' => 'applications/metamta/controller/send',
'PhabricatorMetaMTAViewController' => 'applications/metamta/controller/view',
'PhabricatorOAuthDefaultRegistrationController' => 'applications/auth/controller/oauthregistration/default',
'PhabricatorOAuthDiagnosticsController' => 'applications/auth/controller/oauthdiagnostics',
'PhabricatorOAuthFailureView' => 'applications/auth/view/oauthfailure',
'PhabricatorOAuthLoginController' => 'applications/auth/controller/oauth',
'PhabricatorOAuthProvider' => 'applications/auth/oauth/provider/base',
'PhabricatorOAuthProviderFacebook' => 'applications/auth/oauth/provider/facebook',
'PhabricatorOAuthProviderGithub' => 'applications/auth/oauth/provider/github',
'PhabricatorOAuthRegistrationController' => 'applications/auth/controller/oauthregistration/base',
'PhabricatorOAuthUnlinkController' => 'applications/auth/controller/unlink',
'PhabricatorObjectHandle' => 'applications/phid/handle',
'PhabricatorObjectHandleData' => 'applications/phid/handle/data',
'PhabricatorObjectSelectorDialog' => 'view/control/objectselector',
'PhabricatorPHID' => 'applications/phid/storage/phid',
'PhabricatorPHIDAllocateController' => 'applications/phid/controller/allocate',
'PhabricatorPHIDConstants' => 'applications/phid/constants',
'PhabricatorPHIDController' => 'applications/phid/controller/base',
'PhabricatorPHIDDAO' => 'applications/phid/storage/base',
'PhabricatorPHIDListController' => 'applications/phid/controller/list',
'PhabricatorPHIDLookupController' => 'applications/phid/controller/lookup',
'PhabricatorPHIDType' => 'applications/phid/storage/type',
'PhabricatorPHIDTypeEditController' => 'applications/phid/controller/typeedit',
'PhabricatorPHIDTypeListController' => 'applications/phid/controller/typelist',
'PhabricatorPeopleController' => 'applications/people/controller/base',
'PhabricatorPeopleEditController' => 'applications/people/controller/edit',
'PhabricatorPeopleListController' => 'applications/people/controller/list',
'PhabricatorPeopleProfileController' => 'applications/people/controller/profile',
'PhabricatorPeopleProfileEditController' => 'applications/people/controller/profileedit',
'PhabricatorProject' => 'applications/project/storage/project',
'PhabricatorProjectAffiliation' => 'applications/project/storage/affiliation',
'PhabricatorProjectAffiliationEditController' => 'applications/project/controller/editaffiliation',
'PhabricatorProjectController' => 'applications/project/controller/base',
'PhabricatorProjectDAO' => 'applications/project/storage/base',
'PhabricatorProjectEditController' => 'applications/project/controller/edit',
'PhabricatorProjectListController' => 'applications/project/controller/list',
'PhabricatorProjectProfile' => 'applications/project/storage/profile',
'PhabricatorProjectProfileController' => 'applications/project/controller/profile',
'PhabricatorRemarkupRuleDifferential' => 'infrastructure/markup/remarkup/markuprule/differential',
'PhabricatorRemarkupRuleManiphest' => 'infrastructure/markup/remarkup/markuprule/maniphest',
'PhabricatorRepository' => 'applications/repository/storage/repository',
'PhabricatorRepositoryCommit' => 'applications/repository/storage/commit',
'PhabricatorRepositoryCommitChangeParserWorker' => 'applications/repository/worker/commitchangeparser/base',
'PhabricatorRepositoryCommitData' => 'applications/repository/storage/commitdata',
'PhabricatorRepositoryCommitDiscoveryDaemon' => 'applications/repository/daemon/commitdiscovery/base',
'PhabricatorRepositoryCommitMessageParserWorker' => 'applications/repository/worker/commitmessageparser/base',
'PhabricatorRepositoryCommitParserWorker' => 'applications/repository/worker/base',
'PhabricatorRepositoryCommitTaskDaemon' => 'applications/repository/daemon/committask',
'PhabricatorRepositoryController' => 'applications/repository/controller/base',
'PhabricatorRepositoryCreateController' => 'applications/repository/controller/create',
'PhabricatorRepositoryDAO' => 'applications/repository/storage/base',
'PhabricatorRepositoryDaemon' => 'applications/repository/daemon/base',
'PhabricatorRepositoryEditController' => 'applications/repository/controller/edit',
'PhabricatorRepositoryGitCommitChangeParserWorker' => 'applications/repository/worker/commitchangeparser/git',
'PhabricatorRepositoryGitCommitDiscoveryDaemon' => 'applications/repository/daemon/commitdiscovery/git',
'PhabricatorRepositoryGitCommitMessageParserWorker' => 'applications/repository/worker/commitmessageparser/git',
'PhabricatorRepositoryGitHubNotification' => 'applications/repository/storage/githubnotification',
'PhabricatorRepositoryGitHubPostReceiveController' => 'applications/repository/controller/github-post-receive',
'PhabricatorRepositoryGitPullDaemon' => 'applications/repository/daemon/gitpull',
'PhabricatorRepositoryListController' => 'applications/repository/controller/list',
+ 'PhabricatorRepositorySvnCommitChangeParserWorker' => 'applications/repository/worker/commitchangeparser/svn',
'PhabricatorRepositorySvnCommitDiscoveryDaemon' => 'applications/repository/daemon/commitdiscovery/svn',
'PhabricatorRepositorySvnCommitMessageParserWorker' => 'applications/repository/worker/commitmessageparser/svn',
'PhabricatorRepositoryType' => 'applications/repository/constants/repositorytype',
'PhabricatorSearchAbstractDocument' => 'applications/search/index/abstractdocument',
'PhabricatorSearchBaseController' => 'applications/search/controller/base',
'PhabricatorSearchController' => 'applications/search/controller/search',
'PhabricatorSearchDAO' => 'applications/search/storage/base',
'PhabricatorSearchDifferentialIndexer' => 'applications/search/index/indexer/differential',
'PhabricatorSearchDocument' => 'applications/search/storage/document/document',
'PhabricatorSearchDocumentField' => 'applications/search/storage/document/field',
'PhabricatorSearchDocumentIndexer' => 'applications/search/index/indexer/base',
'PhabricatorSearchDocumentRelationship' => 'applications/search/storage/document/relationship',
'PhabricatorSearchExecutor' => 'applications/search/execute/base',
'PhabricatorSearchField' => 'applications/search/constants/field',
'PhabricatorSearchManiphestIndexer' => 'applications/search/index/indexer/maniphest',
'PhabricatorSearchMySQLExecutor' => 'applications/search/execute/mysql',
'PhabricatorSearchQuery' => 'applications/search/storage/query',
'PhabricatorSearchRelationship' => 'applications/search/constants/relationship',
'PhabricatorStandardPageView' => 'view/page/standard',
'PhabricatorTaskmasterDaemon' => 'infrastructure/daemon/workers/taskmaster',
'PhabricatorTimelineCursor' => 'infrastructure/daemon/timeline/storage/cursor',
'PhabricatorTimelineDAO' => 'infrastructure/daemon/timeline/storage/base',
'PhabricatorTimelineEvent' => 'infrastructure/daemon/timeline/storage/event',
'PhabricatorTimelineEventData' => 'infrastructure/daemon/timeline/storage/eventdata',
'PhabricatorTimelineIterator' => 'infrastructure/daemon/timeline/cursor/iterator',
'PhabricatorTypeaheadCommonDatasourceController' => 'applications/typeahead/controller/common',
'PhabricatorTypeaheadDatasourceController' => 'applications/typeahead/controller/base',
'PhabricatorUser' => 'applications/people/storage/user',
'PhabricatorUserDAO' => 'applications/people/storage/base',
'PhabricatorUserOAuthInfo' => 'applications/people/storage/useroauthinfo',
'PhabricatorUserProfile' => 'applications/people/storage/profile',
'PhabricatorUserSettingsController' => 'applications/people/controller/settings',
'PhabricatorWorker' => 'infrastructure/daemon/workers/worker',
'PhabricatorWorkerDAO' => 'infrastructure/daemon/workers/storage/base',
'PhabricatorWorkerTask' => 'infrastructure/daemon/workers/storage/task',
'PhabricatorWorkerTaskData' => 'infrastructure/daemon/workers/storage/taskdata',
'PhabricatorXHProfController' => 'applications/xhprof/controller/base',
'PhabricatorXHProfProfileController' => 'applications/xhprof/controller/profile',
'PhabricatorXHProfProfileSymbolView' => 'applications/xhprof/view/symbol',
'PhabricatorXHProfProfileTopLevelView' => 'applications/xhprof/view/toplevel',
),
'function' =>
array(
'_qsprintf_check_scalar_type' => 'storage/qsprintf',
'_qsprintf_check_type' => 'storage/qsprintf',
'celerity_generate_unique_node_id' => 'infrastructure/celerity/api',
'celerity_register_resource_map' => 'infrastructure/celerity/map',
'javelin_render_tag' => 'infrastructure/javelin/markup',
'phabricator_format_relative_time' => 'view/utils',
'phabricator_format_timestamp' => 'view/utils',
'phabricator_format_units_generic' => 'view/utils',
'phabricator_render_form' => 'infrastructure/javelin/markup',
'qsprintf' => 'storage/qsprintf',
'queryfx' => 'storage/queryfx',
'queryfx_all' => 'storage/queryfx',
'queryfx_one' => 'storage/queryfx',
'require_celerity_resource' => 'infrastructure/celerity/api',
'vqsprintf' => 'storage/qsprintf',
'vqueryfx' => 'storage/queryfx',
'vqueryfx_all' => 'storage/queryfx',
'xsprintf_query' => 'storage/qsprintf',
),
'requires_class' =>
array(
'Aphront400Response' => 'AphrontResponse',
'Aphront404Response' => 'AphrontResponse',
'AphrontAjaxResponse' => 'AphrontResponse',
'AphrontDefaultApplicationConfiguration' => 'AphrontApplicationConfiguration',
'AphrontDefaultApplicationController' => 'AphrontController',
'AphrontDialogResponse' => 'AphrontResponse',
'AphrontDialogView' => 'AphrontView',
'AphrontErrorView' => 'AphrontView',
'AphrontFileResponse' => 'AphrontResponse',
'AphrontFormCheckboxControl' => 'AphrontFormControl',
'AphrontFormControl' => 'AphrontView',
'AphrontFormDividerControl' => 'AphrontFormControl',
'AphrontFormFileControl' => 'AphrontFormControl',
'AphrontFormMarkupControl' => 'AphrontFormControl',
'AphrontFormPasswordControl' => 'AphrontFormControl',
'AphrontFormRecaptchaControl' => 'AphrontFormControl',
'AphrontFormSelectControl' => 'AphrontFormControl',
'AphrontFormStaticControl' => 'AphrontFormControl',
'AphrontFormSubmitControl' => 'AphrontFormControl',
'AphrontFormTextAreaControl' => 'AphrontFormControl',
'AphrontFormTextControl' => 'AphrontFormControl',
'AphrontFormTokenizerControl' => 'AphrontFormControl',
'AphrontFormView' => 'AphrontView',
'AphrontHeadsupActionListView' => 'AphrontView',
'AphrontHeadsupActionView' => 'AphrontView',
'AphrontMySQLDatabaseConnection' => 'AphrontDatabaseConnection',
'AphrontNullView' => 'AphrontView',
'AphrontPageView' => 'AphrontView',
'AphrontPanelView' => 'AphrontView',
'AphrontQueryConnectionException' => 'AphrontQueryException',
'AphrontQueryConnectionLostException' => 'AphrontQueryRecoverableException',
'AphrontQueryCountException' => 'AphrontQueryException',
'AphrontQueryDuplicateKeyException' => 'AphrontQueryException',
'AphrontQueryObjectMissingException' => 'AphrontQueryException',
'AphrontQueryParameterException' => 'AphrontQueryException',
'AphrontQueryRecoverableException' => 'AphrontQueryException',
'AphrontRedirectException' => 'AphrontException',
'AphrontRedirectResponse' => 'AphrontResponse',
'AphrontRequestFailureView' => 'AphrontView',
'AphrontSideNavView' => 'AphrontView',
'AphrontTableView' => 'AphrontView',
'AphrontWebpageResponse' => 'AphrontResponse',
'CelerityResourceController' => 'AphrontController',
'ConduitAPI_conduit_connect_Method' => 'ConduitAPIMethod',
'ConduitAPI_conduit_ping_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_creatediff_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_createrevision_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_find_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_getcommitmessage_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_getcommitpaths_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_getdiff_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_markcommitted_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_parsecommitmessage_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_setdiffproperty_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_updaterevision_Method' => 'ConduitAPIMethod',
'ConduitAPI_file_upload_Method' => 'ConduitAPIMethod',
'ConduitAPI_user_find_Method' => 'ConduitAPIMethod',
'DarkConsoleConfigPlugin' => 'DarkConsolePlugin',
'DarkConsoleController' => 'PhabricatorController',
'DarkConsoleErrorLogPlugin' => 'DarkConsolePlugin',
'DarkConsoleRequestPlugin' => 'DarkConsolePlugin',
'DarkConsoleServicesPlugin' => 'DarkConsolePlugin',
'DarkConsoleXHProfPlugin' => 'DarkConsolePlugin',
'DifferentialAddCommentView' => 'AphrontView',
'DifferentialAttachController' => 'DifferentialController',
'DifferentialCCWelcomeMail' => 'DifferentialReviewRequestMail',
'DifferentialChangeset' => 'DifferentialDAO',
'DifferentialChangesetDetailView' => 'AphrontView',
'DifferentialChangesetListView' => 'AphrontView',
'DifferentialChangesetViewController' => 'DifferentialController',
'DifferentialComment' => 'DifferentialDAO',
'DifferentialCommentMail' => 'DifferentialMail',
'DifferentialCommentPreviewController' => 'DifferentialController',
'DifferentialCommentSaveController' => 'DifferentialController',
'DifferentialController' => 'PhabricatorController',
'DifferentialDAO' => 'PhabricatorLiskDAO',
'DifferentialDiff' => 'DifferentialDAO',
'DifferentialDiffContentMail' => 'DifferentialMail',
'DifferentialDiffCreateController' => 'DifferentialController',
'DifferentialDiffProperty' => 'DifferentialDAO',
'DifferentialDiffTableOfContentsView' => 'AphrontView',
'DifferentialDiffViewController' => 'DifferentialController',
'DifferentialHunk' => 'DifferentialDAO',
'DifferentialInlineComment' => 'DifferentialDAO',
'DifferentialInlineCommentEditController' => 'DifferentialController',
'DifferentialInlineCommentPreviewController' => 'DifferentialController',
'DifferentialInlineCommentView' => 'AphrontView',
'DifferentialNewDiffMail' => 'DifferentialReviewRequestMail',
'DifferentialReviewRequestMail' => 'DifferentialMail',
'DifferentialRevision' => 'DifferentialDAO',
'DifferentialRevisionCommentListView' => 'AphrontView',
'DifferentialRevisionCommentView' => 'AphrontView',
'DifferentialRevisionDetailView' => 'AphrontView',
'DifferentialRevisionEditController' => 'DifferentialController',
'DifferentialRevisionListController' => 'DifferentialController',
'DifferentialRevisionUpdateHistoryView' => 'AphrontView',
'DifferentialRevisionViewController' => 'DifferentialController',
'DifferentialSubscribeController' => 'DifferentialController',
'DiffusionBrowseController' => 'DiffusionController',
'DiffusionBrowseFileController' => 'DiffusionController',
'DiffusionBrowseTableView' => 'AphrontView',
'DiffusionCommitChangeTableView' => 'AphrontView',
'DiffusionCommitController' => 'DiffusionController',
'DiffusionController' => 'PhabricatorController',
'DiffusionGitBrowseQuery' => 'DiffusionBrowseQuery',
'DiffusionGitFileContentQuery' => 'DiffusionFileContentQuery',
'DiffusionGitHistoryQuery' => 'DiffusionHistoryQuery',
'DiffusionGitRequest' => 'DiffusionRequest',
'DiffusionHistoryController' => 'DiffusionController',
'DiffusionHistoryTableView' => 'AphrontView',
'DiffusionHomeController' => 'DiffusionController',
'ManiphestController' => 'PhabricatorController',
'ManiphestDAO' => 'PhabricatorLiskDAO',
'ManiphestTask' => 'ManiphestDAO',
'ManiphestTaskDetailController' => 'ManiphestController',
'ManiphestTaskEditController' => 'ManiphestController',
'ManiphestTaskListController' => 'ManiphestController',
'ManiphestTaskListView' => 'AphrontView',
'ManiphestTaskSelectorSearchController' => 'ManiphestController',
'ManiphestTaskSummaryView' => 'AphrontView',
'ManiphestTransaction' => 'ManiphestDAO',
'ManiphestTransactionDetailView' => 'AphrontView',
'ManiphestTransactionListView' => 'AphrontView',
'ManiphestTransactionSaveController' => 'ManiphestController',
'Phabricator404Controller' => 'PhabricatorController',
'PhabricatorAuthController' => 'PhabricatorController',
'PhabricatorConduitAPIController' => 'PhabricatorConduitController',
'PhabricatorConduitConnectionLog' => 'PhabricatorConduitDAO',
'PhabricatorConduitConsoleController' => 'PhabricatorConduitController',
'PhabricatorConduitController' => 'PhabricatorController',
'PhabricatorConduitDAO' => 'PhabricatorLiskDAO',
'PhabricatorConduitLogController' => 'PhabricatorConduitController',
'PhabricatorConduitMethodCallLog' => 'PhabricatorConduitDAO',
'PhabricatorController' => 'AphrontController',
'PhabricatorDaemon' => 'PhutilDaemon',
'PhabricatorDaemonConsoleController' => 'PhabricatorDaemonController',
'PhabricatorDaemonController' => 'PhabricatorController',
'PhabricatorDaemonTimelineConsoleController' => 'PhabricatorDaemonController',
'PhabricatorDaemonTimelineEventController' => 'PhabricatorDaemonController',
'PhabricatorDirectoryCategory' => 'PhabricatorDirectoryDAO',
'PhabricatorDirectoryCategoryDeleteController' => 'PhabricatorDirectoryController',
'PhabricatorDirectoryCategoryEditController' => 'PhabricatorDirectoryController',
'PhabricatorDirectoryCategoryListController' => 'PhabricatorDirectoryController',
'PhabricatorDirectoryController' => 'PhabricatorController',
'PhabricatorDirectoryDAO' => 'PhabricatorLiskDAO',
'PhabricatorDirectoryItem' => 'PhabricatorDirectoryDAO',
'PhabricatorDirectoryItemDeleteController' => 'PhabricatorDirectoryController',
'PhabricatorDirectoryItemEditController' => 'PhabricatorDirectoryController',
'PhabricatorDirectoryItemListController' => 'PhabricatorDirectoryController',
'PhabricatorDirectoryMainController' => 'PhabricatorDirectoryController',
'PhabricatorDraft' => 'PhabricatorDraftDAO',
'PhabricatorDraftDAO' => 'PhabricatorLiskDAO',
'PhabricatorEmailLoginController' => 'PhabricatorAuthController',
'PhabricatorEmailTokenController' => 'PhabricatorAuthController',
'PhabricatorFile' => 'PhabricatorFileDAO',
'PhabricatorFileController' => 'PhabricatorController',
'PhabricatorFileDAO' => 'PhabricatorLiskDAO',
'PhabricatorFileListController' => 'PhabricatorFileController',
'PhabricatorFileStorageBlob' => 'PhabricatorFileDAO',
'PhabricatorFileUploadController' => 'PhabricatorFileController',
'PhabricatorFileViewController' => 'PhabricatorFileController',
'PhabricatorGoodForNothingWorker' => 'PhabricatorWorker',
'PhabricatorLiskDAO' => 'LiskDAO',
'PhabricatorLoginController' => 'PhabricatorAuthController',
'PhabricatorLogoutController' => 'PhabricatorAuthController',
'PhabricatorMailImplementationAmazonSESAdapter' => 'PhabricatorMailImplementationPHPMailerLiteAdapter',
'PhabricatorMailImplementationPHPMailerLiteAdapter' => 'PhabricatorMailImplementationAdapter',
'PhabricatorMetaMTAController' => 'PhabricatorController',
'PhabricatorMetaMTADAO' => 'PhabricatorLiskDAO',
'PhabricatorMetaMTAListController' => 'PhabricatorMetaMTAController',
'PhabricatorMetaMTAMail' => 'PhabricatorMetaMTADAO',
'PhabricatorMetaMTAMailingList' => 'PhabricatorMetaMTADAO',
'PhabricatorMetaMTAMailingListEditController' => 'PhabricatorMetaMTAController',
'PhabricatorMetaMTAMailingListsController' => 'PhabricatorMetaMTAController',
'PhabricatorMetaMTASendController' => 'PhabricatorMetaMTAController',
'PhabricatorMetaMTAViewController' => 'PhabricatorMetaMTAController',
'PhabricatorOAuthDefaultRegistrationController' => 'PhabricatorOAuthRegistrationController',
'PhabricatorOAuthDiagnosticsController' => 'PhabricatorAuthController',
'PhabricatorOAuthFailureView' => 'AphrontView',
'PhabricatorOAuthLoginController' => 'PhabricatorAuthController',
'PhabricatorOAuthProviderFacebook' => 'PhabricatorOAuthProvider',
'PhabricatorOAuthProviderGithub' => 'PhabricatorOAuthProvider',
'PhabricatorOAuthRegistrationController' => 'PhabricatorAuthController',
'PhabricatorOAuthUnlinkController' => 'PhabricatorAuthController',
'PhabricatorPHID' => 'PhabricatorPHIDDAO',
'PhabricatorPHIDAllocateController' => 'PhabricatorPHIDController',
'PhabricatorPHIDController' => 'PhabricatorController',
'PhabricatorPHIDDAO' => 'PhabricatorLiskDAO',
'PhabricatorPHIDListController' => 'PhabricatorPHIDController',
'PhabricatorPHIDLookupController' => 'PhabricatorPHIDController',
'PhabricatorPHIDType' => 'PhabricatorPHIDDAO',
'PhabricatorPHIDTypeEditController' => 'PhabricatorPHIDController',
'PhabricatorPHIDTypeListController' => 'PhabricatorPHIDController',
'PhabricatorPeopleController' => 'PhabricatorController',
'PhabricatorPeopleEditController' => 'PhabricatorPeopleController',
'PhabricatorPeopleListController' => 'PhabricatorPeopleController',
'PhabricatorPeopleProfileController' => 'PhabricatorPeopleController',
'PhabricatorPeopleProfileEditController' => 'PhabricatorPeopleController',
'PhabricatorProject' => 'PhabricatorProjectDAO',
'PhabricatorProjectAffiliation' => 'PhabricatorProjectDAO',
'PhabricatorProjectAffiliationEditController' => 'PhabricatorProjectController',
'PhabricatorProjectController' => 'PhabricatorController',
'PhabricatorProjectDAO' => 'PhabricatorLiskDAO',
'PhabricatorProjectEditController' => 'PhabricatorProjectController',
'PhabricatorProjectListController' => 'PhabricatorProjectController',
'PhabricatorProjectProfile' => 'PhabricatorProjectDAO',
'PhabricatorProjectProfileController' => 'PhabricatorProjectController',
'PhabricatorRemarkupRuleDifferential' => 'PhutilRemarkupRule',
'PhabricatorRemarkupRuleManiphest' => 'PhutilRemarkupRule',
'PhabricatorRepository' => 'PhabricatorRepositoryDAO',
'PhabricatorRepositoryCommit' => 'PhabricatorRepositoryDAO',
'PhabricatorRepositoryCommitChangeParserWorker' => 'PhabricatorRepositoryCommitParserWorker',
'PhabricatorRepositoryCommitData' => 'PhabricatorRepositoryDAO',
'PhabricatorRepositoryCommitDiscoveryDaemon' => 'PhabricatorRepositoryDaemon',
'PhabricatorRepositoryCommitMessageParserWorker' => 'PhabricatorRepositoryCommitParserWorker',
'PhabricatorRepositoryCommitParserWorker' => 'PhabricatorWorker',
'PhabricatorRepositoryCommitTaskDaemon' => 'PhabricatorRepositoryDaemon',
'PhabricatorRepositoryController' => 'PhabricatorController',
- 'PhabricatorRepositoryCreateController' => 'PhabricatorController',
+ 'PhabricatorRepositoryCreateController' => 'PhabricatorRepositoryController',
'PhabricatorRepositoryDAO' => 'PhabricatorLiskDAO',
'PhabricatorRepositoryDaemon' => 'PhabricatorDaemon',
- 'PhabricatorRepositoryEditController' => 'PhabricatorController',
+ 'PhabricatorRepositoryEditController' => 'PhabricatorRepositoryController',
'PhabricatorRepositoryGitCommitChangeParserWorker' => 'PhabricatorRepositoryCommitChangeParserWorker',
'PhabricatorRepositoryGitCommitDiscoveryDaemon' => 'PhabricatorRepositoryCommitDiscoveryDaemon',
'PhabricatorRepositoryGitCommitMessageParserWorker' => 'PhabricatorRepositoryCommitMessageParserWorker',
'PhabricatorRepositoryGitHubNotification' => 'PhabricatorRepositoryDAO',
'PhabricatorRepositoryGitHubPostReceiveController' => 'PhabricatorRepositoryController',
'PhabricatorRepositoryGitPullDaemon' => 'PhabricatorRepositoryDaemon',
- 'PhabricatorRepositoryListController' => 'PhabricatorController',
+ 'PhabricatorRepositoryListController' => 'PhabricatorRepositoryController',
+ 'PhabricatorRepositorySvnCommitChangeParserWorker' => 'PhabricatorRepositoryCommitChangeParserWorker',
'PhabricatorRepositorySvnCommitDiscoveryDaemon' => 'PhabricatorRepositoryCommitDiscoveryDaemon',
'PhabricatorRepositorySvnCommitMessageParserWorker' => 'PhabricatorRepositoryCommitMessageParserWorker',
'PhabricatorSearchBaseController' => 'PhabricatorController',
'PhabricatorSearchController' => 'PhabricatorSearchBaseController',
'PhabricatorSearchDAO' => 'PhabricatorLiskDAO',
'PhabricatorSearchDifferentialIndexer' => 'PhabricatorSearchDocumentIndexer',
'PhabricatorSearchDocument' => 'PhabricatorSearchDAO',
'PhabricatorSearchDocumentField' => 'PhabricatorSearchDAO',
'PhabricatorSearchDocumentRelationship' => 'PhabricatorSearchDAO',
'PhabricatorSearchManiphestIndexer' => 'PhabricatorSearchDocumentIndexer',
'PhabricatorSearchMySQLExecutor' => 'PhabricatorSearchExecutor',
'PhabricatorSearchQuery' => 'PhabricatorSearchDAO',
'PhabricatorStandardPageView' => 'AphrontPageView',
'PhabricatorTaskmasterDaemon' => 'PhabricatorDaemon',
'PhabricatorTimelineCursor' => 'PhabricatorTimelineDAO',
'PhabricatorTimelineDAO' => 'PhabricatorLiskDAO',
'PhabricatorTimelineEvent' => 'PhabricatorTimelineDAO',
'PhabricatorTimelineEventData' => 'PhabricatorTimelineDAO',
'PhabricatorTypeaheadCommonDatasourceController' => 'PhabricatorTypeaheadDatasourceController',
'PhabricatorTypeaheadDatasourceController' => 'PhabricatorController',
'PhabricatorUser' => 'PhabricatorUserDAO',
'PhabricatorUserDAO' => 'PhabricatorLiskDAO',
'PhabricatorUserOAuthInfo' => 'PhabricatorUserDAO',
'PhabricatorUserProfile' => 'PhabricatorUserDAO',
'PhabricatorUserSettingsController' => 'PhabricatorPeopleController',
'PhabricatorWorkerDAO' => 'PhabricatorLiskDAO',
'PhabricatorWorkerTask' => 'PhabricatorWorkerDAO',
'PhabricatorWorkerTaskData' => 'PhabricatorWorkerDAO',
'PhabricatorXHProfController' => 'PhabricatorController',
'PhabricatorXHProfProfileController' => 'PhabricatorXHProfController',
'PhabricatorXHProfProfileSymbolView' => 'AphrontView',
'PhabricatorXHProfProfileTopLevelView' => 'AphrontView',
),
'requires_interface' =>
array(
),
));
diff --git a/src/applications/diffusion/view/commitchangetable/__init__.php b/src/applications/diffusion/view/commitchangetable/__init__.php
new file mode 100644
index 0000000000..38dfa02082
--- /dev/null
+++ b/src/applications/diffusion/view/commitchangetable/__init__.php
@@ -0,0 +1,13 @@
+<?php
+/**
+ * This file is automatically generated. Lint this module to rebuild it.
+ * @generated
+ */
+
+
+
+phutil_require_module('phabricator', 'view/base');
+phutil_require_module('phabricator', 'view/control/table');
+
+
+phutil_require_source('DiffusionCommitChangeTableView.php');
diff --git a/src/applications/repository/storage/repository/PhabricatorRepository.php b/src/applications/repository/storage/repository/PhabricatorRepository.php
index ad5041c2e1..71f21bedee 100644
--- a/src/applications/repository/storage/repository/PhabricatorRepository.php
+++ b/src/applications/repository/storage/repository/PhabricatorRepository.php
@@ -1,54 +1,55 @@
<?php
/*
* Copyright 2011 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class PhabricatorRepository extends PhabricatorRepositoryDAO {
const TABLE_PATH = 'repository_path';
const TABLE_PATHCHANGE = 'repository_pathchange';
+ const TABLE_FILESYSTEM = 'repository_filesystem';
protected $phid;
protected $name;
protected $callsign;
protected $versionControlSystem;
protected $details = array();
public function getConfiguration() {
return array(
self::CONFIG_AUX_PHID => true,
self::CONFIG_SERIALIZATION => array(
'details' => self::SERIALIZATION_JSON,
),
) + parent::getConfiguration();
}
public function generatePHID() {
return PhabricatorPHID::generateNewPHID(
PhabricatorPHIDConstants::PHID_TYPE_REPO);
}
public function getDetail($key, $default = null) {
return idx($this->details, $key, $default);
}
public function setDetail($key, $value) {
$this->details[$key] = $value;
return $this;
}
}
diff --git a/src/applications/repository/worker/commitchangeparser/base/PhabricatorRepositoryCommitChangeParserWorker.php b/src/applications/repository/worker/commitchangeparser/base/PhabricatorRepositoryCommitChangeParserWorker.php
index 68a7bc840e..c61250990b 100644
--- a/src/applications/repository/worker/commitchangeparser/base/PhabricatorRepositoryCommitChangeParserWorker.php
+++ b/src/applications/repository/worker/commitchangeparser/base/PhabricatorRepositoryCommitChangeParserWorker.php
@@ -1,69 +1,69 @@
<?php
/*
* Copyright 2011 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
abstract class PhabricatorRepositoryCommitChangeParserWorker
extends PhabricatorRepositoryCommitParserWorker {
protected function lookupOrCreatePaths(array $paths) {
$repository = new PhabricatorRepository();
$conn_w = $repository->establishConnection('w');
$result_map = $this->lookupPaths($paths);
$missing_paths = array_fill_keys($paths, true);
$missing_paths = array_diff_key($missing_paths, $result_map);
$missing_paths = array_keys($missing_paths);
if ($missing_paths) {
- foreach (array_chunk($missing_paths, 512) as $path_chunk) {
+ foreach (array_chunk($missing_paths, 128) as $path_chunk) {
$sql = array();
foreach ($path_chunk as $path) {
$sql[] = qsprintf($conn_w, '(%s)', $path);
}
queryfx(
$conn_w,
'INSERT INTO %T (path) VALUES %Q',
PhabricatorRepository::TABLE_PATH,
implode(', ', $sql));
}
$result_map += $this->lookupPaths($missing_paths);
}
return $result_map;
}
private function lookupPaths(array $paths) {
$repository = new PhabricatorRepository();
$conn_w = $repository->establishConnection('w');
$result_map = array();
- foreach (array_chunk($paths, 512) as $path_chunk) {
+ foreach (array_chunk($paths, 128) as $path_chunk) {
$chunk_map = queryfx_all(
$conn_w,
'SELECT path, id FROM %T WHERE path IN (%Ls)',
PhabricatorRepository::TABLE_PATH,
$path_chunk);
foreach ($chunk_map as $row) {
$result_map[$row['path']] = $row['id'];
}
}
return $result_map;
}
}
diff --git a/src/applications/repository/worker/commitchangeparser/git/PhabricatorRepositoryGitCommitChangeParserWorker.php b/src/applications/repository/worker/commitchangeparser/git/PhabricatorRepositoryGitCommitChangeParserWorker.php
index 5d80ac6ae5..02ce1630c3 100644
--- a/src/applications/repository/worker/commitchangeparser/git/PhabricatorRepositoryGitCommitChangeParserWorker.php
+++ b/src/applications/repository/worker/commitchangeparser/git/PhabricatorRepositoryGitCommitChangeParserWorker.php
@@ -1,215 +1,221 @@
<?php
/*
* Copyright 2011 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class PhabricatorRepositoryGitCommitChangeParserWorker
extends PhabricatorRepositoryCommitChangeParserWorker {
protected function parseCommit(
PhabricatorRepository $repository,
PhabricatorRepositoryCommit $commit) {
$local_path = $repository->getDetail('local-path');
list($raw) = execx(
'(cd %s && git log -n1 -M -C -B --find-copies-harder --raw -t '.
'--abbrev=40 --pretty=format: %s)',
$local_path,
$commit->getCommitIdentifier());
$changes = array();
$move_away = array();
$copy_away = array();
$lines = explode("\n", $raw);
foreach ($lines as $line) {
if (!strlen(trim($line))) {
continue;
}
list($old_mode, $new_mode,
$old_hash, $new_hash,
$more_stuff) = preg_split('/ +/', $line);
// We may only have two pieces here.
list($action, $src_path, $dst_path) = array_merge(
explode("\t", $more_stuff),
array(null));
+ // Normalize the paths for consistency with the SVN workflow.
+ $src_path = '/'.$src_path;
+ if ($dst_path) {
+ $dst_path = '/'.$dst_path;
+ }
+
$old_mode = intval($old_mode, 8);
$new_mode = intval($new_mode, 8);
$file_type = DifferentialChangeType::FILE_NORMAL;
if ($new_mode & 040000) {
$file_type = DifferentialChangeType::FILE_DIRECTORY;
} else if ($new_mode & 0120000) {
$file_type = DifferentialChangeType::FILE_SYMLINK;
}
// TODO: We can detect binary changes as git does, through a combination
// of running 'git check-attr' for stuff like 'binary', 'merge' or 'diff',
// and by falling back to inspecting the first 8,000 characters of the
// buffer for null bytes (this is seriously git's algorithm, see
// buffer_is_binary() in xdiff-interface.c).
$change_type = null;
$change_path = $src_path;
$change_target = null;
switch ($action[0]) {
case 'A':
$change_type = DifferentialChangeType::TYPE_ADD;
break;
case 'D':
$change_type = DifferentialChangeType::TYPE_DELETE;
break;
case 'C':
$change_type = DifferentialChangeType::TYPE_COPY_HERE;
$change_path = $dst_path;
$change_target = $src_path;
$copy_away[$change_target][] = $change_path;
break;
case 'R':
$change_type = DifferentialChangeType::TYPE_MOVE_HERE;
$change_path = $dst_path;
$change_target = $src_path;
$move_away[$change_target][] = $change_path;
break;
case 'M':
$change_type = DifferentialChangeType::TYPE_CHANGE;
break;
default:
throw new Exception("Failed to parse line '{$line}'.");
}
$changes[$change_path] = array(
'repositoryID' => $repository->getID(),
'commitID' => $commit->getID(),
'path' => $change_path,
'changeType' => $change_type,
'fileType' => $file_type,
'isDirect' => true,
'commitSequence' => $commit->getEpoch(),
'targetPath' => $change_target,
'targetCommitID' => $change_target ? $commit->getID() : null,
);
}
foreach ($copy_away as $change_path => $destinations) {
if (isset($move_away[$change_path])) {
$change_type = DifferentialChangeType::TYPE_MULTICOPY;
$is_direct = true;
unset($move_away[$change_path]);
} else {
$change_type = DifferentialChangeType::TYPE_COPY_AWAY;
$is_direct = false;
}
$reference = $changes[reset($destinations)];
$changes[$change_path] = array(
'repositoryID' => $repository->getID(),
'commitID' => $commit->getID(),
'path' => $change_path,
'changeType' => $change_type,
'fileType' => $reference['fileType'],
'isDirect' => $is_direct,
'commitSequence' => $commit->getEpoch(),
'targetPath' => null,
'targetCommitID' => null,
);
}
foreach ($move_away as $change_path => $destinations) {
$reference = $changes[reset($destinations)];
$changes[$change_path] = array(
'repositoryID' => $repository->getID(),
'commitID' => $commit->getID(),
'path' => $change_path,
'changeType' => DifferentialChangeType::TYPE_MOVE_AWAY,
'fileType' => $reference['fileType'],
'isDirect' => true,
'commitSequence' => $commit->getEpoch(),
'targetPath' => null,
'targetCommitID' => null,
);
}
$paths = array();
foreach ($changes as $change) {
$paths[$change['path']] = true;
if ($change['targetPath']) {
$paths[$change['targetPath']] = true;
}
}
$path_map = $this->lookupOrCreatePaths(array_keys($paths));
foreach ($changes as $key => $change) {
$changes[$key]['pathID'] = $path_map[$change['path']];
if ($change['targetPath']) {
$changes[$key]['targetPathID'] = $path_map[$change['targetPath']];
} else {
$changes[$key]['targetPathID'] = null;
}
}
$conn_w = $repository->establishConnection('w');
$changes_sql = array();
foreach ($changes as $change) {
$values = array(
(int)$change['repositoryID'],
(int)$change['pathID'],
(int)$change['commitID'],
$change['targetPathID']
? (int)$change['targetPathID']
: 'null',
$change['targetCommitID']
? (int)$change['targetCommitID']
: 'null',
(int)$change['changeType'],
(int)$change['fileType'],
(int)$change['isDirect'],
(int)$change['commitSequence'],
);
$changes_sql[] = '('.implode(', ', $values).')';
}
queryfx(
$conn_w,
'DELETE FROM %T WHERE commitID = %d',
PhabricatorRepository::TABLE_PATHCHANGE,
$commit->getID());
foreach (array_chunk($changes_sql, 256) as $sql_chunk) {
queryfx(
$conn_w,
'INSERT INTO %T
(repositoryID, pathID, commitID, targetPathID, targetCommitID,
changeType, fileType, isDirect, commitSequence)
VALUES %Q',
PhabricatorRepository::TABLE_PATHCHANGE,
implode(', ', $sql_chunk));
}
}
}
diff --git a/src/applications/repository/worker/commitchangeparser/svn/PhabricatorRepositorySvnCommitChangeParserWorker.php b/src/applications/repository/worker/commitchangeparser/svn/PhabricatorRepositorySvnCommitChangeParserWorker.php
new file mode 100644
index 0000000000..c6e6763c4a
--- /dev/null
+++ b/src/applications/repository/worker/commitchangeparser/svn/PhabricatorRepositorySvnCommitChangeParserWorker.php
@@ -0,0 +1,639 @@
+<?php
+
+/*
+ * Copyright 2011 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+class PhabricatorRepositorySvnCommitChangeParserWorker
+ extends PhabricatorRepositoryCommitChangeParserWorker {
+
+ protected function parseCommit(
+ PhabricatorRepository $repository,
+ PhabricatorRepositoryCommit $commit) {
+
+ // PREAMBLE: This class is absurdly complicated because it is very difficult
+ // to get the information we need out of SVN. The actual data we need is:
+ //
+ // 1. Recursively, what were the affected paths?
+ // 2. For each affected path, is it a file or a directory?
+ // 3. How was each path affected (e.g. add, delete, move, copy)?
+ //
+ // We spend nearly all of our effort figuring out (1) and (2) because
+ // "svn log" is not recursive and does not give us file/directory
+ // information (that is, it will report a directory move as a single move,
+ // even if many thousands of paths are affected).
+ //
+ // Instead, we have to "svn ls -R" the location of each path in its previous
+ // life to figure out whether it is a file or a directory and exactly which
+ // recursive paths were affected if it was moved or copied. This is very
+ // complicated and has many special cases.
+
+ $uri = $repository->getDetail('remote-uri');
+ $svn_commit = $commit->getCommitIdentifier();
+
+ $callsign = $repository->getCallsign();
+ echo "Parsing r{$callsign}{$svn_commit}...\n";
+
+ // Pull the top-level path changes out of "svn log". This is pretty
+ // straightforward; just parse the XML log.
+ list($xml) = execx(
+ 'svn log --verbose --xml --limit 1 --non-interactive %s@%d',
+ $uri,
+ $svn_commit);
+
+ $log = new SimpleXMLElement($xml);
+ $entry = $log->logentry[0];
+
+ if (!$entry->paths) {
+ // TODO: Explicitly mark this commit as broken elsewhere? This isn't
+ // supposed to happen but we have some cases like rE27 and rG935 in the
+ // Facebook repositories where things got all clowned up.
+ return;
+ }
+
+ $raw_paths = array();
+ foreach ($entry->paths->path as $path) {
+ $name = trim((string)$path);
+ $raw_paths[$name] = array(
+ 'rawPath' => $name,
+ 'rawTargetPath' => (string)$path['copyfrom-path'],
+ 'rawChangeType' => (string)$path['action'],
+ 'rawTargetCommit' => (string)$path['copyfrom-rev'],
+ );
+ }
+
+ $copied_or_moved_map = array();
+ $deleted_paths = array();
+ $add_paths = array();
+
+ foreach ($raw_paths as $path => $raw_info) {
+ if ($raw_info['rawTargetPath']) {
+ $copied_or_moved_map[$raw_info['rawTargetPath']][] = $raw_info;
+ }
+ switch ($raw_info['rawChangeType']) {
+ case 'D':
+ $deleted_paths[$path] = $raw_info;
+ break;
+ case 'A':
+ $add_paths[$path] = $raw_info;
+ break;
+ }
+ }
+
+ // If a path was deleted, we need to look in the repository history to
+ // figure out where the former valid location for it is so we can figure out
+ // if it was a directory or not, among other things.
+ $lookup_here = array();
+ foreach ($raw_paths as $path => $raw_info) {
+ if ($raw_info['rawChangeType'] != 'D') {
+ continue;
+ }
+
+ // If a change copies a directory and then deletes something from it,
+ // we need to look at the old location for information about the path, not
+ // the new location. This workflow is pretty ridiculous -- so much so that
+ // Trac gets it wrong. See Facebook rO6 for an example, if you happen to
+ // work at Facebook.
+ $parents = $this->expandAllParentPaths($path, $include_self = true);
+ foreach ($parents as $parent) {
+ if (isset($add_paths[$parent])) {
+ $relative_path = substr($path, strlen($parent));
+ $lookup_here[$path] = array(
+ 'rawPath' => $add_paths[$parent]['rawTargetPath'].$relative_path,
+ 'rawCommit' => $add_paths[$parent]['rawTargetCommit'],
+ );
+ continue 2;
+ }
+ }
+
+ // Otherwise we can just look at the previous revision.
+ $lookup_here[$path] = array(
+ 'rawPath' => $path,
+ 'rawCommit' => $svn_commit - 1,
+ );
+ }
+
+ $lookup = array();
+ foreach ($raw_paths as $path => $raw_info) {
+ if ($raw_info['rawChangeType'] == 'D') {
+ $lookup[$path] = $lookup_here[$path];
+ } else {
+ // For everything that wasn't deleted, we can just look it up directly.
+ $lookup[$path] = array(
+ 'rawPath' => $path,
+ 'rawCommit' => $svn_commit,
+ );
+ }
+ }
+
+ $path_file_types = $this->lookupPathFileTypes($repository, $lookup);
+
+ $effects = array();
+ $resolved_types = array();
+ $supplemental = array();
+ foreach ($raw_paths as $path => $raw_info) {
+ if (isset($resolved_types[$path])) {
+ $type = $resolved_types[$path];
+ } else {
+ switch ($raw_info['rawChangeType']) {
+ case 'D':
+ if (isset($copied_or_moved_map[$path])) {
+ if (count($copied_or_moved_map[$path]) > 1) {
+ $type = DifferentialChangeType::TYPE_MULTICOPY;
+ } else {
+ $type = DifferentialChangeType::TYPE_MOVE_AWAY;
+ }
+ } else {
+ $type = DifferentialChangeType::TYPE_DELETE;
+ $file_type = $path_file_types[$path];
+
+ if ($file_type == DifferentialChangeType::FILE_DIRECTORY) {
+ // Bad. Child paths aren't enumerated in "svn log" so we need
+ // to go fishing.
+
+ $list = $this->lookupRecursiveFileList(
+ $repository,
+ $lookup[$path]);
+
+ foreach ($list as $deleted_path => $path_file_type) {
+ $deleted_path = rtrim($path.'/'.$deleted_path, '/');
+ if (!empty($raw_paths[$deleted_path])) {
+ // We somehow learned about this deletion explicitly?
+ // TODO: Unclear how this is possible.
+ continue;
+ }
+ $effects[$deleted_path] = array(
+ 'rawPath' => $deleted_path,
+ 'rawTargetPath' => null,
+ 'rawTargetCommit' => null,
+ 'rawDirect' => true,
+
+ 'changeType' => $type,
+ 'fileType' => $path_file_type,
+ );
+ }
+ }
+ }
+ break;
+ case 'A':
+ $copy_from = $raw_info['rawTargetPath'];
+ $copy_rev = $raw_info['rawTargetCommit'];
+ if (!strlen($copy_from)) {
+ $type = DifferentialChangeType::TYPE_ADD;
+ } else {
+ if (isset($deleted_paths[$copy_from])) {
+ $type = DifferentialChangeType::TYPE_MOVE_HERE;
+ $other_type = DifferentialChangeType::TYPE_MOVE_AWAY;
+ } else {
+ $type = DifferentialChangeType::TYPE_COPY_HERE;
+ $other_type = DifferentialChangeType::TYPE_COPY_AWAY;
+ }
+
+ $source_file_type = $this->lookupPathFileType(
+ $repository,
+ $path,
+ array(
+ 'rawPath' => $copy_from,
+ 'rawCommit' => $copy_rev,
+ ));
+
+ if ($source_file_type != DifferentialChangeType::FILE_DIRECTORY) {
+ if (isset($raw_paths[$copy_from])) {
+ break;
+ }
+ $effects[$copy_from] = array(
+ 'rawPath' => $copy_from,
+ 'rawTargetPath' => null,
+ 'rawTargetCommit' => null,
+ 'rawDirect' => false,
+
+ 'changeType' => $other_type,
+ 'fileType' => $source_file_type,
+ );
+ } else {
+ // ULTRADISASTER. We've added a directory which was copied
+ // or moved from somewhere else. This is the most complex and
+ // ridiculous case.
+
+ $list = $this->lookupRecursiveFileList(
+ $repository,
+ array(
+ 'rawPath' => $copy_from,
+ 'rawCommit' => $copy_rev,
+ ));
+
+ foreach ($list as $from_path => $from_file_type) {
+ $full_from = rtrim($copy_from.'/'.$from_path, '/');
+ $full_to = rtrim($path.'/'.$from_path, '/');
+
+ if (empty($raw_paths[$full_to])) {
+ $effects[$full_to] = array(
+ 'rawPath' => $full_to,
+ 'rawTargetPath' => $full_from,
+ 'rawTargetCommit' => $copy_rev,
+ 'rawDirect' => true,
+
+ 'changeType' => $type,
+ 'fileType' => $from_file_type,
+ );
+ } else {
+ // This means we picked the file up explicitly elsewhere.
+ // If the file as modified, SVN will drop the copy
+ // information. We need to restore it.
+ $supplemental[$full_to]['rawTargetPath'] = $full_from;
+ $supplemental[$full_to]['rawTargetCommit'] = $copy_rev;
+ if ($raw_paths[$full_to]['rawChangeType'] == 'M') {
+ $resolved_types[$full_to] = $type;
+ }
+ }
+
+ if (empty($raw_paths[$full_from])) {
+ if ($other_type == DifferentialChangeType::TYPE_COPY_AWAY) {
+ $effects[$full_from] = array(
+ 'rawPath' => $full_from,
+ 'rawTargetPath' => null,
+ 'rawTargetCommit' => null,
+ 'rawDirect' => false,
+
+ 'changeType' => $other_type,
+ 'fileType' => $from_file_type,
+ );
+ }
+ }
+ }
+ }
+ }
+ break;
+ // This is "replaced", caused by "svn rm"-ing a file, putting another
+ // in its place, and then "svn add"-ing it. We do not distinguish
+ // between this and "M".
+ case 'R':
+ case 'M':
+ if (isset($copied_or_moved_map[$path])) {
+ $type = DifferentialChangeType::TYPE_COPY_AWAY;
+ } else {
+ $type = DifferentialChangeType::TYPE_CHANGE;
+ }
+ break;
+ }
+ }
+ $resolved_types[$path] = $type;
+ }
+
+ foreach ($raw_paths as $path => $raw_info) {
+ $raw_paths[$path]['changeType'] = $resolved_types[$path];
+ if (isset($supplemental[$path])) {
+ foreach ($supplemental[$path] as $key => $value) {
+ $raw_paths[$path][$key] = $value;
+ }
+ }
+ }
+
+ foreach ($raw_paths as $path => $raw_info) {
+ $effects[$path] = array(
+ 'rawPath' => $path,
+ 'rawTargetPath' => $raw_info['rawTargetPath'],
+ 'rawTargetCommit' => $raw_info['rawTargetCommit'],
+ 'rawDirect' => true,
+
+ 'changeType' => $raw_info['changeType'],
+ 'fileType' => $path_file_types[$path],
+ );
+ }
+
+ $parents = array();
+ foreach ($effects as $path => $effect) {
+ foreach ($this->expandAllParentPaths($path) as $parent_path) {
+ $parents[$parent_path] = true;
+ }
+ }
+ $parents = array_keys($parents);
+
+ foreach ($parents as $parent) {
+ if (isset($effects[$parent])) {
+ continue;
+ }
+
+ $effects[$parent] = array(
+ 'rawPath' => $parent,
+ 'rawTargetPath' => null,
+ 'rawTargetCommit' => null,
+ 'rawDirect' => false,
+
+ 'changeType' => DifferentialChangeType::TYPE_CHILD,
+ 'fileType' => DifferentialChangeType::FILE_DIRECTORY,
+ );
+ }
+
+ $lookup_paths = array();
+ foreach ($effects as $effect) {
+ $lookup_paths[$effect['rawPath']] = true;
+ if ($effect['rawTargetPath']) {
+ $lookup_paths[$effect['rawTargetPath']] = true;
+ }
+ }
+ $lookup_paths = array_keys($lookup_paths);
+
+ $lookup_commits = array();
+ foreach ($effects as $effect) {
+ if ($effect['rawTargetCommit']) {
+ $lookup_commits[$effect['rawTargetCommit']] = true;
+ }
+ }
+ $lookup_commits = array_keys($lookup_commits);
+
+ $path_map = $this->lookupOrCreatePaths($lookup_paths);
+ $commit_map = $this->lookupSvnCommits($repository, $lookup_commits);
+
+ $this->writeChanges($repository, $commit, $effects, $path_map, $commit_map);
+ $this->writeBrowse($repository, $commit, $effects, $path_map);
+ }
+
+ private function writeChanges(
+ PhabricatorRepository $repository,
+ PhabricatorRepositoryCommit $commit,
+ array $effects,
+ array $path_map,
+ array $commit_map) {
+
+ $conn_w = $repository->establishConnection('w');
+
+ $sql = array();
+ foreach ($effects as $effect) {
+ $sql[] = qsprintf(
+ $conn_w,
+ '(%d, %d, %d, %nd, %nd, %d, %d, %d, %d)',
+ $repository->getID(),
+ $path_map[$effect['rawPath']],
+ $commit->getID(),
+ $effect['rawTargetPath']
+ ? $path_map[$effect['rawTargetPath']]
+ : null,
+ $effect['rawTargetCommit']
+ ? $commit_map[$effect['rawTargetCommit']]
+ : null,
+ $effect['changeType'],
+ $effect['fileType'],
+ $effect['rawDirect']
+ ? 1
+ : 0,
+ $commit->getCommitIdentifier());
+ }
+
+ queryfx(
+ $conn_w,
+ 'DELETE FROM %T WHERE commitID = %d',
+ PhabricatorRepository::TABLE_PATHCHANGE,
+ $commit->getID());
+ foreach (array_chunk($sql, 512) as $sql_chunk) {
+ queryfx(
+ $conn_w,
+ 'INSERT INTO %T
+ (repositoryID, pathID, commitID, targetPathID, targetCommitID,
+ changeType, fileType, isDirect, commitSequence)
+ VALUES %Q',
+ PhabricatorRepository::TABLE_PATHCHANGE,
+ implode(', ', $sql_chunk));
+ }
+ }
+
+ private function writeBrowse(
+ PhabricatorRepository $repository,
+ PhabricatorRepositoryCommit $commit,
+ array $effects,
+ array $path_map) {
+
+ $conn_w = $repository->establishConnection('w');
+
+ $sql = array();
+ foreach ($effects as $effect) {
+ $type = $effect['changeType'];
+
+ // Don't write COPY_AWAY to the filesystem table if it isn't a direct
+ // event. We do write CHILD.
+ if (!$effect['rawDirect']) {
+ if ($type == DifferentialChangeType::TYPE_COPY_AWAY) {
+ continue;
+ }
+ }
+
+ $existed = !DifferentialChangeType::isDeleteChangeType($type);
+
+ $sql[] = qsprintf(
+ $conn_w,
+ '(%d, %d, %d, %d, %d, %d)',
+ $repository->getID(),
+ $path_map[$this->getParentPath($effect['rawPath'])],
+ $commit->getCommitIdentifier(),
+ $path_map[$effect['rawPath']],
+ $existed
+ ? 1
+ : 0,
+ $effect['fileType']);
+ }
+
+ queryfx(
+ $conn_w,
+ 'DELETE FROM %T WHERE repositoryID = %d AND svnCommit = %d',
+ PhabricatorRepository::TABLE_FILESYSTEM,
+ $repository->getID(),
+ $commit->getCommitIdentifier());
+
+ foreach (array_chunk($sql, 512) as $sql_chunk) {
+ queryfx(
+ $conn_w,
+ 'INSERT INTO %T
+ (repositoryID, parentID, svnCommit, pathID, existed, fileType)
+ VALUES %Q',
+ PhabricatorRepository::TABLE_FILESYSTEM,
+ implode(', ', $sql_chunk));
+ }
+
+ }
+
+ private function lookupSvnCommits(
+ PhabricatorRepository $repository,
+ array $commits) {
+
+ if (!$commits) {
+ return array();
+ }
+
+ $commit_table = new PhabricatorRepositoryCommit();
+ $commit_data = queryfx_all(
+ $commit_table->establishConnection('w'),
+ 'SELECT id, commitIdentifier FROM %T WHERE commitIdentifier in (%Ld)',
+ $commit_table->getTableName(),
+ $commits);
+
+ return ipull($commit_data, 'id', 'commitIdentifier');
+ }
+
+ private function lookupPathFileType(
+ PhabricatorRepository $repository,
+ $path,
+ array $path_info) {
+
+ $result = $this->lookupPathFileTypes(
+ $repository,
+ array(
+ $path => $path_info,
+ ));
+
+ return $result[$path];
+ }
+
+ private function lookupPathFileTypes(
+ PhabricatorRepository $repository,
+ array $paths) {
+
+ $repository_uri = $repository->getDetail('remote-uri');
+
+ $parents = array();
+ $path_mapping = array();
+ foreach ($paths as $path => $lookup) {
+ $parent = dirname($lookup['rawPath']);
+ $parent = ltrim($parent, '/');
+ $parent = $this->encodeSVNPath($parent);
+ $parent = $repository_uri.$parent.'@'.$lookup['rawCommit'];
+ $parent = escapeshellarg($parent);
+ $parents[$parent] = true;
+ $path_mapping[$parent][] = $path;
+ }
+
+ $result_map = array();
+
+ // Reverse this list so we can pop $path_mapping, as that's more efficient
+ // than shifting it. We need to associate these maps positionally because
+ // a change can copy the same source path from multiple revisions via
+ // "svn cp path@1 a; svn cp path@2 b;" and the XML output gives us no way
+ // to distinguish which revision we're looking at except based on its
+ // position in the document.
+ $all_paths = array_reverse(array_keys($parents));
+ foreach (array_chunk($all_paths, 64) as $path_chunk) {
+ list($raw_xml) = execx(
+ 'svn --non-interactive --xml ls %C',
+ implode(' ', $path_chunk));
+
+ $xml = new SimpleXMLElement($raw_xml);
+ foreach ($xml->list as $list) {
+ $list_path = (string)$list['path'];
+
+ // SVN is a big mess. See Facebook rG8 (a revision which adds files
+ // with spaces in their names) for an example.
+ $list_path = rawurldecode($list_path);
+
+ if ($list_path == $repository_uri) {
+ $base = '/';
+ } else {
+ $base = substr($list_path, strlen($repository_uri));
+ }
+
+ $mapping = array_pop($path_mapping);
+ foreach ($list->entry as $entry) {
+ $val = $this->getFileTypeFromSVNKind($entry['kind']);
+ foreach ($mapping as $base_path) {
+ // rtrim() causes us to handle top-level directories correctly.
+ $key = rtrim($base_path, '/').'/'.$entry->name;
+ $result_map[$key] = $val;
+ }
+ }
+ }
+ }
+
+ foreach ($paths as $path => $lookup) {
+ if (empty($result_map[$path])) {
+ $result_map[$path] = DifferentialChangeType::FILE_DELETED;
+ }
+ }
+
+ return $result_map;
+ }
+
+ private function encodeSVNPath($path) {
+ $path = rawurlencode($path);
+ $path = str_replace('%2F', '/', $path);
+ return $path;
+ }
+
+ private function getFileTypeFromSVNKind($kind) {
+ $kind = (string)$kind;
+ switch ($kind) {
+ case 'dir': return DifferentialChangeType::FILE_DIRECTORY;
+ case 'file': return DifferentialChangeType::FILE_NORMAL;
+ default:
+ throw new Exception("Unknown SVN file kind '{$kind}'.");
+ }
+ }
+
+ private function lookupRecursiveFileList(
+ PhabricatorRepository $repository,
+ array $info) {
+
+ $path = $info['rawPath'];
+ $rev = $info['rawCommit'];
+ $path = $this->encodeSVNPath($path);
+
+ // TODO: This is a scalability nightmare.
+
+ list($raw_xml) = execx(
+ 'svn --non-interactive --xml ls -R %s%s@%d',
+ $repository->getDetail('remote-uri'),
+ $path,
+ $rev);
+
+ $map = array();
+
+ $xml = new SimpleXMLElement($raw_xml);
+ foreach ($xml->list[0] as $entry) {
+ $key = (string)$entry->name;
+ $file_type = $this->getFileTypeFromSVNKind($entry['kind']);
+ $map[$key] = $file_type;
+ }
+
+ return $map;
+ }
+
+ private function getParentPath($path) {
+ $path = rtrim('/', $path);
+ $path = dirname($path);
+ $path = rtrim('/', $path);
+ if (!$path) {
+ $path = '/';
+ }
+ return $path;
+ }
+
+ private function expandAllParentPaths($path, $include_self = false) {
+ $parents = array();
+ if ($include_self) {
+ $parents[] = '/'.rtrim($path, '/');
+ }
+ $parts = explode('/', trim($path, '/'));
+ while (count($parts) >= 1) {
+ array_pop($parts);
+ $parents[] = '/'.implode('/', $parts);
+ }
+ return $parents;
+ }
+
+}
+
+
+
+
+
+
+
diff --git a/src/applications/repository/worker/commitchangeparser/svn/__init__.php b/src/applications/repository/worker/commitchangeparser/svn/__init__.php
new file mode 100644
index 0000000000..d714b622e9
--- /dev/null
+++ b/src/applications/repository/worker/commitchangeparser/svn/__init__.php
@@ -0,0 +1,20 @@
+<?php
+/**
+ * This file is automatically generated. Lint this module to rebuild it.
+ * @generated
+ */
+
+
+
+phutil_require_module('phabricator', 'applications/differential/constants/changetype');
+phutil_require_module('phabricator', 'applications/repository/storage/commit');
+phutil_require_module('phabricator', 'applications/repository/storage/repository');
+phutil_require_module('phabricator', 'applications/repository/worker/commitchangeparser/base');
+phutil_require_module('phabricator', 'storage/qsprintf');
+phutil_require_module('phabricator', 'storage/queryfx');
+
+phutil_require_module('phutil', 'future/exec');
+phutil_require_module('phutil', 'utils');
+
+
+phutil_require_source('PhabricatorRepositorySvnCommitChangeParserWorker.php');
diff --git a/src/applications/repository/worker/commitmessageparser/svn/PhabricatorRepositorySvnCommitMessageParserWorker.php b/src/applications/repository/worker/commitmessageparser/svn/PhabricatorRepositorySvnCommitMessageParserWorker.php
index f31b09f5c0..7e29d1a78d 100644
--- a/src/applications/repository/worker/commitmessageparser/svn/PhabricatorRepositorySvnCommitMessageParserWorker.php
+++ b/src/applications/repository/worker/commitmessageparser/svn/PhabricatorRepositorySvnCommitMessageParserWorker.php
@@ -1,44 +1,49 @@
<?php
/*
* Copyright 2011 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class PhabricatorRepositorySvnCommitMessageParserWorker
extends PhabricatorRepositoryCommitMessageParserWorker {
public function parseCommit(
PhabricatorRepository $repository,
PhabricatorRepositoryCommit $commit) {
$uri = $repository->getDetail('remote-uri');
list($xml) = execx(
'svn log --xml --limit 1 --non-interactive %s@%d',
$uri,
$commit->getCommitIdentifier());
// TODO: Need to slam UTF8.
$log = new SimpleXMLElement($xml);
$entry = $log->logentry[0];
$author = (string)$entry->author;
$message = (string)$entry->msg;
$this->updateCommitData($author, $message);
+
+ $task = new PhabricatorWorkerTask();
+ $task->setTaskClass('PhabricatorRepositorySvnCommitChangeParserWorker');
+ $task->setData($commit->getID());
+ $task->save();
}
}
diff --git a/src/applications/repository/worker/commitmessageparser/svn/__init__.php b/src/applications/repository/worker/commitmessageparser/svn/__init__.php
index e8bb732e78..df72cc9af5 100644
--- a/src/applications/repository/worker/commitmessageparser/svn/__init__.php
+++ b/src/applications/repository/worker/commitmessageparser/svn/__init__.php
@@ -1,14 +1,15 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'applications/repository/worker/commitmessageparser/base');
+phutil_require_module('phabricator', 'infrastructure/daemon/workers/storage/task');
phutil_require_module('phutil', 'future/exec');
phutil_require_source('PhabricatorRepositorySvnCommitMessageParserWorker.php');

File Metadata

Mime Type
text/x-diff
Expires
Thu, Aug 14, 2:48 AM (4 d, 11 h ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
202154
Default Alt Text
(83 KB)

Event Timeline