1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
|
#!/usr/bin/env python3
# Merge dev into main branch
import subprocess
import sys
import os
import sync
def run_command(command):
"""Run a shell command and return the output."""
result = subprocess.run(command, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
return result.stdout.strip()
def main():
try:
# Switch to dev branch if not already on it
original_branch = run_command(['git', 'rev-parse', '--abbrev-ref', 'HEAD'])
if original_branch != "dev":
print("Switching to dev branch")
run_command(['git', 'checkout', 'dev'])
# Make sure the dev branch does not have uncommitted changes.
try:
run_command(['git', 'diff-index', '--quiet', 'HEAD', '--'])
except subprocess.CalledProcessError:
print("Uncommitted changes in the dev branch. Please commit or stash them before merging.")
sys.exit(1)
# Make sure the dev branch is up-to-date with the remote.
run_command(['git', 'fetch', 'origin', 'dev'])
if run_command(['git', 'rev-parse', 'dev']) != run_command(['git', 'rev-parse', 'origin/dev']):
print("dev branch not up-to-date with remote. Do 'git pull'.")
sys.exit(1)
# Call sync to verify that dev is up-to-date with main.
# This is to avoid conflicts when merging dev into main.
sync.main()
# Switch to main branch
print("Switching to main branch")
run_command(['git', 'checkout', 'main'])
run_command(['git', 'fetch', 'origin', 'main'])
# Proceed to merge dev into main. Detect if there are conflicts, if yes
# give instruction to resolve them.
# Find the common ancestor of dev and main
merge_base = run_command(['git', 'merge-base', 'dev', 'main'])
# Check if there are any changes from dev that are not in main
try:
run_command(['git', 'diff', '--quiet', merge_base, 'dev'])
print("No changes to merge from dev to main.")
except subprocess.CalledProcessError:
# Perform the actual merge
try:
run_command(['git', 'merge', '--ff-only', 'dev'])
print("Merged dev into main.")
# Rebase dev to keep on same last commit (that merge that was just done).
run_command(['git', 'checkout', 'dev'])
run_command(['git', 'rebase', 'main'])
run_command(['git', 'push', 'origin', 'dev'])
run_command(['git', 'push', 'origin', 'main'])
except subprocess.CalledProcessError:
print("Merge failed due to conflicts.")
print("To resolve the conflicts, follow these steps:")
print("1. Identify conflicted files using 'git status'.")
print("2. Resolve manually by editing conflicted files.")
print("3. Mark conflicts as resolved using 'git add <file>'.")
print("4. Complete merge with 'git commit' and 'push'.")
sys.exit(1)
except subprocess.CalledProcessError as e:
print(f"An error occurred: {e}")
sys.exit(1)
finally:
# Restore to the branch the user was located before running this script
current_branch = run_command(['git', 'rev-parse', '--abbrev-ref', 'HEAD'])
if current_branch != original_branch:
print(f"Switching back to {original_branch} branch")
run_command(['git', 'checkout', original_branch])
if __name__ == "__main__":
main()
|