Andrew Bogott has submitted this change and it was merged. ( 
https://gerrit.wikimedia.org/r/386331 )

Change subject: git-sync-upstream: perform rebase in a separate, temporary 
workdir
......................................................................


git-sync-upstream: perform rebase in a separate, temporary workdir

This madness allows us to do the rebase away from the puppet
checkout that puppet is actually using.  This prevents puppet
from compiling catalogs out of a repo mid-rebase.

Bug: T177944
Change-Id: I4f56f4339c5440281fd7e9821d026ebc5265507a
---
M modules/puppetmaster/files/git-sync-upstream
1 file changed, 54 insertions(+), 9 deletions(-)

Approvals:
  Andrew Bogott: Looks good to me, approved
  BryanDavis: Looks good to me, but someone else must approve
  jenkins-bot: Verified



diff --git a/modules/puppetmaster/files/git-sync-upstream 
b/modules/puppetmaster/files/git-sync-upstream
index f0e198e..16993fb 100755
--- a/modules/puppetmaster/files/git-sync-upstream
+++ b/modules/puppetmaster/files/git-sync-upstream
@@ -3,6 +3,7 @@
 import datetime
 import logging
 import os
+import shutil
 import sys
 
 # Send all git output to stdout
@@ -14,6 +15,11 @@
 
 
 def rebase_repo(repo_path, track_branch):
+    datestring = datetime.datetime.now().strftime('%Y%m%d%H%M')
+    branchname = "oot-branch-%s" % datestring
+    tagname = "snapshot-%s" % datestring
+    tempdir = "/tmp/%s" % tagname
+
     repo = git.Repo(repo_path)
     assert not repo.bare
 
@@ -26,28 +32,67 @@
 
     repo.remotes.origin.fetch()
 
+    current_branch = repo.git.rev_parse('--abbrev-ref', 'HEAD')
+    latest_commit = repo.git.rev_parse(current_branch)
     latest_upstream_commit = repo.git.show_ref("-s", upstream_branch)
     latest_merged_commit = repo.git.merge_base(upstream_branch, "HEAD")
 
     if latest_upstream_commit == latest_merged_commit:
         print("Up-to-date: %s" % repo_path)
         return True
-
     try:
-        repo.git.rebase("--preserve-merges",
-                        "--stat",
-                        "--strategy=recursive",
-                        "--strategy-option=patience",
-                        upstream_branch)
+        # Rebase in a tempdir to avoid changing the state of the current 
workdir.
+        #  (Rebasing in place causes an occasional puppet race)
+        #
+        # This next bit is largely cribbed from
+        #  https://github.com/encukou/bin/blob/master/oot-rebase
+        #
+        os.makedirs(tempdir)
+
+        tmprepo = git.Repo.init(tempdir)
+
+        # This bit of magic should prevent us from needing to create a full 
duplicate
+        #  of all the objects in repo_path
+        with open(os.path.join(tempdir,".git/objects/info/alternates"), "w") 
as alternates:
+            alternates.write("%s/.git/objects" % repo_path)
+
+        # Get ready to rebase in tmprepo:  fetch from upstream, and create and
+        #  check out a branch 'oot-rebase' that matches the state of the
+        #  main repo in repo_path:
+        tmprepo.git.fetch("-n", repo_path,
+                          "%s:oot-rebase/%s" % (current_branch, 
current_branch),
+                          "%s:oot-rebase/%s" % (upstream_branch, 
upstream_branch))
+        tmprepo.git.checkout("oot-rebase/%s" % current_branch)
+
+        # And... rebase.
+        tmprepo.git.rebase("--preserve-merges",
+                           "--stat",
+                           "--strategy=recursive",
+                           "--strategy-option=patience",
+                           "oot-rebase/%s" % upstream_branch)
+
+        # Now 'oot-rebase' in tmprepo has the final state we need.  Push that
+        #  branch to a temporary branch ('branchname') in the main repo.
+        tmprepo.git.push("--force-with-lease=%s:%s" % (current_branch, 
latest_commit),
+                         repo_path,
+                         "oot-rebase/%s:%s" % (current_branch,branchname))
+
+        # And reset our original repo to this new branch and discard the 
'branchname' branch
+        repo.git.reset("--hard", branchname)
+        repo.git.branch("-D", branchname)
+        shutil.rmtree(tempdir)
+
     except git.exc.GitCommandError:
-        print("Rebase failed! Reverting rebase attempt.", file=sys.stderr)
-        repo.git.rebase("--abort")
+        print("Rebase failed!")
+        shutil.rmtree(tempdir)
         return False
 
     repo.git.submodule("update", "--init", "--recursive")
 
-    tagname = "snapshot-%s" % datetime.datetime.now().strftime('%Y%m%d%H%M')
+    # For the sake of future rollbacks, tag the repo in the
+    #  state we've just set up
     repo.create_tag(tagname)
+
     print("Tagged as %s" % tagname)
 
     print("Local hacks:")

-- 
To view, visit https://gerrit.wikimedia.org/r/386331
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I4f56f4339c5440281fd7e9821d026ebc5265507a
Gerrit-PatchSet: 10
Gerrit-Project: operations/puppet
Gerrit-Branch: production
Gerrit-Owner: Andrew Bogott <abog...@wikimedia.org>
Gerrit-Reviewer: Andrew Bogott <abog...@wikimedia.org>
Gerrit-Reviewer: BryanDavis <bda...@wikimedia.org>
Gerrit-Reviewer: Chad <ch...@wikimedia.org>
Gerrit-Reviewer: Chasemp <r...@wikimedia.org>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to