5 # Author: Simon Hausmann <hausmann@kde.org>
6 # License: MIT <http://www.opensource.org/licenses/mit-license.php>
9 import os
, string
, shelve
, stat
10 import getopt
, sys
, marshal
13 cmd
= "p4 -G %s" % cmd
14 pipe
= os
.popen(cmd
, "rb")
19 entry
= marshal
.load(pipe
)
35 opts
, args
= getopt
.getopt(sys
.argv
[1:], "", [ "continue", "git-dir=", "origin=", "reset", "master=",
36 "submit-log-subst=", "log-substitutions=" ])
37 except getopt
.GetoptError
:
38 print "fixme, syntax error"
42 logSubstitutions
["<enter description here>"] = "%log%"
43 logSubstitutions
["\tDetails:"] = "\tDetails: %log%"
44 gitdir
= os
.environ
.get("GIT_DIR", "")
57 elif o
== "--continue":
62 elif o
== "--submit-log-subst":
64 value
= a
.split("%")[1]
65 logSubstitutions
[key
] = value
66 elif o
== "--log-substitutions":
67 for line
in open(a
, "r").readlines():
68 tokens
= line
[:-1].split("=")
69 logSubstitutions
[tokens
[0]] = tokens
[1]
74 os
.environ
["GIT_DIR"] = gitdir
76 configFile
= gitdir
+ "/p4-git-sync.cfg"
83 sys
.stderr
.write(msg
+ "\n")
87 if os
.system(cmd
) != 0:
88 die("command failed: %s" % cmd
)
92 if len(p4CmdList("opened ...")) > 0:
93 die("You have files opened with perforce! Close them before starting the sync.")
96 if len(config
) > 0 and not reset
:
97 die("Cannot start sync. Previous sync config found at %s" % configFile
)
99 #if len(os.popen("git-update-index --refresh").read()) > 0:
100 # die("Your working tree is not clean. Check with git status!")
103 for line
in os
.popen("git-rev-list --no-merges %s..%s" % (origin
, master
)).readlines():
104 commits
.append(line
[:-1])
107 config
["commits"] = commits
109 # print "Cleaning index..."
110 # system("git checkout -f")
112 def prepareLogMessage(template
, message
):
115 substs
= logSubstitutions
116 for k
in substs
.keys():
117 substs
[k
] = substs
[k
].replace("%log%", message
)
119 for line
in template
.split("\n"):
120 if line
.startswith("#"):
121 result
+= line
+ "\n"
125 for key
in substs
.keys():
126 if line
.find(key
) != -1:
128 if value
!= "@remove@":
129 result
+= line
.replace(key
, value
) + "\n"
134 result
+= line
+ "\n"
139 print "Applying %s" % (os
.popen("git-log --max-count=1 --pretty=oneline %s" % id).read())
140 diff
= os
.popen("git diff-tree -r --name-status \"%s^\" \"%s\"" % (id, id)).readlines()
142 filesToDelete
= set()
145 path
= line
[1:].strip()
147 system("p4 edit %s" % path
)
148 elif modifier
== "A":
150 if path
in filesToDelete
:
151 filesToDelete
.remove(path
)
152 elif modifier
== "D":
153 filesToDelete
.add(path
)
154 if path
in filesToAdd
:
155 filesToAdd
.remove(path
)
157 die("unknown modifier %s for %s" % (modifier
, path
))
159 system("git-diff-files --name-only -z | git-update-index --remove -z --stdin")
160 system("git cherry-pick --no-commit \"%s\"" % id)
163 system("p4 add %s" % f
)
164 for f
in filesToDelete
:
165 system("p4 revert %s" % f
)
166 system("p4 delete %s" % f
)
170 for log
in os
.popen("git-cat-file commit %s" % id).readlines():
177 if len(logMessage
) > 0:
179 logMessage
+= log
+ "\n"
181 template
= os
.popen("p4 change -o").read()
182 fileName
= "submit.txt"
183 file = open(fileName
, "w+")
184 file.write(prepareLogMessage(template
, logMessage
))
186 print "Perforce submit template written as %s. Please review/edit and then use p4 submit -i < %s to submit directly!" % (fileName
, fileName
)
190 config
= shelve
.open(configFile
, writeback
=True)
195 commits
= config
.get("commits", [])
200 commits
= commits
[1:]
201 config
["commits"] = commits
206 if len(commits
) == 0:
208 print "No changes found to apply between %s and current HEAD" % origin
210 print "All changes applied!"
211 os
.remove(configFile
)