1. Augie Fackler
  2. hgsubversion

Commits

Augie Fackler  committed e775ffb

push: also suggest user rebase if we get SVN_ERR_FS_ALREADY_EXISTS

Subversion differentiates adding an already-added file from
transaction being out of date and edit conflicts. Fixes #400.

  • Participants
  • Parent commits 2c64453
  • Branches default

Comments (0)

Files changed (4)

File hgsubversion/pushmod.py

View file
                    props, newcopies)
     except svnwrap.SubversionException, e:
         if len(e.args) > 0 and e.args[1] in (svnwrap.ERR_FS_TXN_OUT_OF_DATE,
-                                             svnwrap.ERR_FS_CONFLICT):
+                                             svnwrap.ERR_FS_CONFLICT,
+                                             svnwrap.ERR_FS_ALREADY_EXISTS):
             raise hgutil.Abort('Outgoing changesets parent is not at '
                                'subversion HEAD\n'
                                '(pull again and rebase on a newer revision)')

File hgsubversion/svnwrap/subvertpy_wrapper.py

View file
     return (svnvers, 'Subvertpy ' + _versionstr(subvertpy.__version__))
 
 # exported values
+ERR_FS_ALREADY_EXISTS = subvertpy.ERR_FS_ALREADY_EXISTS
 ERR_FS_CONFLICT = subvertpy.ERR_FS_CONFLICT
 ERR_FS_NOT_FOUND = subvertpy.ERR_FS_NOT_FOUND
 ERR_FS_TXN_OUT_OF_DATE = subvertpy.ERR_FS_TXN_OUT_OF_DATE
 ERR_RA_DAV_PATH_NOT_FOUND = subvertpy.ERR_RA_DAV_PATH_NOT_FOUND
 ERR_RA_DAV_REQUEST_FAILED = subvertpy.ERR_RA_DAV_REQUEST_FAILED
 ERR_REPOS_HOOK_FAILURE = subvertpy.ERR_REPOS_HOOK_FAILURE
+SSL_CNMISMATCH = subvertpy.SSL_CNMISMATCH
+SSL_EXPIRED = subvertpy.SSL_EXPIRED
+SSL_NOTYETVALID = subvertpy.SSL_NOTYETVALID
+SSL_OTHER = subvertpy.SSL_OTHER
 SSL_UNKNOWNCA = subvertpy.SSL_UNKNOWNCA
-SSL_CNMISMATCH = subvertpy.SSL_CNMISMATCH
-SSL_NOTYETVALID = subvertpy.SSL_NOTYETVALID
-SSL_EXPIRED = subvertpy.SSL_EXPIRED
-SSL_OTHER = subvertpy.SSL_OTHER
 SubversionException = subvertpy.SubversionException
 apply_txdelta = delta.apply_txdelta_handler
 # superclass for editor.HgEditor

File hgsubversion/svnwrap/svn_swig_wrapper.py

View file
     return '%d.%d.%d' % current_bindings, 'SWIG'
 
 # exported values
+ERR_FS_ALREADY_EXISTS = core.SVN_ERR_FS_ALREADY_EXISTS
 ERR_FS_CONFLICT = core.SVN_ERR_FS_CONFLICT
 ERR_FS_NOT_FOUND = core.SVN_ERR_FS_NOT_FOUND
 ERR_FS_TXN_OUT_OF_DATE = core.SVN_ERR_FS_TXN_OUT_OF_DATE
 ERR_INCOMPLETE_DATA = core.SVN_ERR_INCOMPLETE_DATA
 ERR_RA_DAV_REQUEST_FAILED = core.SVN_ERR_RA_DAV_REQUEST_FAILED
 ERR_REPOS_HOOK_FAILURE = core.SVN_ERR_REPOS_HOOK_FAILURE
+SSL_CNMISMATCH = core.SVN_AUTH_SSL_CNMISMATCH
+SSL_EXPIRED = core.SVN_AUTH_SSL_EXPIRED
+SSL_NOTYETVALID = core.SVN_AUTH_SSL_NOTYETVALID
+SSL_OTHER = core.SVN_AUTH_SSL_OTHER
 SSL_UNKNOWNCA = core.SVN_AUTH_SSL_UNKNOWNCA
-SSL_CNMISMATCH = core.SVN_AUTH_SSL_CNMISMATCH
-SSL_NOTYETVALID = core.SVN_AUTH_SSL_NOTYETVALID
-SSL_EXPIRED = core.SVN_AUTH_SSL_EXPIRED
-SSL_OTHER = core.SVN_AUTH_SSL_OTHER
 SubversionException = core.SubversionException
 Editor = delta.Editor
 

File tests/test_push_command.py

View file
         tip = self.repo['tip']
         self.assertEqual(tip.node(), old_tip)
 
+    def test_push_add_of_added_upstream_gives_sane_error(self):
+        repo = self.repo
+        def file_callback(repo, memctx, path):
+            if path == 'adding_file':
+                return context.memfilectx(path=path,
+                                          data='foo',
+                                          islink=False,
+                                          isexec=False,
+                                          copied=False)
+            raise IOError()
+        p1 = repo['default'].node()
+        ctx = context.memctx(repo,
+                             (p1, node.nullid),
+                             'automated test',
+                             ['adding_file'],
+                             file_callback,
+                             'an_author',
+                             '2008-10-07 20:59:48 -0500',
+                             {'branch': 'default', })
+        new_hash = repo.commitctx(ctx)
+        hg.update(repo, repo['tip'].node())
+        old_tip = repo['tip'].node()
+        self.pushrevisions()
+        tip = self.repo['tip']
+        self.assertNotEqual(tip.node(), old_tip)
+
+        # This node adds the same file as the first one we added, and
+        # will be refused by the server for adding a file that already
+        # exists. We should respond with an error suggesting the user
+        # rebase.
+        ctx = context.memctx(repo,
+                             (p1, node.nullid),
+                             'automated test',
+                             ['adding_file'],
+                             file_callback,
+                             'an_author',
+                             '2008-10-07 20:59:48 -0500',
+                             {'branch': 'default', })
+        new_hash = repo.commitctx(ctx)
+        hg.update(repo, repo['tip'].node())
+        old_tip = repo['tip'].node()
+        try:
+          self.pushrevisions()
+        except hgutil.Abort, e:
+          assert "pull again and rebase" in str(e)
+        tip = self.repo['tip']
+        self.assertEqual(tip.node(), old_tip)
+
     def test_cant_push_with_changes(self):
         repo = self.repo
         def file_callback(repo, memctx, path):