[Erp5-report] r44025 jm - in /erp5/trunk: bt5/erp5_forge/SkinTemplateItem/portal_skins/erp5...

nobody at svn.erp5.org nobody at svn.erp5.org
Mon Mar 7 21:00:42 CET 2011


Author: jm
Date: Mon Mar  7 21:00:42 2011
New Revision: 44025

URL: http://svn.erp5.org?rev=44025&view=rev
Log:
EPR5VCS: handle some cases where git couldn't push because working copy wasn't up-to-date

Modified:
    erp5/trunk/bt5/erp5_forge/SkinTemplateItem/portal_skins/erp5_vcs/BusinessTemplate_viewVcsChangelog/your_push.xml
    erp5/trunk/products/ERP5VCS/Git.py
    erp5/trunk/products/ERP5VCS/WorkingCopy.py

Modified: erp5/trunk/bt5/erp5_forge/SkinTemplateItem/portal_skins/erp5_vcs/BusinessTemplate_viewVcsChangelog/your_push.xml
URL: http://svn.erp5.org/erp5/trunk/bt5/erp5_forge/SkinTemplateItem/portal_skins/erp5_vcs/BusinessTemplate_viewVcsChangelog/your_push.xml?rev=44025&r1=44024&r2=44025&view=diff
==============================================================================
--- erp5/trunk/bt5/erp5_forge/SkinTemplateItem/portal_skins/erp5_vcs/BusinessTemplate_viewVcsChangelog/your_push.xml [utf8] (original)
+++ erp5/trunk/bt5/erp5_forge/SkinTemplateItem/portal_skins/erp5_vcs/BusinessTemplate_viewVcsChangelog/your_push.xml [utf8] Mon Mar  7 21:00:42 2011
@@ -151,7 +151,7 @@
       <dictionary>
         <item>
             <key> <string>_text</string> </key>
-            <value> <string>python: not (lambda vcs: vcs.getAheadCount() or vcs.getBehindCount())(here.getVcsTool())</string> </value>
+            <value> <string>python: not here.getVcsTool().getAheadCount()</string> </value>
         </item>
       </dictionary>
     </pickle>

Modified: erp5/trunk/products/ERP5VCS/Git.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5VCS/Git.py?rev=44025&r1=44024&r2=44025&view=diff
==============================================================================
--- erp5/trunk/products/ERP5VCS/Git.py [utf8] (original)
+++ erp5/trunk/products/ERP5VCS/Git.py [utf8] Mon Mar  7 21:00:42 2011
@@ -36,9 +36,10 @@ from Products.ERP5VCS.WorkingCopy import
   WorkingCopy, NotAWorkingCopyError, Dir, File, selfcached
 
 class GitError(EnvironmentError):
-  def __init__(self, err, out):
+  def __init__(self, err, out, returncode):
     EnvironmentError.__init__(self, err)
     self.stdout = out
+    self.returncode = returncode
 
 class Git(WorkingCopy):
 
@@ -58,7 +59,7 @@ class Git(WorkingCopy):
     p = self._git(stdout=subprocess.PIPE, stderr=subprocess.PIPE, *args, **kw)
     out, err = p.communicate()
     if p.returncode:
-      raise GitError(err, out)
+      raise GitError(err, out, p.returncode)
     if strip:
       return out.strip()
     return out
@@ -223,6 +224,12 @@ class Git(WorkingCopy):
   def commit(self, changelog, added=(), modified=(), removed=()):
     context = self.aq_parent
     request = context.REQUEST
+    push = request.get('push')
+    reset = 1
+    if push:
+      # if we can't push because we are not up-to-date, we'll either 'merge' or
+      # 'rebase' depending on we already have local commits or not
+      merge = self.getAheadCount() and 'merge' or 'rebase'
 
     selected_set = set(added)
     selected_set.update(modified)
@@ -234,13 +241,42 @@ class Git(WorkingCopy):
     if author:
       args[1:1] = '--author', author
     self.git(*(args + list(selected_set)))
+    self.clean()
     try:
-      if request.get('push'):
+      if push:
         src, remote = self._getBranch()
         remote, dst = remote.split('/', 1)
-        self.git('push', '--porcelain', remote, '%s:%s' % (src, dst))
+        push_args = 'push', '--porcelain', remote, '%s:%s' % (src, dst)
+        try:
+          self.git(*push_args)
+        except GitError, e:
+          # first check why we could not push
+          status = [x for x in e.stdout.splitlines() if x[:1] == '!']
+          if (len(status) !=  1 or
+              status[0].split()[2:] != ['[rejected]', '(non-fast-forward)']):
+            raise
+          self.git('fetch', '--prune', remote)
+          if not self.getBehindCount():
+            raise
+          # try to update our working copy
+          # TODO: find a solution if there are other local changes
+          # TODO: solve conflicts on */bt/revision automatically
+          try:
+            self.git(merge, '@{u}')
+          except GitError, e:
+            # XXX: how to know how it failed ?
+            try:
+              self.git(merge, '--abort')
+            except GitError:
+              pass
+            raise e
+          # no need to keep a merge commit if push fails again
+          if merge == 'merge':
+            reset += 1
+          # retry to push everything
+          self.git(*push_args)
     except GitError, e:
-      self.git('reset', '--soft', '@{1}')
+      self.git('reset', '--soft', '@{%u}' % reset)
       portal_status_message = str(e)
     else:
       head = self.git('rev-parse', '--short', 'HEAD')
@@ -262,6 +298,11 @@ class Git(WorkingCopy):
                       message=message))
     return log
 
+  def clean(self):
+    self.git('reset', '-q', '.') # WKRD: "git checkout HEAD ." is inefficient
+    self.git('checkout', '.')    # because it deletes and recreates all files
+    self.git('clean', '-qfd')
+
   def _clean(self):
     # XXX unsafe if user doesn't configure files to exclude
     self.git('clean', '-fd', cwd=self.toplevel)

Modified: erp5/trunk/products/ERP5VCS/WorkingCopy.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5VCS/WorkingCopy.py?rev=44025&r1=44024&r2=44025&view=diff
==============================================================================
--- erp5/trunk/products/ERP5VCS/WorkingCopy.py [utf8] (original)
+++ erp5/trunk/products/ERP5VCS/WorkingCopy.py [utf8] Mon Mar  7 21:00:42 2011
@@ -379,7 +379,9 @@ class BusinessTemplateWorkingCopy(Busine
       try:
         file = open(path, 'r+b')
       except IOError, e:
-        if e.errno != errno.ENOENT:
+        if e.errno == errno.EISDIR:
+          shutil.rmtree(path, ignore_errors=True)
+        elif e.errno != errno.ENOENT:
           raise
         file = open(path, 'wb')
       else:



More information about the Erp5-report mailing list