1
0
Fork 0
llvm-premerge-checks/scripts/git_utils_test.py
Mikhail Goncharov 5a16fb7b9a sync all branches for llvm-project fork
There are multiple scenarios when script expects to see same branches
and commits. E.g. when upstream commits to release branch trigger
the build.

Reported by Louis Dionne.
2022-03-05 17:35:41 +01:00

109 lines
3.9 KiB
Python

# Copyright 2022 Google LLC
#
# Licensed under the the Apache License v2.0 with LLVM Exceptions (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://llvm.org/LICENSE.txt
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import git
import os
import scripts.git_utils as git_utils
def assertForkIsSynced(upstreamPath, forkPath):
upstream = git.Repo(path=upstreamPath)
fork = git.Repo(path=forkPath)
forkBranches = {}
for b in fork.branches:
forkBranches[b.name] = b
for b in upstream.branches:
assert b.name in forkBranches
assert b.commit.hexsha == forkBranches[b.name].commit.hexsha, f'branch {b.name} head'
def forkIsSynced(upstreamPath, forkPath) -> bool:
upstream = git.Repo(path=upstreamPath)
fork = git.Repo(path=forkPath)
forkBranches = {}
for b in fork.branches:
forkBranches[b.name] = b
for b in upstream.branches:
if b.name not in forkBranches:
return False
if b.commit.hexsha != forkBranches[b.name].commit.hexsha:
return False
return True
def add_simple_commit(remote, name: str):
with open(os.path.join(remote.working_tree_dir, name), 'wt') as f:
f.write('first line\n')
remote.index.add([os.path.join(remote.working_tree_dir, name)])
remote.index.commit(name)
def test_sync_branches(tmp_path):
upstreamRemote = os.path.join(tmp_path, 'upstreamBare')
forkRemote = os.path.join(tmp_path, 'forkBare')
git.Repo.init(path=upstreamRemote, bare=True)
git.Repo.init(path=forkRemote, bare=True)
upstreamPath = os.path.join(tmp_path, 'upstream')
forkPath = os.path.join(tmp_path, 'fork')
upstream = git.Repo.clone_from(url=upstreamRemote, to_path=upstreamPath)
add_simple_commit(upstream, '1')
upstream.git.push('origin', 'main')
fork = git.Repo.clone_from(url=forkRemote, to_path=forkPath)
fork.create_remote('upstream', url=upstreamRemote)
git_utils.syncRemotes(fork, 'upstream', 'origin')
fork.remotes.upstream.fetch()
fork.create_head('main', fork.remotes.upstream.refs.main)
fork.heads.main.checkout()
# Sync init commit.
git_utils.syncRemotes(fork, 'upstream', 'origin')
assertForkIsSynced(upstreamRemote, forkRemote)
# Add new change upstream.
add_simple_commit(upstream, '2')
upstream.git.push('--all')
git_utils.syncRemotes(fork, 'upstream', 'origin')
assertForkIsSynced(upstreamRemote, forkRemote)
# Add new branch.
upstream.create_head('branch1')
upstream.heads['branch1'].checkout()
add_simple_commit(upstream, '3')
upstream.git.push('--all')
git_utils.syncRemotes(fork, 'upstream', 'origin')
assertForkIsSynced(upstreamRemote, forkRemote)
# Add another branch commit.
add_simple_commit(upstream, '4')
upstream.git.push('--all')
git_utils.syncRemotes(fork, 'upstream', 'origin')
assertForkIsSynced(upstreamRemote, forkRemote)
# Discard changes in fork.
fork.remotes.origin.pull()
fork.heads.main.checkout()
add_simple_commit(fork, '5')
fork.remotes.origin.push()
upstream.remotes.origin.pull('main')
upstream.heads.main.checkout()
add_simple_commit(upstream, '6')
upstream.remotes.origin.push()
assert not forkIsSynced(upstreamRemote, forkRemote)
assert os.path.isfile(os.path.join(fork.working_tree_dir, '5'))
git_utils.syncRemotes(fork, 'upstream', 'origin')
assertForkIsSynced(upstreamRemote, forkRemote)
fork.git.pull('origin', 'main')
fork.heads.main.checkout()
assert not os.path.isfile(os.path.join(fork.working_tree_dir, '5'))
assert os.path.isfile(os.path.join(fork.working_tree_dir, '6'))