From aa138a80d29313c528728e2d22c73a3ac5eea1fe Mon Sep 17 00:00:00 2001 From: epriestley Date: Tue, 23 Aug 2011 18:48:55 -0700 Subject: [PATCH] Attach local commit information to DVCS revisions Summary: When a revision is created, attach relevant information about the local commits which it came from if applicable. This supports T473, for DCVSes and DCVS workflows with immutable history where we can't just amend commit messages. It will also allow us to enrich the web interface. Test Plan: Will verify this info shows up for this very diff. Reviewers: fratrik, aran, jungejason, tuomaspelkonen Reviewed By: fratrik CC: aran, epriestley, fratrik Differential Revision: 857 --- .../api/base/ArcanistRepositoryAPI.php | 1 + src/repository/api/git/ArcanistGitAPI.php | 29 +++++++++++++++++++ .../api/mercurial/ArcanistMercurialAPI.php | 20 +++++++++++++ .../api/subversion/ArcanistSubversionAPI.php | 4 +++ src/workflow/diff/ArcanistDiffWorkflow.php | 11 +++++++ 5 files changed, 65 insertions(+) diff --git a/src/repository/api/base/ArcanistRepositoryAPI.php b/src/repository/api/base/ArcanistRepositoryAPI.php index 1acdd39f..1a987707 100644 --- a/src/repository/api/base/ArcanistRepositoryAPI.php +++ b/src/repository/api/base/ArcanistRepositoryAPI.php @@ -157,5 +157,6 @@ abstract class ArcanistRepositoryAPI { abstract public function getRawDiffText($path); abstract public function getOriginalFileData($path); abstract public function getCurrentFileData($path); + abstract public function getLocalCommitInformation(); } diff --git a/src/repository/api/git/ArcanistGitAPI.php b/src/repository/api/git/ArcanistGitAPI.php index 520aad78..17181d76 100644 --- a/src/repository/api/git/ArcanistGitAPI.php +++ b/src/repository/api/git/ArcanistGitAPI.php @@ -46,6 +46,35 @@ class ArcanistGitAPI extends ArcanistRepositoryAPI { return $this; } + public function getLocalCommitInformation() { + list($info) = execx( + '(cd %s && git log %s..%s --format=%s --)', + $this->getPath(), + $this->getRelativeCommit(), + 'HEAD', + '%H%x00%T%x00%P%x00%at%x00%an%x00%s'); + + $commits = array(); + + $info = trim($info); + $info = explode("\n", $info); + foreach ($info as $line) { + list($commit, $tree, $parents, $time, $author, $title) + = explode("\0", $line, 6); + + $commits[] = array( + 'commit' => $commit, + 'tree' => $tree, + 'parents' => array_filter(explode(' ', $parents)), + 'time' => $time, + 'author' => $author, + 'summary' => $title, + ); + } + + return $commits; + } + public function getRelativeCommit() { if ($this->relativeCommit === null) { list($err) = exec_manual( diff --git a/src/repository/api/mercurial/ArcanistMercurialAPI.php b/src/repository/api/mercurial/ArcanistMercurialAPI.php index 0571cced..d9de1a1b 100644 --- a/src/repository/api/mercurial/ArcanistMercurialAPI.php +++ b/src/repository/api/mercurial/ArcanistMercurialAPI.php @@ -82,6 +82,16 @@ class ArcanistMercurialAPI extends ArcanistRepositoryAPI { return $this->relativeCommit; } + public function getLocalCommitInformation() { + list($info) = execx( + '(cd %s && hg log --rev %s..%s --)', + $this->getPath(), + $this->getRelativeCommit(), + 'tip'); + return $this->parseMercurialLog($info); + } + + public function getBlame($path) { list($stdout) = execx( '(cd %s && hg blame -u -v -c --rev %s -- %s)', @@ -284,6 +294,16 @@ class ArcanistMercurialAPI extends ArcanistRepositoryAPI { $commit['local'] = $local; $commit['rev'] = $rev; break; + case 'parent': + if (empty($commit['parents'])) { + $commit['parents'] = array(); + } + list($local, $rev) = explode(':', $value, 2); + $commit['parents'][] = array( + 'local' => $local, + 'rev' => $rev, + ); + break; default: throw new Exception("Unknown Mercurial log field '{$name}'!"); } diff --git a/src/repository/api/subversion/ArcanistSubversionAPI.php b/src/repository/api/subversion/ArcanistSubversionAPI.php index 9a6941e2..4616ed35 100644 --- a/src/repository/api/subversion/ArcanistSubversionAPI.php +++ b/src/repository/api/subversion/ArcanistSubversionAPI.php @@ -478,4 +478,8 @@ EODIFF; return $info['Repository UUID']; } + public function getLocalCommitInformation() { + return null; + } + } diff --git a/src/workflow/diff/ArcanistDiffWorkflow.php b/src/workflow/diff/ArcanistDiffWorkflow.php index 0a8c4cde..8fa93390 100644 --- a/src/workflow/diff/ArcanistDiffWorkflow.php +++ b/src/workflow/diff/ArcanistDiffWorkflow.php @@ -339,6 +339,17 @@ EOTEXT )); } + $local_info = $repository_api->getLocalCommitInformation(); + if ($local_info) { + $conduit->callMethodSynchronous( + 'differential.setdiffproperty', + array( + 'diff_id' => $diff_info['diffid'], + 'name' => 'local:commits', + 'data' => json_encode($local_info), + )); + } + if ($this->unresolvedTests) { $data = array(); foreach ($this->unresolvedTests as $test) {