aboutsummaryrefslogtreecommitdiff
path: root/bin
diff options
context:
space:
mode:
Diffstat (limited to 'bin')
-rwxr-xr-xbin/git-deli55
1 files changed, 46 insertions, 9 deletions
diff --git a/bin/git-deli b/bin/git-deli
index 6cca2cc..ca45002 100755
--- a/bin/git-deli
+++ b/bin/git-deli
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/bin/bash
#
# git-deli.sh: delinearized git workflows helper
#
@@ -11,17 +11,17 @@
OPTS_SPEC="\
git deli head [-b=<branch>] [-m=<msg>] [<commit>] [-s]
-git deli go [-c] [-s] [-b=<branch>] [-m=<msg>] <commit>
+git deli eat [-c] [-s] [-b=<branch>] [-m=<msg>] <commit>
git deli commit ...
git deli boundary [-d] <commit>
git deli merge <commit> ...
-git deli push [-f] <repository> <refspec>
-git deli pull <repository> <ref>
+git deli push [-f] [<repository>] [<refspec>]
+git deli pull [<repository>] [<ref>]
--
common options:
h,help! show the help
m,message!= specify the commit message
- 'head' and 'go' options:
+ 'head' and 'eat' actions:
b,branch!= start a new branch instead of using the target one
s,set-boundary use the <commit> as a boundary for the new head
c,create-head start a new head at <commit> and delinearize into it
@@ -110,7 +110,7 @@ main() {
shift # drop the command, we already got it
case "$arg_command" in
head) cmd_head "$arg_msg" "$arg_branch" "$arg_set_boundary" "$@" ;;
- go) cmd_go "$arg_msg" "$arg_branch" "$@" ;;
+ eat) cmd_eat "$arg_msg" "$arg_branch" "$@" ;;
commit) cmd_commit "$arg_msg" "$@" ;;
boundary) cmd_boundary "$arg_delete" "$@" ;;
merge) cmd_merge "$@" ;;
@@ -156,14 +156,16 @@ cmd_head () {
git reset --soft "$new_head" || die "git-reset failed to set the new HEAD"
}
-cmd_go () {
+cmd_eat () {
# we're squashing whatever has been done atop of a given head view
+ false
}
cmd_commit () {
msg="$1"
shift
# TODO run a git commit with all extra args, THEN run head with the original commit
+ false
}
cmd_boundary () {
@@ -173,6 +175,7 @@ cmd_boundary () {
commit="$1"
# TODO this adds or removes the "extra parents" to the head commit
+ false
}
cmd_merge () {
@@ -279,6 +282,7 @@ stream_independent_commit_set () {
}
# usage: revision <diff >shas
+# TODO: Binary files (match ^Binary in output, ask for all lines)
deli_diff_to_source_lines () {
awk -f '
BEGIN {
@@ -300,10 +304,40 @@ match($0, /^@@ -([0-9]+),([0-9]+) /, matched) && file!="" {
END {
if(ranges!="") print(ranges, "--", file);
}
- ' | xargs -l git annotate -l "$1" | cut -d'\t' -f1
+ ' \
+ | xargs -l git annotate -l "$1" \
+ | cut -d'\t' -f1
}
-deli_commit () {
+deli_eat_commit () {
+ delihead="$1"
+ target="$2"
+ # TODO insert bounds
+ parents=$( git diff ${DELI_DIFF_ARGS:-} -p "$delihead" "$target" | deli_diff_to_source_lines | sort | uniq | stream_independent_commit_set )
+ # check if the parents are ok
+ for i in parents
+ do git merge-base --is-ancestor "$delihead" "$i" || die "changes in $target are based on $delihead"
+ done
+ set -- $parents
+ echo "sourcing commit $1..." >&2
+ merged_tree="$1^{tree}"
+ shift
+ while test $# -gt 0
+ do
+ echo "merging commit $1..." >&2
+ merged_tree=$( git merge-tree --write-tree "$merged_tree" "$1^{tree}" || die "merging of the parents failed" )
+ shift
+ done
+
+ new_commit=$(
+ ( echo "tree $merged_tree"
+ for i in $parents
+ do echo "parent $i"
+ done
+ git cat-file commit "$target" | sed '/^$/bx; /^tree /d ; /^parent /d ; n ; :x'
+ ) | git hash-object -t commit --stdin -w || die "could not save new commit for tree $merged_tree"
+ )
+
false
}
@@ -317,6 +351,7 @@ deli_commit () {
# Given the heads merge cleanly, the algorithm actually reduces to a very
# simple task:
#
+# - we do a normal merge (this must solve cleanly)
# - all parents from the original 2 commits are combined and reduced to
# independent set
# - all bounds from the original 2 commits are also reduced to an independent
@@ -326,6 +361,8 @@ deli_commit () {
# (TODO does it make sense to check this?)
# - we write out the new commit with all parents and all bounds
#
+# TODO tbh this should be the very same as doing the `eat` operation after a
+# merge, but the eat would need to handle multiple parents correctly.
deli_merge () {
false