threads / patch / 15020

patchtg redepend: New command.

Subject: [TopGit PATCH] tg redepend: New command.

## tl;dr

7 messages between Aug 15, 2008 and Sep 1, 2008. Diffs are folded; open one to read it.

replies: 6people: 3as markdown or json

Jan Nieuwenhuizen· Aug 15, 2008, 13:53 UTC · lore
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
Show changes to 3 files +160 −1

Makefile, README, 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
Bert Wesarg· Aug 15, 2008, 17:16 UTC · re: Jan Nieuwenhuizen · lore

Re: [TopGit PATCH] tg redepend: New command.

On Fri, Aug 15, 2008 at 15:53, Jan Nieuwenhuizen <janneke-list@xs4all.nl> wrote: Why don't you call this command 'depend', as per README TODO?

> +
> +# Local Variables:
> +# sh-basic-offset:8
> +# End:

This would be the first file in this project with such editor infos. IMHO this shouldn't belong to a patch.

Regards Bert

Jonathan Nieder· Aug 15, 2008, 18:20 UTC · re: Jan Nieuwenhuizen · lore

Re: [TopGit PATCH] tg redepend: New command.

Hi,
Jan Nieuwenhuizen wrote:
Show 13 quoted lines
> 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
[...]
> +		-h|--help)
> +			echo "Usage: tg [--add|--remove] DEPENDENCY..." >&2
s/tg/tg redepend/?
[...]
Show 5 quoted lines
> +# 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

Why not move the base-creation code in tg-create.sh to a new function in tg.sh to use here?

[...]
Show 6 quoted lines
> +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
[snip continuing-a-merge case]
> +fi
> +git read-tree -m -u $(git rev-parse $p_)
[snip topdeps juggling]
> +git commit -m "Rebased-using-merge onto new dependencies: $redeps."  > /dev/null 2>&1

I know I suggested that code before, but the merge with B' is wasted, so perhaps

	git checkout P
	head=$(git rev-parse --verify HEAD^0)
	result_tree=$(git log -1 --pretty=format:%T P')
	result_commit=$(git commit-tree "$result_tree" -p P -p B')
	git update-ref -m "commit (merge): tg-redepend" HEAD \
			"$result_commit" "$head" || ... (fail)
	test -x "$GIT_DIR/hooks/post-merge" && $GIT_DIR/hooks/post-merge 0

I'm not sure. Is there some more porcelain-ish way to do this (create a merge commit when you already know the resulting and parents)?

But with that change the entire restarted=merge branch would go away, so I hope there is a nice way to do it. I'll think more.

Hope that helps, Jonathan

Show 13 quoted lines
> +
> +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:
> 
Jan Nieuwenhuizen· Aug 18, 2008, 09:23 UTC · re: Jonathan Nieder · lore

Re: [TopGit PATCH] tg redepend: New command.

On vr, 2008-08-15 at 13:20 -0500, Jonathan Nieder wrote:
Hi,
> s/tg/tg redepend/?
Yes.
> Why not move the base-creation code in tg-create.sh to a new
> function in tg.sh to use here?
Yes, that's better.
 
Show 16 quoted lines
> I know I suggested that code before, but the merge with B' is wasted, so
> perhaps
> 
> 	git checkout P
> 	head=$(git rev-parse --verify HEAD^0)
> 	result_tree=$(git log -1 --pretty=format:%T P')
> 	result_commit=$(git commit-tree "$result_tree" -p P -p B')
> 	git update-ref -m "commit (merge): tg-redepend" HEAD \
> 			"$result_commit" "$head" || ... (fail)
> 	test -x "$GIT_DIR/hooks/post-merge" && $GIT_DIR/hooks/post-merge 0
> 
> I'm not sure.  Is there some more porcelain-ish way to do this (create a
> merge commit when you already know the resulting and parents)?
> 
> But with that change the entire restarted=merge branch would go away,
> so I hope there is a nice way to do it.  I'll think more.
Yes, the user should get a nice chance to resolve any conflicts...

Thanks! Jan.

-- 
Jan Nieuwenhuizen <janneke@gnu.org> | GNU LilyPond - The music typesetter
http://www.xs4all.nl/~jantien       | http://www.lilypond.org
Bert Wesarg· Sep 1, 2008, 09:31 UTC · re: Jan Nieuwenhuizen · lore

Re: [TopGit PATCH] tg redepend: New command.

Hi,
On Fri, Aug 15, 2008 at 15:53, Jan Nieuwenhuizen <janneke-list@xs4all.nl> wrote:
Show 7 quoted lines
> As discussed previously
>
>    http://kerneltrap.org/mailarchive/git/2008/8/13/2925144
>
> Change a topgit branch's dependencies by doing a rebase-by-merge.
>
>
is this script in use by you, or is it abandoned in favor of another idea?

Anyway, I have tried it today but it looks like the top-bases wasn't updated to the new deps. It points still to the old base. Second, I got an empty line in my .topdeps file.

Show 15 quoted lines
> +
> +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
IMHO all these "| tr '\n' ' '" aren't needed. bash do the right thing here.
Bert
Jan Nieuwenhuizen· Sep 1, 2008, 10:11 UTC · re: Bert Wesarg · lore

Re: [TopGit PATCH] tg redepend: New command.

On ma, 2008-09-01 at 11:31 +0200, Bert Wesarg wrote:
Hi Bert,
Show 10 quoted lines
> 
> On Fri, Aug 15, 2008 at 15:53, Jan Nieuwenhuizen <janneke-list@xs4all.nl> wrote:
> > As discussed previously
> >
> >    http://kerneltrap.org/mailarchive/git/2008/8/13/2925144
> >
> > Change a topgit branch's dependencies by doing a rebase-by-merge.
> >
> >
> is this script in use by you, or is it abandoned in favor of another idea?

I haven't had the time to digest the several new takes on this, esp. http://kerneltrap.org/mailarchive/git/2008/8/15/2954214 and combining my previous attempt's use of git revert and git cherry-pick with git read-tree to make for a much faster adding or removal of dependencies.

> Anyway, I have tried it today but it looks like the top-bases wasn't
> updated to the new deps.

How odd. It also looks like "redeps" contains the new set of dependencies, which is written to .topdeps. I guess that most of this script will be abandoned anyway, but a nice bug report ie: how to reproduce this error never hurts ;-)

> IMHO all these "| tr '\n' ' '" aren't needed. bash do the right thing
> here.

Thanks, I'll have a look. You did try --add, --remove and "new dep list" right?

Greetings, Jan.

-- 
Jan Nieuwenhuizen <janneke@gnu.org> | GNU LilyPond - The music typesetter
http://www.xs4all.nl/~jantien       | http://www.lilypond.org
Bert Wesarg· Sep 1, 2008, 10:36 UTC · re: Jan Nieuwenhuizen · lore

Re: [TopGit PATCH] tg redepend: New command.

On Mon, Sep 1, 2008 at 12:11, Jan Nieuwenhuizen <janneke-list@xs4all.nl> wrote:
Show 28 quoted lines
> On ma, 2008-09-01 at 11:31 +0200, Bert Wesarg wrote:
>
> Hi Bert,
>
>>
>> On Fri, Aug 15, 2008 at 15:53, Jan Nieuwenhuizen <janneke-list@xs4all.nl> wrote:
>> > As discussed previously
>> >
>> >    http://kerneltrap.org/mailarchive/git/2008/8/13/2925144
>> >
>> > Change a topgit branch's dependencies by doing a rebase-by-merge.
>> >
>> >
>> is this script in use by you, or is it abandoned in favor of another idea?
>
> I haven't had the time to digest the several new takes on this, esp.
> http://kerneltrap.org/mailarchive/git/2008/8/15/2954214 and combining
> my previous attempt's use of git revert and git cherry-pick with git
> read-tree to make for a much faster adding or removal of
> dependencies.
>
>> Anyway, I have tried it today but it looks like the top-bases wasn't
>> updated to the new deps.
>
> How odd.  It also looks like "redeps" contains the new set of
> dependencies, which is written to .topdeps.  I guess that most of
> this script will be abandoned anyway, but a nice bug report ie: how to
> reproduce this error never hurts ;-)
Yeah, sorry, here comes part two:

I have tried to switch the order of two topics, which are the only two in this 'series'. T1 depdens on master, and T2 on T1 with definitive merge conflicts.

first step was to redepend T2 to master: $ tg redepend master

after that, I saw the above odds, i.e.:
 * the refs/top-bases/T2 points still to T1 not master
 * (NEW) the .topmsg is lost (which I discovered after step two)
 * a trailing empty line is in .topdeps

(NEW) step two was to redpend T1 on T2: $ git checkout T2 $ tg redepend T2

after that, my T1 changes were lost, i.e. the worktree is in state of T2.
I have attached the log of this session (slightly edited).
Thanks anyway for working on this.

Regards Bert

> Greetings,
> Jan.

← back to recent threads