-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmerge.bash
97 lines (79 loc) · 3.04 KB
/
merge.bash
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
89
90
91
92
93
94
95
96
97
#!/bin/bash
# check for the correct number of arguments
if [ ! $# == 2 ]; then
echo "use: $0 base_branch target_branch"
exit
fi
BASE_BRANCH=$1
TARGET_BRANCH=$2
# check for a clean working directory
if [ -z "$(git status --porcelain)" ]; then
echo "Working directory is clean, continuing..."
else
echo "Unclean working directory, exiting..."
exit
fi
# get locally up to date versions of the base and target branches
echo "Fetching updates..."
git fetch --all
echo "Checking out target branch $TARGET_BRANCH..."
git checkout $TARGET_BRANCH
git pull
git reset --hard origin/$TARGET_BRANCH
echo "Checking out base branch $BASE_BRANCH..."
git checkout $BASE_BRANCH
git pull
git reset --hard origin/$BASE_BRANCH
# searches within the commit difference between the base and target branches the commits with #skipMerge in their commit message
SKIPMERGES=($(git log --reverse --pretty=format:"%H" -i --grep="#skipMerge" $BASE_BRANCH..$TARGET_BRANCH))
echo "Found ${#SKIPMERGES[@]} skipmerge(s)..."
# for each skip commit found do the following
for i in ${SKIPMERGES[@]}; do
# find the commit just above the skip merge commit
BEFORE_SKIP_COMMIT=$(git log ${i}^ -n 1 --pretty=format:"%H")
# store the skip merge commit hash
SKIP_COMMIT=${i}
# do a default merge with the before skip commit
echo "Merging commit before skip '$BEFORE_SKIP_COMMIT' into '$BASE_BRANCH' with 'default' strategy..."
git merge $BEFORE_SKIP_COMMIT --no-edit -m "Merge '$BEFORE_SKIP_COMMIT' into '$BASE_BRANCH'"
# check for merge conflicts
if [ -z "$(git status --porcelain)" ]; then
echo "Merging before skip commit successful, continuing..."
else
echo "Merging before skip commit unsuccessful, breaking for loop..."
MERGE_CONFLICT_COMMIT=$BEFORE_SKIP_COMMIT
break
fi
# do an ours merge to skip changes with the skip commit
echo "Merging skip commit '$SKIP_COMMIT' into '$BASE_BRANCH' with 'ours' strategy..."
git merge $SKIP_COMMIT -s ours --no-edit -m "Merge '$SKIP_COMMIT' into '$BASE_BRANCH' without changes"
done
# if there where no conflicts so far continue
if [ "$MERGE_CONFLICT_COMMIT" == "" ]; then
# just an extra message for if there where skip related merges
if [ ${#SKIPMERGES[@]} -ge 1 ]; then
echo "Merged all skip related merges successfully, continuing..."
fi
echo "Merging '$TARGET_BRANCH' branch into '$BASE_BRANCH' branch..."
git merge $TARGET_BRANCH -m "Merging head of '$TARGET_BRANCH' branch into '$BASE_BRANCH' branch"
# check for merge conflicts
if [ -z "$(git status --porcelain)" ]; then
echo "Merging '$TARGET_BRANCH' branch successfully, continuing..."
else
echo "Merging '$TARGET_BRANCH' branch unsuccessfully, continuing..."
MERGE_CONFLICT_COMMIT=$(git log $TARGET_BRANCH -n 1 --pretty=format:"%H")
break
fi
fi
# final check for merge conflicts
if [ "$MERGE_CONFLICT_COMMIT" == "" ]; then
echo "Everything successfully completed, pushing commits..."
git push
echo "Successful pushed, exiting..."
exit
else
# report on the failed commit
echo "Merging failed on commit '$MERGE_CONFLICT_COMMIT', exiting..."
git merge --abort
exit 1
fi