{"thread":{"id":"12755","subject":"[patch] Import \"git-forest\" into contrib/","startedAt":"2008-03-18T18:25:38Z","lastAt":"2008-03-20T02:16:30Z","messageCount":7,"participants":["Jan Engelhardt","Miklos Vajna","Jakub Narebski","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"72387","messageId":"alpine.LNX.1.00.0803181924560.8851@fbirervta.pbzchgretzou.qr","threadId":"12755","inReplyTo":null,"subject":"[patch] Import \"git-forest\" into contrib/","fromName":"Jan Engelhardt","fromEmail":"jengelh@computergmbh.de","sentAt":"2008-03-18T18:25:38Z","receivedAt":"2008-03-18T18:25:38Z","isPatch":true,"sender":{"key":"jengelh@computergmbh.de","avatar":null},"body":"commit b6612a2efe93660be7ecdb799625015efedadff1\nAuthor: Jan Engelhardt <jengelh@computergmbh.de>\nDate:   Tue Mar 18 19:24:33 2008 +0100\n\n     Import \"git-forest\" into contrib/\n\ndiff --git a/contrib/git-forest/git-forest b/contrib/git-forest/git-forest\nnew file mode 100755\nindex 0000000..f5d6f81\n--- /dev/null\n+++ b/contrib/git-forest/git-forest\n@@ -0,0 +1,391 @@\n+#!/usr/bin/perl\n+#\n+#\tgit-森林\n+#\ttext-based tree visualisation\n+#\tCopyright © Jan Engelhardt <jengelh [at] gmx de>, 2008\n+#\n+#\tThis program is free software; you can redistribute it and/or modify\n+#\tit under the terms of the GNU General Public License as published by\n+#\tthe Free Software Foundation; either version 2 or 3 of the license.\n+#\n+use Getopt::Long;\n+use Git;\n+use strict;\n+use encoding \"utf8\";\n+my $Repo     = Git->repository($ENV{\"GIT_DIR\"} || \".\");\n+my $Style    = 2;\n+my $With_sha = 0;\n+my %Color    = (\n+\t\"default\" => \"\\e[0m\",\n+\t\"at\"      => \"\\e[1;30m\",\n+\t\"head\"    => \"\\e[1;32m\",\n+\t\"ref\"     => \"\\e[1;34m\",\n+\t\"remote\"  => \"\\e[1;35m\",\n+\t\"sha\"     => \"\\e[0;31m\",\n+\t\"tag\"     => \"\\e[1;33m\",\n+\t\"tree\"    => \"\\e[0;33m\",\n+);\n+\n+&main();\n+\n+sub main ()\n+{\n+\t&Getopt::Long::Configure(qw(bundling pass_through));\n+\t&GetOptions(\n+\t\t\"no-color\" => sub { %Color = (); },\n+\t\t\"style=i\"  => \\$Style,\n+\t\t\"sha\"      => \\$With_sha,\n+\t);\n+\t&process();\n+}\n+\n+sub process ()\n+{\n+\tmy(@vine);\n+\tmy $refs = &get_refs();\n+\tmy($fh, $fhc) = $Repo->command_output_pipe(\"log\", \"--date-order\",\n+\t                \"--pretty=format:<%H><%h><%P>%s\", @ARGV);\n+\n+\twhile (defined(my $line = <$fh>)) {\n+\t\tchomp $line;\n+\t\tmy($sha, $mini_sha, $parents, $msg) =\n+\t\t\t($line =~ /^<(.*?)><(.*?)><(.*?)>(.*)/s);\n+\t\tmy @parents = split(\" \", $parents);\n+\n+\t\t&vine_branch(\\@vine, $sha);\n+\t\tmy $ra = &vine_commit(\\@vine, $sha, \\@parents);\n+\n+\t\tif (exists($refs->{$sha})) {\n+\t\t\tprint &vis_post(&vis_commit($ra,\n+\t\t\t      $Color{at}.\"─\".$Color{default}));\n+\t\t\t&ref_print($refs->{$sha});\n+\t\t} else {\n+\t\t\tprint &vis_post(&vis_commit($ra, \" \"));\n+\t\t}\n+\t\tif ($With_sha) {\n+\t\t\tprint $msg, $Color{at}, \"──(\", $Color{sha}, $mini_sha,\n+\t\t\t      $Color{at}, \")\", $Color{default}, \"\\n\";\n+\t\t} else {\n+\t\t\tprint $msg, \"\\n\";\n+\t\t}\n+\n+\t\t&vine_merge(\\@vine, $sha, \\@parents);\n+\t}\n+\t$Repo->command_close_pipe($fh, $fhc);\n+}\n+\n+sub get_refs ()\n+{\n+\tmy($fh, $c) = $Repo->command_output_pipe(\"show-ref\");\n+\tmy $ret = {};\n+\n+\twhile (defined(my $ln = <$fh>)) {\n+\t\tchomp $ln;\n+\t\tif (length($ln) == 0) {\n+\t\t\tnext;\n+\t\t}\n+\n+\t\tmy($sha, $name) = ($ln =~ /^(\\S+)\\s+(.*)/s);\n+\t\tif (!exists($ret->{$sha})) {\n+\t\t\t$ret->{$sha} = [];\n+\t\t}\n+\t\tpush(@{$ret->{$sha}}, $name);\n+\t\tif ($name =~ m{^refs/tags/}) {\n+\t\t\tmy $sub_sha = $Repo->command(\"log\", \"-1\",\n+\t\t\t              \"--pretty=format:%H\", $name);\n+\t\t\tchomp $sub_sha;\n+\t\t\tif ($sha ne $sub_sha) {\n+\t\t\t\tpush(@{$ret->{$sub_sha}}, $name);\n+\t\t\t}\n+\t\t}\n+\t}\n+\n+\t$Repo->command_close_pipe($fh, $c);\n+\treturn $ret;\n+}\n+\n+sub ref_print ($)\n+{\n+\tforeach my $symbol (@{shift @_}) {\n+\t\tprint $Color{at}, \"[\";\n+\t\tif ($symbol =~ m{^refs/(remotes/[^/]+)/(.*)}s) {\n+\t\t\tprint $Color{remote}, $1, $Color{head}, \"/$2\";\n+\t\t} elsif ($symbol =~ m{^refs/heads/(.*)}s) {\n+\t\t\tprint $Color{head}, $1;\n+\t\t} elsif ($symbol =~ m{^refs/tags/(.*)}s) {\n+\t\t\tprint $Color{tag}, $1;\n+\t\t} elsif ($symbol =~ m{^refs/(.*)}s) {\n+\t\t\tprint $Color{ref}, $1;\n+\t\t}\n+\t\tprint $Color{at}, \"]──\", $Color{default};\n+\t}\n+}\n+\n+sub vine_branch ($$)\n+{\n+\tmy($vine, $rev) = @_;\n+\tmy $idx;\n+\n+\tmy $left = \"╠\";\n+\tmy $matched = 0;\n+\tmy $ret;\n+\n+\tfor ($idx = 0; $idx < scalar(@$vine); ++$idx) {\n+\t\tif (!defined($vine->[$idx])) {\n+\t\t\t$ret .= \"═\";\n+\t\t\tnext;\n+\t\t} elsif ($vine->[$idx] ne $rev) {\n+\t\t\t$ret .= \"╪\";\n+\t\t\tnext;\n+\t\t}\n+\t\tif ($matched == 0) {\n+\t\t\t$ret .= \"╠\";\n+\t\t} else {\n+\t\t\t$ret .= \"╩\";\n+\t\t\t$vine->[$idx] = undef;\n+\t\t}\n+\t\t++$matched;\n+\t}\n+\n+\tif ($matched < 2) {\n+\t\treturn;\n+\t}\n+\n+\twhile (!defined($vine->[$#$vine])) {\n+\t\tpop(@$vine);\n+\t}\n+\n+\tprint &vis_post(&vis_branch($ret)), \"\\n\";\n+}\n+\n+sub vine_commit ($$$)\n+{\n+\tmy($vine, $rev, $parents) = @_;\n+\tmy $ret;\n+\n+\tfor (my $i = 0; $i <= $#$vine; ++$i) {\n+\t\tif (!defined($vine->[$i])) {\n+\t\t\t$ret .= \" \";\n+\t\t} elsif ($vine->[$i] eq $rev) {\n+\t\t\t$ret .= \"╟\";\n+\t\t} else {\n+\t\t\t$ret .= \"║\";\n+\t\t}\n+\t}\n+\n+\tif ($ret !~ /╟/) {\n+\t\t# Not having produced a ╟ before means this is a HEAD\n+\t\t$ret .= \"╓\";\n+\t\tpush(@$vine, $rev);\n+\t}\n+\n+\twhile (scalar(@$vine) > 0 && !defined($vine->[$#$vine])) {\n+\t\tpop(@$vine);\n+\t}\n+\n+\tif (scalar(@$parents) == 0) {\n+\t\t# tree root\n+\t\t$ret =~ s/╟/╙/g;\n+\t}\n+\n+\treturn $ret;\n+}\n+\n+#\n+#\tGenerate vine graphics for a merge\n+#\n+sub vine_merge ($$$)\n+{\n+\tmy($vine, $rev, $parents) = @_;\n+\tmy $orig_vine = -1;\n+\tmy @slot;\n+\tmy($ret, $max);\n+\n+\tfor (my $i = 0; $i <= $#$vine; ++$i) {\n+\t\tif ($vine->[$i] eq $rev) {\n+\t\t\t$orig_vine = $i;\n+\t\t\tlast;\n+\t\t}\n+\t}\n+\n+\tif ($orig_vine == -1) {\n+\t\tdie \"vine_commit() did not add this vine.\";\n+\t}\n+\n+\tif (scalar(@$parents) <= 1) {\n+\t\t#\n+\t\t# A single parent does not need a visual. Update and return.\n+\t\t#\n+\t\t$vine->[$orig_vine] = $parents->[0];\n+\n+\t\twhile (scalar(@$vine) > 0 && !defined($vine->[$#$vine])) {\n+\t\t\tpop(@$vine);\n+\t\t}\n+\t\treturn;\n+\t}\n+\n+\t#\n+\t# Find some good spots to split out into.\n+\t#\n+\tpush(@slot, $orig_vine);\n+\tmy $parent = 0;\n+\n+\tfor (my $seeker = 2; $parent < $#$parents &&\n+\t    $seeker < 2 + 2 * $#$vine; ++$seeker)\n+\t{\n+\t\tmy $idx = ($seeker % 2 == 0) ? -1 : 1;\n+\t\t$idx   *= int($seeker / 2);\n+\t\t$idx   += $orig_vine;\n+\n+\t\tif ($idx >= 0 && $idx <= $#$vine && !defined($vine->[$idx])) {\n+\t\t\tpush(@slot, $idx);\n+\t\t\t++$parent;\n+\t\t}\n+\t}\n+\tfor (my $idx = $orig_vine + 1; $parent < $#$parents; ++$idx) {\n+\t\tif (!defined($vine->[$idx])) {\n+\t\t\tpush(@slot, $idx);\n+\t\t\t++$parent;\n+\t\t}\n+\t}\n+\n+\tif (scalar(@slot) != scalar(@$parents)) {\n+\t\tdie \"Serious internal problem\";\n+\t}\n+\n+\t@slot = sort { $a <=> $b } @slot;\n+\t$max  = scalar(@$vine) + scalar(@slot);\n+\n+\tfor (my $i = 0; $i < $max; ++$i) {\n+\t\tif ($#slot >= 0 && $i == $slot[0]) {\n+\t\t\tshift @slot;\n+\t\t\t$vine->[$i] = shift @$parents;\n+\t\t\t$ret .= ($i == $orig_vine) ? \"S\" : \"s\";\n+\t\t} elsif (defined($vine->[$i])) {\n+\t\t\t$ret .= \"║\";\n+\t\t} else {\n+\t\t\t$ret .= \" \";\n+\t\t}\n+\n+\t}\n+\n+\t$ret =~ s/ +$//gs;\n+\tprint &vis_post(&vis_merge($ret)), \"\\n\";\n+}\n+\n+sub vis_branch ($)\n+{\n+\t# Sample input: ╬═╠╬╬╬╩╬═╬╬╬╬╬╬╩╬╩═╬╬\n+\tmy $ra = shift @_;\n+\tmy $i;\n+\n+\t$ra =~ s{^(.+?)╠}{\n+\t\t$_ = $1;\n+\t\t$_ =~ tr/╪═/║ /;\n+\t\t$_ =~ s/(.)/$1 /gs;\n+\t\t$_ .= '╠';\n+\t}es;\n+\t$ra =~ s{(╠.*)╩}{\n+\t\t$_ = $1;\n+\t\t$_ =~ s/(.)/$1═/gs;\n+\t\t$_ .= '╝';\n+\t}es;\n+\t$ra =~ s{╝(.*)$}{\n+\t\t$_ = $1;\n+\t\t$_ =~ tr/╪═/║ /;\n+\t\t$_ =~ s/(.)/$1 /gs;\n+\t\t$_ = \"╝ $_\";\n+\t}es;\n+\treturn $ra;\n+}\n+\n+sub vis_commit ($$)\n+{\n+\tmy($ra, $sep) = @_;\n+\tmy($l, $r) = ($ra =~ /^(.*?)([╟╓╙].*)/);\n+\t$l =~ s/(.)/$1 /gs;\n+\t$r =~ s/(.)/$1 /gs;\n+\t$r =~ s/ /$sep/gs;\n+\treturn $l.$r;\n+}\n+\n+sub vis_merge ($)\n+{\n+\tmy $s = shift @_;\n+\n+\tif ($s =~ s/(s.*)S(.*s)/&vis_merge3($1, $2)/es) {\n+\t\t;\n+\t} elsif ($s =~ /(?:s.*)S/s) {\n+\t\twhile ($s =~ s/(s.*)║(.*S)/$1╪$2/s) {\n+\t\t\t;\n+\t\t}\n+\t\t$s =~ s/(s.*)S/&vis_merge2L($1).\"╣\"/es;\n+\t} elsif ($s =~ /S(?:.*s)/s) {\n+\t\twhile ($s =~ s/(S.*)║(.*s)/$1╪$2/s) {\n+\t\t\t;\n+\t\t}\n+\t\t$s =~ /S(.*s)/;\n+\t\t$s =~ s/S(.*s)/\"╠\".&vis_merge2R($1)/es;\n+\t} else {\n+\t\t# $s =~ s/S/║/s;\n+\t\tdie \"Should not come here\";\n+\t}\n+\t$s =~ s{(.)}{&vis_merge1($1)}egs;\n+\treturn $s;\n+}\n+\n+sub vis_merge1 ($)\n+{\n+\tif ($_[0] eq \"╔\" || $_[0] eq \"╦\" || $_[0] eq \"╠\" || $_[0] eq \"╪\") {\n+\t\treturn $_[0].\"═\";\n+\t} else {\n+\t\treturn $_[0].\" \";\n+\t}\n+}\n+\n+sub vis_merge2L ($)\n+{\n+\tmy $l = shift @_;\n+\t$l =~ s/^s/╔/;\n+\t$l =~ s/s/╦/g;\n+\treturn $l;\n+}\n+\n+sub vis_merge2R ($)\n+{\n+\tmy $r = shift @_;\n+\t$r =~ s/s$/╗/;\n+\t$r =~ s/s/╦/g;\n+\treturn $r;\n+}\n+\n+sub vis_merge3 ($$)\n+{\n+\tmy($l, $r) = shift @_;\n+\t$l =~ s/^s/╔/;\n+\t$l =~ s/s/╦/g;\n+\t$r =~ s/s$/╗/;\n+\t$r =~ s/s/╦/g;\n+\treturn \"$l╪$r\";\n+}\n+\n+#\n+#\tpost-process vine graphic\n+#\n+sub vis_post ($)\n+{\n+\tmy $s = shift @_;\n+\n+\tif ($Style == 1) {\n+\t\t$s =~ tr/╔╦╗╠╬╣╚╩╝║═╟╓╙╪/┌┬┐├┼┤└┴┘│─├┌└┼/;\n+\t} elsif ($Style == 2) {\n+\t\t$s =~ tr/╪/╬/;\n+\t} elsif ($Style == 3) {\n+\t\t$s =~ tr/╔╦╗╠╬╣╚╩╝║╟╓╙/╒╤╕╞╪╡╘╧╛│├┌└/;\n+\t}\n+\n+\tif ($Color{default} ne \"\") {\n+\t\t$s =~ s{\\Q$Color{default}\\E}{$&$Color{tree}}g;\n+\t}\n+\treturn $Color{tree}, $s, $Color{default};\n+}\ndiff --git a/contrib/git-forest/git-forest.txt b/contrib/git-forest/git-forest.txt\nnew file mode 100644\nindex 0000000..0adfd6d\n--- /dev/null\n+++ b/contrib/git-forest/git-forest.txt\n@@ -0,0 +1,34 @@\n+\n+Options:\n+\n+--style=1\n+\tUse single-line visuals\n+--style=2\n+\tUse double-line visuals (default)\n+--style=3\n+\tUse single-line visuals in vertical direction,\n+\tand double-line ones in horizontal direction.\n+--sha\n+\tDisplay SHAs for each commit\n+\n+All other options and arguments are passed down to git-log.\n+Commonly useful are --all and --topo-order; along with the\n+tag name or commit range.\n+\n+This tool does not try to minimize the empty space between branches\n+like gitk does. Take it as a feature.\n+\n+Notes on interpretation:\n+\n+'╬' (or variants thereof, like ╪) is meant to be a \"path bridge\", i.e.\n+traversal is only \"allowed\" horizontal OR vertical direction.\n+\n+Branching:\n+C D E F G\n+╠═╬═╩═╩═╝  A->{C,E,F,G} and B->D.\n+A B\n+\n+Merging:\n+E F\n+╠═╬═╦═╗    {A,C,D}->E, B->F.\n+A B C D\n"},{"id":"72404","messageId":"20080319211140.GK2663@genesis.frugalware.org","threadId":"12755","inReplyTo":"alpine.LNX.1.00.0803181924560.8851@fbirervta.pbzchgretzou.qr","subject":"Re: [patch] Import \"git-forest\" into contrib/","fromName":"Miklos Vajna","fromEmail":"vmiklos@frugalware.org","sentAt":"2008-03-19T21:11:40Z","receivedAt":"2008-03-19T21:11:40Z","isPatch":true,"sender":{"key":"vmiklos@frugalware.org","avatar":"https://gravatar.com/avatar/401c1cbbb3a5d13e650c691a2c71d6fd0b80df1a01bc74d9f1972675dd58f2bd?d=mp&s=160"},"body":"On Tue, Mar 18, 2008 at 07:25:38PM +0100, Jan Engelhardt <jengelh@computergmbh.de> wrote:\n> commit b6612a2efe93660be7ecdb799625015efedadff1\n> Author: Jan Engelhardt <jengelh@computergmbh.de>\n> Date:   Tue Mar 18 19:24:33 2008 +0100\n> \n>     Import \"git-forest\" into contrib/\n\nmissing signed-off-by?\n"},{"id":"72407","messageId":"frs05b$qke$1@ger.gmane.org","threadId":"12755","inReplyTo":"alpine.LNX.1.00.0803181924560.8851@fbirervta.pbzchgretzou.qr","subject":"Re: [patch] Import \"git-forest\" into contrib/","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2008-03-19T21:21:47Z","receivedAt":"2008-03-19T21:21:47Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Jan Engelhardt wrote:\n\n> diff --git a/contrib/git-forest/git-forest b/contrib/git-forest/git-forest\n> new file mode 100755\n> index 0000000..f5d6f81\n> --- /dev/null\n> +++ b/contrib/git-forest/git-forest\n> @@ -0,0 +1,391 @@\n> +#!/usr/bin/perl\n> +#\n> +#      git-??\n\nEh?\n\n-- \nJakub Narebski\nWarsaw, Poland\nShadeHawk on #git\n"},{"id":"72408","messageId":"alpine.LNX.1.00.0803192222350.25695@fbirervta.pbzchgretzou.qr","threadId":"12755","inReplyTo":"20080319211140.GK2663@genesis.frugalware.org","subject":"Re: [patch] Import \"git-forest\" into contrib/","fromName":"Jan Engelhardt","fromEmail":"jengelh@computergmbh.de","sentAt":"2008-03-19T21:22:54Z","receivedAt":"2008-03-19T21:22:54Z","isPatch":true,"sender":{"key":"jengelh@computergmbh.de","avatar":null},"body":"\nOn Mar 19 2008 22:11, Miklos Vajna wrote:\n\n> On Tue, Mar 18, 2008 at 07:25:38PM +0100, Jan Engelhardt <jengelh@computergmbh.de> wrote:\n>> commit b6612a2efe93660be7ecdb799625015efedadff1\n>> Author: Jan Engelhardt <jengelh@computergmbh.de>\n>> Date:   Tue Mar 18 19:24:33 2008 +0100\n>>\n>>     Import \"git-forest\" into contrib/\n>\n> missing signed-off-by?\n>\n\nWasnot sure if it's used for git too;\n\nSigned-off-by: Jan Engelhardt <jengelh@computergmbh.de>\n"},{"id":"72418","messageId":"7v4pb22xgc.fsf@gitster.siamese.dyndns.org","threadId":"12755","inReplyTo":"alpine.LNX.1.00.0803192222350.25695@fbirervta.pbzchgretzou.qr","subject":"Re: [patch] Import \"git-forest\" into contrib/","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-03-19T21:52:35Z","receivedAt":"2008-03-19T21:52:35Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jan Engelhardt <jengelh@computergmbh.de> writes:\n\n> On Mar 19 2008 22:11, Miklos Vajna wrote:\n>\n>> On Tue, Mar 18, 2008 at 07:25:38PM +0100, Jan Engelhardt <jengelh@computergmbh.de> wrote:\n>>> commit b6612a2efe93660be7ecdb799625015efedadff1\n>>> Author: Jan Engelhardt <jengelh@computergmbh.de>\n>>> Date:   Tue Mar 18 19:24:33 2008 +0100\n>>>\n>>>     Import \"git-forest\" into contrib/\n>>\n>> missing signed-off-by?\n>>\n>\n> Wasnot sure if it's used for git too;\n\nYes.\n\ngit also expects the kernel style e-mails, and it is _NOT_ \"dump output\nfrom 'git show' in the message, commit/Author:/Date: headers and message\nindented by 4-spaces\" format.\n\nAs to the contents, I did not understand this part.\n\n+Notes on interpretation:\n+\n+'╬' (or variants thereof, like ╪) is meant to be a \"path bridge\", i.e.\n+traversal is only \"allowed\" horizontal OR vertical direction.\n+\n+Branching:\n+C D E F G\n+╠═╬═╩═╩═╝  A->{C,E,F,G} and B->D.\n+A B\n\nSo the horizontal line bridge goes over the vertical road between B and D\nand these two will not get connection to anything else.  That part I\nunderstand.\n\n (1) Why then is that horizontal bridge connected to E, F and G?  Do\n     pluses and inverted Ts have different meaning?  What about the\n     sideway T between A and C?\n\n (2) If you want to express D is merge between A and B, and C, E, F, G are\n     independent children of A, how would you write it?\n\nDid you mean \"Connection with three legs (T, inverted T, sideways T) mean\nall sides are connected, connection with four legs (+) mean horizontal and\nvertical are independent and disconnected\"?\n"},{"id":"72427","messageId":"alpine.LNX.1.00.0803192301330.25695@fbirervta.pbzchgretzou.qr","threadId":"12755","inReplyTo":"7v4pb22xgc.fsf@gitster.siamese.dyndns.org","subject":"Re: [patch] Import \"git-forest\" into contrib/","fromName":"Jan Engelhardt","fromEmail":"jengelh@computergmbh.de","sentAt":"2008-03-19T22:23:55Z","receivedAt":"2008-03-19T22:23:55Z","isPatch":true,"sender":{"key":"jengelh@computergmbh.de","avatar":null},"body":"\nOn Mar 19 2008 14:52, Junio C Hamano wrote:\n>\n> git also expects the kernel style e-mails, and it is _NOT_ \"dump output\n> from 'git show' in the message, commit/Author:/Date: headers and message\n> indented by 4-spaces\" format.\n\nActually, it's `git log -1 -p` that I used. PINE traditionally\ntrashes the direct mbox output of git, i.e. Message-ID is rewritten\nby PINE again when using Continue Postponed, but apparently only on\nnon-PINE messages to begin with. I just recently switched to alpine,\nmaybe it's better there.\n\n> As to the contents, I did not understand this part.\n>\n> +Notes on interpretation:\n> +\n> +'╬' (or variants thereof, like ╪) is meant to be a \"path bridge\", i.e.\n> +traversal is only \"allowed\" horizontal OR vertical direction.\n> +\n> +Branching:\n> +C D E F G\n> +╠═╬═╩═╩═╝  A->{C,E,F,G} and B->D.\n> +A B\n>\n> So the horizontal line bridge goes over the vertical road between B and D\n> and these two will not get connection to anything else.  That part I\n> understand.\n>\n> (1) Why then is that horizontal bridge connected to E, F and G?  Do\n>     pluses and inverted Ts have different meaning?  What about the\n>     sideway T between A and C?\n\n> Did you mean \"Connection with three legs (T, inverted T, sideways T) mean\n> all sides are connected, connection with four legs (+) mean horizontal and\n> vertical are independent and disconnected\"?\n\nYes. Would\n\n#       Connections with four \"legs\" ('╬' or variants thereof, like\n#       '╪') are \n#       meant to be interpreted as being connected only in the\n#       horizontal and \n#       vertical direction, NOT around-the-corner. \n# \n#       Connections with three or less \"legs\" ('╠', '╩', '╦', etc.)\n#       imply \n#       a connection to all connected directions.\n\nwork as help text?\n\n> (2) If you want to express D is merge between A and B, and C, E, F, G are\n>     independent children of A, how would you write it?\n\nA..G in the above are actually placeholders for more wood\ninstead of placeholders for commits.\n\nSo (one possible) answer to your question — since you can only\nbe referring to commits :-) — would be:\n\n\n╓─[master]──[G]──sm7\n║ ╓─[F]──sm6\n║ ║ ╓─[E]──sm5\n║ ║ ║ ╓─[C]──sm4\n║ ║ ║ ║ ╓─[D]──something3\n║ ║ ║ ║ ╠═╗ \n║ ║ ║ ║ ╟─║─[B]──something2\n╠═╩═╩═╩═╬═╝ \n╟───────║─[A]──something1\n╠═══════╝ \n╙ Initial\n\ndepending on the order you committed (or flags like\n--date-order/--topo-order).\n\nIf one commit is added to D, the picture shifts a bit:\n\n╓─[master]──c8\n║ ╓─[G]──sm7\n║ ║ ╓─[F]──sm6\n║ ║ ║ ╓─[E]──sm5\n║ ║ ║ ║ ╓─[C]──sm4\n╟─║─║─║─║─[D]──something3\n╠═╬═╬═╬═╬═╗ \n╟─║─║─║─║─║─[B]──something2\n║ ╠═╩═╩═╩═╝ \n║ ╟─[A]──something1\n╠═╝ \n╙ Initial\n"},{"id":"72468","messageId":"20080320021630.GR2663@genesis.frugalware.org","threadId":"12755","inReplyTo":"alpine.LNX.1.00.0803192301330.25695@fbirervta.pbzchgretzou.qr","subject":"Re: [patch] Import \"git-forest\" into contrib/","fromName":"Miklos Vajna","fromEmail":"vmiklos@frugalware.org","sentAt":"2008-03-20T02:16:30Z","receivedAt":"2008-03-20T02:16:30Z","isPatch":true,"sender":{"key":"vmiklos@frugalware.org","avatar":"https://gravatar.com/avatar/401c1cbbb3a5d13e650c691a2c71d6fd0b80df1a01bc74d9f1972675dd58f2bd?d=mp&s=160"},"body":"On Wed, Mar 19, 2008 at 11:23:55PM +0100, Jan Engelhardt <jengelh@computergmbh.de> wrote:\n> Actually, it's `git log -1 -p` that I used. PINE traditionally\n> trashes the direct mbox output of git, i.e. Message-ID is rewritten\n> by PINE again when using Continue Postponed, but apparently only on\n> non-PINE messages to begin with. I just recently switched to alpine,\n> maybe it's better there.\n\nor just use git-send-email if your mailer is broken.\n"}]}