Author: danielsh Date: Sun Mar 29 07:15:17 2015 New Revision: 1669863 URL: http://svn.apache.org/r1669863 Log: backport: Fix an svn:mergeinfo validation.
* tools/dist/backport.pl (merge): Fix the validation added in r1471467. * tools/dist/backport_tests.py (backport_otherproject_change): New regression test. * tools/dist/backport/merger.py (_includes_only_svn_mergeinfo_changes): New helper. (merge): Add the validation here, too. Modified: subversion/trunk/tools/dist/backport.pl subversion/trunk/tools/dist/backport/merger.py subversion/trunk/tools/dist/backport_tests.py Modified: subversion/trunk/tools/dist/backport.pl URL: http://svn.apache.org/viewvc/subversion/trunk/tools/dist/backport.pl?rev=1669863&r1=1669862&r2=1669863&view=diff ============================================================================== --- subversion/trunk/tools/dist/backport.pl (original) +++ subversion/trunk/tools/dist/backport.pl Sun Mar 29 07:15:17 2015 @@ -431,7 +431,7 @@ fi $SVNq up $SVNq merge @mergeargs if [ "`$SVN status -q | wc -l`" -eq 1 ]; then - if [ -n "`$SVN diff | perl -lne 'print if s/^(Added|Deleted|Modified): //' | grep -vx svn:mergeinfo`" ]; then + if [ -z "`$SVN diff | perl -lne 'print if s/^(Added|Deleted|Modified): //' | grep -vx svn:mergeinfo`" ]; then # This check detects STATUS entries that name non-^/subversion/ revnums. # ### Q: What if we actually commit a mergeinfo fix to trunk and then want # ### to backport it? Modified: subversion/trunk/tools/dist/backport/merger.py URL: http://svn.apache.org/viewvc/subversion/trunk/tools/dist/backport/merger.py?rev=1669863&r1=1669862&r2=1669863&view=diff ============================================================================== --- subversion/trunk/tools/dist/backport/merger.py (original) +++ subversion/trunk/tools/dist/backport/merger.py Sun Mar 29 07:15:17 2015 @@ -121,6 +121,24 @@ def last_changed_revision(path_or_url): else: raise Exception("'svn info' did not print last changed revision") +def _includes_only_svn_mergeinfo_changes(status_output): + """Return TRUE iff there is exactly one local mod, and it is an svn:mergeinfo + change. Use the provided `status -q` output.""" + + if len(status_output.splitlines()) != 1: + return False + + _, diff_output, _ = run_svn(['diff']) + + pattern = re.compile(r'^(Added|Modified|Deleted): ') + targets = (line.split(':', 1)[1].strip() + for line in diff_output.splitlines() + if pattern.match(line)) + if set(targets) == {'svn:mergeinfo'}: + return True + + return False + def merge(entry, expected_stderr=None, *, commit=False, sf=None): """Merges ENTRY into the working copy at cwd. @@ -173,7 +191,11 @@ def merge(entry, expected_stderr=None, * _, stdout, stderr = run_svn_quiet(['merge'] + mergeargs, expected_stderr) sys.stdout.write(stdout) sys.stderr.write(stderr) - run_svn(['status', '-q']) + + _, stdout, _ = run_svn(['status', '-q']) + if _includes_only_svn_mergeinfo_changes(stdout): + raise UnableToMergeException("Entry %s includes only svn:mergeinfo changes" + % entry) if commit: sf.remove(entry) @@ -187,7 +209,6 @@ def merge(entry, expected_stderr=None, * run_svn_quiet(['commit', '-m', logmsg]) - # TODO: add the 'only mergeinfo changes' check (and regression test it) # TODO(interactive mode): add the 'svn status' display if entry.branch: Modified: subversion/trunk/tools/dist/backport_tests.py URL: http://svn.apache.org/viewvc/subversion/trunk/tools/dist/backport_tests.py?rev=1669863&r1=1669862&r2=1669863&view=diff ============================================================================== --- subversion/trunk/tools/dist/backport_tests.py (original) +++ subversion/trunk/tools/dist/backport_tests.py Sun Mar 29 07:15:17 2015 @@ -592,6 +592,38 @@ def backport_branch_with_original_revisi #---------------------------------------------------------------------- +@BackportTest(None) +def backport_otherproject_change(sbox): + "inoperative revision" + + # r6: a change outside ^/subversion + sbox.simple_mkdir('elsewhere') + sbox.simple_commit() + + # r7: Nominate r6 by mistake + approved_entries = [ + make_entry([6]) + ] + sbox.simple_append(STATUS, serialize_STATUS(approved_entries)) + sbox.simple_commit(message='Nominate r6 by mistake') + + # Run it. + exit_code, output, errput = run_backport(sbox, error_expected=True) + + # Verify no commit occurred. + svntest.actions.run_and_verify_svnlook(["7\n"], [], + 'youngest', sbox.repo_dir) + + # Verify the failure mode. + expected_stdout = None + expected_stderr = ".*only svn:mergeinfo changes.*" + if exit_code == 0: + # Can't use verify_exit_code() since the exact code used varies. + raise svntest.Failure("exit_code should be non-zero") + svntest.verify.verify_outputs(None, output, errput, + expected_stdout, expected_stderr) + +#---------------------------------------------------------------------- ######################################################################## # Run the tests @@ -607,6 +639,7 @@ test_list = [ None, backport_branch_contains, backport_double_conflict, backport_branch_with_original_revision, + backport_otherproject_change, # When adding a new test, include the test number in the last # 6 bytes of the UUID. ]