summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThibault Saunier <tsaunier@gnome.org>2016-08-08 16:17:06 -0400
committerThibault Saunier <tsaunier@gnome.org>2016-08-10 12:15:01 -0400
commit9eddfaf1e840f8b9bd0aa68b649cfbfa90e2476d (patch)
tree726b07e58f9a57c5c087b1ea2c7ed96ad6e07487
parentb4c2d0a1fa26260a6091adeb6aaaed486bbd3ac3 (diff)
Rename merge to apply handling both revisions and tasks
And remove the cherry-pick command merging it into 'apply --no-dependencies' Reviewed-by: Daniel Stone <daniels@collabora.com> Differential Revision: https://phabricator.freedesktop.org/D1260
-rwxr-xr-xgit-phab119
1 files changed, 81 insertions, 38 deletions
diff --git a/git-phab b/git-phab
index 4d4799c..7ea8b0a 100755
--- a/git-phab
+++ b/git-phab
@@ -452,6 +452,7 @@ Paste API Token from that page and press <enter>: """ % self.phabricator_uri)
452 except: 452 except:
453 print("%s%s not a valid remote, can't use it%s." % ( 453 print("%s%s not a valid remote, can't use it%s." % (
454 Colors.HEADER, self.remote, Colors.ENDC)) 454 Colors.HEADER, self.remote, Colors.ENDC))
455 self.remote = None
455 return 456 return
456 457
457 # Get remote's fetch URL. Unfortunately we can't get it from config 458 # Get remote's fetch URL. Unfortunately we can't get it from config
@@ -1438,7 +1439,7 @@ Paste API Token from that page and press <enter>: """ % self.phabricator_uri)
1438 1439
1439 return True 1440 return True
1440 1441
1441 def do_cherry_pick(self): 1442 def cherry_pick(self):
1442 if self.repo.is_dirty(): 1443 if self.repo.is_dirty():
1443 self.die("Repository is dirty. Aborting.") 1444 self.die("Repository is dirty. Aborting.")
1444 1445
@@ -1464,10 +1465,7 @@ Paste API Token from that page and press <enter>: """ % self.phabricator_uri)
1464 self.am_patch(filename, diff.get("sourceControlBaseRevision")) 1465 self.am_patch(filename, diff.get("sourceControlBaseRevision"))
1465 os.unlink(filename) 1466 os.unlink(filename)
1466 1467
1467 def get_differentials_to_apply(self): 1468 def get_differentials_to_apply_for_revision(self):
1468 if self.repo.is_dirty():
1469 self.die("Repository is dirty. Aborting.")
1470
1471 print("Checking revision:", self.differential) 1469 print("Checking revision:", self.differential)
1472 did = self.differential.strip("D") 1470 did = self.differential.strip("D")
1473 1471
@@ -1491,8 +1489,8 @@ Paste API Token from that page and press <enter>: """ % self.phabricator_uri)
1491 dq.append((revision, diff)) 1489 dq.append((revision, diff))
1492 return pq 1490 return pq
1493 1491
1494 def do_merge(self): 1492 def apply_differential_with_dependencies(self):
1495 pq = self.get_differentials_to_apply() 1493 pq = self.get_differentials_to_apply_for_revision()
1496 n = 0 1494 n = 0
1497 while pq != []: 1495 while pq != []:
1498 (r, d) = pq.pop() 1496 (r, d) = pq.pop()
@@ -1506,27 +1504,80 @@ Paste API Token from that page and press <enter>: """ % self.phabricator_uri)
1506 os.unlink(filename) 1504 os.unlink(filename)
1507 n += 1 1505 n += 1
1508 1506
1507 def do_apply(self):
1508 if self.repo.is_dirty():
1509 self.die("Repository is dirty. Aborting.")
1510 elif not self.differential and not self.task:
1511 self.die("No task or revision provided. Aborting.")
1512
1513 if self.differential:
1514 if self.no_dependencies:
1515 self.cherry_pick()
1516 else:
1517 self.apply_differential_with_dependencies()
1518
1519 return
1520
1521 commit_info = self.fetch_from_task()
1522 if self.no_dependencies:
1523 if commit_info[0]:
1524 self.repo.git.cherry_pick(commit_info[0].hexsha)
1525 return
1526 else:
1527 self.die("Can not apply revisions from a task"
1528 " without its dependencies as the task"
1529 " might refer to several revisions.")
1530
1531 starting_commit = self.repo.head.commit
1532 try:
1533 common_ancestor = self.repo.merge_base(commit_info[0],
1534 starting_commit)
1535 except git.exc.GitCommandError:
1536 self.die("No common ancestor found between Task commit"
1537 " and the current repository.")
1538
1539 for commit in reversed(list(self.repo.iter_commits(
1540 common_ancestor[0].hexsha + '^..' + commit_info[0].hexsha))):
1541 try:
1542 self.repo.git.cherry_pick(commit.hexsha)
1543 except git.exc.GitCommandError as e:
1544 stderr = e.stderr.decode("utf-8")
1545 if "The previous cherry-pick is now empty," \
1546 " possibly due to conflict resolution." \
1547 in stderr:
1548 self.repo.git.reset()
1549 elif stderr.startswith("error: could not apply"):
1550 self.die("%s\\nnWhen the conflict are fixed run"
1551 " `git phab apply %s` again." % (
1552 stderr, self.task))
1553 else:
1554 raise e
1555
1509 def do_log(self): 1556 def do_log(self):
1510 commits = self.get_commits(self.revision_range) 1557 commits = self.get_commits(self.revision_range)
1511 self.print_commits(commits) 1558 self.print_commits(commits)
1512 1559
1513 def fetch_from_task(self): 1560 def fetch_from_task(self):
1514
1515 reply = self.phabricator.maniphest.query(ids=[int(self.task[1:])]) 1561 reply = self.phabricator.maniphest.query(ids=[int(self.task[1:])])
1562 if not reply:
1563 self.die("Not task found for ID: %s" % self.task)
1564
1565 props = list(reply.values())[0]
1566 auxiliary = props['auxiliary']
1567 if not auxiliary or not auxiliary.get('std:maniphest:git:uri-branch'):
1568 # FIXME: There is currently no way to retrieve revisions
1569 # associated with a task from the conduit API
1570 self.die("%sCan not apply revisions from a task"
1571 " if no 'remote branch' has been set for it.%s\n"
1572 "INFO: You need to find what revisions are"
1573 " associated with the tasks and apply them."
1574 % (Colors.FAIL, Colors.ENDC))
1575
1576 uri = auxiliary['std:maniphest:git:uri-branch']
1577 remote, branch = uri.split('#')
1516 1578
1517 try:
1518 props = list(reply.values())[0]
1519 uri = props['auxiliary']['std:maniphest:git:uri-branch']
1520 remote, branch = uri.split('#')
1521 except:
1522 self.die("Git URI is not set on task; cannot fetch it.")
1523
1524 print("Git URI: %s, branch: %s" % (remote, branch))
1525 self.repo.git.fetch(remote, "%s" % branch) 1579 self.repo.git.fetch(remote, "%s" % branch)
1526
1527 commit = self.repo.commit('FETCH_HEAD') 1580 commit = self.repo.commit('FETCH_HEAD')
1528 print("Commit '%s' from remote branch '%s' has been fetched" %
1529 (commit.hexsha, branch))
1530 1581
1531 return (commit, remote, branch) 1582 return (commit, remote, branch)
1532 1583
@@ -1619,7 +1670,7 @@ Paste API Token from that page and press <enter>: """ % self.phabricator_uri)
1619 branchname_match_method = self.revision_from_branchname 1670 branchname_match_method = self.revision_from_branchname
1620 branch_name = self.differential 1671 branch_name = self.differential
1621 else: 1672 else:
1622 pq = self.get_differentials_to_apply() 1673 pq = self.get_differentials_to_apply_for_revision()
1623 if not pq: 1674 if not pq:
1624 print("Not differential to apply.") 1675 print("Not differential to apply.")
1625 return 1676 return
@@ -1893,28 +1944,20 @@ if __name__ == '__main__':
1893 "the tracking branch is used") \ 1944 "the tracking branch is used") \
1894 .completer = DisabledCompleter 1945 .completer = DisabledCompleter
1895 1946
1896 cherrypick_parser = subparsers.add_parser( 1947 apply_parser = subparsers.add_parser(
1897 'cherry-pick', help="Cherrypick a patch from differential") 1948 'apply', help="Apply a revision and its dependencies"
1898 cherrypick_parser.add_argument( 1949 " on the current tree")
1950 apply_parser.add_argument(
1899 '--output-directory', '-o', 1951 '--output-directory', '-o',
1900 metavar='<directory>', 1952 metavar='<directory>',
1901 help="Directory to put patches in") 1953 help="Directory to put patches in")
1902 cherrypick_parser.add_argument( 1954 apply_parser.add_argument(
1903 'differential', metavar='Differential ID', 1955 'task_or_revision', metavar='<(T|D)123>', nargs='?',
1904 default=None, 1956 help="The task or revision to fetch") \
1905 help="help Differential ID to cherrypick") \
1906 .completer = DisabledCompleter 1957 .completer = DisabledCompleter
1907 1958 apply_parser.add_argument(
1908 merge_parser = subparsers.add_parser( 1959 '--no-dependencies', "-n", action="store_true",
1909 'merge', help="Merge a revision and its dependencies") 1960 help="Do not apply dependencies of a revision.") \
1910 merge_parser.add_argument(
1911 '--output-directory', '-o',
1912 metavar='<directory>',
1913 help="Directory to put patches in")
1914 merge_parser.add_argument(
1915 'differential', metavar='Differential ID',
1916 default=None,
1917 help="help Differential ID to merge") \
1918 .completer = DisabledCompleter 1961 .completer = DisabledCompleter
1919 1962
1920 log_parser = subparsers.add_parser( 1963 log_parser = subparsers.add_parser(