1
0
Fork 0
mirror of https://we.phorge.it/source/arcanist.git synced 2024-11-25 16:22:42 +01:00

Use git-cherry-pick for arc patch

Summary:
This changes what --nobranch does, though not what it means.  In git, the patch
is applied to the git commit it is based off where it will commit cleanly, and
if you specify --nobranch then arc-patch will then switch back to your original
branch and try to cherry-pick the commit there.

If this fails, you end up with merge-conflict markers in the file which can be
handy.

Test Plan: https://secure.phabricator.com/P572

Reviewers: epriestley, btrahan

Reviewed By: epriestley

CC: aran, Korvin

Differential Revision: https://secure.phabricator.com/D3712
This commit is contained in:
Edward Speyer 2012-10-16 16:46:21 -07:00
parent a850f1c6ef
commit 2d269aefed

View file

@ -111,9 +111,9 @@ EOTEXT
),
'help' =>
"Normally under git, a new branch is created and then the patch ".
"is applied and committed in the new branch. This flag skips the ".
"branch creation step and applies and commits the patch to the ".
"current branch.",
"is applied and committed in the new branch. This flag ".
"cherry-picks the resultant commit onto the original branch and ".
"deletes the temporary branch.",
'conflicts' => array(
'update' => true,
),
@ -219,18 +219,20 @@ EOTEXT
return true;
}
private function shouldBranch() {
private function canBranch() {
// git only for now
$repository_api = $this->getRepositoryAPI();
if (!($repository_api instanceof ArcanistGitAPI)) {
return false;
}
return true;
}
private function shouldBranch() {
$no_branch = $this->getArgument('nobranch', false);
if ($no_branch) {
return false;
}
return true;
}
@ -328,10 +330,9 @@ EOTEXT
return $bookmark_name;
}
private function createBranch(ArcanistBundle $bundle) {
$branch_name = $this->getBranchName($bundle);
$repository_api = $this->getRepositoryAPI();
private function hasBaseRevision(ArcanistBundle $bundle) {
$base_revision = $bundle->getBaseRevision();
$repository_api = $this->getRepositoryAPI();
// verify the base revision is valid
// in a working copy that uses the git-svn bridge, the base revision might
@ -343,8 +344,15 @@ EOTEXT
list($err) = $repository_api->execManualLocal(
'cat-file -t %s',
$base_revision);
return !$err;
}
if ($base_revision && !$err) {
private function createBranch(ArcanistBundle $bundle, $has_base_revision) {
$branch_name = $this->getBranchName($bundle);
$base_revision = $bundle->getBaseRevision();
$repository_api = $this->getRepositoryAPI();
if ($base_revision && $has_base_revision) {
$repository_api->execxLocal(
'checkout -b %s %s',
$branch_name,
@ -358,6 +366,8 @@ EOTEXT
echo phutil_console_format(
"Created and checked out branch %s.\n",
$branch_name);
return $branch_name;
}
private function createBookmark(ArcanistBundle $bundle) {
@ -454,15 +464,18 @@ EOTEXT
$this->updateWorkingCopy();
}
if ($this->shouldBranch()) {
$this->createBranch($bundle);
$repository_api = $this->getRepositoryAPI();
$has_base_revision = $this->hasBaseRevision($bundle);
if ($this->canBranch() && ($this->shouldBranch() || $has_base_revision)) {
$original_branch = $repository_api->getBranchName();
$new_branch = $this->createBranch($bundle, $has_base_revision);
}
if ($this->shouldBookmark()) {
$this->createBookmark($bundle);
}
$repository_api = $this->getRepositoryAPI();
if ($repository_api instanceof ArcanistSubversionAPI) {
$patch_err = 0;
@ -706,6 +719,21 @@ EOTEXT
} else {
$verb = 'applied';
}
if ($this->canBranch() && !$this->shouldBranch() && $has_base_revision) {
$repository_api->execxLocal('checkout %s', $original_branch);
$ex = null;
try {
$repository_api->execxLocal('cherry-pick %s', $new_branch);
} catch (Exception $ex) {}
$repository_api->execxLocal('branch -D %s', $new_branch);
if ($ex) {
echo phutil_console_format(
"\n<bg:red>** Cherry Pick Failed!**</bg>\n");
throw $ex;
}
}
echo phutil_console_format(
"<bg:green>** OKAY **</bg> Successfully {$verb} patch.\n");
} else if ($repository_api instanceof ArcanistMercurialAPI) {