From: Jan Nieuwenhuizen <janneke-list@xs4all.nl>
To: git <git@vger.kernel.org>
Cc: Jan Holesovsky <kendy@suse.cz>
Subject: [TopGit PATCH] tg redepend: New command.
Date: Fri, 15 Aug 2008 15:53:47 +0200 [thread overview]
Message-ID: <1218808427.25300.2.camel@heerbeest> (raw)
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 reply other threads:[~2008-08-15 13:54 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-08-15 13:53 Jan Nieuwenhuizen [this message]
2008-08-15 17:16 ` [TopGit PATCH] tg redepend: New command Bert Wesarg
2008-08-15 18:20 ` Jonathan Nieder
2008-08-18 9:23 ` Jan Nieuwenhuizen
2008-09-01 9:31 ` Bert Wesarg
2008-09-01 10:11 ` Jan Nieuwenhuizen
2008-09-01 10:36 ` Bert Wesarg
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1218808427.25300.2.camel@heerbeest \
--to=janneke-list@xs4all.nl \
--cc=git@vger.kernel.org \
--cc=kendy@suse.cz \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).