Author: danielsh Date: Thu Oct 20 23:34:26 2016 New Revision: 1765903 URL: http://svn.apache.org/viewvc?rev=1765903&view=rev Log: backport.py: Fix a race condition involving concurrent commits to STATUS (see r1764633).
The fix is to run 'update' at the top of the outermost loop, rather than immediately before calling 'svn merge'. * tools/dist/backport/merger.py (merge): Don't run revert+update; instead, expect the caller to have done so. * tools/dist/merge-approved-backports.py: Run 'update' and re-parse STATUS before each merge. * tools/dist/detect-conflicting-backports.py: Track API change of merge(). Modified: subversion/trunk/tools/dist/backport/merger.py subversion/trunk/tools/dist/detect-conflicting-backports.py subversion/trunk/tools/dist/merge-approved-backports.py Modified: subversion/trunk/tools/dist/backport/merger.py URL: http://svn.apache.org/viewvc/subversion/trunk/tools/dist/backport/merger.py?rev=1765903&r1=1765902&r2=1765903&view=diff ============================================================================== --- subversion/trunk/tools/dist/backport/merger.py (original) +++ subversion/trunk/tools/dist/backport/merger.py Thu Oct 20 23:34:26 2016 @@ -195,11 +195,8 @@ def merge(entry, expected_stderr=None, * mergeargs.extend(['--', sf.trunk_url()]) logmsg += entry.raw - # TODO(interactive mode): exclude STATUS from reverts - # TODO(interactive mode): save local mods to disk, as backport.pl does - run_revert() + no_local_mods('.') - run_svn_quiet(['update']) # TODO: use select() to restore interweaving of stdout/stderr _, stdout, stderr = run_svn_quiet(['merge'] + mergeargs, expected_stderr) sys.stdout.write(stdout) Modified: subversion/trunk/tools/dist/detect-conflicting-backports.py URL: http://svn.apache.org/viewvc/subversion/trunk/tools/dist/detect-conflicting-backports.py?rev=1765903&r1=1765902&r2=1765903&view=diff ============================================================================== --- subversion/trunk/tools/dist/detect-conflicting-backports.py (original) +++ subversion/trunk/tools/dist/detect-conflicting-backports.py Thu Oct 20 23:34:26 2016 @@ -77,6 +77,7 @@ ERRORS = collections.defaultdict(list) for entry_para in sf.entries_paras(): entry = entry_para.entry() # SVN_ERR_WC_FOUND_CONFLICT = 155015 + backport.merger.run_svn_quiet(['update']) # TODO: what to do if this pulls in a STATUS mod? backport.merger.merge(entry, 'svn: E155015' if entry.depends else None) _, output, _ = backport.merger.run_svn(['status']) Modified: subversion/trunk/tools/dist/merge-approved-backports.py URL: http://svn.apache.org/viewvc/subversion/trunk/tools/dist/merge-approved-backports.py?rev=1765903&r1=1765902&r2=1765903&view=diff ============================================================================== --- subversion/trunk/tools/dist/merge-approved-backports.py (original) +++ subversion/trunk/tools/dist/merge-approved-backports.py Thu Oct 20 23:34:26 2016 @@ -40,11 +40,14 @@ if sys.argv[1:]: sys.exit(0) backport.merger.no_local_mods('./STATUS') -sf = backport.status.StatusFile(open('./STATUS', encoding="UTF-8")) -# Duplicate sf.paragraphs, since merge() will be removing elements from it. -entries_paras = list(sf.entries_paras()) -for entry_para in entries_paras: - if entry_para.approved(): - entry = entry_para.entry() - backport.merger.merge(entry, commit=True) +while True: + backport.merger.run_svn_quiet(['update']) + sf = backport.status.StatusFile(open('./STATUS', encoding="UTF-8")) + for entry_para in sf.entries_paras(): + if entry_para.approved(): + entry = entry_para.entry() + backport.merger.merge(entry, commit=True) + break # 'continue' the outer loop + else: + break