{"thread":{"id":"28408","subject":"[PATCH v3] git svn dcommit: new option --interactive.","startedAt":"2011-09-16T21:02:01Z","lastAt":"2011-09-18T01:13:49Z","messageCount":5,"participants":["Frédéric Heitzmann","Junio C Hamano","Carlos Martín Nieto","Eric Wong"],"isPatch":true,"patchVersion":3,"patchTotal":null},"messages":[{"id":"175668","messageId":"1316206921-29311-1-git-send-email-frederic.heitzmann@gmail.com","threadId":"28408","inReplyTo":null,"subject":"[PATCH v3] git svn dcommit: new option --interactive.","fromName":"Frédéric Heitzmann","fromEmail":"frederic.heitzmann@gmail.com","sentAt":"2011-09-16T21:02:01Z","receivedAt":"2011-09-16T21:02:01Z","isPatch":true,"sender":{"key":"frederic.heitzmann@gmail.com","avatar":null},"body":"Allow the user to check the patch set before it is commited to SNV. It is\nthen possible to accept/discard one patch, accept all, or quit.\n\nThis interactive mode is similar with 'git send email' behaviour. However,\n'git svn dcommit' returns as soon as one patch is discarded.\nPart of the code was taken from git-send-email.perl (see 'ask' function)\n\nTests several combinations of potential answers to\n'git svn dcommit --interactive'. For each of them, test whether patches\nwere commited to SVN or not.\n\nThanks-to Eric Wong <normalperson@yhbt.net> for the initial idea.\n\nReviewed-by: Eric Wong <normalperson@yhbt.net>\nSigned-off-by: Frédéric Heitzmann <frederic.heitzmann@gmail.com>\n---\n Minor change from v2 : rename t9160... to t9162... to avoid name\n collision\n ref: <1316202903-5085-1-git-send-email-frederic.heitzmann@gmail.com>\n\n Documentation/git-svn.txt              |    8 +++\n git-svn.perl                           |   76 +++++++++++++++++++++++++++++++-\n t/t9162-git-svn-dcommit-interactive.sh |   64 +++++++++++++++++++++++++++\n 3 files changed, 147 insertions(+), 1 deletions(-)\n create mode 100644 t/t9162-git-svn-dcommit-interactive.sh\n\ndiff --git a/Documentation/git-svn.txt b/Documentation/git-svn.txt\nindex 08cad6d..c8f0883 100644\n--- a/Documentation/git-svn.txt\n+++ b/Documentation/git-svn.txt\n@@ -234,6 +234,14 @@ svn:mergeinfo property in the SVN repository when possible. Currently, this can\n only be done when dcommitting non-fast-forward merges where all parents but the\n first have already been pushed into SVN.\n \n+--interactive;;\n+\tAsk the user to confirm that a patch set should actually be sent to SVN.\n+\tFor each patch, one may answer \"yes\" (accept this patch), \"no\" (discard this\n+\tpatch), \"all\" (accept all patches), or \"quit\".\n+\t+\n+\t'git svn dcommit' returns immediately if answer if \"no\" or \"quit\", without\n+\tcommiting anything to SVN.\n+\n 'branch'::\n \tCreate a branch in the SVN repository.\n \ndiff --git a/git-svn.perl b/git-svn.perl\nindex 351e743..121332d 100755\n--- a/git-svn.perl\n+++ b/git-svn.perl\n@@ -87,7 +87,7 @@ my ($_stdin, $_help, $_edit,\n \t$_version, $_fetch_all, $_no_rebase, $_fetch_parent,\n \t$_merge, $_strategy, $_dry_run, $_local,\n \t$_prefix, $_no_checkout, $_url, $_verbose,\n-\t$_git_format, $_commit_url, $_tag, $_merge_info);\n+\t$_git_format, $_commit_url, $_tag, $_merge_info, $_interactive);\n $Git::SVN::_follow_parent = 1;\n $SVN::Git::Fetcher::_placeholder_filename = \".gitignore\";\n $_q ||= 0;\n@@ -163,6 +163,7 @@ my %cmd = (\n \t\t\t  'revision|r=i' => \\$_revision,\n \t\t\t  'no-rebase' => \\$_no_rebase,\n \t\t\t  'mergeinfo=s' => \\$_merge_info,\n+\t\t\t  'interactive|i' => \\$_interactive,\n \t\t\t%cmt_opts, %fc_opts } ],\n \tbranch => [ \\&cmd_branch,\n \t            'Create a branch in the SVN repository',\n@@ -256,6 +257,27 @@ my %cmd = (\n \t\t{} ],\n );\n \n+use Term::ReadLine;\n+package FakeTerm;\n+sub new {\n+\tmy ($class, $reason) = @_;\n+\treturn bless \\$reason, shift;\n+}\n+sub readline {\n+\tmy $self = shift;\n+\tdie \"Cannot use readline on FakeTerm: $$self\";\n+}\n+package main;\n+\n+my $term = eval {\n+\t$ENV{\"GIT_SVN_NOTTY\"}\n+\t\t? new Term::ReadLine 'git-svn', \\*STDIN, \\*STDOUT\n+\t\t: new Term::ReadLine 'git-svn';\n+};\n+if ($@) {\n+\t$term = new FakeTerm \"$@: going non-interactive\";\n+}\n+\n my $cmd;\n for (my $i = 0; $i < @ARGV; $i++) {\n \tif (defined $cmd{$ARGV[$i]}) {\n@@ -366,6 +388,36 @@ sub version {\n \texit 0;\n }\n \n+sub ask {\n+\tmy ($prompt, %arg) = @_;\n+\tmy $valid_re = $arg{valid_re};\n+\tmy $default = $arg{default};\n+\tmy $resp;\n+\tmy $i = 0;\n+\n+\tif ( !( defined($term->IN)\n+            && defined( fileno($term->IN) )\n+            && defined( $term->OUT )\n+            && defined( fileno($term->OUT) ) ) ){\n+\t\treturn defined($default) ? $default : undef;\n+\t}\n+\n+\twhile ($i++ < 10) {\n+\t\t$resp = $term->readline($prompt);\n+\t\tif (!defined $resp) { # EOF\n+\t\t\tprint \"\\n\";\n+\t\t\treturn defined $default ? $default : undef;\n+\t\t}\n+\t\tif ($resp eq '' and defined $default) {\n+\t\t\treturn $default;\n+\t\t}\n+\t\tif (!defined $valid_re or $resp =~ /$valid_re/) {\n+\t\t\treturn $resp;\n+\t\t}\n+\t}\n+\treturn undef;\n+}\n+\n sub do_git_init_db {\n \tunless (-d $ENV{GIT_DIR}) {\n \t\tmy @init_db = ('init');\n@@ -746,6 +798,28 @@ sub cmd_dcommit {\n \t\t     \"If these changes depend on each other, re-running \",\n \t\t     \"without --no-rebase may be required.\"\n \t}\n+\n+\tif (defined $_interactive){\n+\t\tmy $ask_default = \"y\";\n+\t\tforeach my $d (@$linear_refs){\n+\t\t\tprint \"debug : d = $d\\n\";\n+\t\t\tmy ($fh, $ctx) = command_output_pipe(qw(show --summary), \"$d\");\n+\t\t\twhile (<$fh>){\n+\t\t\t\tprint $_;\n+\t\t\t}\n+\t\t\tcommand_close_pipe($fh, $ctx);\n+\t\t\t$_ = ask(\"Commit this patch to SVN? ([y]es (default)|[n]o|[q]uit|[a]ll): \",\n+\t\t\t         valid_re => qr/^(?:yes|y|no|n|quit|q|all|a)/i,\n+\t\t\t         default => $ask_default);\n+\t\t\tdie \"Commit this patch reply required\" unless defined $_;\n+\t\t\tif (/^[nq]/i) {\n+\t\t\t\texit(0);\n+\t\t\t} elsif (/^a/i) {\n+\t\t\t\tlast;\n+\t\t\t}\n+\t\t}\n+\t}\n+\n \tmy $expect_url = $url;\n \n \tmy $push_merge_info = eval {\ndiff --git a/t/t9162-git-svn-dcommit-interactive.sh b/t/t9162-git-svn-dcommit-interactive.sh\nnew file mode 100644\nindex 0000000..e38d9fa\n--- /dev/null\n+++ b/t/t9162-git-svn-dcommit-interactive.sh\n@@ -0,0 +1,64 @@\n+#!/bin/sh\n+#\n+# Copyright (c) 2011 Frédéric Heitzmann\n+\n+test_description='git svn dcommit --interactive series'\n+. ./lib-git-svn.sh\n+\n+test_expect_success 'initialize repo' '\n+\tsvn_cmd mkdir -m\"mkdir test-interactive\" \"$svnrepo/test-interactive\" &&\n+\tgit svn clone \"$svnrepo/test-interactive\" test-interactive &&\n+\tcd test-interactive &&\n+\ttouch foo && git add foo && git commit -m\"foo: first commit\" &&\n+\tgit svn dcommit\n+\t'\n+\n+test_expect_success 'answers: y [\\n] yes' '\n+\t(\n+\t\techo \"change #1\" >> foo && git commit -a -m\"change #1\" &&\n+\t\techo \"change #2\" >> foo && git commit -a -m\"change #2\" &&\n+\t\techo \"change #3\" >> foo && git commit -a -m\"change #3\" &&\n+\t\t( echo \"y\n+\n+y\" | GIT_SVN_NOTTY=1 git svn dcommit --interactive ) &&\n+\t\ttest $(git rev-parse HEAD) = $(git rev-parse remotes/git-svn)\n+\t)\n+\t'\n+\n+test_expect_success 'answers: yes yes no' '\n+\t(\n+\t\techo \"change #1\" >> foo && git commit -a -m\"change #1\" &&\n+\t\techo \"change #2\" >> foo && git commit -a -m\"change #2\" &&\n+\t\techo \"change #3\" >> foo && git commit -a -m\"change #3\" &&\n+\t\t( echo \"yes\n+yes\n+no\" | GIT_SVN_NOTTY=1 git svn dcommit --interactive ) &&\n+\t\ttest $(git rev-parse HEAD^^^) = $(git rev-parse remotes/git-svn) &&\n+\t\tgit reset --hard remotes/git-svn\n+\t)\n+\t'\n+\n+test_expect_success 'answers: yes quit' '\n+\t(\n+\t\techo \"change #1\" >> foo && git commit -a -m\"change #1\" &&\n+\t\techo \"change #2\" >> foo && git commit -a -m\"change #2\" &&\n+\t\techo \"change #3\" >> foo && git commit -a -m\"change #3\" &&\n+\t\t( echo \"yes\n+quit\" | GIT_SVN_NOTTY=1 git svn dcommit --interactive ) &&\n+\t\ttest $(git rev-parse HEAD^^^) = $(git rev-parse remotes/git-svn) &&\n+\t\tgit reset --hard remotes/git-svn\n+\t)\n+\t'\n+\n+test_expect_success 'answers: all' '\n+\t(\n+\t\techo \"change #1\" >> foo && git commit -a -m\"change #1\" &&\n+\t\techo \"change #2\" >> foo && git commit -a -m\"change #2\" &&\n+\t\techo \"change #3\" >> foo && git commit -a -m\"change #3\" &&\n+\t\t( echo \"all\" | GIT_SVN_NOTTY=1 git svn dcommit --interactive ) &&\n+\t\ttest $(git rev-parse HEAD) = $(git rev-parse remotes/git-svn) &&\n+\t\tgit reset --hard remotes/git-svn\n+\t)\n+\t'\n+\n+test_done\n-- \n1.7.7.rc0.200.g2f9e2e\n"},{"id":"175670","messageId":"7vehzgdwlh.fsf@alter.siamese.dyndns.org","threadId":"28408","inReplyTo":"1316206921-29311-1-git-send-email-frederic.heitzmann@gmail.com","subject":"Re: [PATCH v3] git svn dcommit: new option --interactive.","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-09-16T21:08:10Z","receivedAt":"2011-09-16T21:08:10Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"I am not accepting any new features at this point in the release cycle, so\nplease do not Cc me unless it is a patch to fix regression or minor\ndocumentation.\n\nThanks.\n"},{"id":"175691","messageId":"1316261904.6897.9.camel@bee.lab.cmartin.tk","threadId":"28408","inReplyTo":"1316206921-29311-1-git-send-email-frederic.heitzmann@gmail.com","subject":"Re: [PATCH v3] git svn dcommit: new option --interactive.","fromName":"Carlos Martín Nieto","fromEmail":"carlos@cmartin.tk","sentAt":"2011-09-17T12:18:23Z","receivedAt":"2011-09-17T12:18:23Z","isPatch":true,"sender":{"key":"carlos@cmartin.tk","avatar":"https://gravatar.com/avatar/956bfe8371004f2960febf266a6af789f60cdc01fbae48bb151ad4c9b532c3a2?d=mp&s=160"},"body":"[removed Junio from CC as he doesn't want to know about this patch at\nthis stage]\n\nOn Fri, 2011-09-16 at 23:02 +0200, Frédéric Heitzmann wrote:\n> Allow the user to check the patch set before it is commited to SNV. It is\n\nTypo: SNV -> SVN\n\nMy perl-foo isn't strong enough to properly review the rest.\n\n   cmn\n"},{"id":"175692","messageId":"4E749C67.9060308@gmail.com","threadId":"28408","inReplyTo":"1316261904.6897.9.camel@bee.lab.cmartin.tk","subject":"Re: [PATCH v3] git svn dcommit: new option --interactive.","fromName":"Frédéric Heitzmann","fromEmail":"frederic.heitzmann@gmail.com","sentAt":"2011-09-17T13:11:03Z","receivedAt":"2011-09-17T13:11:03Z","isPatch":true,"sender":{"key":"frederic.heitzmann@gmail.com","avatar":null},"body":"\nLe 17/09/2011 14:18, Carlos Martín Nieto a écrit :\n> [removed Junio from CC as he doesn't want to know about this patch at\n> this stage]\n>\n> On Fri, 2011-09-16 at 23:02 +0200, Frédéric Heitzmann wrote:\n>> Allow the user to check the patch set before it is commited to SNV. It is\n> Typo: SNV ->  SVN\n>\n> My perl-foo isn't strong enough to properly review the rest.\n>\n>     cmn\nThanks.\n\n--\nFred\n"},{"id":"175700","messageId":"20110918011349.GA22037@dcvr.yhbt.net","threadId":"28408","inReplyTo":"1316261904.6897.9.camel@bee.lab.cmartin.tk","subject":"Re: [PATCH v3] git svn dcommit: new option --interactive.","fromName":"Eric Wong","fromEmail":"normalperson@yhbt.net","sentAt":"2011-09-18T01:13:49Z","receivedAt":"2011-09-18T01:13:49Z","isPatch":true,"sender":{"key":"e@80x24.org","avatar":null},"body":"Carlos Martín Nieto <carlos@cmartin.tk> wrote:\n> On Fri, 2011-09-16 at 23:02 +0200, Frédéric Heitzmann wrote:\n> > Allow the user to check the patch set before it is commited to SNV. It is\n> \n> Typo: SNV -> SVN\n\nThanks, fixed locally\n\n> My perl-foo isn't strong enough to properly review the rest.\n\nI also squashed the following cleanup:\n\n--- a/git-svn.perl\n+++ b/git-svn.perl\n@@ -802,7 +802,6 @@ sub cmd_dcommit {\n \tif (defined $_interactive){\n \t\tmy $ask_default = \"y\";\n \t\tforeach my $d (@$linear_refs){\n-\t\t\tprint \"debug : d = $d\\n\";\n \t\t\tmy ($fh, $ctx) = command_output_pipe(qw(show --summary), \"$d\");\n \t\t\twhile (<$fh>){\n \t\t\t\tprint $_;\n\n\nOtherwise things good to me.  Acked and pushed out to master of\ngit://bogomips.org/git-svn.git\n"}]}