From: "Jörg Sommer" <joerg@alea.gnuu.de>
To: Brian Gernhardt <benji@silverinsanity.com>
Cc: git@vger.kernel.org
Subject: Re: [PATCH] Use perl instead of tac
Date: Mon, 5 May 2008 00:13:20 +0200 [thread overview]
Message-ID: <20080504221319.GA14584@alea.gnuu.de> (raw)
In-Reply-To: <5374CF8E-3E6E-480B-A23B-13BE85C7ABCF@silverinsanity.com>
[-- Attachment #1: Type: text/plain, Size: 5613 bytes --]
Hallo Brian,
Brian Gernhardt schrieb am Wed 30. Apr, 11:25 (-0400):
> On Apr 30, 2008, at 5:02 AM, Jörg Sommer wrote:
>
>>> I also dislike the large lists this is carrying around in shell
>>> variables. If I'm reading it correctly, the tag list could be
>>> replaced
>>> by invocations of "git describe --exact-match".
>>
>> Yes. How to get all tags of a commit?
>>
>> % git tag foo v1.5.5
>> % git describe --exact-match 9d831805195ba40b62f632acc6bb6e53d3
>> warning: tag 'v1.5.5' is really 'foo' here
>> v1.5.5
And how can I get only tags no annotated tags? We can't recreate
annotated tags with git rebase.
> Those concerns being: overrunning the length of a shell variable,
Are you shure there is any such bounding? I didn't saw anything about the
size of a variables in IEEE 1003.1-2004, but didn't look very carfully.
All my shells (bash, dash, zsh) can handle more than 16777217 characters:
dash -c 'a=a; while :; do a=$a$a; echo $a | wc -c; done'
This would be a new version of create_extended_todo_list() without tac.
What do you think about it? Is it better readable? But there's a bug.
create_extended_todo_list () {
# The idea of this function is to
# 1. build a list of tags
# 2. go through the list and
# * issue a reset command to the parent of the commit, if the last
# commit was not the parent of the current commit,
# * issue a pick command for simple commits,
# * issue for each merge commit a merge command with the hashs of
# the parent commits,
# * register each parent of a merge and issue a mark command
# (without an ID) after the commit for each registered commit and
# * issue a tag command, if the commit is in the tag list.
# 3. Then go through the created list and
# * add an ID to each mark command and
# * replace all occurences of the hash in reset and merge commands
# by the mark ID
test -e "$DOTEST"/cetl.tmp \
&& die "Someone else uses our filename cetl.tmp." \
"That's not nice"
if test t = "${PRESERVE_TAGS:-}"
then
tag_list=$(git show-ref --abbrev=7 --tags | \
(
while read sha1 tag
do
tag=${tag#refs/tags/}
if test ${last_sha1:-0000} = $sha1
then
saved_tags="$saved_tags:$tag"
else
printf "%s" "${last_sha1:+ $last_sha1#$saved_tags}"
last_sha1=$sha1
saved_tags=$tag
fi
done
echo "${last_sha1:+ $last_sha1:$saved_tags}"
) )
else
tag_list=
fi
mark_these_commits=
while IFS=_ read commit parents subject
do
first_parent=${parents%% *}
if test "${last_commit:-$SHORTUPSTREAM}" != $first_parent
then
test "$first_parent" = $SHORTUPSTREAM &&
first_parent=$SHORTONTO
echo reset $first_parent
fi
unset first_parent
last_commit=$commit
case "$parents" in
*' '*)
new_parents=
for p in $parents
do
mark_these_commits=$(insert_value_at_key_into_list \
"$commit" "$p" "$mark_these_commits")
if test "$p" = $SHORTUPSTREAM
then
new_parents="$new_parents $SHORTONTO"
else
new_parents="$new_parents $p"
fi
done
unset p
echo merge $commit ${new_parents# * }
unset new_parents
;;
*)
echo "pick $commit $subject"
;;
esac
if tmp=$(get_value_from_list $commit "$tag_list")
then
for t in $(echo $tmp | tr : ' ')
do
echo tag $t
done
fi
done > "$DOTEST"/cetl.tmp
unset commit parents subject
commit_mark_list=
next_mark=0
last_commit=
while read cmd args
do
case "$cmd" in
pick)
this_commit="${args%% *}"
;;
reset)
this_commit=$args
if tmp=$(get_value_from_list $args "$commit_mark_list")
then
args=":$tmp"
fi
;;
merge)
new_args=
for i in ${args#* }
do
if tmp=$(get_value_from_list $i \
"$commit_mark_list")
then
new_args="$new_args :$tmp"
else
new_args="$new_args $i"
fi
done
this_commit="${args%% *}"
args="$this_commit ${new_args# }"
;;
esac
if tmp=$(get_value_from_list "$last_commit" \
"$mark_these_commits") && \
test "${this_commit:-$last_commit}" != $tmp
then
if tmp=$(get_value_from_list "$last_commit" \
"$commit_mark_list")
then
test "$last_cmd" = reset -o "$last_cmd" = tag \
|| echo mark ":$tmp"
else
commit_mark_list=$(insert_value_at_key_into_list \
$next_mark $last_commit "$commit_mark_list")
echo mark ":$next_mark"
next_mark=$(($next_mark + 1))
fi
fi
last_commit=${this_commit:-$last_commit}
unset this_commit
echo "$cmd $args"
last_cmd=$cmd
done < "$DOTEST"/cetl.tmp
rm "$DOTEST"/cetl.tmp
unset last_cmd last_commit next_mark cmd args tmp commit_mark_list \
mark_these_commits
}
The problem is the mark command. If you walk from ONTO to HEAD trough the
list, you must know for a commit, if it is used _later_. But don't create
a mark if it is used immediately, e.g. pick; merge not pick; mark; merge.
If you walk from HEAD to ONTO, this is much easier. I delayed the mark
for the first head of a merge and checked if the next commit is this
commit. This way I keep the todo list clean and don't get something like
this for --first-parent:
pick abc
pick def
mark :0
merge 012 foreign-branch
Bye, Jörg.
--
Es ist außerdem ein weit verbreiteter Irrtum das USENET ‚helfen‘ soll.
Tatsächlich wurde USENET nachweislich zur persönlichen Belustigung
seiner Erfinder geschaffen.
Jörg Klemenz <joerg@gmx.net>, <b4ai4o$1u8vmt$2@ID-21915.news.dfncis.de>
[-- Attachment #2: Digital signature http://en.wikipedia.org/wiki/OpenPGP --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
next prev parent reply other threads:[~2008-05-04 22:15 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-04-27 6:24 Use of tac in git-rebase--interactive Brian Gernhardt
2008-04-27 6:42 ` Jeff King
2008-04-27 6:55 ` [PATCH] Use perl instead of tac Brian Gernhardt
2008-04-28 7:44 ` [PATCH] rebase--interactive: Replace unportable 'tac' by a sed script Johannes Sixt
2008-04-28 8:19 ` Junio C Hamano
2008-04-28 8:58 ` Paolo Bonzini
2008-04-28 9:04 ` Jeff King
2008-04-28 9:11 ` Andreas Ericsson
2008-04-28 11:46 ` [PATCH] Use perl instead of tac Jörg Sommer
2008-04-28 12:58 ` Randal L. Schwartz
2008-04-28 13:12 ` David Symonds
2008-04-28 13:31 ` Paolo Bonzini
2008-04-28 14:11 ` Brian Gernhardt
2008-04-28 14:22 ` Johannes Schindelin
2008-04-28 15:15 ` Jörg Sommer
2008-04-28 17:26 ` Avery Pennarun
2008-04-28 17:34 ` Matthieu Moy
2008-04-28 17:50 ` Brian Gernhardt
2008-04-28 19:13 ` Brian Gernhardt
2008-04-30 9:02 ` Jörg Sommer
2008-04-30 9:39 ` Jörg Sommer
2008-04-30 16:12 ` Brian Gernhardt
2008-04-30 15:25 ` Brian Gernhardt
2008-05-04 22:13 ` Jörg Sommer [this message]
2008-05-06 4:32 ` Brian Gernhardt
2008-04-28 13:46 ` Johannes Schindelin
2008-04-28 14:07 ` Brian Gernhardt
2008-04-28 14:20 ` Johannes Schindelin
2008-04-27 7:33 ` Use of tac in git-rebase--interactive しらいしななこ
2008-04-30 0:25 ` Junio C Hamano
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=20080504221319.GA14584@alea.gnuu.de \
--to=joerg@alea.gnuu.de \
--cc=benji@silverinsanity.com \
--cc=git@vger.kernel.org \
/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).