blob: 64a6bffe00521c8f0d0c695b9ef0bd94e0f46a68 (
plain) (
blame)
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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
|
##
# systr_merge_tree <commit>
#
# Merge the contents of <commit> into the current worktree, using
# the calculated merge-base of <commit> and BASE (since your worktree
# is essentally BASE plus pending changes).
#
# The merge is staged in a separate directory. This is because systrunk
# doesn't want to overwrite the worktree unless the merge will run
# successfully. We don't want to write garbage to the worktree and lose
# uncommitted changes to other files. Users can resolve conflicts in
# this separate tree and either apply the complete merge when ready;
# or abort the merge alltogether, if problems arise.
#
# Invoke systr_merge_finish to apply new content to the worktree and
# prep for a merge-commit.
##
function systr_merge_tree
{
if [ $# -lt 1 ]; then
echo "Fatal: too few args to merge_tree" >&2
exit 1
fi
commit=$(systr_repo_resolve_reference "$1")
mergebase=$(systr_repo_merge_base "$commit" "$BASE")
mergebase=$(
cd "$path/revs/$mergebase/"
echo $PWD
)
rm -rf .systr/merge/ .systr/tmp/
mkdir .systr/merge .systr/tmp
systr_rsync_diff "$path/revs/$commit/" "$mergebase" .systr/tmp/
systr_rsync_diff . "$mergebase" .systr/merge/
systr_rsync_del "$path/revs/$commit/" "$mergebase" .systr/merge/
systr_rsync_del . "$mergebase" .systr/tmp/
systr_rsync_merge .systr/tmp/ .systr/merge/
}
##
# systr_merge_finish <commit>
#
# Apply merged contents to the worktree. This works by first deleted
# removed files from <commit> then copying the local merge directory
# into the worktree.
#
# Once this completes, the user should run systrunk commit to record
# the merged tree in the repository.
##
function systr_merge_finish
{
if [ $# -lt 1 ]; then
echo "Fatal: too few args to merge_finish" >&2
exit 1
fi
branch="$1"
commit=$(systr_repo_resolve_reference "$1")
mergebase=$(systr_repo_merge_base "$commit" "$BASE")
mergebase=$(
cd "$path/revs/$mergebase/"
echo $PWD
)
rsync -az --existing --ignore-existing --delete --compare-dest="$mergebase" \
--exclude='*.systr' "$path/revs/$commit/" .
rsync -azi .systr/merge/ .
rm -rf .systr/merge/ .systr/tmp/
if [[ "$branch" == "TRAC" ]]; then
echo "NULL" >.systr/MERG
echo "$commit" >.systr/BASE
fi
}
##
# systrunk merge <commit>
#
# Merge the tree of <commit> into the worktree. If conflicts are found,
# they are interactively addressed. Once all conflicts are resolved,
# the merged content is moved into the worktree, ready for commit.
# Otherwise, the user may abort the merge, leaving the worktree intact.
#
# If <commit>=TRAC, as is the case for an 'update' operation, a merge
# commit is not expected and the MERG pointer will be cleared after
# the worktree is successfully updated.
#
# If the interactive prompt is left, user can invoke 'systrunk apply-merge'
# to proceed or 'systrunk abort-merge' to abort.
##
function systr_merge
{
if [ $# -lt 1 ]; then
echo "Fatal: too few args to merge" >&2
exit 1
fi
commit="$1"
(systr_merge_tree "$commit")
echo "$commit" >.systr/MERG
# resolve conflicts #
for file in `find .systr/merge/ -name '*\*'`;
do
orig=${file::-1}
vimdiff "$orig" "$file"
rm "$file"
done
for file in `find .systr/merge/ -name '*~'`;
do
name=${file::-1}
echo "$name removed on $commit // {created on worktree}"
while true;
do
echo "Use [d]eleted file Use [e]dited file Inspect in [v]im [A]bort"
read opt
if [[ "$opt" == "d" ]]; then
rm "$file"
break
elif [[ "$opt" == "e" ]]; then
mv "$file" "$name"
break
elif [[ "$opt" == "v" ]]; then
vim "$file"
elif [[ "$opt" == "A" ]]; then
exit
fi
done
done
for file in `find .systr/merge/ -name '*\&'`;
do
name=${file::-1}
echo "$name removed on worktree // {created on $commit}"
while true;
do
echo "Use [d]eleted file Use [e]dited file Inspect in [v]im [A]bort"
read opt
if [[ "$opt" == "d" ]]; then
rm "$file"
break
elif [[ "$opt" == "e" ]]; then
mv "$file" "$name"
break
elif [[ "$opt" == "v" ]]; then
vim "$file"
elif [[ "$opt" == "A" ]]; then
exit
fi
done
done
# apply merge #
(systr_merge_finish "$commit")
}
##
# systrunk abort-merge
#
# Abort an in-progress merge that has *not* yet been incorporated
# into the worktree. This purges the merge staging directories and
# clears the MERG pointer.
##
function systr_merge_abort
{
rm -rf .systr/merge/ .systr/tmp/
echo "NULL" >.systr/MERG
}
|