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

Re: [RFC/PATCH 1/4] Add git-sequencer shell prototype

From
Johannes Schindelin <johannes.schindelin@gmx.de>
Date
Jul 3, 2008, 11:03 UTC
Message-ID
<alpine.DEB.1.00.0807031142540.9925@racer>
In-Reply-To
<7vbq1f68rh.fsf@gitster.siamese.dyndns.org>
Hi,
On Wed, 2 Jul 2008, Junio C Hamano wrote:
Show 25 quoted lines
> Stephan Beyer <s-beyer@gmx.net> writes:
> 
> > git sequencer is planned as a backend for user scripts
> > that execute a sequence of git instructions and perhaps
> > need manual intervention, for example git-rebase or git-am.
> 
> ...
> > +output () {
> > +	case "$VERBOSE" in
> > +	0)
> > +		"$@" >/dev/null
> > +		;;
> > +	1)
> > +		output=$("$@" 2>&1 )
> > +		status=$?
> > +		test $status -ne 0 && printf '%s\n' "$output"
> > +		return $status
> > +		;;
> > +	2)
> > +		"$@"
> > +		;;
> > +	esac
> > +}
> 
> Perhaps misnamed?  This feels more like "do" or "perform" or "run".
My fault.  I like "perform".
Show 10 quoted lines
> > +require_clean_work_tree () {
> > +	# test if working tree is dirty
> > +	git rev-parse --verify HEAD >/dev/null &&
> > +	git update-index --ignore-submodules --refresh &&
> > +	git diff-files --quiet --ignore-submodules &&
> > +	git diff-index --cached --quiet HEAD --ignore-submodules -- ||
> > +	die 'Working tree is dirty'
> > +}
> 
> When is it necessary to ignore submodules and why?

Submodules are not updated by checkout. Indeed, the _only_ Git command that actually changes the state of a submodule is "git submodule update".

Therefore, it is wrong to assume that rebase/am/whatever works with submodules as far as the working directory is concerned. Updating submodules with any Git command other than "git submodule update" is a _pure_ index operation.

Of course, that means that if you use rebase -i's "edit" command to go back to a certain revision, edit that, and want to test, it is _your_ responsibility to make sure that the submodules are at their correct revision.

> Are there cases where submodules should not be ignored?

With above reasoning, it would always be wrong for sequencer to require the submodules to be up-to-date.

Show 12 quoted lines
> > +LAST_COUNT=
> > +mark_action_done () {
> > +	sed -e 1q <"$TODO" >>"$DONE"
> > +	sed -e 1d <"$TODO" >"$TODO.new"
> > +	mv -f "$TODO.new" "$TODO"
> > +	if test "$VERBOSE" -gt 0
> > +	then
> > +		count=$(grep -c '^[^#]' <"$DONE")
> > +		total=$(expr "$count" + "$(grep -c '^[^#]' <"$TODO")")
> 
> Here we are not counting lines that are comments as insns (I am not
> complaining; just making a mental note).

As "count" and "total" are only used for the progress output, anything else would not make sense.

Show 18 quoted lines
> > +		if test "$LAST_COUNT" != "$count"
> > +		then
> > +			LAST_COUNT="$count"
> > +			test "$VERBOSE" -lt 1 ||
> > +				printf 'Sequencing (%d/%d)\r' "$count" "$total"
> > +			test "$VERBOSE" -lt 2 || echo
> > +		fi
> > +	fi
> > +}
> > +
> > +# Generate message, patch and author script files
> > +make_patch () {
> > +	parent_sha1=$(git rev-parse --verify "$1"^) ||
> > +		die "Cannot get patch for $1^"
> > +	git diff-tree -p "$parent_sha1..$1" >"$PATCH"
> 
> Could there be a case where we need/want to deal with a root commit
> without parents?

Yes. I had exactly that need a few days ago, where I wanted to import a few zips, and rebase them on top of an existing branch (which was generated in the same manner).

I worked around that limitation of rebase (actually, I only tried rebase -i, come to think of it), by rewriting the first commit object, inserting the "parent" line. "fast-export > a1; vi a1; fast-import < a1" can be so much fun!

Show 24 quoted lines
> > +	test -f "$MSG" ||
> > +		commit_message "$1" >"$MSG"
> > +	test -f "$AUTHOR_SCRIPT" ||
> > +		get_author_ident_from_commit "$1" >"$AUTHOR_SCRIPT"
> > +}
> > +
> > +# Generate a patch and die with "conflict" status code
> > +die_with_patch () {
> > +	make_patch "$1"
> > +	git rerere
> > +	die_to_continue "$2"
> > +}
> > +
> > +restore () {
> > +	git rerere clear
> > +
> > +	HEADNAME=$(cat "$SEQ_DIR/head-name")
> > +	HEAD=$(cat "$SEQ_DIR/head")
> 
> Perhaps
> 
> 	read HEADNAME <"$SEQ_DIR/head-name"
> 
> provided if these values are $IFS safe?

Again, my fault (as this was most likely copied from rebase -i). All the files written to $DOTEST in rebase -i should be $IFS safe.

Show 19 quoted lines
> > +	case $HEADNAME in
> > +	refs/*)
> > +		git symbolic-ref HEAD "$HEADNAME"
> > +		;;
> > +	esac &&
> > +	output git reset --hard "$HEAD"
> > +}
> > +
> > +has_action () {
> > +	grep '^[^#]' "$1" >/dev/null
> > +}
> > +
> > +# Check if text file $1 contains a commit message
> > +has_message () {
> > +	test -n "$(sed -n -e '/^Signed-off-by:/d;/^[^#]/p' <"$1")"
> > +}
> 
> Makes one wonder if we would want to special case other kinds like
> "Acked-by:" as well...
I think this just mimicks "git commit".
Show 25 quoted lines
> > +# Usage: pick_one (cherry-pick|revert) [-*|--edit] sha1
> > +pick_one () {
> > +	what="$1"
> > +	# we just assume that this is either cherry-pick or revert
> > +	shift
> > +
> > +	# check for fast-forward if no options are given
> > +	if expr "x$1" : 'x[^-]' >/dev/null
> > +	then
> > +		test "$(git rev-parse --verify "$1^")" = \
> > +			"$(git rev-parse --verify HEAD)" &&
> > +			output git reset --hard "$1" &&
> > +			return
> > +	fi
> > +	test "$1" != '--edit' -a "$what" = 'revert' &&
> > +		what='revert --no-edit'
> 
> This looks somewhat wrong.
> 
> When the history looks like ---A---B and we are at A, cherry-picking B can
> be optimized to just advancing to B, but that optimization has a slight
> difference (or two) in the semantics.
> 
>  (1) The committer information would not record the user and time of the
>      sequencer operation, which actually may be a good thing.

This is debatable. But I think you are correct, for all the same reasons why a merge can result in a fast-forward.

>  (2) When $what is revert, this codepath shouldn't be exercised, should 
>  it?
Yes.
>  (3) If B is a merge, even if $what is pick, this codepath shouldn't be
>      exercised, should it?

I think it should, again for the same reason why a merge can result in a fast-forward.

Show 33 quoted lines
> > +make_squash_message () {
> > +	if test -f "$squash_msg"
> > +	then
> > +		count=$(($(sed -n -e 's/^# This is [^0-9]*\([1-9][0-9]*\).*/\1/p' \
> > +			<"$squash_msg" | sed -n -e '$p')+1))
> > +		echo "# This is a combination of $count commits."
> > +		sed -e '1d' -e '2,/^./{
> > +			/^$/d
> > +		}' <"$squash_msg"
> > +	else
> > +		count=2
> > +		echo '# This is a combination of 2 commits.'
> > +		echo '# The first commit message is:'
> > +		echo
> > +		commit_message HEAD
> > +	fi
> > +	echo
> > +	echo "# This is the $(nth_string "$count") commit message:"
> > +	echo
> > +	commit_message "$1"
> > +}
> > +
> > +make_squash_message_multiple () {
> > +	echo '# This is a dummy to get the 0.' >"$squash_msg"
> > +	for cur_sha1 in $(git rev-list --reverse "$sha1..HEAD")
> > +	do
> > +		make_squash_message "$cur_sha1" >"$MSG"
> > +		cp "$MSG" "$squash_msg"
> > +	done
> > +}
> 
> Hmm, I know this is how rebase-i is written, but we should be able to do
> better than writing and flipping temporary times N times, shouldn't we?
Right, again my fault.
Show 8 quoted lines
> > +peek_next_command () {
> > +	sed -n -e '1s/ .*$//p' <"$TODO"
> > +}
> 
> ... which could respond "the next command is '#' (comment)", so we are
> actively counting a comment as a step here.  Does this contradict with the
> mental note we made earlier, and if so, does the discrepancy hurt us
> somewhere in this program?
Yes, this is wrong.  it must be
	sed -n -e '/^#/d' -e '1s .*$//p' < "$TODO"
Show 11 quoted lines
> > +strategy_check () {
> > +	case "$1" in
> > +	resolve|recursive|octopus|ours|subtree|theirs)
> > +		return
> > +		;;
> > +	esac
> > +	todo_warn "Strategy '$1' not known."
> > +}
> 
> Hmm.  Do we need to maintain list of available strategies here and then in
> git-merge separately?

I'd not check in sequencer for the strategy. Especially given that we want to support user-written strategies in the future.

Ciao, Dscho

Previous: Junio C HamanoNext: Stephan Beyer
Message 23 of 52 in “git sequencer prototype”
  1. Stephan BeyerJul 1, 2008
  2. 1/4 Add git-sequencer shell prototypeStephan Beyer, Jul 1, 2008
  3. 2/4 Add git-sequencer prototype documentationStephan Beyer, Jul 1, 2008
  4. 3/4 Add git-sequencer test suite (t3350)Stephan Beyer, Jul 1, 2008
  5. 4/4 Migrate git-am to use git-sequencerStephan Beyer, Jul 1, 2008
  6. git-rebase-i migration to sequencerStephan Beyer, Jul 1, 2008
  7. 1/2 Make rebase--interactive use OPTIONS_SPECStephan Beyer, Jul 1, 2008
  8. 2/2 Migrate git-rebase--i to use git-sequencerStephan Beyer, Jul 1, 2008
  9. Stephan BeyerJul 5, 2008
  10. Junio C HamanoJul 5, 2008
  11. Jakub NarebskiJul 1, 2008
  12. Stephan BeyerJul 1, 2008
  13. Jakub NarebskiJul 1, 2008
  14. Stephan BeyerJul 1, 2008
  15. Jakub NarebskiJul 2, 2008
  16. Junio C HamanoJul 2, 2008
  17. Stephan BeyerJul 2, 2008
  18. 2/4 Add git-sequencer prototype documentationStephan Beyer, Jul 5, 2008
  19. Jakub NarebskiJul 8, 2008
  20. Stephan BeyerJul 8, 2008
  21. Karl HasselströmJul 9, 2008
  22. Junio C HamanoJul 3, 2008
  23. Johannes SchindelinJul 3, 2008
  24. Stephan BeyerJul 3, 2008
  25. Junio C HamanoJul 3, 2008
  26. Stephan BeyerJul 3, 2008
  27. Stephan BeyerJul 3, 2008
  28. Johannes SchindelinJul 3, 2008
  29. Stephan BeyerJul 4, 2008
  30. Johannes SchindelinJul 4, 2008
  31. Stephan BeyerJul 4, 2008
  32. Allow cherry-picking root commitsJohannes Schindelin, Jul 4, 2008
  33. Stephan BeyerJul 4, 2008
  34. Junio C HamanoJul 6, 2008
  35. Johannes SchindelinJul 6, 2008
  36. t3503: Add test case for identical filesStephan Beyer, Jul 6, 2008
  37. Stephan BeyerJul 6, 2008
  38. Johannes SchindelinJul 6, 2008
  39. Stephan BeyerJul 4, 2008
  40. Johannes SchindelinJul 4, 2008
  41. Junio C HamanoJul 3, 2008
  42. Jakub NarebskiJul 3, 2008
  43. Stephan BeyerJul 3, 2008
  44. 1/4 Add git-sequencer shell prototypeStephan Beyer, Jul 5, 2008
  45. Junio C HamanoJul 1, 2008
  46. Stephan BeyerJul 1, 2008
  47. Alex RiesenJul 4, 2008
  48. Junio C HamanoJul 4, 2008
  49. Stephan BeyerJul 4, 2008
  50. Alex RiesenJul 5, 2008
  51. Thomas AdamJul 5, 2008
  52. Johannes SchindelinJul 5, 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.