mirror of
https://we.phorge.it/source/arcanist.git
synced 2024-11-10 08:52:39 +01:00
Augment arc patch behavior
Summary: under git, we now create a branch that is at the patch's base revision if we know it or whatever the working copy happened to be at if we don't. This diff also adds the --nobranch flag to disable this new behavior. Also added an --update flag. When specified, we run the appropriate "update" command in the VCS. By default this is off. Finally, tried to give the user more information about what the heck arc just did to their working copy. Test Plan: // verify --update flag works // -- git Assume we are at HEAD and we got to HEAD from HEAD^1 via DX git reset --hard <THE BEGINNING> arc patch --update DX // ...versus svn Assume we are at HEAD and we got to HEAD from HEAD^1 via DX svn checkout -r 1 arc patch --update DX // ...versus hg Assume we are at HEAD and we got to HEAD from HEAD^1 via DX hg update -r 1 arc patch --update DX // verify under git a nice branch is made // -- test where we should get a good name // -- test where we have a base revision to check out the branch at Assume we are at HEAD and we got to HEAD from HEAD^1 via DX git reset --hard HEAD^1 arc patch DX // verify under git an "okay" branch is made if we can't get "nice" // -- test where we should get a "bad" name // -- test where we DON'T have a base revision to check out the branch at git diff HEAD^1 > ~/example.patch git reset --hard HEAD^1 arc patch --patch ~/example.patch // verify --nobranch flag skips the test for git Assume we are at HEAD and we got to HEAD from HEAD^1 via DX git reset --head HEAD^1 arc patch --nobranch DX Reviewers: epriestley Reviewed By: epriestley CC: aran Maniphest Tasks: T479 Differential Revision: https://secure.phabricator.com/D1459
This commit is contained in:
parent
2c4eb00a12
commit
a1a25f72f5
1 changed files with 142 additions and 2 deletions
|
@ -75,6 +75,16 @@ EOTEXT
|
|||
'help' =>
|
||||
"Apply changes from a git patchfile or unified patchfile.",
|
||||
),
|
||||
'update' => array(
|
||||
'supports' => array(
|
||||
'git', 'svn', 'hg'
|
||||
),
|
||||
'help' =>
|
||||
"Update the local working copy before applying the patch.",
|
||||
'conflicts' => array(
|
||||
'nobranch' => true,
|
||||
),
|
||||
),
|
||||
'nocommit' => array(
|
||||
'supports' => array(
|
||||
'git'
|
||||
|
@ -83,6 +93,19 @@ EOTEXT
|
|||
"Normally under git if the patch is successful the changes are ".
|
||||
"committed to the working copy. This flag prevents the commit.",
|
||||
),
|
||||
'nobranch' => array(
|
||||
'supports' => array(
|
||||
'git'
|
||||
),
|
||||
'help' =>
|
||||
"Normally under git a new branch is created and then the patch ".
|
||||
"is applied and committed in the branch. This flag skips the ".
|
||||
"branch creation step and applies and commits the patch to the ".
|
||||
"current branch.",
|
||||
'conflicts' => array(
|
||||
'update' => true,
|
||||
),
|
||||
),
|
||||
'force' => array(
|
||||
'help' =>
|
||||
"Do not run any sanity checks.",
|
||||
|
@ -171,6 +194,114 @@ EOTEXT
|
|||
return true;
|
||||
}
|
||||
|
||||
private function shouldBranch() {
|
||||
// git only for now
|
||||
$repository_api = $this->getRepositoryAPI();
|
||||
if (!($repository_api instanceof ArcanistGitAPI)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$no_branch = $this->getArgument('nobranch', false);
|
||||
if ($no_branch) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private function getBranchName(ArcanistBundle $bundle) {
|
||||
$branch_name = null;
|
||||
$repository_api = $this->getRepositoryAPI();
|
||||
$revision_id = $bundle->getRevisionID();
|
||||
if ($revision_id) {
|
||||
$base_name = "D{$revision_id}";
|
||||
} else {
|
||||
$base_name = "Arcanist-created-branch";
|
||||
}
|
||||
|
||||
$suffixes = array(null, '-1', '-2', '-3');
|
||||
foreach ($suffixes as $suffix) {
|
||||
$proposed_name = $base_name.$suffix;
|
||||
|
||||
list($err) = exec_manual(
|
||||
'(cd %s; git rev-parse --verify %s)',
|
||||
$repository_api->getPath(),
|
||||
$proposed_name
|
||||
);
|
||||
|
||||
// no error means git rev-parse found a branch
|
||||
if (!$err) {
|
||||
echo phutil_console_format(
|
||||
"Branch name {$proposed_name} alread exists; trying a new name.\n"
|
||||
);
|
||||
continue;
|
||||
} else {
|
||||
$branch_name = $proposed_name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$branch_name) {
|
||||
throw new Exception(
|
||||
"Arc was unable to automagically make a name for this patch. ".
|
||||
"Please clean up your working copy and try again."
|
||||
);
|
||||
}
|
||||
|
||||
return $branch_name;
|
||||
}
|
||||
|
||||
private function createBranch(ArcanistBundle $bundle) {
|
||||
$branch_name = $this->getBranchName($bundle);
|
||||
$repository_api = $this->getRepositoryAPI();
|
||||
$base_revision = $bundle->getBaseRevision();
|
||||
|
||||
if ($base_revision) {
|
||||
execx(
|
||||
'(cd %s; git checkout -b %s %s)',
|
||||
$repository_api->getPath(),
|
||||
$branch_name,
|
||||
$base_revision);
|
||||
} else {
|
||||
execx(
|
||||
'(cd %s; git checkout -b %s)',
|
||||
$repository_api->getPath(),
|
||||
$branch_name);
|
||||
}
|
||||
|
||||
echo phutil_console_format(
|
||||
"Created and checked out branch {$branch_name}.\n"
|
||||
);
|
||||
}
|
||||
|
||||
private function shouldUpdateWorkingCopy() {
|
||||
return $this->getArgument('update', false);
|
||||
}
|
||||
|
||||
private function updateWorkingCopy() {
|
||||
$repository_api = $this->getRepositoryAPI();
|
||||
if ($repository_api instanceof ArcanistSubversionAPI) {
|
||||
execx(
|
||||
'(cd %s; svn up)',
|
||||
$repository_api->getPath());
|
||||
$message = "Updated to HEAD. ";
|
||||
} else if ($repository_api instanceof ArcanistGitAPI) {
|
||||
execx(
|
||||
'(cd %s; git pull)',
|
||||
$repository_api->getPath());
|
||||
$message = "Updated to HEAD. ";
|
||||
} else if ($repository_api instanceof ArcanistMercurialAPI) {
|
||||
execx(
|
||||
'(cd %s; hg up)',
|
||||
$repository_api->getPath());
|
||||
$message = "Updated to tip. ";
|
||||
} else {
|
||||
throw new Exception('Unknown version control system.');
|
||||
}
|
||||
|
||||
echo phutil_console_format($message."\n");
|
||||
}
|
||||
|
||||
public function run() {
|
||||
|
||||
$source = $this->getSource();
|
||||
|
@ -215,6 +346,15 @@ EOTEXT
|
|||
}
|
||||
}
|
||||
|
||||
// we should update the working copy before we do ANYTHING else
|
||||
if ($this->shouldUpdateWorkingCopy()) {
|
||||
$this->updateWorkingCopy();
|
||||
}
|
||||
|
||||
if ($this->shouldBranch()) {
|
||||
$this->createBranch($bundle);
|
||||
}
|
||||
|
||||
$force = $this->getArgument('force', false);
|
||||
if ($force) {
|
||||
// force means don't do any sanity checks about the patch
|
||||
|
@ -405,8 +545,8 @@ EOTEXT
|
|||
|
||||
if ($patch_err == 0) {
|
||||
echo phutil_console_format(
|
||||
"<bg:green>** OKAY **</bg> Successfully applied patch to the ".
|
||||
"working copy.\n");
|
||||
"<bg:green>** OKAY **</bg> Successfully applied patch ".
|
||||
"to the working copy.\n");
|
||||
} else {
|
||||
echo phutil_console_format(
|
||||
"\n\n<bg:yellow>** WARNING **</bg> Some hunks could not be applied ".
|
||||
|
|
Loading…
Reference in a new issue