git p4: add submit --prepare-p4-only option

This option can be used to prepare the client workspace for submission, only. It does not invoke the final "p4 submit". A message describes how to proceed, either submitting the changes or reverting. Signed-off-by: Pete Wyckoff <pw@padd.com> Acked-by: Luke Diamand <luke@diamand.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Pete Wyckoff committed Sep 9, 2012 at 16:16 UTC 728b7ad8bb6491d1d8bcd7498e06474b15812d52
3 files changed +77
Documentation/git-p4.txt
+7
@@ -273,6 +273,13 @@ These options can be used to modify 'git p4 submit' behavior.
273 Show just what commits would be submitted to p4; do not change
274 state in git or p4.
275
276 +--prepare-p4-only::
277 + Apply a commit to the p4 workspace, opening, adding and deleting
278 + files in p4 as for a normal submit operation. Do not issue the
279 + final "p4 submit", but instead print a message about how to
280 + submit manually or revert. This option always stops after the
281 + first (oldest) commit. Git tags are not exported to p4.
282 +
283 Rebase options
284 ~~~~~~~~~~~~~~
285 These options can be used to modify 'git p4 rebase' behavior.
git-p4.py
+46
@@ -854,6 +854,7 @@ class P4Submit(Command, P4UserMap):
854 optparse.make_option("--preserve-user", dest="preserveUser", action="store_true"),
855 optparse.make_option("--export-labels", dest="exportLabels", action="store_true"),
856 optparse.make_option("--dry-run", "-n", dest="dry_run", action="store_true"),
857 + optparse.make_option("--prepare-p4-only", dest="prepare_p4_only", action="store_true"),
858 ]
859 self.description = "Submit changes from git to the perforce depot."
860 self.usage += " [name of git branch to submit into perforce depot]"
@@ -861,6 +862,7 @@ class P4Submit(Command, P4UserMap):
862 self.detectRenames = False
863 self.preserveUser = gitConfig("git-p4.preserveUser").lower() == "true"
864 self.dry_run = False
865 + self.prepare_p4_only = False
866 self.isWindows = (platform.system() == "Windows")
867 self.exportLabels = False
868 self.p4HasMoveCommand = p4_has_command("move")
@@ -1270,6 +1272,41 @@ class P4Submit(Command, P4UserMap):
1272 tmpFile.write(submitTemplate + separatorLine + diff + newdiff)
1273 tmpFile.close()
1274
1275 + if self.prepare_p4_only:
1276 + #
1277 + # Leave the p4 tree prepared, and the submit template around
1278 + # and let the user decide what to do next
1279 + #
1280 + print
1281 + print "P4 workspace prepared for submission."
1282 + print "To submit or revert, go to client workspace"
1283 + print " " + self.clientPath
1284 + print
1285 + print "To submit, use \"p4 submit\" to write a new description,"
1286 + print "or \"p4 submit -i %s\" to use the one prepared by" \
1287 + " \"git p4\"." % fileName
1288 + print "You can delete the file \"%s\" when finished." % fileName
1289 +
1290 + if self.preserveUser and p4User and not self.p4UserIsMe(p4User):
1291 + print "To preserve change ownership by user %s, you must\n" \
1292 + "do \"p4 change -f <change>\" after submitting and\n" \
1293 + "edit the User field."
1294 + if pureRenameCopy:
1295 + print "After submitting, renamed files must be re-synced."
1296 + print "Invoke \"p4 sync -f\" on each of these files:"
1297 + for f in pureRenameCopy:
1298 + print " " + f
1299 +
1300 + print
1301 + print "To revert the changes, use \"p4 revert ...\", and delete"
1302 + print "the submit template file \"%s\"" % fileName
1303 + if filesToAdd:
1304 + print "Since the commit adds new files, they must be deleted:"
1305 + for f in filesToAdd:
1306 + print " " + f
1307 + print
1308 + return True
1309 +
1310 #
1311 # Let the user edit the change description, then submit it.
1312 #
@@ -1370,6 +1407,9 @@ class P4Submit(Command, P4UserMap):
1407
1408 if self.dry_run:
1409 print "Would create p4 label %s for tag" % name
1410 + elif self.prepare_p4_only:
1411 + print "Not creating p4 label %s for tag due to option" \
1412 + " --prepare-p4-only" % name
1413 else:
1414 p4_write_pipe(["label", "-i"], labelTemplate)
1415
@@ -1510,6 +1550,10 @@ class P4Submit(Command, P4UserMap):
1550 if ok:
1551 applied.append(commit)
1552 else:
1553 + if self.prepare_p4_only and i < last:
1554 + print "Processing only the first commit due to option" \
1555 + " --prepare-p4-only"
1556 + break
1557 if i < last:
1558 quit = False
1559 while True:
@@ -1532,6 +1576,8 @@ class P4Submit(Command, P4UserMap):
1576
1577 if self.dry_run:
1578 pass
1579 + elif self.prepare_p4_only:
1580 + pass
1581 elif len(commits) == len(applied):
1582 print "All commits applied!"
1583
t/t9807-git-p4-submit.sh
+24
@@ -375,6 +375,30 @@ test_expect_success 'description with Jobs section and bogus following text' '
375 make_job $(cat jobname) &&
376 test_must_fail git p4 submit 2>err &&
377 test_i18ngrep "Unknown field name" err
378 + ) &&
379 + (
380 + cd "$cli" &&
381 + p4 revert desc6 &&
382 + rm desc6
383 + )
384 +'
385 +
386 +test_expect_success 'submit --prepare-p4-only' '
387 + test_when_finished cleanup_git &&
388 + git p4 clone --dest="$git" //depot &&
389 + (
390 + cd "$git" &&
391 + echo prep-only-add >prep-only-add &&
392 + git add prep-only-add &&
393 + git commit -m "prep only add" &&
394 + git p4 submit --prepare-p4-only >out &&
395 + test_i18ngrep "prepared for submission" out &&
396 + test_i18ngrep "must be deleted" out
397 + ) &&
398 + (
399 + cd "$cli" &&
400 + test_path_is_file prep-only-add &&
401 + p4 fstat -T action prep-only-add | grep -w add
402 )
403 '
404