blob: 64a6bffe00521c8f0d0c695b9ef0bd94e0f46a68 (
plain) (
tree)
|
|
##
# 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
}
|