{"thread":{"id":"28297","subject":"[PATCH] git svn dcommit : new option --interactive","startedAt":"2011-09-04T19:21:51Z","lastAt":"2011-09-07T20:02:36Z","messageCount":5,"participants":["Frédéric Heitzmann","Eric Wong"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"174826","messageId":"1315164113-26539-1-git-send-email-frederic.heitzmann@gmail.com","threadId":"28297","inReplyTo":null,"subject":"[PATCH] git svn dcommit : new option --interactive","fromName":"Frédéric Heitzmann","fromEmail":"frederic.heitzmann@gmail.com","sentAt":"2011-09-04T19:21:51Z","receivedAt":"2011-09-04T19:21:51Z","isPatch":true,"sender":{"key":"frederic.heitzmann@gmail.com","avatar":null},"body":"I use git svn daily, at work, and it is so useful that I started using it to\ntrack some files which are not supposed to find their way up to the SVN\nserver.\nFor instance, it may be useful to 'git add & commit' some reference data\nfiles, refactor some code, check against the data files, git commit, ..., then discard\ncommits with data files.\nThis way, it is very easy to monitor the functional changes in your code.\n\nUnfortunately, it may happen that I forget to remove useless commits, and 'git\nsvn dcommit' everything ... forever.\n\nThese 2 patches add a --interactive option to 'git svn dcommit', which provides\nan interactive mode, similar to git-send-email.\n\n Documentation/git-svn.txt              |    8 ++++\n git-svn.perl                           |   71 +++++++++++++++++++++++++++++++-\n t/t9160-git-svn-dcommit-interactive.sh |   64 ++++++++++++++++++++++++++++\n 3 files changed, 142 insertions(+), 1 deletions(-)\n"},{"id":"174827","messageId":"1315164113-26539-2-git-send-email-frederic.heitzmann@gmail.com","threadId":"28297","inReplyTo":"1315164113-26539-1-git-send-email-frederic.heitzmann@gmail.com","subject":"[PATCH 1/2] git svn dcommit: new option --interactive.","fromName":"Frédéric Heitzmann","fromEmail":"frederic.heitzmann@gmail.com","sentAt":"2011-09-04T19:21:52Z","receivedAt":"2011-09-04T19:21:52Z","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 then\npossible 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.\n\nPart of the code was taken from git-send-email.perl\n\nThanks-to: Eric Wong <normalperson@yhbt.net> for the initial idea.\nSigned-off-by: Frédéric Heitzmann <frederic.heitzmann@gmail.com>\n---\n\n I would have preferred not duplicating the code snippets taken from\n git-send-email ('ask' function, Term related code, ...) but I preferred not\n to spoil Git.pm with it.\n Any comment on a better way to factor perl code would be appreciated.\n\n Documentation/git-svn.txt |    8 +++++\n git-svn.perl              |   71 ++++++++++++++++++++++++++++++++++++++++++++-\n 2 files changed, 78 insertions(+), 1 deletions(-)\n\ndiff --git a/Documentation/git-svn.txt b/Documentation/git-svn.txt\nindex ed5eca1..08188a5 100644\n--- a/Documentation/git-svn.txt\n+++ b/Documentation/git-svn.txt\n@@ -214,6 +214,14 @@ discouraged.\n \tversion 1.5 can make use of it. 'git svn' currently does not use it\n \tand does not set it automatically.\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 89f83fd..fd5eaa2 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 $_q ||= 0;\n my %remote_opts = ( 'username=s' => \\$Git::SVN::Prompt::_username,\n@@ -158,6 +158,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@@ -251,6 +252,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@@ -361,6 +383,31 @@ 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+\treturn defined $default ? $default : undef\n+\t\tunless defined $term->IN and defined fileno($term->IN) and\n+\t\t       defined $term->OUT and defined fileno($term->OUT);\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@@ -546,6 +593,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 \tGit::SVN::remove_username($expect_url);\n \twhile (1) {\n-- \n1.7.6.447.gb9176\n"},{"id":"174828","messageId":"1315164113-26539-3-git-send-email-frederic.heitzmann@gmail.com","threadId":"28297","inReplyTo":"1315164113-26539-1-git-send-email-frederic.heitzmann@gmail.com","subject":"[PATCH 2/2] git svn dcommit: add a test serie for 'git svn dcommit --interactive'","fromName":"Frédéric Heitzmann","fromEmail":"frederic.heitzmann@gmail.com","sentAt":"2011-09-04T19:21:53Z","receivedAt":"2011-09-04T19:21:53Z","isPatch":true,"sender":{"key":"frederic.heitzmann@gmail.com","avatar":null},"body":"test several combinations of potential answers to 'git svn dcommit\n--interactive'. For each of them, test whether patches were commited to SVN or\nnot\n\nSigned-off-by: Frédéric Heitzmann <frederic.heitzmann@gmail.com>\n---\n t/t9160-git-svn-dcommit-interactive.sh |   64 ++++++++++++++++++++++++++++++++\n 1 files changed, 64 insertions(+), 0 deletions(-)\n create mode 100644 t/t9160-git-svn-dcommit-interactive.sh\n\ndiff --git a/t/t9160-git-svn-dcommit-interactive.sh b/t/t9160-git-svn-dcommit-interactive.sh\nnew file mode 100644\nindex 0000000..e38d9fa\n--- /dev/null\n+++ b/t/t9160-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.6.447.gb9176\n"},{"id":"174957","messageId":"20110906202601.GA11668@dcvr.yhbt.net","threadId":"28297","inReplyTo":"1315164113-26539-2-git-send-email-frederic.heitzmann@gmail.com","subject":"Re: [PATCH 1/2] git svn dcommit: new option --interactive.","fromName":"Eric Wong","fromEmail":"normalperson@yhbt.net","sentAt":"2011-09-06T20:26:01Z","receivedAt":"2011-09-06T20:26:01Z","isPatch":true,"sender":{"key":"e@80x24.org","avatar":null},"body":"Frédéric Heitzmann <frederic.heitzmann@gmail.com> wrote:\n> Allow the user to check the patch set before it is commited to SNV. It is then\n> possible to accept/discard one patch, accept all, or quit.\n> \n> This interactive mode is similar with 'git send email' behaviour. However,\n> 'git svn dcommit' returns as soon as one patch is discarded.\n> \n> Part of the code was taken from git-send-email.perl\n\n> Thanks-to: Eric Wong <normalperson@yhbt.net> for the initial idea.\n> Signed-off-by: Frédéric Heitzmann <frederic.heitzmann@gmail.com>\n\nI agree with this feature, a few comments inline.\n\n>  I would have preferred not duplicating the code snippets taken from\n>  git-send-email ('ask' function, Term related code, ...) but I preferred not\n>  to spoil Git.pm with it.\n>  Any comment on a better way to factor perl code would be appreciated.\n\nWe should put this into Git.pm at some point.\n(Somebody should refactor git-svn.perl into separate files too... :x)\n\n>  Documentation/git-svn.txt |    8 +++++\n>  git-svn.perl              |   71 ++++++++++++++++++++++++++++++++++++++++++++-\n>  2 files changed, 78 insertions(+), 1 deletions(-)\n\nTests and feature should be the same patch\n\n> +\treturn defined $default ? $default : undef\n> +\t\tunless defined $term->IN and defined fileno($term->IN) and\n> +\t\t       defined $term->OUT and defined fileno($term->OUT);\n\nThings to make life easier for (mainly) C programmers:\n\n* Use C-style \"&&\" and \"||\" for conditionals.  \"and\" and \"or\" are lower\n  precedence and better used for control flow (see perlop(1) manpage).\n\n* Also, use parentheses for defined(foo) to disambiguate multiple\n  conditions/statements.\n\n-- \nEric Wong\n"},{"id":"175026","messageId":"4E67CDDC.1020305@gmail.com","threadId":"28297","inReplyTo":"20110906202601.GA11668@dcvr.yhbt.net","subject":"Re: [PATCH 1/2] git svn dcommit: new option --interactive.","fromName":"Frédéric Heitzmann","fromEmail":"frederic.heitzmann@gmail.com","sentAt":"2011-09-07T20:02:36Z","receivedAt":"2011-09-07T20:02:36Z","isPatch":true,"sender":{"key":"frederic.heitzmann@gmail.com","avatar":null},"body":"\n\nLe 06/09/2011 22:26, Eric Wong a écrit :\n> Frédéric Heitzmann<frederic.heitzmann@gmail.com>  wrote:\n>> Allow the user to check the patch set before it is commited to SNV. It is then\n>> possible to accept/discard one patch, accept all, or quit.\n>>\n>> This interactive mode is similar with 'git send email' behaviour. However,\n>> 'git svn dcommit' returns as soon as one patch is discarded.\n>>\n>> Part of the code was taken from git-send-email.perl\n>> Thanks-to: Eric Wong<normalperson@yhbt.net>  for the initial idea.\n>> Signed-off-by: Frédéric Heitzmann<frederic.heitzmann@gmail.com>\n> I agree with this feature, a few comments inline.\n>\n>>   I would have preferred not duplicating the code snippets taken from\n>>   git-send-email ('ask' function, Term related code, ...) but I preferred not\n>>   to spoil Git.pm with it.\n>>   Any comment on a better way to factor perl code would be appreciated.\n> We should put this into Git.pm at some point.\n> (Somebody should refactor git-svn.perl into separate files too... :x)\n>\n>>   Documentation/git-svn.txt |    8 +++++\n>>   git-svn.perl              |   71 ++++++++++++++++++++++++++++++++++++++++++++-\n>>   2 files changed, 78 insertions(+), 1 deletions(-)\n> Tests and feature should be the same patch\n>> +\treturn defined $default ? $default : undef\n>> +\t\tunless defined $term->IN and defined fileno($term->IN) and\n>> +\t\t       defined $term->OUT and defined fileno($term->OUT);\n> Things to make life easier for (mainly) C programmers:\n>\n> * Use C-style \"&&\" and \"||\" for conditionals.  \"and\" and \"or\" are lower\n>    precedence and better used for control flow (see perlop(1) manpage).\n>\n> * Also, use parentheses for defined(foo) to disambiguate multiple\n>    conditions/statements.\n>\nMy fault : I copied-pasted the 'ask' function from git-send-email.\nEven if I rewrite it a litlle, it should not prevent anyone to mutalize \nsome code into Git.pm.\nAnd, indeed, it will improve readability.\n\nI wait a few days to see if anyone else has some comments and I send a \nV2 patch serie.\n\nThanks for reviewing.\n\n--\nFred\n"}]}