def createEquivalentMergeCommit(db, review, user, old_head, old_upstream, new_head, new_upstream, onto_branch=None): repository = review.repository old_upstream_name = repository.findInterestingTag(db, old_upstream.sha1) or old_upstream.sha1 new_upstream_name = repository.findInterestingTag(db, new_upstream.sha1) or new_upstream.sha1 if onto_branch: merged_thing = "branch '%s'" % onto_branch else: merged_thing = "commit '%s'" % new_upstream_name commit_message = """\ Merge %(merged_thing)s into %(review.branch.name)s This commit was generated automatically by Critic as an equivalent merge to the rebase of the commits %(old_upstream_name)s..%(old_head.sha1)s onto the %(merged_thing)s.""" % { "merged_thing": merged_thing, "review.branch.name": review.branch.name, "old_upstream_name": old_upstream_name, "old_head.sha1": old_head.sha1 } merge_sha1 = repository.run('commit-tree', new_head.tree, '-p', old_head.sha1, '-p', new_upstream.sha1, input=commit_message, env=gitutils.getGitEnvironment()).strip() merge = gitutils.Commit.fromSHA1(db, repository, merge_sha1) gituser_id = merge.author.getGitUserId(db) cursor = db.cursor() cursor.execute("""INSERT INTO commits (sha1, author_gituser, commit_gituser, author_time, commit_time) VALUES (%s, %s, %s, %s, %s) RETURNING id""", (merge.sha1, gituser_id, gituser_id, timestamp(merge.author.time), timestamp(merge.committer.time))) merge.id = cursor.fetchone()[0] cursor.executemany("INSERT INTO edges (parent, child) VALUES (%s, %s)", [(old_head.getId(db), merge.id), (new_upstream.getId(db), merge.id)]) # Need to commit the transaction to make the new commit available # to other database sessions right away, specifically so that the # changeset service can see it. db.commit() return merge
def replayRebase(db, review, user, old_head, old_upstream, new_head, new_upstream, onto_branch=None): repository = review.repository old_upstream_name = repository.findInterestingTag(db, old_upstream.sha1) or old_upstream.sha1 if onto_branch: new_upstream_name = "branch '%s'" % onto_branch else: new_upstream_name = "commit '%s'" % (repository.findInterestingTag(db, new_upstream.sha1) or new_upstream.sha1) commit_message = """\ Rebased %(review.branch.name)s onto %(new_upstream_name)s This commit was generated automatically by Critic to "replay" the rebase of the commits %(old_upstream_name)s..%(old_head.sha1)s onto the %(new_upstream_name)s.""" % { "review.branch.name": review.branch.name, "old_head.sha1": old_head.sha1, "old_upstream_name": old_upstream_name, "new_upstream_name": new_upstream_name } original_sha1 = repository.run( 'commit-tree', old_head.tree, '-p', old_upstream.sha1, env=gitutils.getGitEnvironment(), input=commit_message).strip() with repository.workcopy(original_sha1) as workcopy: with repository.temporaryref(new_upstream) as new_upstream_ref, \ repository.temporaryref(original_sha1) as original_ref: workcopy.run("fetch", "--quiet", "origin", "%s:refs/heads/temporary" % new_upstream_ref, "%s:refs/heads/original" % original_ref) workcopy.run("checkout", "refs/heads/temporary") returncode, stdout, stderr = workcopy.run( "cherry-pick", "refs/heads/original", env=gitutils.getGitEnvironment(), check_errors=False) # If the rebase produced conflicts, just stage and commit them: if returncode != 0: # Reset any submodule gitlinks with conflicts: since we don't # have the submodules checked out, "git commit --all" below # may fail to index them. for line in stdout.splitlines(): if line.startswith("CONFLICT (submodule):"): submodule_path = line.split()[-1] workcopy.run("reset", "--", submodule_path, check_errors=False) # Then stage and commit the result, with conflict markers and all. workcopy.run("commit", "--all", "--reuse-message=%s" % original_sha1, env=gitutils.getGitEnvironment()) rebased_sha1 = workcopy.run("rev-parse", "HEAD").strip() workcopy.run("push", "origin", "HEAD:refs/keepalive/" + rebased_sha1) return gitutils.Commit.fromSHA1(db, repository, rebased_sha1)
def replayRebase(db, review, user, old_head, old_upstream, new_head, new_upstream, onto_branch=None): repository = review.repository old_upstream_name = repository.findInterestingTag( db, old_upstream.sha1) or old_upstream.sha1 if onto_branch: new_upstream_name = "branch '%s'" % onto_branch else: new_upstream_name = "commit '%s'" % (repository.findInterestingTag( db, new_upstream.sha1) or new_upstream.sha1) commit_message = """\ Rebased %(review.branch.name)s onto %(new_upstream_name)s This commit was generated automatically by Critic to "replay" the rebase of the commits %(old_upstream_name)s..%(old_head.sha1)s onto the %(new_upstream_name)s.""" % { "review.branch.name": review.branch.name, "old_head.sha1": old_head.sha1, "old_upstream_name": old_upstream_name, "new_upstream_name": new_upstream_name } original_sha1 = repository.run('commit-tree', old_head.tree, '-p', old_upstream.sha1, env=gitutils.getGitEnvironment(), input=commit_message).strip() with repository.workcopy(original_sha1) as workcopy: with repository.temporaryref(new_upstream) as new_upstream_ref, \ repository.temporaryref(original_sha1) as original_ref: workcopy.run("fetch", "--quiet", "origin", "%s:refs/heads/temporary" % new_upstream_ref, "%s:refs/heads/original" % original_ref) workcopy.run("checkout", "refs/heads/temporary") returncode, stdout, stderr = workcopy.run( "cherry-pick", "refs/heads/original", env=gitutils.getGitEnvironment(), check_errors=False) # If the rebase produced conflicts, just stage and commit them: if returncode != 0: # Reset any submodule gitlinks with conflicts: since we don't # have the submodules checked out, "git commit --all" below # may fail to index them. for line in stdout.splitlines(): if line.startswith("CONFLICT (submodule):"): submodule_path = line.split()[-1] workcopy.run("reset", "--", submodule_path, check_errors=False) # Then stage and commit the result, with conflict markers and all. workcopy.run("commit", "--all", "--reuse-message=%s" % original_sha1, env=gitutils.getGitEnvironment()) rebased_sha1 = workcopy.run("rev-parse", "HEAD").strip() workcopy.run("push", "origin", "HEAD:refs/keepalive/" + rebased_sha1) return gitutils.Commit.fromSHA1(db, repository, rebased_sha1)
def createEquivalentMergeCommit(db, review, user, old_head, old_upstream, new_head, new_upstream, onto_branch=None): repository = review.repository old_upstream_name = repository.findInterestingTag( db, old_upstream.sha1) or old_upstream.sha1 new_upstream_name = repository.findInterestingTag( db, new_upstream.sha1) or new_upstream.sha1 if onto_branch: merged_thing = "branch '%s'" % onto_branch else: merged_thing = "commit '%s'" % new_upstream_name commit_message = """\ Merge %(merged_thing)s into %(review.branch.name)s This commit was generated automatically by Critic as an equivalent merge to the rebase of the commits %(old_upstream_name)s..%(old_head.sha1)s onto the %(merged_thing)s.""" % { "merged_thing": merged_thing, "review.branch.name": review.branch.name, "old_upstream_name": old_upstream_name, "old_head.sha1": old_head.sha1 } merge_sha1 = repository.run('commit-tree', new_head.tree, '-p', old_head.sha1, '-p', new_upstream.sha1, input=commit_message, env=gitutils.getGitEnvironment()).strip() merge = gitutils.Commit.fromSHA1(db, repository, merge_sha1) gituser_id = merge.author.getGitUserId(db) cursor = db.cursor() cursor.execute( """INSERT INTO commits (sha1, author_gituser, commit_gituser, author_time, commit_time) VALUES (%s, %s, %s, %s, %s) RETURNING id""", (merge.sha1, gituser_id, gituser_id, timestamp( merge.author.time), timestamp(merge.committer.time))) merge.id = cursor.fetchone()[0] cursor.executemany("INSERT INTO edges (parent, child) VALUES (%s, %s)", [(old_head.getId(db), merge.id), (new_upstream.getId(db), merge.id)]) # Need to commit the transaction to make the new commit available # to other database sessions right away, specifically so that the # changeset service can see it. db.commit() return merge