mirror of
https://chromium.googlesource.com/chromium/tools/depot_tools.git
synced 2026-01-11 18:51:29 +00:00
Make marked merge base invalid when the upstream changes.
This should let the base marker transparently work with plain-old-git tools which was the idea in the first place. Specifically `git branch -u` without a corresponding rebase. R=agable@chromium.org BUG=373977 Review URL: https://codereview.chromium.org/288323002 git-svn-id: svn://svn.chromium.org/chrome/trunk/tools/depot_tools@271112 0039d316-1c4b-4281-b951-d872f2087c98
This commit is contained in:
@@ -352,9 +352,16 @@ def get_or_create_merge_base(branch, parent=None):
|
|||||||
If parent is supplied, it's used instead of calling upstream(branch).
|
If parent is supplied, it's used instead of calling upstream(branch).
|
||||||
"""
|
"""
|
||||||
base = branch_config(branch, 'base')
|
base = branch_config(branch, 'base')
|
||||||
|
base_upstream = branch_config(branch, 'base-upstream')
|
||||||
parent = parent or upstream(branch)
|
parent = parent or upstream(branch)
|
||||||
|
if not parent:
|
||||||
|
return None
|
||||||
actual_merge_base = run('merge-base', parent, branch)
|
actual_merge_base = run('merge-base', parent, branch)
|
||||||
|
|
||||||
|
if base_upstream != parent:
|
||||||
|
base = None
|
||||||
|
base_upstream = None
|
||||||
|
|
||||||
def is_ancestor(a, b):
|
def is_ancestor(a, b):
|
||||||
return run_with_retcode('merge-base', '--is-ancestor', a, b) == 0
|
return run_with_retcode('merge-base', '--is-ancestor', a, b) == 0
|
||||||
|
|
||||||
@@ -370,7 +377,7 @@ def get_or_create_merge_base(branch, parent=None):
|
|||||||
|
|
||||||
if not base:
|
if not base:
|
||||||
base = actual_merge_base
|
base = actual_merge_base
|
||||||
manual_merge_base(branch, base)
|
manual_merge_base(branch, base, parent)
|
||||||
|
|
||||||
return base
|
return base
|
||||||
|
|
||||||
@@ -409,8 +416,9 @@ def is_dormant(branch):
|
|||||||
return branch_config(branch, 'dormant', 'false') != 'false'
|
return branch_config(branch, 'dormant', 'false') != 'false'
|
||||||
|
|
||||||
|
|
||||||
def manual_merge_base(branch, base):
|
def manual_merge_base(branch, base, parent):
|
||||||
set_branch_config(branch, 'base', base)
|
set_branch_config(branch, 'base', base)
|
||||||
|
set_branch_config(branch, 'base-upstream', parent)
|
||||||
|
|
||||||
|
|
||||||
def mktree(treedict):
|
def mktree(treedict):
|
||||||
@@ -475,6 +483,7 @@ def rebase(parent, start, branch, abort=False):
|
|||||||
|
|
||||||
def remove_merge_base(branch):
|
def remove_merge_base(branch):
|
||||||
del_branch_config(branch, 'base')
|
del_branch_config(branch, 'base')
|
||||||
|
del_branch_config(branch, 'base-upstream')
|
||||||
|
|
||||||
|
|
||||||
def root():
|
def root():
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ def main():
|
|||||||
current = current_branch()
|
current = current_branch()
|
||||||
all_branches = set(branches())
|
all_branches = set(branches())
|
||||||
merge_base_map = {b: get_or_create_merge_base(b) for b in all_branches}
|
merge_base_map = {b: get_or_create_merge_base(b) for b in all_branches}
|
||||||
|
merge_base_map = {b: v for b, v in merge_base_map.iteritems() if v}
|
||||||
if current in all_branches:
|
if current in all_branches:
|
||||||
all_branches.remove(current)
|
all_branches.remove(current)
|
||||||
all_tags = set(tags())
|
all_tags = set(tags())
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import sys
|
|||||||
from subprocess2 import CalledProcessError
|
from subprocess2 import CalledProcessError
|
||||||
|
|
||||||
from git_common import remove_merge_base, manual_merge_base, current_branch
|
from git_common import remove_merge_base, manual_merge_base, current_branch
|
||||||
from git_common import get_or_create_merge_base, hash_one
|
from git_common import get_or_create_merge_base, hash_one, upstream
|
||||||
|
|
||||||
|
|
||||||
def main(argv):
|
def main(argv):
|
||||||
@@ -51,7 +51,7 @@ def main(argv):
|
|||||||
)
|
)
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
manual_merge_base(cur, opts.merge_base)
|
manual_merge_base(cur, opts.merge_base, upstream(cur))
|
||||||
|
|
||||||
ret = 0
|
ret = 0
|
||||||
actual = get_or_create_merge_base(cur)
|
actual = get_or_create_merge_base(cur)
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import sys
|
|||||||
import subprocess2
|
import subprocess2
|
||||||
|
|
||||||
from git_common import upstream, current_branch, run, tags, set_branch_config
|
from git_common import upstream, current_branch, run, tags, set_branch_config
|
||||||
from git_common import get_or_create_merge_base, root
|
from git_common import get_or_create_merge_base, root, manual_merge_base
|
||||||
|
|
||||||
import git_rebase_update
|
import git_rebase_update
|
||||||
|
|
||||||
@@ -44,7 +44,7 @@ def main(args):
|
|||||||
if new_parent == cur_parent:
|
if new_parent == cur_parent:
|
||||||
parser.error('Cannot reparent a branch to its existing parent')
|
parser.error('Cannot reparent a branch to its existing parent')
|
||||||
|
|
||||||
get_or_create_merge_base(branch, cur_parent)
|
mbase = get_or_create_merge_base(branch, cur_parent)
|
||||||
|
|
||||||
all_tags = tags()
|
all_tags = tags()
|
||||||
if cur_parent in all_tags:
|
if cur_parent in all_tags:
|
||||||
@@ -66,6 +66,8 @@ def main(args):
|
|||||||
% (branch, new_parent, cur_parent))
|
% (branch, new_parent, cur_parent))
|
||||||
run('branch', '--set-upstream-to', new_parent, branch)
|
run('branch', '--set-upstream-to', new_parent, branch)
|
||||||
|
|
||||||
|
manual_merge_base(branch, mbase, new_parent)
|
||||||
|
|
||||||
# TODO(iannucci): ONLY rebase-update the branch which moved (and dependants)
|
# TODO(iannucci): ONLY rebase-update the branch which moved (and dependants)
|
||||||
return git_rebase_update.main(['--no_fetch'])
|
return git_rebase_update.main(['--no_fetch'])
|
||||||
|
|
||||||
|
|||||||
@@ -375,6 +375,8 @@ class GitMutableStructuredTest(git_test_utils.GitRepoReadWriteTestBase,
|
|||||||
J L
|
J L
|
||||||
|
|
||||||
X Y Z
|
X Y Z
|
||||||
|
|
||||||
|
CAT DOG
|
||||||
"""
|
"""
|
||||||
|
|
||||||
COMMIT_B = {'file': {'data': 'B'}}
|
COMMIT_B = {'file': {'data': 'B'}}
|
||||||
@@ -396,18 +398,18 @@ class GitMutableStructuredTest(git_test_utils.GitRepoReadWriteTestBase,
|
|||||||
for i in xrange(30):
|
for i in xrange(30):
|
||||||
self.repo.git('branch', 'a'*i)
|
self.repo.git('branch', 'a'*i)
|
||||||
|
|
||||||
with self.assertRaises(SystemExit):
|
_, rslt = self.repo.capture_stdio(list, self.gc.branches())
|
||||||
self.repo.run(list, self.gc.branches())
|
self.assertIn('too many branches (39/20)', rslt)
|
||||||
|
|
||||||
self.repo.git('config', 'depot-tools.branch-limit', 'cat')
|
self.repo.git('config', 'depot-tools.branch-limit', 'cat')
|
||||||
|
|
||||||
with self.assertRaises(SystemExit):
|
_, rslt = self.repo.capture_stdio(list, self.gc.branches())
|
||||||
self.repo.run(list, self.gc.branches())
|
self.assertIn('too many branches (39/20)', rslt)
|
||||||
|
|
||||||
self.repo.git('config', 'depot-tools.branch-limit', '100')
|
self.repo.git('config', 'depot-tools.branch-limit', '100')
|
||||||
|
|
||||||
# should not raise
|
# should not raise
|
||||||
self.assertEqual(36, len(self.repo.run(list, self.gc.branches())))
|
self.assertEqual(38, len(self.repo.run(list, self.gc.branches())))
|
||||||
|
|
||||||
def testMergeBase(self):
|
def testMergeBase(self):
|
||||||
self.repo.git('checkout', 'branch_K')
|
self.repo.git('checkout', 'branch_K')
|
||||||
@@ -425,9 +427,12 @@ class GitMutableStructuredTest(git_test_utils.GitRepoReadWriteTestBase,
|
|||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
self.repo['B'], self.repo.run(self.gc.config, 'branch.branch_K.base')
|
self.repo['B'], self.repo.run(self.gc.config, 'branch.branch_K.base')
|
||||||
)
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
'branch_G', self.repo.run(self.gc.config, 'branch.branch_K.base-upstream')
|
||||||
|
)
|
||||||
|
|
||||||
# deadbeef is a bad hash, so this will result in repo['B']
|
# deadbeef is a bad hash, so this will result in repo['B']
|
||||||
self.repo.run(self.gc.manual_merge_base, 'branch_K', 'deadbeef')
|
self.repo.run(self.gc.manual_merge_base, 'branch_K', 'deadbeef', 'branch_G')
|
||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
self.repo['B'],
|
self.repo['B'],
|
||||||
@@ -435,7 +440,8 @@ class GitMutableStructuredTest(git_test_utils.GitRepoReadWriteTestBase,
|
|||||||
)
|
)
|
||||||
|
|
||||||
# but if we pick a real ancestor, then it'll work
|
# but if we pick a real ancestor, then it'll work
|
||||||
self.repo.run(self.gc.manual_merge_base, 'branch_K', self.repo['I'])
|
self.repo.run(self.gc.manual_merge_base, 'branch_K', self.repo['I'],
|
||||||
|
'branch_G')
|
||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
self.repo['I'],
|
self.repo['I'],
|
||||||
@@ -454,16 +460,28 @@ class GitMutableStructuredTest(git_test_utils.GitRepoReadWriteTestBase,
|
|||||||
self.assertEqual({}, self.repo.run(self.gc.branch_config_map, 'base'))
|
self.assertEqual({}, self.repo.run(self.gc.branch_config_map, 'base'))
|
||||||
|
|
||||||
# if it's too old, then it caps at merge-base
|
# if it's too old, then it caps at merge-base
|
||||||
self.repo.run(self.gc.manual_merge_base, 'branch_K', self.repo['A'])
|
self.repo.run(self.gc.manual_merge_base, 'branch_K', self.repo['A'],
|
||||||
|
'branch_G')
|
||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
self.repo['B'],
|
self.repo['B'],
|
||||||
self.repo.run(self.gc.get_or_create_merge_base, 'branch_K', 'branch_G')
|
self.repo.run(self.gc.get_or_create_merge_base, 'branch_K', 'branch_G')
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# If the user does --set-upstream-to something else, then we discard the
|
||||||
|
# base and recompute it.
|
||||||
|
self.repo.run(self.gc.run, 'branch', '-u', 'root_A')
|
||||||
|
self.assertEqual(
|
||||||
|
self.repo['A'],
|
||||||
|
self.repo.run(self.gc.get_or_create_merge_base, 'branch_K')
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertIsNone(
|
||||||
|
self.repo.run(self.gc.get_or_create_merge_base, 'branch_DOG'))
|
||||||
|
|
||||||
def testGetBranchTree(self):
|
def testGetBranchTree(self):
|
||||||
skipped, tree = self.repo.run(self.gc.get_branch_tree)
|
skipped, tree = self.repo.run(self.gc.get_branch_tree)
|
||||||
self.assertEqual(skipped, {'master', 'root_X'})
|
self.assertEqual(skipped, {'master', 'root_X', 'branch_DOG', 'root_CAT'})
|
||||||
self.assertEqual(tree, {
|
self.assertEqual(tree, {
|
||||||
'branch_G': 'root_A',
|
'branch_G': 'root_A',
|
||||||
'root_A': 'root_X',
|
'root_A': 'root_X',
|
||||||
@@ -517,6 +535,8 @@ class GitMutableStructuredTest(git_test_utils.GitRepoReadWriteTestBase,
|
|||||||
J L
|
J L
|
||||||
|
|
||||||
X Y Z
|
X Y Z
|
||||||
|
|
||||||
|
CAT DOG
|
||||||
""")
|
""")
|
||||||
|
|
||||||
rslt = self.repo.run(
|
rslt = self.repo.run(
|
||||||
@@ -528,6 +548,8 @@ class GitMutableStructuredTest(git_test_utils.GitRepoReadWriteTestBase,
|
|||||||
B H I J L
|
B H I J L
|
||||||
|
|
||||||
X Y Z
|
X Y Z
|
||||||
|
|
||||||
|
CAT DOG
|
||||||
""")
|
""")
|
||||||
|
|
||||||
rslt = self.repo.run(
|
rslt = self.repo.run(
|
||||||
@@ -551,6 +573,8 @@ class GitMutableStructuredTest(git_test_utils.GitRepoReadWriteTestBase,
|
|||||||
A B C D E F G H I J K L
|
A B C D E F G H I J K L
|
||||||
|
|
||||||
X Y Z
|
X Y Z
|
||||||
|
|
||||||
|
CAT DOG
|
||||||
""")
|
""")
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user