概要
Perforceの学習記録を残す目的で投稿しました。
簡単に記載していますので、ご了承ください。
サブミット前後のファイルをローカルフォルダに格納する。
実行コマンド
py test.py
test.py
import subprocess
import os
import re
import pathlib
def run_p4_binary(cmd):
"""p4 コマンドを実行して stdout を bytes で返す"""
result = subprocess.run(
["p4"] + cmd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
if result.returncode != 0:
raise RuntimeError(result.stderr.decode("utf-8", errors="ignore"))
return result.stdout # bytes
def parse_describe_output(output):
"""
p4 describe -s の出力から
[(depot_path, rev)] のリストを返す
"""
files = []
for line in output.splitlines():
m = re.match(r"\.\.\. (//.+)#(\d+)", line)
if m:
depot_path = m.group(1)
rev = int(m.group(2))
files.append((depot_path, rev))
return files
def make_filename_from_depot_path(depot_path):
"""depot パスから元のファイル名を取得"""
p = pathlib.PurePosixPath(depot_path)
return p.name
def save_file(depot_path, rev, out_dir):
"""
p4 print -q でファイルを取得して保存(バイナリ完全対応)
"""
# -q を付けることでヘッダ行を出さない
content = run_p4_binary(["print", "-q", f"{depot_path}#{rev}"])
filename = make_filename_from_depot_path(depot_path)
out_path = os.path.join(out_dir, filename)
# バイナリとしてそのまま保存
with open(out_path, "wb") as f:
f.write(content)
print(f"Saved: {out_path}")
def export_change_files(cl_number, base_dir="output"):
before_dir = os.path.join(base_dir, "00_修正前")
after_dir = os.path.join(base_dir, "99_修正後")
os.makedirs(before_dir, exist_ok=True)
os.makedirs(after_dir, exist_ok=True)
# describe はテキストで十分
desc = subprocess.run(
["p4", "describe", "-s", str(cl_number)],
capture_output=True,
text=True
).stdout
files = parse_describe_output(desc)
for depot_path, rev in files:
# 修正後(新)
save_file(depot_path, rev, after_dir)
# 修正前(旧)
if rev > 1:
save_file(depot_path, rev - 1, before_dir)
else:
print(f"Skipping old version for {depot_path} (rev=1)")
if __name__ == "__main__":
cl = input("チェンジリスト番号を入力してください: ")
export_change_files(cl)