## # systr_merge_tree # # Merge the contents of into the current worktree, using # the calculated merge-base of 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 # # Apply merged contents to the worktree. This works by first deleted # removed files from 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 # # Merge the tree of 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 =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 }