aboutsummaryrefslogtreecommitdiff
path: root/git-p4.py
diff options
context:
space:
mode:
Diffstat (limited to 'git-p4.py')
-rwxr-xr-xgit-p4.py96
1 files changed, 67 insertions, 29 deletions
diff --git a/git-p4.py b/git-p4.py
index 242217821..13bf44768 100755
--- a/git-p4.py
+++ b/git-p4.py
@@ -267,6 +267,10 @@ def p4_revert(f):
def p4_reopen(type, f):
p4_system(["reopen", "-t", type, wildcard_encode(f)])
+def p4_reopen_in_change(changelist, files):
+ cmd = ["reopen", "-c", str(changelist)] + files
+ p4_system(cmd)
+
def p4_move(src, dest):
p4_system(["move", "-k", wildcard_encode(src), wildcard_encode(dest)])
@@ -1010,18 +1014,20 @@ class LargeFileSystem(object):
steps."""
if self.exceedsLargeFileThreshold(relPath, contents) or self.hasLargeFileExtension(relPath):
contentTempFile = self.generateTempFile(contents)
- (git_mode, contents, localLargeFile) = self.generatePointer(contentTempFile)
-
- # Move temp file to final location in large file system
- largeFileDir = os.path.dirname(localLargeFile)
- if not os.path.isdir(largeFileDir):
- os.makedirs(largeFileDir)
- shutil.move(contentTempFile, localLargeFile)
- self.addLargeFile(relPath)
- if gitConfigBool('git-p4.largeFilePush'):
- self.pushFile(localLargeFile)
- if verbose:
- sys.stderr.write("%s moved to large file system (%s)\n" % (relPath, localLargeFile))
+ (pointer_git_mode, contents, localLargeFile) = self.generatePointer(contentTempFile)
+ if pointer_git_mode:
+ git_mode = pointer_git_mode
+ if localLargeFile:
+ # Move temp file to final location in large file system
+ largeFileDir = os.path.dirname(localLargeFile)
+ if not os.path.isdir(largeFileDir):
+ os.makedirs(largeFileDir)
+ shutil.move(contentTempFile, localLargeFile)
+ self.addLargeFile(relPath)
+ if gitConfigBool('git-p4.largeFilePush'):
+ self.pushFile(localLargeFile)
+ if verbose:
+ sys.stderr.write("%s moved to large file system (%s)\n" % (relPath, localLargeFile))
return (git_mode, contents)
class MockLFS(LargeFileSystem):
@@ -1061,6 +1067,9 @@ class GitLFS(LargeFileSystem):
the actual content. Return also the new location of the actual
content.
"""
+ if os.path.getsize(contentFile) == 0:
+ return (None, '', None)
+
pointerProcess = subprocess.Popen(
['git', 'lfs', 'pointer', '--file=' + contentFile],
stdout=subprocess.PIPE
@@ -1294,6 +1303,12 @@ class P4Submit(Command, P4UserMap):
optparse.make_option("--conflict", dest="conflict_behavior",
choices=self.conflict_behavior_choices),
optparse.make_option("--branch", dest="branch"),
+ optparse.make_option("--shelve", dest="shelve", action="store_true",
+ help="Shelve instead of submit. Shelved files are reverted, "
+ "restoring the workspace to the state before the shelve"),
+ optparse.make_option("--update-shelve", dest="update_shelve", action="store", type="int",
+ metavar="CHANGELIST",
+ help="update an existing shelved changelist, implies --shelve")
]
self.description = "Submit changes from git to the perforce depot."
self.usage += " [name of git branch to submit into perforce depot]"
@@ -1301,6 +1316,8 @@ class P4Submit(Command, P4UserMap):
self.detectRenames = False
self.preserveUser = gitConfigBool("git-p4.preserveUser")
self.dry_run = False
+ self.shelve = False
+ self.update_shelve = None
self.prepare_p4_only = False
self.conflict_behavior = None
self.isWindows = (platform.system() == "Windows")
@@ -1469,7 +1486,7 @@ class P4Submit(Command, P4UserMap):
return 1
return 0
- def prepareSubmitTemplate(self):
+ def prepareSubmitTemplate(self, changelist=None):
"""Run "p4 change -o" to grab a change specification template.
This does not use "p4 -G", as it is nice to keep the submission
template in original order, since a human might edit it.
@@ -1481,7 +1498,11 @@ class P4Submit(Command, P4UserMap):
template = ""
inFilesSection = False
- for line in p4_read_pipe_lines(['change', '-o']):
+ args = ['change', '-o']
+ if changelist:
+ args.append(str(changelist))
+
+ for line in p4_read_pipe_lines(args):
if line.endswith("\r\n"):
line = line[:-2] + "\n"
if inFilesSection:
@@ -1580,11 +1601,14 @@ class P4Submit(Command, P4UserMap):
editedFiles = set()
pureRenameCopy = set()
filesToChangeExecBit = {}
+ all_files = list()
for line in diff:
diff = parseDiffTreeEntry(line)
modifier = diff['status']
path = diff['src']
+ all_files.append(path)
+
if modifier == "M":
p4_edit(path)
if isModeExecChanged(diff['src_mode'], diff['dst_mode']):
@@ -1710,6 +1734,10 @@ class P4Submit(Command, P4UserMap):
mode = filesToChangeExecBit[f]
setP4ExecBit(f, mode)
+ if self.update_shelve:
+ print("all_files = %s" % str(all_files))
+ p4_reopen_in_change(self.update_shelve, all_files)
+
#
# Build p4 change description, starting with the contents
# of the git commit message.
@@ -1718,7 +1746,7 @@ class P4Submit(Command, P4UserMap):
logMessage = logMessage.strip()
(logMessage, jobs) = self.separate_jobs_from_description(logMessage)
- template = self.prepareSubmitTemplate()
+ template = self.prepareSubmitTemplate(self.update_shelve)
submitTemplate = self.prepareLogMessage(template, logMessage, jobs)
if self.preserveUser:
@@ -1790,7 +1818,17 @@ class P4Submit(Command, P4UserMap):
if self.isWindows:
message = message.replace("\r\n", "\n")
submitTemplate = message[:message.index(separatorLine)]
- p4_write_pipe(['submit', '-i'], submitTemplate)
+
+ if self.update_shelve:
+ p4_write_pipe(['shelve', '-r', '-i'], submitTemplate)
+ elif self.shelve:
+ p4_write_pipe(['shelve', '-i'], submitTemplate)
+ else:
+ p4_write_pipe(['submit', '-i'], submitTemplate)
+ # The rename/copy happened by applying a patch that created a
+ # new file. This leaves it writable, which confuses p4.
+ for f in pureRenameCopy:
+ p4_sync(f, "-f")
if self.preserveUser:
if p4User:
@@ -1800,23 +1838,20 @@ class P4Submit(Command, P4UserMap):
changelist = self.lastP4Changelist()
self.modifyChangelistUser(changelist, p4User)
- # The rename/copy happened by applying a patch that created a
- # new file. This leaves it writable, which confuses p4.
- for f in pureRenameCopy:
- p4_sync(f, "-f")
submitted = True
finally:
# skip this patch
- if not submitted:
- print "Submission cancelled, undoing p4 changes."
- for f in editedFiles:
+ if not submitted or self.shelve:
+ if self.shelve:
+ print ("Reverting shelved files.")
+ else:
+ print ("Submission cancelled, undoing p4 changes.")
+ for f in editedFiles | filesToDelete:
p4_revert(f)
for f in filesToAdd:
p4_revert(f)
os.remove(f)
- for f in filesToDelete:
- p4_revert(f)
os.remove(fileName)
return submitted
@@ -1912,6 +1947,9 @@ class P4Submit(Command, P4UserMap):
if len(self.origin) == 0:
self.origin = upstream
+ if self.update_shelve:
+ self.shelve = True
+
if self.preserveUser:
if not self.canChangeChangelists():
die("Cannot preserve user names without p4 super-user or admin permissions")
@@ -2072,13 +2110,13 @@ class P4Submit(Command, P4UserMap):
break
chdir(self.oldWorkingDirectory)
-
+ shelved_applied = "shelved" if self.shelve else "applied"
if self.dry_run:
pass
elif self.prepare_p4_only:
pass
elif len(commits) == len(applied):
- print "All commits applied!"
+ print ("All commits {0}!".format(shelved_applied))
sync = P4Sync()
if self.branch:
@@ -2090,9 +2128,9 @@ class P4Submit(Command, P4UserMap):
else:
if len(applied) == 0:
- print "No commits applied."
+ print ("No commits {0}.".format(shelved_applied))
else:
- print "Applied only the commits marked with '*':"
+ print ("{0} only the commits marked with '*':".format(shelved_applied.capitalize()))
for c in commits:
if c in applied:
star = "*"