Modify git squash-branch to perform reparenting
Bug: 40264739 Change-Id: I4ad7f4f8a670334b32c239458048e56c6af44098 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/tools/depot_tools/+/6227541 Reviewed-by: Josip Sokcevic <sokcevic@chromium.org> Reviewed-by: Yiwei Zhang <yiwzhang@google.com> Commit-Queue: Alexander Cooper <alcooper@chromium.org>changes/41/6227541/6
parent
569d698b0b
commit
380df04b62
@ -0,0 +1,146 @@
|
||||
#!/usr/bin/env vpython3
|
||||
# coding=utf-8
|
||||
# Copyright 2024 The Chromium Authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
"""Tests for git_squash_branch."""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
DEPOT_TOOLS_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
sys.path.insert(0, DEPOT_TOOLS_ROOT)
|
||||
|
||||
from testing_support import git_test_utils
|
||||
|
||||
import git_squash_branch
|
||||
import git_common
|
||||
|
||||
git_common.TEST_MODE = True
|
||||
|
||||
|
||||
class GitSquashBranchTest(git_test_utils.GitRepoReadWriteTestBase):
|
||||
# Empty repo.
|
||||
REPO_SCHEMA = """
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
super(GitSquashBranchTest, self).setUp()
|
||||
|
||||
# Note: Using the REPO_SCHEMA wouldn't simplify this test so it is not
|
||||
# used.
|
||||
#
|
||||
# Create a repo with the follow schema
|
||||
#
|
||||
# main <- branchA <- branchB <- branchC
|
||||
# ^
|
||||
# \ branchD
|
||||
#
|
||||
# where each branch has 2 commits.
|
||||
|
||||
# The repo is empty. Add the first commit or else most commands don't
|
||||
# work, including `git branch`, which doesn't even show the main branch.
|
||||
self.repo.git('commit', '-m', 'First commit', '--allow-empty')
|
||||
|
||||
# Create the first branch downstream from `main` with 2 commits.
|
||||
self.repo.git('checkout', '-B', 'branchA', '--track', 'main')
|
||||
self._createFileAndCommit('fileA1')
|
||||
self._createFileAndCommit('fileA2')
|
||||
|
||||
# Create a branch downstream from `branchA` with 2 commits.
|
||||
self.repo.git('checkout', '-B', 'branchB', '--track', 'branchA')
|
||||
self._createFileAndCommit('fileB1')
|
||||
self._createFileAndCommit('fileB2')
|
||||
|
||||
# Create another branch downstream from `branchB` with 2 commits.
|
||||
self.repo.git('checkout', '-B', 'branchC', '--track', 'branchB')
|
||||
self._createFileAndCommit('fileC1')
|
||||
self._createFileAndCommit('fileC2')
|
||||
|
||||
# Create another branch downstream from `branchA` with 2 commits.
|
||||
self.repo.git('checkout', '-B', 'branchD', '--track', 'branchA')
|
||||
self._createFileAndCommit('fileD1')
|
||||
self._createFileAndCommit('fileD2')
|
||||
|
||||
def testGitSquashBranchFailsWithDivergedBranch(self):
|
||||
self.assertEqual(self._getCountAheadOfUpstream('branchA'), 2)
|
||||
self.assertEqual(self._getCountAheadOfUpstream('branchB'), 2)
|
||||
self.assertEqual(self._getCountAheadOfUpstream('branchC'), 2)
|
||||
self.assertEqual(self._getCountAheadOfUpstream('branchD'), 2)
|
||||
self.repo.git('checkout', 'branchB')
|
||||
self._createFileAndCommit('fileB3')
|
||||
self.repo.git('checkout', 'branchA')
|
||||
|
||||
# We have now made a state where branchC has diverged from branchB.
|
||||
output, _ = self.repo.capture_stdio(git_squash_branch.main, [])
|
||||
self.assertIn('some children have diverged', output)
|
||||
|
||||
def testGitSquashBranchRootOnly(self):
|
||||
self.assertEqual(self._getCountAheadOfUpstream('branchA'), 2)
|
||||
self.assertEqual(self._getCountAheadOfUpstream('branchB'), 2)
|
||||
self.assertEqual(self._getCountAheadOfUpstream('branchC'), 2)
|
||||
self.assertEqual(self._getCountAheadOfUpstream('branchD'), 2)
|
||||
|
||||
self.repo.git('checkout', 'branchA')
|
||||
self.repo.run(git_squash_branch.main, [])
|
||||
|
||||
self.assertEqual(self._getCountAheadOfUpstream('branchA'), 1)
|
||||
self.assertEqual(self._getCountAheadOfUpstream('branchB'), 2)
|
||||
self.assertEqual(self._getCountAheadOfUpstream('branchC'), 2)
|
||||
self.assertEqual(self._getCountAheadOfUpstream('branchD'), 2)
|
||||
|
||||
def testGitSquashBranchLeaf(self):
|
||||
self.assertEqual(self._getCountAheadOfUpstream('branchA'), 2)
|
||||
self.assertEqual(self._getCountAheadOfUpstream('branchB'), 2)
|
||||
self.assertEqual(self._getCountAheadOfUpstream('branchC'), 2)
|
||||
self.assertEqual(self._getCountAheadOfUpstream('branchD'), 2)
|
||||
|
||||
self.repo.git('checkout', 'branchD')
|
||||
self.repo.run(git_squash_branch.main, [])
|
||||
|
||||
self.assertEqual(self._getCountAheadOfUpstream('branchA'), 2)
|
||||
self.assertEqual(self._getCountAheadOfUpstream('branchB'), 2)
|
||||
self.assertEqual(self._getCountAheadOfUpstream('branchC'), 2)
|
||||
self.assertEqual(self._getCountAheadOfUpstream('branchD'), 1)
|
||||
|
||||
def testGitSquashBranchSequential(self):
|
||||
self.assertEqual(self._getCountAheadOfUpstream('branchA'), 2)
|
||||
self.assertEqual(self._getCountAheadOfUpstream('branchB'), 2)
|
||||
self.assertEqual(self._getCountAheadOfUpstream('branchC'), 2)
|
||||
self.assertEqual(self._getCountAheadOfUpstream('branchD'), 2)
|
||||
|
||||
self.repo.git('checkout', 'branchA')
|
||||
self.repo.run(git_squash_branch.main, [])
|
||||
|
||||
self.assertEqual(self._getCountAheadOfUpstream('branchA'), 1)
|
||||
self.assertEqual(self._getCountAheadOfUpstream('branchB'), 2)
|
||||
self.assertEqual(self._getCountAheadOfUpstream('branchC'), 2)
|
||||
self.assertEqual(self._getCountAheadOfUpstream('branchD'), 2)
|
||||
|
||||
self.repo.git('checkout', 'branchB')
|
||||
self.repo.run(git_squash_branch.main, [])
|
||||
|
||||
self.assertEqual(self._getCountAheadOfUpstream('branchA'), 1)
|
||||
self.assertEqual(self._getCountAheadOfUpstream('branchB'), 1)
|
||||
self.assertEqual(self._getCountAheadOfUpstream('branchC'), 2)
|
||||
self.assertEqual(self._getCountAheadOfUpstream('branchD'), 2)
|
||||
|
||||
# Creates a file with arbitrary contents and commit it to the current
|
||||
# branch.
|
||||
def _createFileAndCommit(self, filename):
|
||||
with self.repo.open(filename, 'w') as f:
|
||||
f.write('content')
|
||||
self.repo.git('add', filename)
|
||||
self.repo.git_commit('Added file ' + filename)
|
||||
|
||||
# Returns the count of how many commits `branch` is ahead of its upstream.
|
||||
def _getCountAheadOfUpstream(self, branch):
|
||||
upstream = branch + '@{u}'
|
||||
output = self.repo.git('rev-list', '--count',
|
||||
upstream + '..' + branch).stdout
|
||||
return int(output)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
Loading…
Reference in New Issue