{"thread":{"id":"5619","subject":"[PATCH] cvsimport move over to using git for each ref to read refs","startedAt":"2006-09-20T08:52:00Z","lastAt":"2006-09-22T04:57:52Z","messageCount":15,"participants":["Andy Whitcroft","Jakub Narebski","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"27217","messageId":"20060920085200.GA21865@shadowen.org","threadId":"5619","inReplyTo":null,"subject":"[PATCH] cvsimport move over to using git for each ref to read refs","fromName":"Andy Whitcroft","fromEmail":"apw@shadowen.org","sentAt":"2006-09-20T08:52:00Z","receivedAt":"2006-09-20T08:52:00Z","isPatch":true,"sender":{"key":"apw@shadowen.org","avatar":"https://gravatar.com/avatar/d3088262854661a913ef35cc40fedcc270142d4461791142bc1ea0b2a4e2e147?d=mp&s=160"},"body":"cvsimport: move over to using git-for-each-ref to read refs\n\ncvsimport opens all of the files in $GIT_DIR/refs/heads and reads\nout the sha1's in order to work out what time the last commit on\nthat branch was made (in CVS) thus allowing incremental updates.\nHowever, this takes no account of hierachical refs naming producing\nthe following error for each directory in $GIT_DIR/refs:\n\n  Use of uninitialized value in chomp at /usr/bin/git-cvsimport line 503.\n  Use of uninitialized value in concatenation (.) or string at\n\t\t\t\t\t/usr/bin/git-cvsimport line 505.\n  usage: git-cat-file [-t|-s|-e|-p|<type>] <sha1>\n\nTake advantage of the new packed refs work to use the new\nfor-each-ref iterator to get this information.  Use the format\nspecifier to ensure we are neutral to changes in default.\n\n[Junio: although although for-each-ref offers a --perl quoting mode\nthis patch does not use it as it seems only to make parsing the\noutput harder in perl.  If there is a neat trick for handling this\n'perl' form please educate me.  Here, rely on sha1's to contain\nno spaces.]\n\nSigned-off-by: Andy Whitcroft <apw@shadowen.org>\n---\ndiff --git a/git-cvsimport.perl b/git-cvsimport.perl\nindex e5a00a1..1a62afa 100755\n--- a/git-cvsimport.perl\n+++ b/git-cvsimport.perl\n@@ -495,13 +495,14 @@ unless(-d $git_dir) {\n \t$tip_at_start = `git-rev-parse --verify HEAD`;\n \n \t# Get the last import timestamps\n-\topendir(D,\"$git_dir/refs/heads\");\n-\twhile(defined(my $head = readdir(D))) {\n-\t\tnext if $head =~ /^\\./;\n-\t\topen(F,\"$git_dir/refs/heads/$head\")\n-\t\t\tor die \"Bad head branch: $head: $!\\n\";\n-\t\tchomp(my $ftag = <F>);\n-\t\tclose(F);\n+\topen(H, \"git-for-each-ref --format='%(objectname) %(refname)'|\") or\n+\t\tdie \"Cannot run git-for-each-ref: $!\\n\";\n+\twhile(defined(my $entry = <H>)) {\n+\t\tchomp($entry);\n+\t\tmy ($ftag, $name) = split(' ', $entry, 2);\n+\t\tnext if ($name !~ m@^refs/heads/(.*)$@);\n+\t\tmy ($head) = ($1);\n+\n \t\topen(F,\"git-cat-file commit $ftag |\");\n \t\twhile(<F>) {\n \t\t\tnext unless /^author\\s.*\\s(\\d+)\\s[-+]\\d{4}$/;\n@@ -510,7 +511,7 @@ unless(-d $git_dir) {\n \t\t}\n \t\tclose(F);\n \t}\n-\tclosedir(D);\n+\tclose(H);\n }\n \n -d $git_dir\n"},{"id":"27218","messageId":"eer19l$6hm$1@sea.gmane.org","threadId":"5619","inReplyTo":"20060920085200.GA21865@shadowen.org","subject":"Re: [PATCH] cvsimport move over to using git for each ref to read refs","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-09-20T09:23:02Z","receivedAt":"2006-09-20T09:23:02Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Andy Whitcroft wrote:\n\n> +       open(H, \"git-for-each-ref --format='%(objectname) %(refname)'|\") or\n\nBy the way, this is equivalent to using \"git-show-ref\" introduced by Linus.\nBut if you want commit timestamp\n\n> cvsimport opens all of the files in $GIT_DIR/refs/heads and reads\n> out the sha1's in order to work out what time the last commit on\n> that branch was made (in CVS) thus allowing incremental updates.\n\nyou can use it in --format as well.\n\n-- \nJakub Narebski\nWarsaw, Poland\nShadeHawk on #git\n"},{"id":"27221","messageId":"4511173D.7020702@shadowen.org","threadId":"5619","inReplyTo":"eer19l$6hm$1@sea.gmane.org","subject":"Re: [PATCH] cvsimport move over to using git for each ref to read refs","fromName":"Andy Whitcroft","fromEmail":"apw@shadowen.org","sentAt":"2006-09-20T10:26:05Z","receivedAt":"2006-09-20T10:26:05Z","isPatch":true,"sender":{"key":"apw@shadowen.org","avatar":"https://gravatar.com/avatar/d3088262854661a913ef35cc40fedcc270142d4461791142bc1ea0b2a4e2e147?d=mp&s=160"},"body":"Jakub Narebski wrote:\n> Andy Whitcroft wrote:\n> \n>> +       open(H, \"git-for-each-ref --format='%(objectname) %(refname)'|\") or\n> \n> By the way, this is equivalent to using \"git-show-ref\" introduced by Linus.\n> But if you want commit timestamp\n> \n>> cvsimport opens all of the files in $GIT_DIR/refs/heads and reads\n>> out the sha1's in order to work out what time the last commit on\n>> that branch was made (in CVS) thus allowing incremental updates.\n> \n> you can use it in --format as well.\n\nUnfortuantly, for-each-ref only offers us the textual version of this\ninformation not the numeric offset from the epoch which is what\ncvsimport is after.\n\nI guess we could teach for-each-ref to output this as well?  Perhaps\nsomething like authorstamp?\n\n-apw\n"},{"id":"27222","messageId":"20060920103119.GA30145@shadowen.org","threadId":"5619","inReplyTo":"4511173D.7020702@shadowen.org","subject":"[PATCH 1/2] for each ref add a raw timestamp field type","fromName":"Andy Whitcroft","fromEmail":"apw@shadowen.org","sentAt":"2006-09-20T10:31:19Z","receivedAt":"2006-09-20T10:31:19Z","isPatch":true,"sender":{"key":"apw@shadowen.org","avatar":"https://gravatar.com/avatar/d3088262854661a913ef35cc40fedcc270142d4461791142bc1ea0b2a4e2e147?d=mp&s=160"},"body":"for-each-ref: add a raw timestamp field type\n\ncvsimport is interested in the raw time stamps (in seconds since\nthe epoch) to do its time comparisons.  Export the raw timestamp under\n{author,committer,tagger}stamp.\n\nSigned-off-by: Andy Whitcroft <apw@shadowen.org>\n---\ndiff --git a/builtin-for-each-ref.c b/builtin-for-each-ref.c\nindex 698618b..9d6c4f0 100644\n--- a/builtin-for-each-ref.c\n+++ b/builtin-for-each-ref.c\n@@ -51,14 +51,17 @@ static struct {\n \t{ \"authorname\" },\n \t{ \"authoremail\" },\n \t{ \"authordate\", FIELD_TIME },\n+\t{ \"authorstamp\", FIELD_TIME },\n \t{ \"committer\" },\n \t{ \"committername\" },\n \t{ \"committeremail\" },\n \t{ \"committerdate\", FIELD_TIME },\n+\t{ \"committerstamp\", FIELD_TIME },\n \t{ \"tagger\" },\n \t{ \"taggername\" },\n \t{ \"taggeremail\" },\n \t{ \"taggerdate\", FIELD_TIME },\n+\t{ \"taggerstamp\", FIELD_TIME },\n \t{ \"subject\" },\n \t{ \"body\" },\n \t{ \"contents\" },\n@@ -344,9 +347,10 @@ static char *copy_email(const char *buf)\n \treturn line;\n }\n \n-static void grab_date(const char *buf, struct atom_value *v)\n+static void grab_date(const char *buf, struct atom_value *v, int raw)\n {\n \tconst char *eoemail = strstr(buf, \"> \");\n+\tconst char *eol = strchr(buf, '\\n');\n \tchar *zone;\n \tunsigned long timestamp;\n \tlong tz;\n@@ -359,7 +363,15 @@ static void grab_date(const char *buf, s\n \ttz = strtol(zone, NULL, 10);\n \tif ((tz == LONG_MIN || tz == LONG_MAX) && errno == ERANGE)\n \t\tgoto bad;\n-\tv->s = xstrdup(show_date(timestamp, tz, 0));\n+\tif (raw) {\n+\t\tint len = (eol - eoemail - 2);\n+\t\tchar *stamp = xmalloc(len + 1);\n+\n+\t\tmemcpy(stamp, eoemail + 2, len);\n+\t\tstamp[len] = 0;\n+\t\tv->s = stamp;\n+\t} else\n+\t\tv->s = xstrdup(show_date(timestamp, tz, 0));\n \tv->ul = timestamp;\n \treturn;\n  bad:\n@@ -386,7 +398,8 @@ static void grab_person(const char *who,\n \t\tif (name[wholen] != 0 &&\n \t\t    strcmp(name + wholen, \"name\") &&\n \t\t    strcmp(name + wholen, \"email\") &&\n-\t\t    strcmp(name + wholen, \"date\"))\n+\t\t    strcmp(name + wholen, \"date\") &&\n+\t\t    strcmp(name + wholen, \"stamp\"))\n \t\t\tcontinue;\n \t\tif (!wholine)\n \t\t\twholine = find_wholine(who, wholen, buf, sz);\n@@ -399,7 +412,9 @@ static void grab_person(const char *who,\n \t\telse if (!strcmp(name + wholen, \"email\"))\n \t\t\tv->s = copy_email(wholine);\n \t\telse if (!strcmp(name + wholen, \"date\"))\n-\t\t\tgrab_date(wholine, v);\n+\t\t\tgrab_date(wholine, v, 0);\n+\t\telse if (!strcmp(name + wholen, \"stamp\"))\n+\t\t\tgrab_date(wholine, v, 1);\n \t}\n }\n \n"},{"id":"27223","messageId":"20060920103134.GA30253@shadowen.org","threadId":"5619","inReplyTo":"4511173D.7020702@shadowen.org","subject":"[PATCH 2/2] cvsimport move over to using git for each ref to read refs V2","fromName":"Andy Whitcroft","fromEmail":"apw@shadowen.org","sentAt":"2006-09-20T10:31:34Z","receivedAt":"2006-09-20T10:31:34Z","isPatch":true,"sender":{"key":"apw@shadowen.org","avatar":"https://gravatar.com/avatar/d3088262854661a913ef35cc40fedcc270142d4461791142bc1ea0b2a4e2e147?d=mp&s=160"},"body":"cvsimport: move over to using git-for-each-ref to read refs V2\n\ncvsimport opens all of the files in $GIT_DIR/refs/heads and reads\nout the sha1's in order to work out what time the last commit on\nthat branch was made (in CVS) thus allowing incremental updates.\nHowever, this takes no account of hierachical refs naming producing\nthe following error for each directory in $GIT_DIR/refs:\n\n  Use of uninitialized value in chomp at /usr/bin/git-cvsimport line 503.\n  Use of uninitialized value in concatenation (.) or string at\n\t\t\t\t\t/usr/bin/git-cvsimport line 505.\n  usage: git-cat-file [-t|-s|-e|-p|<type>] <sha1>\n\nTake advantage of the new packed refs work to use the new\nfor-each-ref iterator to get this information.  Use the format\nspecifier to ensure we are neutral to changes in default.\n\n[Junio: although although for-each-ref offers a --perl quoting mode\nthis patch does not use it as it seems only to make parsing the\noutput harder in perl.  If there is a neat trick for handling this\n'perl' form please educate me.  Here, rely on sha1's and refnames\nto contain no spaces.]\n\nSigned-off-by: Andy Whitcroft <apw@shadowen.org>\n---\ndiff --git a/git-cvsimport.perl b/git-cvsimport.perl\nindex e5a00a1..5b13c23 100755\n--- a/git-cvsimport.perl\n+++ b/git-cvsimport.perl\n@@ -495,22 +495,17 @@ unless(-d $git_dir) {\n \t$tip_at_start = `git-rev-parse --verify HEAD`;\n \n \t# Get the last import timestamps\n-\topendir(D,\"$git_dir/refs/heads\");\n-\twhile(defined(my $head = readdir(D))) {\n-\t\tnext if $head =~ /^\\./;\n-\t\topen(F,\"$git_dir/refs/heads/$head\")\n-\t\t\tor die \"Bad head branch: $head: $!\\n\";\n-\t\tchomp(my $ftag = <F>);\n-\t\tclose(F);\n-\t\topen(F,\"git-cat-file commit $ftag |\");\n-\t\twhile(<F>) {\n-\t\t\tnext unless /^author\\s.*\\s(\\d+)\\s[-+]\\d{4}$/;\n-\t\t\t$branch_date{$head} = $1;\n-\t\t\tlast;\n-\t\t}\n-\t\tclose(F);\n+\topen(H, \"git-for-each-ref --format='%(objectname) %(refname) %(authorstamp)'|\") or\n+\t\tdie \"Cannot run git-for-each-ref: $!\\n\";\n+\twhile(defined(my $entry = <H>)) {\n+\t\tchomp($entry);\n+\t\tmy ($ftag, $name, $stamp, $zone) = split(/ /, $entry, 4);\n+\t\tnext if ($name !~ m@^refs/heads/(.*)$@);\n+\t\tmy ($head) = ($1);\n+\n+\t\t$branch_date{$head} = $stamp;\n \t}\n-\tclosedir(D);\n+\tclose(H);\n }\n \n -d $git_dir\n"},{"id":"27225","messageId":"200609201300.09266.jnareb@gmail.com","threadId":"5619","inReplyTo":"4511173D.7020702@shadowen.org","subject":"Re: [PATCH] cvsimport move over to using git for each ref to read refs","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-09-20T11:00:08Z","receivedAt":"2006-09-20T11:00:08Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Andy Whitcroft wrote:\n> Jakub Narebski wrote:\n> > Andy Whitcroft wrote:\n> > \n> >> +       open(H, \"git-for-each-ref --format='%(objectname) %(refname)'|\") or\n> > \n> > By the way, this is equivalent to using \"git-show-ref\" introduced by Linus.\n> > But if you want commit timestamp\n> > \n> >> cvsimport opens all of the files in $GIT_DIR/refs/heads and reads\n> >> out the sha1's in order to work out what time the last commit on\n> >> that branch was made (in CVS) thus allowing incremental updates.\n> > \n> > you can use it in --format as well.\n> \n> Unfortuantly, for-each-ref only offers us the textual version of this\n> information not the numeric offset from the epoch which is what\n> cvsimport is after.\n> \n> I guess we could teach for-each-ref to output this as well?  Perhaps\n> something like authorstamp?\n\nOr authorepoch. \n\nI thought about following rpm idea of format modifiers, like \nauthorepoch:date for strftime(3) \"%c\" format or \ncommiterepoch:day for strftime(3) \"%a %b %d %Y\" format.\n\nFeel free to provide patches ;-)\n-- \nJakub Narebski\nPoland\n"},{"id":"27237","messageId":"7vodtak00n.fsf@assigned-by-dhcp.cox.net","threadId":"5619","inReplyTo":"4511173D.7020702@shadowen.org","subject":"Re: [PATCH] cvsimport move over to using git for each ref to read refs","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-09-20T15:53:12Z","receivedAt":"2006-09-20T15:53:12Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Andy Whitcroft <apw@shadowen.org> writes:\n\n> I guess we could teach for-each-ref to output this as well?  Perhaps\n> something like authorstamp?\n\nI think you can work with \"author\" or \"committer\" to grab the\nwhole raw line.\n\nAbout the quoting and parsing, language specific quoting mode is\nmeant for git-for-each-ref to produce a string that can be eval'ed\nin the host language.  Think of the command as a tool to write a\nshort program for you.\n\nThe original is like this:\n\n\t# Get the last import timestamps\n\topendir(D,\"$git_dir/refs/heads\");\n\twhile(defined(my $head = readdir(D))) {\n\t\tnext if $head =~ /^\\./;\n\t\topen(F,\"$git_dir/refs/heads/$head\")\n\t\t\tor die \"Bad head branch: $head: $!\\n\";\n\t\tchomp(my $ftag = <F>);\n\t\tclose(F);\n\t\topen(F,\"git-cat-file commit $ftag |\");\n\t\twhile(<F>) {\n\t\t\tnext unless /^author\\s.*\\s(\\d+)\\s[-+]\\d{4}$/;\n\t\t\t$branch_date{$head} = $1;\n\t\t\tlast;\n\t\t}\n\t\tclose(F);\n\t}\n\tclosedir(D);\n\nThe purpose of the loop is to grab all branch heads, and grab\nauthor timestamp for all of them, _and_ stash that in\n%branch_date hash indexed by head name.  You would want to have\nsomething like this executed for each branch:\n\n\t$refname = %(refname);\n\t$authorline = %(author);\n\t$authorline =~ /^author\\s.*\\s(\\d+)\\s[-+]\\d{4}$/;\n        $branch_date{$refname} = $1;\n\nSo, you have the tool to write such a program for you, by doing\nsomething like this:\n\n\tmy $template = '\n                $refname = %(refname);\n                $authorline = %(author);\n                $authorline =~ /^author\\s.*\\s(\\d+)\\s[-+]\\d{4}$/;\n                $branch_date{$refname} = $1;\n\t';\n        my @cmd = ('git-for-each-ref', '--perl', \"--format=$template\");\n\n\topen I, '-|', @cmd, 'refs/heads';\n        my $script = join('',<I>);\n        close I;\n\n\tmy ($refname, $authorline);\n        eval \"$script\";\n\nThe language specific quoting flag --perl affects how %() are\ninterpolated into the generated program text as literals.\nThat's why there is no quote around %(refname) or %(author)\nin the example above when defining the $template.\n"},{"id":"27245","messageId":"45116888.4050806@shadowen.org","threadId":"5619","inReplyTo":"7vodtak00n.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] cvsimport move over to using git for each ref to read refs","fromName":"Andy Whitcroft","fromEmail":"apw@shadowen.org","sentAt":"2006-09-20T16:12:56Z","receivedAt":"2006-09-20T16:12:56Z","isPatch":true,"sender":{"key":"apw@shadowen.org","avatar":"https://gravatar.com/avatar/d3088262854661a913ef35cc40fedcc270142d4461791142bc1ea0b2a4e2e147?d=mp&s=160"},"body":"Junio C Hamano wrote:\n> Andy Whitcroft <apw@shadowen.org> writes:\n> \n>> I guess we could teach for-each-ref to output this as well?  Perhaps\n>> something like authorstamp?\n> \n> I think you can work with \"author\" or \"committer\" to grab the\n> whole raw line.\n> \n> About the quoting and parsing, language specific quoting mode is\n> meant for git-for-each-ref to produce a string that can be eval'ed\n> in the host language.  Think of the command as a tool to write a\n> short program for you.\n\nThanks for the education.  Very simple, and very powerful.  I knew there\nwas a reason for it out there.  Will respin a V3 patch in a bit.\n\n-apw\n"},{"id":"27256","messageId":"20060920163704.GA27407@shadowen.org","threadId":"5619","inReplyTo":"45116888.4050806@shadowen.org","subject":"[PATCH] cvsimport move over to using git for each ref to read refs V3","fromName":"Andy Whitcroft","fromEmail":"apw@shadowen.org","sentAt":"2006-09-20T16:37:04Z","receivedAt":"2006-09-20T16:37:04Z","isPatch":true,"sender":{"key":"apw@shadowen.org","avatar":"https://gravatar.com/avatar/d3088262854661a913ef35cc40fedcc270142d4461791142bc1ea0b2a4e2e147?d=mp&s=160"},"body":"cvsimport: move over to using git-for-each-ref to read refs V3\n\ncvsimport opens all of the files in $GIT_DIR/refs/heads and reads\nout the sha1's in order to work out what time the last commit on\nthat branch was made (in CVS) thus allowing incremental updates.\nHowever, this takes no account of hierachical refs naming producing\nthe following error for each directory in $GIT_DIR/refs:\n\n  Use of uninitialized value in chomp at /usr/bin/git-cvsimport line 503.\n  Use of uninitialized value in concatenation (.) or string at\n\t\t\t\t\t/usr/bin/git-cvsimport line 505.\n  usage: git-cat-file [-t|-s|-e|-p|<type>] <sha1>\n\nTake advantage of the new packed refs work to use the new\nfor-each-ref iterator to get this information.\n\nSigned-off-by: Andy Whitcroft <apw@shadowen.org>\n---\ndiff --git a/git-cvsimport.perl b/git-cvsimport.perl\nindex e5a00a1..92d14c3 100755\n--- a/git-cvsimport.perl\n+++ b/git-cvsimport.perl\n@@ -495,22 +495,19 @@ unless(-d $git_dir) {\n \t$tip_at_start = `git-rev-parse --verify HEAD`;\n \n \t# Get the last import timestamps\n-\topendir(D,\"$git_dir/refs/heads\");\n-\twhile(defined(my $head = readdir(D))) {\n-\t\tnext if $head =~ /^\\./;\n-\t\topen(F,\"$git_dir/refs/heads/$head\")\n-\t\t\tor die \"Bad head branch: $head: $!\\n\";\n-\t\tchomp(my $ftag = <F>);\n-\t\tclose(F);\n-\t\topen(F,\"git-cat-file commit $ftag |\");\n-\t\twhile(<F>) {\n-\t\t\tnext unless /^author\\s.*\\s(\\d+)\\s[-+]\\d{4}$/;\n-\t\t\t$branch_date{$head} = $1;\n-\t\t\tlast;\n-\t\t}\n-\t\tclose(F);\n+\tmy $fmt = '($ref, $author) = (%(refname), %(author));';\n+\topen(H, \"git-for-each-ref --perl --format='$fmt'|\") or\n+\t\tdie \"Cannot run git-for-each-ref: $!\\n\";\n+\twhile(defined(my $entry = <H>)) {\n+\t\tmy ($ref, $author);\n+\t\teval($entry) || die \"cannot eval refs list: $@\";\n+\n+\t\tnext if ($ref !~ m@^refs/heads/(.*)$@);\n+\t\tmy ($head) = ($1);\n+\t\t$author =~ /^.*\\s(\\d+)\\s[-+]\\d{4}$/;\n+\t\t$branch_date{$head} = $1;\n \t}\n-\tclosedir(D);\n+\tclose(H);\n }\n \n -d $git_dir\n"},{"id":"27258","messageId":"7vwt7yij12.fsf@assigned-by-dhcp.cox.net","threadId":"5619","inReplyTo":"45116888.4050806@shadowen.org","subject":"Re: [PATCH] cvsimport move over to using git for each ref to read refs","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-09-20T16:45:29Z","receivedAt":"2006-09-20T16:45:29Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Andy Whitcroft <apw@shadowen.org> writes:\n\n>> About the quoting and parsing, language specific quoting mode is\n>> meant for git-for-each-ref to produce a string that can be eval'ed\n>> in the host language.  Think of the command as a tool to write a\n>> short program for you.\n>\n> Thanks for the education.  Very simple, and very powerful.  I knew there\n> was a reason for it out there.  Will respin a V3 patch in a bit.\n\nThis probably showed that my initial description and example for\nthe feature found in Documentation/git-for-each-ref was lacking.\n\nI would appreciate a separate patch to enhance it if you are so\ninclined.\n"},{"id":"27262","messageId":"7vodtaiijt.fsf@assigned-by-dhcp.cox.net","threadId":"5619","inReplyTo":"20060920163704.GA27407@shadowen.org","subject":"Re: [PATCH] cvsimport move over to using git for each ref to read refs V3","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-09-20T16:55:50Z","receivedAt":"2006-09-20T16:55:50Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Andy Whitcroft <apw@shadowen.org> writes:\n\n> +\tmy $fmt = '($ref, $author) = (%(refname), %(author));';\n> +\topen(H, \"git-for-each-ref --perl --format='$fmt'|\") or\n> +\t\tdie \"Cannot run git-for-each-ref: $!\\n\";\n> +\twhile(defined(my $entry = <H>)) {\n> +\t\tmy ($ref, $author);\n> +\t\teval($entry) || die \"cannot eval refs list: $@\";\n> +\n> +\t\tnext if ($ref !~ m@^refs/heads/(.*)$@);\n> +\t\tmy ($head) = ($1);\n> +\t\t$author =~ /^.*\\s(\\d+)\\s[-+]\\d{4}$/;\n> +\t\t$branch_date{$head} = $1;\n>  \t}\n> -\tclosedir(D);\n> +\tclose(H);\n>  }\n\nfor-each-ref let's you limit the refs by leading path, so I do\nnot think \"next if\" inside the loop is needed if you say\n\n\tfor-each-ref --perl --format=$fmt refs/heads\n\nAny reason you did not like my version that allows you to get\nrid of the while() loop altogether?  (hint: replace eval in my\nexample with \"print\" and see what you are evaling)\n"},{"id":"27264","messageId":"451173B1.4060305@shadowen.org","threadId":"5619","inReplyTo":"7vodtaiijt.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] cvsimport move over to using git for each ref to read refs V3","fromName":"Andy Whitcroft","fromEmail":"apw@shadowen.org","sentAt":"2006-09-20T17:00:33Z","receivedAt":"2006-09-20T17:00:33Z","isPatch":true,"sender":{"key":"apw@shadowen.org","avatar":"https://gravatar.com/avatar/d3088262854661a913ef35cc40fedcc270142d4461791142bc1ea0b2a4e2e147?d=mp&s=160"},"body":"Junio C Hamano wrote:\n> Andy Whitcroft <apw@shadowen.org> writes:\n> \n>> +\tmy $fmt = '($ref, $author) = (%(refname), %(author));';\n>> +\topen(H, \"git-for-each-ref --perl --format='$fmt'|\") or\n>> +\t\tdie \"Cannot run git-for-each-ref: $!\\n\";\n>> +\twhile(defined(my $entry = <H>)) {\n>> +\t\tmy ($ref, $author);\n>> +\t\teval($entry) || die \"cannot eval refs list: $@\";\n>> +\n>> +\t\tnext if ($ref !~ m@^refs/heads/(.*)$@);\n>> +\t\tmy ($head) = ($1);\n>> +\t\t$author =~ /^.*\\s(\\d+)\\s[-+]\\d{4}$/;\n>> +\t\t$branch_date{$head} = $1;\n>>  \t}\n>> -\tclosedir(D);\n>> +\tclose(H);\n>>  }\n> \n> for-each-ref let's you limit the refs by leading path, so I do\n> not think \"next if\" inside the loop is needed if you say\n> \n> \tfor-each-ref --perl --format=$fmt refs/heads\n\nStupid boy :)\n\n> \n> Any reason you did not like my version that allows you to get\n> rid of the while() loop altogether?  (hint: replace eval in my\n> example with \"print\" and see what you are evaling)\n\nTo my mind we avoid the 'mozilla repo' issue of 1000's of heads\nbusting some string length limit, or requiring some _vast_ string to\nhold it (as perl is likely to cope).  Given we are sifting a small\npercentage of the data out of it.\n\nLet me know which way you want it and we'll go that way :).\n\n-apw\n"},{"id":"27267","messageId":"7v64fiihk1.fsf@assigned-by-dhcp.cox.net","threadId":"5619","inReplyTo":"451173B1.4060305@shadowen.org","subject":"Re: [PATCH] cvsimport move over to using git for each ref to read refs V3","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-09-20T17:17:18Z","receivedAt":"2006-09-20T17:17:18Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Andy Whitcroft <apw@shadowen.org> writes:\n\n> Junio C Hamano wrote:\n>> \n>> for-each-ref let's you limit the refs by leading path, so I do\n>> not think \"next if\" inside the loop is needed if you say\n>> \n>> \tfor-each-ref --perl --format=$fmt refs/heads\n>\n> Stupid boy :)\n>> \n>> Any reason you did not like my version that allows you to get\n>> rid of the while() loop altogether?  (hint: replace eval in my\n>> example with \"print\" and see what you are evaling)\n>\n> To my mind we avoid the 'mozilla repo' issue of 1000's of heads\n> busting some string length limit, or requiring some _vast_ string to\n> hold it (as perl is likely to cope).  Given we are sifting a small\n> percentage of the data out of it.\n\nQuite valid reasoning.\n\nWill apply V3 with refs/heads filtering added; no need to\nresend.\n"},{"id":"27359","messageId":"4512804C.8060807@shadowen.org","threadId":"5619","inReplyTo":"7vwt7yij12.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] cvsimport move over to using git for each ref to read refs","fromName":"Andy Whitcroft","fromEmail":"apw@shadowen.org","sentAt":"2006-09-21T12:06:36Z","receivedAt":"2006-09-21T12:06:36Z","isPatch":true,"sender":{"key":"apw@shadowen.org","avatar":"https://gravatar.com/avatar/d3088262854661a913ef35cc40fedcc270142d4461791142bc1ea0b2a4e2e147?d=mp&s=160"},"body":"Junio C Hamano wrote:\n> Andy Whitcroft <apw@shadowen.org> writes:\n> \n>>> About the quoting and parsing, language specific quoting mode is\n>>> meant for git-for-each-ref to produce a string that can be eval'ed\n>>> in the host language.  Think of the command as a tool to write a\n>>> short program for you.\n>> Thanks for the education.  Very simple, and very powerful.  I knew there\n>> was a reason for it out there.  Will respin a V3 patch in a bit.\n> \n> This probably showed that my initial description and example for\n> the feature found in Documentation/git-for-each-ref was lacking.\n> \n> I would appreciate a separate patch to enhance it if you are so\n> inclined.\n\nActually the description in that manual page is pretty good.  But I\nthought it was undocumented as the standard install does not install the\nmanual pages and I was getting the ones from my stable install to fool\nme into thinking they were installed.  New developer error, doh.\n\nThat said I've taken the liberty of updating and clarifying the language\nto make it very obvious from the outset that the language specific\noutput formats are for generating eval'able snippets and added a simple\nexample of it to complement your complex one.\n\nPatch to follow.\n\n-apw\n"},{"id":"27404","messageId":"7vbqp87b1r.fsf@assigned-by-dhcp.cox.net","threadId":"5619","inReplyTo":"4512804C.8060807@shadowen.org","subject":"Re: [PATCH] cvsimport move over to using git for each ref to read refs","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-09-22T04:57:52Z","receivedAt":"2006-09-22T04:57:52Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Andy Whitcroft <apw@shadowen.org> writes:\n\n> ... I've taken the liberty of updating and clarifying the language\n> to make it very obvious from the outset that the language specific\n> output formats are for generating eval'able snippets and added a simple\n> example of it to complement your complex one.\n>\n> Patch to follow.\n\nThanks.\n"}]}