Updates to apply-patch
- use other commit then master as a base - recursively find dependent commits - commit dependent changes before applying main diff
This commit is contained in:
parent
ee420f2911
commit
7ba1fd18ac
1 changed files with 37 additions and 20 deletions
|
@ -18,7 +18,6 @@ import json
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
|
||||||
from typing import List, Optional, Tuple
|
from typing import List, Optional, Tuple
|
||||||
|
|
||||||
from phabricator import Phabricator
|
from phabricator import Phabricator
|
||||||
|
@ -50,7 +49,7 @@ class ApplyPatch:
|
||||||
if not self.host.endswith('/api/'):
|
if not self.host.endswith('/api/'):
|
||||||
self.host += '/api/'
|
self.host += '/api/'
|
||||||
self.phab = self._create_phab()
|
self.phab = self._create_phab()
|
||||||
self.git_hash = git_hash # type: Optional[str]
|
self.base_revision = git_hash # type: Optional[str]
|
||||||
self.msg = [] # type: List[str]
|
self.msg = [] # type: List[str]
|
||||||
self.repo = Repo(os.getcwd()) # type: Repo
|
self.repo = Repo(os.getcwd()) # type: Repo
|
||||||
|
|
||||||
|
@ -72,10 +71,12 @@ class ApplyPatch:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
revision_id, dependencies, base_revision = self._get_dependencies()
|
revision_id, dependencies, base_revision = self._get_dependencies(self.diff_id)
|
||||||
if self.git_hash is not None:
|
dependencies.reverse() # Arrange deps in chronological order.
|
||||||
print('Using base revision provided by command line')
|
if self.base_revision is not None:
|
||||||
base_revision = self.git_hash
|
print('Using base revision provided by command line\n{} instead of resolved\n{}'.format(
|
||||||
|
self.base_revision, base_revision))
|
||||||
|
base_revision = self.base_revision
|
||||||
print('Checking out {}...'.format(base_revision))
|
print('Checking out {}...'.format(base_revision))
|
||||||
try:
|
try:
|
||||||
self.repo.git.checkout(base_revision)
|
self.repo.git.checkout(base_revision)
|
||||||
|
@ -91,10 +92,14 @@ class ApplyPatch:
|
||||||
if len(dependencies) > 0:
|
if len(dependencies) > 0:
|
||||||
print('This diff depends on: {}'.format(diff_list_to_str(dependencies)))
|
print('This diff depends on: {}'.format(diff_list_to_str(dependencies)))
|
||||||
missing, landed = self._get_missing_landed_dependencies(dependencies)
|
missing, landed = self._get_missing_landed_dependencies(dependencies)
|
||||||
print(' These have already landed: {}'.format(diff_list_to_str(landed)))
|
print(' Already landed: {}'.format(diff_list_to_str(landed)))
|
||||||
print(' These are missing on master: {}'.format(diff_list_to_str(missing)))
|
print(' Will be applied: {}'.format(diff_list_to_str(missing)))
|
||||||
|
if missing:
|
||||||
for revision in missing:
|
for revision in missing:
|
||||||
self._apply_revision(revision)
|
self._apply_revision(revision)
|
||||||
|
self.repo.config_writer().set_value("user", "name", "myusername").release()
|
||||||
|
self.repo.config_writer().set_value("user", "email", "myemail@example.com").release()
|
||||||
|
self.repo.git.commit('-a', '-m', 'dependencies')
|
||||||
print('All depended diffs are applied')
|
print('All depended diffs are applied')
|
||||||
self._apply_diff(self.diff_id, revision_id)
|
self._apply_diff(self.diff_id, revision_id)
|
||||||
print('done.')
|
print('done.')
|
||||||
|
@ -124,9 +129,12 @@ class ApplyPatch:
|
||||||
return []
|
return []
|
||||||
return self.phab.differential.query(phids=phids)
|
return self.phab.differential.query(phids=phids)
|
||||||
|
|
||||||
def _get_dependencies(self) -> Tuple[int, List[int], str]:
|
def _get_dependencies(self, diff_id) -> Tuple[int, List[int], str]:
|
||||||
"""Get all dependencies for the diff."""
|
"""Get all dependencies for the diff.
|
||||||
diff = self._get_diff(self.diff_id)
|
They are listed in reverse chronological order - from most recent to least recent."""
|
||||||
|
|
||||||
|
print('Getting dependencies of {}'.format(diff_id))
|
||||||
|
diff = self._get_diff(diff_id)
|
||||||
revision_id = int(diff.revisionID)
|
revision_id = int(diff.revisionID)
|
||||||
revision = self._get_revision(revision_id)
|
revision = self._get_revision(revision_id)
|
||||||
base_revision = diff['sourceControlBaseRevision']
|
base_revision = diff['sourceControlBaseRevision']
|
||||||
|
@ -134,12 +142,14 @@ class ApplyPatch:
|
||||||
base_revision = 'master'
|
base_revision = 'master'
|
||||||
dependency_ids = revision['auxiliary']['phabricator:depends-on']
|
dependency_ids = revision['auxiliary']['phabricator:depends-on']
|
||||||
revisions = self._get_revisions(phids=dependency_ids)
|
revisions = self._get_revisions(phids=dependency_ids)
|
||||||
diff_ids = [int(rev['id']) for rev in revisions]
|
result = []
|
||||||
# It seems Phabricator lists the dependencies in the opposite order,
|
# Recursively resolve dependencies of those diffs.
|
||||||
# so we reverse the order before returning the list, so that they
|
for r in revisions:
|
||||||
# can be applied in this order
|
_, sub, _ = self._get_dependencies(r['diffs'][0])
|
||||||
diff_ids.reverse()
|
result.append(r['id'])
|
||||||
return revision_id, diff_ids, base_revision
|
result.extend(sub)
|
||||||
|
|
||||||
|
return revision_id, result, base_revision
|
||||||
|
|
||||||
def _apply_diff(self, diff_id: int, revision_id: int):
|
def _apply_diff(self, diff_id: int, revision_id: int):
|
||||||
"""Download and apply a diff to the local working copy."""
|
"""Download and apply a diff to the local working copy."""
|
||||||
|
@ -173,10 +183,17 @@ class ApplyPatch:
|
||||||
def _get_landed_revisions(self, limit: int = 1000):
|
def _get_landed_revisions(self, limit: int = 1000):
|
||||||
"""Get list of landed revisions from current git branch."""
|
"""Get list of landed revisions from current git branch."""
|
||||||
diff_regex = re.compile(r'^Differential Revision: https:\/\/reviews\.llvm\.org\/(.*)$', re.MULTILINE)
|
diff_regex = re.compile(r'^Differential Revision: https:\/\/reviews\.llvm\.org\/(.*)$', re.MULTILINE)
|
||||||
for commit in self.repo.iter_commits("master", max_count=limit):
|
earliest_commit = None
|
||||||
|
rev = self.base_revision
|
||||||
|
if rev is None:
|
||||||
|
rev = 'master'
|
||||||
|
for commit in self.repo.iter_commits(rev, max_count=limit):
|
||||||
|
earliest_commit = commit
|
||||||
result = diff_regex.search(commit.message)
|
result = diff_regex.search(commit.message)
|
||||||
if result is not None:
|
if result is not None:
|
||||||
yield result.group(1)
|
yield result.group(1)
|
||||||
|
if earliest_commit is not None:
|
||||||
|
print('Earliest analyzed commit in history', earliest_commit.hexsha, earliest_commit.committed_datetime)
|
||||||
return
|
return
|
||||||
|
|
||||||
def _get_missing_landed_dependencies(self, dependencies: List[int]) -> Tuple[List[int], List[int]]:
|
def _get_missing_landed_dependencies(self, dependencies: List[int]) -> Tuple[List[int], List[int]]:
|
||||||
|
|
Loading…
Reference in a new issue