diff --git a/fdroidserver/checkupdates.py b/fdroidserver/checkupdates.py index 68bd2cc1..d9ad8048 100644 --- a/fdroidserver/checkupdates.py +++ b/fdroidserver/checkupdates.py @@ -18,6 +18,7 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . +import configparser import git import os import re @@ -688,11 +689,17 @@ def get_last_build_from_app(app: metadata.App) -> metadata.Build: return metadata.Build() -def get_git_repo_and_main_branch(): - git_repo = git.Repo.init('.') - with git_repo.config_reader() as reader: - main_branch = reader.get_value('init', 'defaultBranch') - return git_repo, main_branch +def get_upstream_main_branch(git_repo): + if len(git_repo.remotes.upstream.refs) == 1: + return git_repo.remotes.upstream.refs[0].name + for name in ('main', 'master'): + if name in git_repo.remotes.upstream.refs: + return f'upstream/{name}' + try: + with git_repo.config_reader() as reader: + return 'upstream/%s' % reader.get_value('init', 'defaultBranch') + except configparser.NoSectionError: + return 'upstream/main' def checkout_appid_branch(appid): @@ -711,7 +718,8 @@ def checkout_appid_branch(appid): """ logging.debug(f'Creating merge request branch for {appid}') - git_repo, main_branch = get_git_repo_and_main_branch() + git_repo = git.Repo.init('.') + upstream_main = get_upstream_main_branch(git_repo) for remote in git_repo.remotes: remote.fetch() try: @@ -721,16 +729,14 @@ def checkout_appid_branch(appid): if appid in git_repo.remotes.origin.refs: start_point = f"origin/{appid}" for commit in git_repo.iter_commits( - f'upstream/{main_branch}...{start_point}', right_only=True + f'{upstream_main}...{start_point}', right_only=True ): if commit.committer.email != BOT_EMAIL or commit.author.email != BOT_EMAIL: return False else: - start_point = f"upstream/{main_branch}" + start_point = upstream_main git_repo.git.checkout('-B', appid, start_point) - git_repo.git.rebase( - f'upstream/{main_branch}', strategy_option='ours', kill_after_timeout=120 - ) + git_repo.git.rebase(upstream_main, strategy_option='ours', kill_after_timeout=120) return True @@ -751,11 +757,11 @@ def push_commits(remote_name='origin', branch_name='checkupdates', verbose=False * https://docs.gitlab.com/ee/user/project/push_options.html """ - git_repo, default = get_git_repo_and_main_branch() + git_repo = git.Repo.init('.') + upstream_main = get_upstream_main_branch(git_repo) files = set() - upstream_main = default if default in git_repo.remotes.upstream.refs else 'main' for commit in git_repo.iter_commits( - f'upstream/{upstream_main}...HEAD', right_only=True + f'{upstream_main}...HEAD', right_only=True ): files.update(commit.stats.files.keys()) @@ -780,7 +786,7 @@ def push_commits(remote_name='origin', branch_name='checkupdates', verbose=False current_version_only = True for m in re.findall( r"^[+-].*", - git_repo.git.diff(f"upstream/{upstream_main}...HEAD"), + git_repo.git.diff(f"{upstream_main}...HEAD"), flags=re.MULTILINE, ): if re.match(r"^(\+\+\+|---) ", m): @@ -835,8 +841,9 @@ def push_commits(remote_name='origin', branch_name='checkupdates', verbose=False def prune_empty_appid_branches(git_repo=None, main_branch='main'): """Remove empty branches from checkupdates-bot git remote.""" if git_repo is None: - git_repo, main_branch = get_git_repo_and_main_branch() - upstream_main = 'upstream/' + main_branch + git_repo = git.Repo.init('.') + upstream_main = get_upstream_main_branch(git_repo) + main_branch = upstream_main.split('/')[1] remote = git_repo.remotes.origin remote.update(prune=True) diff --git a/tests/test_checkupdates.py b/tests/test_checkupdates.py index e9637190..2e802741 100755 --- a/tests/test_checkupdates.py +++ b/tests/test_checkupdates.py @@ -453,20 +453,47 @@ class CheckupdatesTest(unittest.TestCase): fdroidserver.checkupdates.main() sys_exit.assert_not_called() - def test_get_git_repo_and_main_branch(self): + def test_get_upstream_main_branch(self): os.chdir(self.testdir.name) - git_repo = git.Repo.init() + testvalue = 'foo' + git_repo = git.Repo.init('.', initial_branch=testvalue) + open('foo', 'w').close() git_repo.git.add(all=True) git_repo.index.commit("all files") + git_repo.create_remote('upstream', os.getcwd()).fetch() - repo, branch = fdroidserver.checkupdates.get_git_repo_and_main_branch() - self.assertTrue(branch in repo.heads) + branch = fdroidserver.checkupdates.get_upstream_main_branch(git_repo) + self.assertEqual( + f'upstream/{testvalue}', + branch, + f'The default branch should be called {testvalue}!', + ) + + def test_get_upstream_main_branch_git_config(self): + os.chdir(self.testdir.name) + testvalue = 'foo' + git_repo = git.Repo.init('.', initial_branch=testvalue) + with git_repo.config_writer() as cw: + cw.set_value('init', 'defaultBranch', testvalue) + + open('foo', 'w').close() + git_repo.git.add(all=True) + git_repo.index.commit("all files") + git_repo.git.branch('somethingelse') # make another remote branch + git_repo.create_remote('upstream', os.getcwd()).fetch() + + branch = fdroidserver.checkupdates.get_upstream_main_branch(git_repo) + self.assertEqual( + f'upstream/{testvalue}', + branch, + f'The default branch should be called {testvalue}!', + ) def test_checkout_appid_branch_does_not_exist(self): appid = 'com.example' os.chdir(self.testdir.name) - git_repo, main_branch = fdroidserver.checkupdates.get_git_repo_and_main_branch() + git_repo = git.Repo.init('.') open('foo', 'w').close() git_repo.git.add(all=True) git_repo.index.commit("all files") @@ -491,7 +518,7 @@ class CheckupdatesTest(unittest.TestCase): local_dir = os.path.join(self.testdir.name, 'local_git') git.Repo.clone_from(upstream_dir, local_dir) os.chdir(local_dir) - git_repo, main_branch = fdroidserver.checkupdates.get_git_repo_and_main_branch() + git_repo = git.Repo.init('.') # --merge-request assumes remotes called 'origin' and 'upstream' git_repo.create_remote('upstream', upstream_dir).fetch() @@ -513,7 +540,7 @@ class CheckupdatesTest(unittest.TestCase): local_dir = os.path.join(self.testdir.name, 'local_git') git.Repo.clone_from(upstream_dir, local_dir) os.chdir(local_dir) - git_repo, main_branch = fdroidserver.checkupdates.get_git_repo_and_main_branch() + git_repo = git.Repo.init('.') # --merge-request assumes remotes called 'origin' and 'upstream' git_repo.create_remote('upstream', upstream_dir).fetch() @@ -530,7 +557,8 @@ class CheckupdatesTest(unittest.TestCase): # set up starting from remote branch git_repo.remotes.origin.push(appid) - git_repo.git.checkout(main_branch) + upstream_main = fdroidserver.checkupdates.get_upstream_main_branch(git_repo) + git_repo.git.checkout(upstream_main.split('/')[1]) git_repo.delete_head(appid, force=True) self.assertTrue( @@ -552,7 +580,7 @@ class CheckupdatesTest(unittest.TestCase): local_dir = os.path.join(self.testdir.name, 'local_git') git.Repo.clone_from(upstream_dir, local_dir) os.chdir(local_dir) - git_repo, main_branch = fdroidserver.checkupdates.get_git_repo_and_main_branch() + git_repo = git.Repo.init('.') # --merge-request assumes remotes called 'origin' and 'upstream' git_repo.create_remote('upstream', upstream_dir).fetch() @@ -577,7 +605,8 @@ class CheckupdatesTest(unittest.TestCase): # set up starting from remote branch git_repo.remotes.origin.push(appid) - git_repo.git.reset(main_branch) + upstream_main = fdroidserver.checkupdates.get_upstream_main_branch(git_repo) + git_repo.git.reset(upstream_main.split('/')[1]) self.assertFalse( fdroidserver.checkupdates.checkout_appid_branch(appid),