aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMirek Kratochvil <exa.exa@gmail.com>2025-12-27 20:38:45 +0100
committerMirek Kratochvil <exa.exa@gmail.com>2025-12-27 20:38:45 +0100
commitf550022df4918036eb2a2b3bf745cf446f30db19 (patch)
tree9ca6c9744fcdab06e19c7f270b119ac18cb7d7ab
parent4e9ee8c61695df19b14db5fc053172f6494b598d (diff)
downloadgit-deli-master.tar.gz
git-deli-master.tar.bz2
structure the frontend a littleHEADmaster
-rwxr-xr-xbin/git-deli140
1 files changed, 140 insertions, 0 deletions
diff --git a/bin/git-deli b/bin/git-deli
new file mode 100755
index 0000000..6a00b40
--- /dev/null
+++ b/bin/git-deli
@@ -0,0 +1,140 @@
+#!/bin/sh
+#
+# git-deli.sh: delinearized git workflows helper
+#
+# Copytight (C) 2025 Mirek Kratochvil <exa.exa@gmail.com>
+#
+
+OPTS_SPEC="\
+git deli head [-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>
+--
+h,help! show the help
+m,message!= specify the commit message
+ 'head' options:
+b,branch!= start a new branch instead of using the target one
+ 'boundary' options:
+d,delete delete the boundary commit instead of adding it
+ 'push' options:
+f,force internally do a true force-push instead of the safe force-with-lease
+"
+
+main() {
+ if test $# -eq 0
+ then set -- -h
+ fi
+
+ set_args="$(echo "$OPTS_SPEC" | git-rev-parse --parseopt --stuck-long -- "$@" || echo exit $?)"
+ eval "$set_args"
+ . git-sh-setup
+ require_work_tree
+
+ # find the command right away (TODO: actually validate if the options
+ # belong to the given command later)
+ while test $# -gt 0
+ do
+ opt="$1"
+ shift
+ [ "$opt" = "--" ] && break
+ done
+ arg_command=$1
+ eval "$set_args"
+
+ arg_msg=
+ arg_branch=
+ arg_all=
+ arg_patch=
+ arg_delete=
+ arg_force=
+ while test $# -gt 0
+ do
+ opt="$1"
+ shift
+ case "$opt" in
+ --message=*)
+ [ -z "$arg_msg" ] || die "conflicting options for --message"]
+ arg_msg="${opt#*=}" ;;
+ --branch=*)
+ [ -z "$arg_branch" ] || die "conflicting options for --branch"]
+ arg_branch="${opt#*=}" ;;
+ --delete)
+ [ -z "$arg_delete" ] || die "conflicting options for --delete"]
+ arg_delete=yes ;;
+ --no-delete)
+ [ -z "$arg_delete" ] || die "conflicting options for --delete"]
+ arg_delete=no ;;
+ --force)
+ [ -z "$arg_force" ] || die "conflicting options for --force"]
+ arg_force=yes ;;
+ --no-force)
+ [ -z "$arg_force" ] || die "conflicting options for --force"]
+ arg_force=no ;;
+ --)
+ break ;;
+ *)
+ die "fatal: unexpected option: $opt"
+ esac
+ done
+
+ shift # drop the command, we already got it
+ case "$arg_command" in
+ head) cmd_head "$arg_msg" "$arg_branch" "$@" ;;
+ commit) cmd_commit "$arg_msg" "$@" ;;
+ boundary) cmd_boundary "$arg_delete" "$@" ;;
+ merge) cmd_merge "$@" ;;
+ push) cmd_push "$arg_force" "$@" ;;
+ pull) cmd_pull "$@" ;;
+ *)
+ die "fatal: unknonwn command: $arg_command" ;;
+ esac
+}
+
+cmd_head () {
+ msg="$1"
+ branch="$2"
+ # TODO one extra optional commit arg
+ # if the arg is there, this is "rebase" mode that picks up a deli view
+ # from the history and separates the commits into branches below it
+ #
+ # if it's not there, we make a new head on the current branch, possibly
+ # making a new one in the process
+}
+
+cmd_commit () {
+ msg="$1"
+ shift
+ # TODO run a git commit with all extra args, THEN run head with the original commit
+}
+
+cmd_boundary () {
+ delete="$1"
+ shift
+ [ $# -eq 1 ] || die "specify one boundary commit"
+ commit="$1"
+
+ # TODO this adds or removes the "extra parents" to the head commit
+}
+
+cmd_merge () {
+ # TODO this should merge multiple "head" commits
+ # notably, there must not be any actual merging involved -- there must
+ # be no conflicts etc. What happens is that, quite simply, the parents
+ # of the new head become all (latest) parents of all original heads. If
+ # there is any actual merging required, it must be resolved elsewhere
+ # and recorded in the history so that branches merge cleanly.
+}
+
+cmd_push () {
+ # TODO like git-push but actually force-pushes the current multihead.
+ # Uses a force-with-lease by default.
+}
+
+cmd_pull () {
+ # TODO like a normal git fetch followed by git deli merge
+}
+
+main "$@"