git-p4: add submit --conflict option and config varaiable
authorPete Wyckoff <pw@padd.com>
Sun, 9 Sep 2012 20:16:13 +0000 (16:16 -0400)
committerJunio C Hamano <gitster@pobox.com>
Mon, 17 Sep 2012 04:52:53 +0000 (21:52 -0700)
This allows specifying what to do when a conflict
happens when applying a commit to p4, automating the
interactive prompt.

Signed-off-by: Pete Wyckoff <pw@padd.com>
Acked-by: Luke Diamand <luke@diamand.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/git-p4.txt
git-p4.py
t/t9815-git-p4-submit-fail.sh

index 4be42902eea5c6eebf58cbb1d300ae8e5432f09e..beff6229c8cc4541ca3a8ddd0faf724fceb439e7 100644 (file)
@@ -280,6 +280,13 @@ 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.
 
+--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
+       skip this commit and continue, or quit.  This option can be used
+       to bypass the prompt, causing conflicting commits to be automatically
+       skipped, or to quit trying to apply commits, without prompting.
+
 Rebase options
 ~~~~~~~~~~~~~~
 These options can be used to modify 'git p4 rebase' behavior.
@@ -530,6 +537,10 @@ git-p4.labelExportRegexp::
        Only p4 labels matching this regular expression will be exported. The
        default value is '[a-zA-Z0-9_\-.]+$'.
 
+git-p4.conflict::
+       Specify submit behavior when a conflict with p4 is found, as per
+       --conflict.  The default behavior is 'ask'.
+
 IMPLEMENTATION DETAILS
 ----------------------
 * Changesets from p4 are imported using git fast-import.
index 2dd2b76b1c3057df3b484cf5973e978d7d37654c..96f6bc0a76a13a9109150a583b4285bdb63b4985 100755 (executable)
--- a/git-p4.py
+++ b/git-p4.py
@@ -844,6 +844,9 @@ class P4RollBack(Command):
         return True
 
 class P4Submit(Command, P4UserMap):
+
+    conflict_behavior_choices = ("ask", "skip", "quit")
+
     def __init__(self):
         Command.__init__(self)
         P4UserMap.__init__(self)
@@ -855,6 +858,8 @@ class P4Submit(Command, P4UserMap):
                 optparse.make_option("--export-labels", dest="exportLabels", action="store_true"),
                 optparse.make_option("--dry-run", "-n", dest="dry_run", action="store_true"),
                 optparse.make_option("--prepare-p4-only", dest="prepare_p4_only", action="store_true"),
+                optparse.make_option("--conflict", dest="conflict_behavior",
+                                     choices=self.conflict_behavior_choices)
         ]
         self.description = "Submit changes from git to the perforce depot."
         self.usage += " [name of git branch to submit into perforce depot]"
@@ -863,6 +868,7 @@ class P4Submit(Command, P4UserMap):
         self.preserveUser = gitConfig("git-p4.preserveUser").lower() == "true"
         self.dry_run = False
         self.prepare_p4_only = False
+        self.conflict_behavior = None
         self.isWindows = (platform.system() == "Windows")
         self.exportLabels = False
         self.p4HasMoveCommand = p4_has_command("move")
@@ -1445,6 +1451,16 @@ class P4Submit(Command, P4UserMap):
             if not self.canChangeChangelists():
                 die("Cannot preserve user names without p4 super-user or admin permissions")
 
+        # if not set from the command line, try the config file
+        if self.conflict_behavior is None:
+            val = gitConfig("git-p4.conflict")
+            if val:
+                if val not in self.conflict_behavior_choices:
+                    die("Invalid value '%s' for config git-p4.conflict" % val)
+            else:
+                val = "ask"
+            self.conflict_behavior = val
+
         if self.verbose:
             print "Origin branch is " + self.origin
 
@@ -1557,11 +1573,21 @@ class P4Submit(Command, P4UserMap):
                 if i < last:
                     quit = False
                     while True:
-                        print "What do you want to do?"
-                        response = raw_input("[s]kip this commit but apply"
-                                             " the rest, or [q]uit? ")
-                        if not response:
-                            continue
+                        # prompt for what to do, or use the option/variable
+                        if self.conflict_behavior == "ask":
+                            print "What do you want to do?"
+                            response = raw_input("[s]kip this commit but apply"
+                                                 " the rest, or [q]uit? ")
+                            if not response:
+                                continue
+                        elif self.conflict_behavior == "skip":
+                            response = "s"
+                        elif self.conflict_behavior == "quit":
+                            response = "q"
+                        else:
+                            die("Unknown conflict_behavior '%s'" %
+                                self.conflict_behavior)
+
                         if response[0] == "s":
                             print "Skipping this commit, but applying the rest"
                             break
index 1823cff12bf6b4b3a037a56632494c14de349ca5..d2b7b3d98d77a18657f536af54b159230a1ea057 100755 (executable)
@@ -108,6 +108,69 @@ test_expect_success 'conflict on first of two commits, quit' '
        )
 '
 
+test_expect_success 'conflict cli and config options' '
+       test_when_finished cleanup_git &&
+       git p4 clone --dest="$git" //depot &&
+       (
+               cd "$git" &&
+               git p4 submit --conflict=ask &&
+               git p4 submit --conflict=skip &&
+               git p4 submit --conflict=quit &&
+               test_expect_code 2 git p4 submit --conflict=foo &&
+               test_expect_code 2 git p4 submit --conflict &&
+               git config git-p4.conflict foo &&
+               test_expect_code 1 git p4 submit &&
+               git config --unset git-p4.conflict &&
+               git p4 submit
+       )
+'
+
+test_expect_success 'conflict on first of two commits, --conflict=skip' '
+       test_when_finished cleanup_git &&
+       git p4 clone --dest="$git" //depot &&
+       (
+               cd "$cli" &&
+               p4 open file1 &&
+               echo line9 >>file1 &&
+               p4 submit -d "line9 in file1"
+       ) &&
+       (
+               cd "$git" &&
+               git config git-p4.skipSubmitEdit true &&
+               # this submit should cause a conflict
+               echo line10 >>file1 &&
+               git add file1 &&
+               git commit -m "line10 in file1 will conflict" &&
+               # but this commit is okay
+               test_commit "okay_commit_after_auto_skip" &&
+               test_expect_code 1 git p4 submit --conflict=skip >out &&
+               test_i18ngrep "Applied only the commits" out
+       )
+'
+
+test_expect_success 'conflict on first of two commits, --conflict=quit' '
+       test_when_finished cleanup_git &&
+       git p4 clone --dest="$git" //depot &&
+       (
+               cd "$cli" &&
+               p4 open file1 &&
+               echo line11 >>file1 &&
+               p4 submit -d "line11 in file1"
+       ) &&
+       (
+               cd "$git" &&
+               git config git-p4.skipSubmitEdit true &&
+               # this submit should cause a conflict
+               echo line12 >>file1 &&
+               git add file1 &&
+               git commit -m "line12 in file1 will conflict" &&
+               # but this commit is okay
+               test_commit "okay_commit_after_auto_quit" &&
+               test_expect_code 1 git p4 submit --conflict=quit >out &&
+               test_i18ngrep "No commits applied" out
+       )
+'
+
 #
 # Cleanup after submit fail, all cases.  Some modifications happen
 # before trying to apply the patch.  Make sure these are unwound