diff --git a/Documentation/git-p4.txt b/Documentation/git-p4.txt index c83aaf39c33505ead72d523f278620fcc6f8f757..1bbf43d1572c7ff82afed3a91a2f871e0a8d3750 100644 --- a/Documentation/git-p4.txt +++ b/Documentation/git-p4.txt @@ -303,6 +303,11 @@ These options can be used to modify 'git p4 submit' behavior. submit manually or revert. This option always stops after the first (oldest) commit. Git tags are not exported to p4. +--shelve:: + Instead of submitting create a series of shelved changelists. + After creating each shelve, the relevant files are reverted/deleted. + If you have multiple commits pending multiple shelves will be created. + --conflict=(ask|skip|quit):: Conflicts can occur when applying a commit to p4. When this happens, the default behavior ("ask") is to prompt whether to diff --git a/git-p4.py b/git-p4.py index fd5ca524626c40823371422e52a3457fd1d45579..0c4f2afd2382092fbe9c8d79525e797c687e33a8 100755 --- a/git-p4.py +++ b/git-p4.py @@ -1289,6 +1289,9 @@ def __init__(self): 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"), ] self.description = "Submit changes from git to the perforce depot." self.usage += " [name of git branch to submit into perforce depot]" @@ -1296,6 +1299,7 @@ def __init__(self): self.detectRenames = False self.preserveUser = gitConfigBool("git-p4.preserveUser") self.dry_run = False + self.shelve = False self.prepare_p4_only = False self.conflict_behavior = None self.isWindows = (platform.system() == "Windows") @@ -1785,7 +1789,14 @@ def applyCommit(self, id): if self.isWindows: message = message.replace("\r\n", "\n") submitTemplate = message[:message.index(separatorLine)] - p4_write_pipe(['submit', '-i'], submitTemplate) + if 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: @@ -1795,23 +1806,20 @@ def applyCommit(self, id): 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 @@ -2067,13 +2075,13 @@ def run(self, args): 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: @@ -2085,9 +2093,9 @@ def run(self, args): 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 = "*" diff --git a/t/t9807-git-p4-submit.sh b/t/t9807-git-p4-submit.sh index 593152817dadaf1804f4a851c51b8bf1cbf52db9..42a5fada58a9c7c7e146153eafd31c6bb3022a9a 100755 --- a/t/t9807-git-p4-submit.sh +++ b/t/t9807-git-p4-submit.sh @@ -413,6 +413,37 @@ test_expect_success 'submit --prepare-p4-only' ' ) ' +test_expect_success 'submit --shelve' ' + test_when_finished cleanup_git && + git p4 clone --dest="$git" //depot && + ( + cd "$cli" && + p4 revert ... && + cd "$git" && + git config git-p4.skipSubmitEdit true && + test_commit "shelveme1" && + git p4 submit --origin=HEAD^ && + + echo 654321 >shelveme2.t && + echo 123456 >>shelveme1.t && + git add shelveme* && + git commit -m"shelvetest" && + git p4 submit --shelve --origin=HEAD^ && + + test_path_is_file shelveme1.t && + test_path_is_file shelveme2.t + ) && + ( + cd "$cli" && + change=$(p4 -G changes -s shelved -m 1 //depot/... | \ + marshal_dump change) && + p4 describe -S $change | grep shelveme2 && + p4 describe -S $change | grep 123456 && + test_path_is_file shelveme1.t && + test_path_is_missing shelveme2.t + ) +' + test_expect_success 'kill p4d' ' kill_p4d '