mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-17 06:09:19 +00:00
Bug 1500188 - Don't modify working tree, index or HEAD when pushing to try with git. r=releng-reviewers,sheehan,ahal
Differential Revision: https://phabricator.services.mozilla.com/D214215
This commit is contained in:
parent
1644cb07e3
commit
cb4c0526d5
@ -8,6 +8,7 @@ import os
|
||||
import re
|
||||
import shutil
|
||||
import subprocess
|
||||
import uuid
|
||||
from contextlib import contextmanager
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
@ -989,21 +990,68 @@ class GitRepository(Repository):
|
||||
`changed_files` may contain a dict of file paths and their contents,
|
||||
see `stage_changes`.
|
||||
"""
|
||||
if changed_files:
|
||||
self.stage_changes(changed_files)
|
||||
current_head = self.head_ref
|
||||
|
||||
self._run(
|
||||
"-c",
|
||||
"commit.gpgSign=false",
|
||||
"commit",
|
||||
"--allow-empty",
|
||||
"-m",
|
||||
commit_message,
|
||||
def data(content):
|
||||
return f"data {len(content)}\n{content}"
|
||||
|
||||
author = self._run("var", "GIT_AUTHOR_IDENT").strip()
|
||||
committer = self._run("var", "GIT_COMMITTER_IDENT").strip()
|
||||
# A random enough temporary branch name that shouldn't conflict with
|
||||
# anything else, even in the machtry namespace.
|
||||
branch = str(uuid.uuid4())
|
||||
# The following fast-import script creates a new commit on a temporary
|
||||
# branch that it deletes at the end, based off the current HEAD, and
|
||||
# adding or modifying the files from `changed_files`.
|
||||
# fast-import will output the sha1 for that temporary commit on stdout
|
||||
# (via `get-mark`).
|
||||
fast_import = "\n".join(
|
||||
[
|
||||
f"commit refs/machtry/{branch}",
|
||||
"mark :1",
|
||||
f"author {author}",
|
||||
f"committer {committer}",
|
||||
data(commit_message),
|
||||
f"from {current_head}",
|
||||
"\n".join(
|
||||
f"M 100644 inline {path}\n{data(content)}"
|
||||
for path, content in (changed_files or {}).items()
|
||||
),
|
||||
f"reset refs/machtry/{branch}",
|
||||
"from 0000000000000000000000000000000000000000",
|
||||
"get-mark :1",
|
||||
"",
|
||||
]
|
||||
)
|
||||
|
||||
yield "HEAD"
|
||||
cmd = (str(self._tool), "fast-import", "--quiet")
|
||||
stdout = subprocess.check_output(
|
||||
cmd,
|
||||
cwd=self.path,
|
||||
env=self._env,
|
||||
input=fast_import,
|
||||
text=True,
|
||||
)
|
||||
|
||||
self._run("reset", "HEAD~")
|
||||
try_head = stdout.strip()
|
||||
yield try_head
|
||||
|
||||
# Keep trace of the temporary push in the reflog, as if we did actually commit.
|
||||
# This does update HEAD for a small window of time.
|
||||
# If we raced with something else that changed the HEAD after we created our
|
||||
# commit, update-ref will fail and print an error message. Only the update in
|
||||
# the reflog would be lost in this case.
|
||||
self._run("update-ref", "-m", "mach try: push", "HEAD", try_head, current_head)
|
||||
# Likewise, if we raced with something else that updated the HEAD between our
|
||||
# two update-ref, update-ref will fail and print an error message.
|
||||
self._run(
|
||||
"update-ref",
|
||||
"-m",
|
||||
"mach try: restore",
|
||||
"HEAD",
|
||||
current_head,
|
||||
try_head,
|
||||
)
|
||||
|
||||
def get_last_modified_time_for_file(self, path: Path):
|
||||
"""Return last modified in VCS time for the specified file."""
|
||||
|
@ -4,6 +4,8 @@
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
import textwrap
|
||||
import uuid
|
||||
|
||||
import mozunit
|
||||
import pytest
|
||||
@ -16,15 +18,28 @@ def test_push_to_try(repo, monkeypatch):
|
||||
vcs = get_repository_object(repo.dir)
|
||||
|
||||
captured_commands = []
|
||||
captured_inputs = []
|
||||
|
||||
def fake_run(*args, **kwargs):
|
||||
cmd = args[0]
|
||||
captured_commands.append(cmd)
|
||||
if cmd[1] == "var" and cmd[2] in ("GIT_AUTHOR_IDENT", "GIT_COMMITTER_IDENT"):
|
||||
return "FooBar <foobar@example.com> 0 +0000"
|
||||
if cmd[1:] == ("rev-parse", "HEAD"):
|
||||
return "0987654321098765432109876543210987654321"
|
||||
if cmd[1:] == ("fast-import", "--quiet"):
|
||||
if input := kwargs.get("input"):
|
||||
captured_inputs.append(input)
|
||||
return "1234567890123456789012345678901234567890"
|
||||
if os.path.basename(cmd[0]).startswith("hg") and cmd[1] == "--version":
|
||||
return "version 6.7"
|
||||
|
||||
def fake_uuid():
|
||||
return "974284fd-f395-4a15-a9d7-814a71241242"
|
||||
|
||||
monkeypatch.setattr(subprocess, "check_output", fake_run)
|
||||
monkeypatch.setattr(subprocess, "check_call", fake_run)
|
||||
monkeypatch.setattr(uuid, "uuid4", fake_uuid)
|
||||
|
||||
vcs.push_to_try(
|
||||
commit_message,
|
||||
@ -49,33 +64,62 @@ def test_push_to_try(repo, monkeypatch):
|
||||
(str(tool), "push-to-try", "-m", commit_message),
|
||||
(str(tool), "revert", "-a"),
|
||||
]
|
||||
expected_inputs = []
|
||||
else:
|
||||
expected = [
|
||||
(str(tool), "cinnabar", "--version"),
|
||||
(
|
||||
str(tool),
|
||||
"add",
|
||||
os.path.join(vcs.path, "extra-file"),
|
||||
os.path.join(vcs.path, "other", "extra-file"),
|
||||
),
|
||||
(
|
||||
str(tool),
|
||||
"-c",
|
||||
"commit.gpgSign=false",
|
||||
"commit",
|
||||
"--allow-empty",
|
||||
"-m",
|
||||
commit_message,
|
||||
),
|
||||
(str(tool), "rev-parse", "HEAD"),
|
||||
(str(tool), "var", "GIT_AUTHOR_IDENT"),
|
||||
(str(tool), "var", "GIT_COMMITTER_IDENT"),
|
||||
(str(tool), "fast-import", "--quiet"),
|
||||
(
|
||||
str(tool),
|
||||
"-c",
|
||||
"cinnabar.data=never",
|
||||
"push",
|
||||
"hg::ssh://hg.mozilla.org/try",
|
||||
"+HEAD:refs/heads/branches/default/tip",
|
||||
"+1234567890123456789012345678901234567890:refs/heads/branches/default/tip",
|
||||
),
|
||||
(
|
||||
str(tool),
|
||||
"update-ref",
|
||||
"-m",
|
||||
"mach try: push",
|
||||
"HEAD",
|
||||
"1234567890123456789012345678901234567890",
|
||||
"0987654321098765432109876543210987654321",
|
||||
),
|
||||
(
|
||||
str(tool),
|
||||
"update-ref",
|
||||
"-m",
|
||||
"mach try: restore",
|
||||
"HEAD",
|
||||
"0987654321098765432109876543210987654321",
|
||||
"1234567890123456789012345678901234567890",
|
||||
),
|
||||
]
|
||||
expected_inputs = [
|
||||
textwrap.dedent(
|
||||
f"""\
|
||||
commit refs/machtry/974284fd-f395-4a15-a9d7-814a71241242
|
||||
mark :1
|
||||
author FooBar <foobar@example.com> 0 +0000
|
||||
committer FooBar <foobar@example.com> 0 +0000
|
||||
data {len(commit_message)}
|
||||
{commit_message}
|
||||
from 0987654321098765432109876543210987654321
|
||||
M 100644 inline extra-file
|
||||
data 7
|
||||
content
|
||||
M 100644 inline other/extra-file
|
||||
data 8
|
||||
content2
|
||||
reset refs/machtry/974284fd-f395-4a15-a9d7-814a71241242
|
||||
from 0000000000000000000000000000000000000000
|
||||
get-mark :1
|
||||
"""
|
||||
),
|
||||
(str(tool), "reset", "HEAD~"),
|
||||
]
|
||||
|
||||
for i, value in enumerate(captured_commands):
|
||||
@ -83,6 +127,11 @@ def test_push_to_try(repo, monkeypatch):
|
||||
|
||||
assert len(captured_commands) == len(expected)
|
||||
|
||||
for i, value in enumerate(captured_inputs):
|
||||
assert value == expected_inputs[i]
|
||||
|
||||
assert len(captured_inputs) == len(expected_inputs)
|
||||
|
||||
|
||||
def test_push_to_try_missing_extensions(repo, monkeypatch):
|
||||
if repo.vcs != "git":
|
||||
|
Loading…
x
Reference in New Issue
Block a user