$ ./p4-patch-create.py > test.p4patch
※注: このスクリプトでは、p4 diff
コマンドの出力を使用しています。p4 diff
で出力されない、新規ファイルなどの内容は出力されないことに注意してください。
$ ./p4-patch-apply.py < test.p4patch
ここでは、手順 (1) で作成したパッチファイルを適用しています。
p4 edit
コマンドも自動的に実行します。
#!/usr/bin/env python
#######################################################
# Perforce tool
# Create p4patch file using p4 diff command.
#
# Usage:
# $ ./p4-patch-create.py > test.p4patch
#
#######################################################
import subprocess
def do_command(command):
return subprocess.check_output(command, shell=True)
def get_p4path(path):
return do_command('p4 where ' + path).split()[0]
### First value of returned tuple means that it should be written.
def convert_path(line):
if line.startswith('--- '):
return (False, )
if line.startswith('+++ '):
line = '## ' + get_p4path(line.split()[1])
return (True, line)
if __name__ == '__main__':
for line in do_command('p4 diff -du').split('\n'):
ret = convert_path(line)
if (ret[0]):
print(ret[1])
#!/usr/bin/env python
#######################################################
# Perforce tool
# Apply p4patch file to your local files.
#
# Usage:
# $ ./p4-patch-apply.py < test.p4patch
#
#######################################################
import subprocess
import sys
def do_p4edit(path):
subprocess.call('p4 edit ' + path, shell=True)
def get_local_path(path):
output = subprocess.check_output('p4 where ' + path, shell=True)
return output.split()[2]
def apply_patch(patch_text):
p = subprocess.Popen('patch -p0 -N', shell=True, stdin=subprocess.PIPE)
p.stdin.write(patch_text)
p.stdin.close()
### If the first value of returned value is True,
### it means that the second value is a local file path.
### Otherwise, the second value is the same as the passed parameter.
def convert_path(line):
if line.startswith('## '):
local_path = get_local_path(line.split()[1])
return (True, local_path)
return (False, line)
if __name__ == '__main__':
patch_text = ''
for line in sys.stdin:
line = line.rstrip('\r\n')
ret = convert_path(line)
if (ret[0]):
patch_text += '--- ' + ret[1] + '\n'
patch_text += '+++ ' + ret[1] + '\n'
do_p4edit(ret[1])
else:
patch_text += ret[1] + '\n'
print('')
apply_patch(patch_text)
結論から言うと、p4 diff コマンドでは、GNU patch コマンドが扱える形式のパッチファイルを作ることはできません。 仮に近いものが作れたとしても、次のような理由により、他のユーザーはそのパッチファイルを適用することができません。
p4 diff
コマンドには unified 形式の diff を出力する -du
オプションがあるが、ファイルパスが Perforce の独自形式のパスになっている。そこで、ここでは、以下のようなアプローチで解決しています。
.p4patch
とします。.p4patch
) を適用するときは、独自のスクリプトを使い、パッチファイル内のファイルパスを、そのクライアントのローカルファイルパスに書き換えてから適用する。作成するパッチファイル内には、以下のように Perforce のパス形式を含めるようにします。
##
で始まっている行が、p4patch ファイル独自の Perforce パスを示している行です。
## //Project/dir1/dir2/sample.txt
@@ -1,1 +1,1 @@
- AAA
+ BBB
そして、パッチファイルを適用するときに、##
で始まる Perforce パスを、そのユーザのローカルパスに変換してから適用します。
--- /home/jack/p4work/Project/dir1/dir2/sample.txt
+++ /home/jack/p4work/Project/dir1/dir2/sample.txt
@@ -1,1 +1,1 @@
- AAA
+ BBB