git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[TopGit PATCH] tg redepend: New command.

From
JNJan Nieuwenhuizen <janneke-list@xs4all.nl>
Date
Aug 15, 2008, 13:53 UTC
Message-ID
<1218808427.25300.2.camel@heerbeest>
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@gnu.org>
---
 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@gnu.org>
+# 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@gnu.org> | GNU LilyPond - The music typesetter
http://www.xs4all.nl/~jantien       | http://www.lilypond.org
Next: Bert Wesarg
Message 1 of 7 in “tg redepend: New command.”
  1. tg redepend: New command.Jan Nieuwenhuizen, Aug 15, 2008
  2. Bert WesargAug 15, 2008
  3. Jonathan NiederAug 15, 2008
  4. Jan NieuwenhuizenAug 18, 2008
  5. Bert WesargSep 1, 2008
  6. Jan NieuwenhuizenSep 1, 2008
  7. Bert WesargSep 1, 2008

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.