[TopGit PATCH] tg redepend: New command.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



As discussed previously

    http://kerneltrap.org/mailarchive/git/2008/8/13/2925144

Change a topgit branch's dependencies by doing a rebase-by-merge.


Signed-off-by: Jan Nieuwenhuizen <janneke@xxxxxxx>
---
 Makefile       |    2 +-
 README         |    5 ++
 tg-redepend.sh |  154 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 160 insertions(+), 1 deletions(-)
 create mode 100644 tg-redepend.sh

diff --git a/Makefile b/Makefile
index ea6489e..3988251 100644
--- a/Makefile
+++ b/Makefile
@@ -5,7 +5,7 @@ sharedir = $(prefix)/share/topgit
 hooksdir = $(cmddir)/hooks
 
 
-commands_in = tg-create.sh tg-delete.sh tg-export.sh tg-info.sh tg-patch.sh tg-summary.sh tg-update.sh
+commands_in = tg-create.sh tg-delete.sh tg-export.sh tg-info.sh tg-patch.sh tg-redepend.sh tg-summary.sh tg-update.sh
 hooks_in = hooks/pre-commit.sh
 
 commands_out = $(patsubst %.sh,%,$(commands_in))
diff --git a/README b/README
index b58a1b4..3528602 100644
--- a/README
+++ b/README
@@ -330,6 +330,11 @@ tg export
 	TODO: Make stripping of [PATCH] and other prefixes configurable
 	TODO: --mbox option for other mode of operation
 
+tg redepend
+~~~~~~~~~~~
+	Change the current topic branch's list of dependencies
+	by doing a rebase-by-merge onto the new dependencies.
+
 tg update
 ~~~~~~~~~
 	Update the current topic branch wrt. changes in the branches
diff --git a/tg-redepend.sh b/tg-redepend.sh
new file mode 100644
index 0000000..e1612ea
--- /dev/null
+++ b/tg-redepend.sh
@@ -0,0 +1,154 @@
+#! /bin/sh
+# TopGit - A different patch queue manager
+# (c) 2008  Jan Nieuwenhuizen <janneke@xxxxxxx>
+# GNU GPL version 2
+
+add=
+remove=
+redeps=
+restarted=
+
+## Parse options
+
+while [ -n "$1" ]; do
+	arg="$1"; shift
+	case "$arg" in
+		--add)
+			[ -z "$redeps" ] || die "already specified new list of dependencies ($redeps)"
+			[ -z "$remove" ] || die "already specified dependencies to remove ($remove)"
+			add="$add "
+			;;
+		-h|--help)
+			echo "Usage: tg [--add|--remove] DEPENDENCY..." >&2
+			;;
+		--remove)
+			[ -z "$redeps" ] || die "already specified new list of dependencies ($redeps)"
+			[ -z "$add" ] || die "already specified dependencies to add ($add)"
+			remove="$remove "
+			;;
+		*)
+			[ -z "$add" ] || add="$add$arg "
+			[ -z "$remove" ] || remove="$remove$arg "
+			[ ! -z "$add$remove" ] || redeps="$redeps$arg "
+	esac
+done
+
+if [ -n "$add" ]; then
+	add="${add/# }"
+	add="${add//  / }"
+	dupes=$(grep -E "^${add// /|}/\$" "$root_dir/.topdeps" | tr '\n' ' ')
+	[ -z "$dupes" ] || die "already depend on: $dupes"
+	redeps=$(echo "$add" | cat "$root_dir/.topdeps" - | tr '\n' ' ' | sed -e 's/ \+$//')
+elif [ -n "$remove" ]; then
+	remove="${remove//  / }"
+	remove="${remove/# }"
+	avail=$(grep -E "^${remove// /|}/\$" "$root_dir/.topdeps" | sort | tr '\n' ' ')
+	remove_sorted=$(echo "$remove" | tr ' ' '\n' | grep -v '^$' | sort | tr '\n' ' ')
+	[ "$avail" = "$remove_sorted" ] || die "not depending on some of: $remove"
+	redeps=$(grep -vE "^${remove// /|}/\$" "$root_dir/.topdeps" | tr '\n' ' ')
+fi
+
+redeps="${redeps/# }"
+redeps="${redeps/# }"
+
+if [ -z "$redeps" ]; then
+	if [ -s "$git_dir/top-name" -a -s "$git_dir/top-redeps" -a -f "$git_dir/top-rebase" ]; then
+		restarted=rebase
+	elif [ -s "$git_dir/top-name" -a -s "$git_dir/top-redeps" -a -f "$git_dir/top-merge" ]; then
+		restarted=merge
+	else
+		echo "Usage: tg [--add|--remove] DEPENDENCY..." >&2
+		exit 2
+	fi
+fi
+
+function fail () {
+	info "Please resolve conflicts and call: tg redepend"
+	info "It is also safe to abort this operation using:"
+	info "tg delete $b_; git reset --hard some_branch"
+	echo "$p" > "$git_dir/top-name"
+	echo "$redeps" > "$git_dir/top-redeps"
+	touch "$git_dir/top-$1"
+	exit 1
+}
+
+# See http://kerneltrap.org/mailarchive/git/2008/8/13/2925144
+#
+# B -- (some mess) -- P
+#
+# Do "git rebase --onto B' B P" while preserving history to get
+#
+# B -- (some mess) -- old P -- P
+#                             /
+#                           B'
+
+if [ -z "$restarted" ]; then
+	info "New list of dependencies: $redeps."
+	p=$(git symbolic-ref HEAD | cut -b 12-)
+else
+	p="$(cat "$git_dir/top-name")"
+	redeps="$(cat "$git_dir/top-redeps")"
+fi
+
+# Clean up any restart stuff
+rm -f "$git_dir/top-name" "$git_dir/top-redeps" "$git_dir/top-rebase" "$git_dir/top-merge"
+
+b="$(git rev-parse --short --verify "refs/top-bases/$p" 2>/dev/null)" \
+	|| die "not a TopGit-controlled branch"
+p_=tg-redepend/tmp/${p}_
+b_=tg-redepend/tmp/$p.base_
+
+# Create new base B' -- does not have to be a topgit branch, but that's easiest
+if [ -z "$restarted" ]; then
+	git branch -D $p_  > /dev/null 2>&1 || :
+
+	tg create $b_ $redeps
+	git commit -m 'tg redepend: add TopGit .top* info.'
+
+# Do "git rebase --onto B' B P" while preserving history
+	git checkout -b $p_ $p
+
+	if ! git rebase --onto $b_ $b; then
+		fail rebase
+	fi
+elif [ "$restarted" = "rebase" ]; then
+	[ ! -d "$git_dir/rebase-apply" ] || git add "$root_dir"
+	[ ! -d "$git_dir/rebase-apply" ] || git add -u "$root_dir"
+	[ ! -d "$git_dir/rebase-apply" ] || if ! git rebase --continue; then
+		fail rebase
+	fi
+	rm -f "$git_dir/top-name" "$git_dir/top-redeps"
+	restarted=
+fi
+
+if [ "$restarted" != "merge" ]; then
+	git checkout $(git rev-parse $p)
+	if ! git merge --no-ff --no-commit $b_; then
+		touch "$git_dir/top-merge"
+		fail merge
+	fi
+elif ! git status | grep 'nothing to commit' > /dev/null; then
+	git add "$root_dir"
+	git add -u "$root_dir"
+	git commit -m 'tg redepend: resolve merge.' > /dev/null 2>&1
+fi
+git read-tree -m -u $(git rev-parse $p_)
+
+echo "$redeps" | tr ' ' '\n' > "$root_dir/.topdeps"
+
+git add "$root_dir"
+git add -u "$root_dir"
+
+git commit -m "Rebased-using-merge onto new dependencies: $redeps."  > /dev/null 2>&1
+
+git branch -f $p
+git checkout $p
+
+tg delete $b_  > /dev/null 2>&1
+git branch -D $p_
+
+info "Rebased-using-merge onto new dependencies: $redeps."
+
+# Local Variables:
+# sh-basic-offset:8
+# End:
-- 
1.6.0.rc0.44.g67270


-- 
Jan Nieuwenhuizen <janneke@xxxxxxx> | GNU LilyPond - The music typesetter
http://www.xs4all.nl/~jantien       | http://www.lilypond.org

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux