Subject: Re: [PATCH v2 04/13] Teach rebase interactive the mark command

From: Junio C Hamano <[email-masked]>
Date: Mon, 21 Apr 2008 22:32:17 -0700

Jörg Sommer <[email-masked]> writes:

> This new command can be used to set symbolic marks for an commit while
> doing a rebase. This symbolic name can later be used for merges or
> resets.
>
> The decision to use references for the marks and not files like done with
> the rewritten commits for preserve merges was made to ensure no commit
> objects get lost if prune is started while (a long term) rebase is
> running. This also unifies the checking of the validity of marks and
> references by using rev-parse for it.
>
> The usage of : as the sign for marks conforms with the tag sign of
> fast-export and fast-import.
>
> Signed-off-by: Jörg Sommer <[email-masked]>
> ---
>  git-rebase--interactive.sh    |   37 ++++++++++++++++++++++++++++++++++++-
>  t/t3404-rebase-interactive.sh |   17 +++++++++++++++++
>  2 files changed, 53 insertions(+), 1 deletions(-)
>
> diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
> index 531ee94..6ac316a 100755
> --- a/git-rebase--interactive.sh
> +++ b/git-rebase--interactive.sh
> @@ -35,6 +35,8 @@ mark the corrected paths with 'git add <paths>', and
>  run 'git rebase --continue'"
>  export GIT_CHERRY_PICK_HELP
>  
> +mark_prefix=refs/rebase-marks/
> +
>  warn () {
>  	echo "$*" >&2
>  }
> @@ -105,7 +107,13 @@ die_with_patch () {
>  }
>  
>  cleanup_before_quit () {
> -	rm -rf "$DOTEST"
> +	rm -rf "$DOTEST" &&
> +	for ref in "$GIT_DIR/$mark_prefix"*
> +	do
> +		test "$ref" = "$GIT_DIR/$mark_prefix*" && continue
> +		git update-ref -d "${ref#$GIT_DIR/}" "${ref#$GIT_DIR/}" || \
> +			return 1
> +	done

In practice nobody would "run" pack-refs during the rebase session, but I
have to wonder if it can be triggered to run as part of automated gc or
something, in which case this loop does not work as intended. It needs to
be rewritten using for-each-ref.

> @@ -244,6 +252,19 @@ peek_next_command () {
>  	sed -n "1s/ .*$//p" < "$TODO"
>  }
>  
> +mark_to_ref () {
> +	case "$1" in
> +	:[!/]*)
> +		# :/SOMETHING is a reference for the last commit whose
> +                # message starts with SOMETHING
> +		echo "$mark_prefix${1#:}"
> +		;;

What was the conclusion of the mark-syntax discussion?

While I know the bang in ":[!negated]" is POSIX, I wonder if everybody's
shell we care about groks it.

Could people run this with the shell they care about being supported
(Solaris /bin/sh does not count) try this and yell loudly if you get
"matches" please?  I know bash and dash are Ok, but I do not have easy
access to various flabours of BSDs (OSX included).

	case ":/foo" in
        :[!/]*)	echo matches ;;
	*)	echo does not ;;
	esac