git-p4: add submit --conflict option and config varaiable

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>

Pete Wyckoff committed Sep 9, 2012 at 16:16 UTC 6bbfd1372d2aa5b856fc7fb1616cb06c982fcb83
3 files changed +105 -5
Documentation/git-p4.txt
+11
@@ -280,6 +280,13 @@ These options can be used to modify 'git p4 submit' behavior.
280 submit manually or revert. This option always stops after the
281 first (oldest) commit. Git tags are not exported to p4.
282
283 +--conflict=(ask|skip|quit)::
284 + Conflicts can occur when applying a commit to p4. When this
285 + happens, the default behavior ("ask") is to prompt whether to
286 + skip this commit and continue, or quit. This option can be used
287 + to bypass the prompt, causing conflicting commits to be automatically
288 + skipped, or to quit trying to apply commits, without prompting.
289 +
290 Rebase options
291 ~~~~~~~~~~~~~~
292 These options can be used to modify 'git p4 rebase' behavior.
@@ -530,6 +537,10 @@ git-p4.labelExportRegexp::
537 Only p4 labels matching this regular expression will be exported. The
538 default value is '[a-zA-Z0-9_\-.]+$'.
539
540 +git-p4.conflict::
541 + Specify submit behavior when a conflict with p4 is found, as per
542 + --conflict. The default behavior is 'ask'.
543 +
544 IMPLEMENTATION DETAILS
545 ----------------------
546 * Changesets from p4 are imported using git fast-import.
git-p4.py
+31 -5
@@ -844,6 +844,9 @@ class P4RollBack(Command):
844 return True
845
846 class P4Submit(Command, P4UserMap):
847 +
848 + conflict_behavior_choices = ("ask", "skip", "quit")
849 +
850 def __init__(self):
851 Command.__init__(self)
852 P4UserMap.__init__(self)
@@ -855,6 +858,8 @@ class P4Submit(Command, P4UserMap):
858 optparse.make_option("--export-labels", dest="exportLabels", action="store_true"),
859 optparse.make_option("--dry-run", "-n", dest="dry_run", action="store_true"),
860 optparse.make_option("--prepare-p4-only", dest="prepare_p4_only", action="store_true"),
861 + optparse.make_option("--conflict", dest="conflict_behavior",
862 + choices=self.conflict_behavior_choices)
863 ]
864 self.description = "Submit changes from git to the perforce depot."
865 self.usage += " [name of git branch to submit into perforce depot]"
@@ -863,6 +868,7 @@ class P4Submit(Command, P4UserMap):
868 self.preserveUser = gitConfig("git-p4.preserveUser").lower() == "true"
869 self.dry_run = False
870 self.prepare_p4_only = False
871 + self.conflict_behavior = None
872 self.isWindows = (platform.system() == "Windows")
873 self.exportLabels = False
874 self.p4HasMoveCommand = p4_has_command("move")
@@ -1445,6 +1451,16 @@ class P4Submit(Command, P4UserMap):
1451 if not self.canChangeChangelists():
1452 die("Cannot preserve user names without p4 super-user or admin permissions")
1453
1454 + # if not set from the command line, try the config file
1455 + if self.conflict_behavior is None:
1456 + val = gitConfig("git-p4.conflict")
1457 + if val:
1458 + if val not in self.conflict_behavior_choices:
1459 + die("Invalid value '%s' for config git-p4.conflict" % val)
1460 + else:
1461 + val = "ask"
1462 + self.conflict_behavior = val
1463 +
1464 if self.verbose:
1465 print "Origin branch is " + self.origin
1466
@@ -1557,11 +1573,21 @@ class P4Submit(Command, P4UserMap):
1573 if i < last:
1574 quit = False
1575 while True:
1560 - print "What do you want to do?"
1561 - response = raw_input("[s]kip this commit but apply"
1562 - " the rest, or [q]uit? ")
1563 - if not response:
1564 - continue
1576 + # prompt for what to do, or use the option/variable
1577 + if self.conflict_behavior == "ask":
1578 + print "What do you want to do?"
1579 + response = raw_input("[s]kip this commit but apply"
1580 + " the rest, or [q]uit? ")
1581 + if not response:
1582 + continue
1583 + elif self.conflict_behavior == "skip":
1584 + response = "s"
1585 + elif self.conflict_behavior == "quit":
1586 + response = "q"
1587 + else:
1588 + die("Unknown conflict_behavior '%s'" %
1589 + self.conflict_behavior)
1590 +
1591 if response[0] == "s":
1592 print "Skipping this commit, but applying the rest"
1593 break
t/t9815-git-p4-submit-fail.sh
+63
@@ -108,6 +108,69 @@ test_expect_success 'conflict on first of two commits, quit' '
108 )
109 '
110
111 +test_expect_success 'conflict cli and config options' '
112 + test_when_finished cleanup_git &&
113 + git p4 clone --dest="$git" //depot &&
114 + (
115 + cd "$git" &&
116 + git p4 submit --conflict=ask &&
117 + git p4 submit --conflict=skip &&
118 + git p4 submit --conflict=quit &&
119 + test_expect_code 2 git p4 submit --conflict=foo &&
120 + test_expect_code 2 git p4 submit --conflict &&
121 + git config git-p4.conflict foo &&
122 + test_expect_code 1 git p4 submit &&
123 + git config --unset git-p4.conflict &&
124 + git p4 submit
125 + )
126 +'
127 +
128 +test_expect_success 'conflict on first of two commits, --conflict=skip' '
129 + test_when_finished cleanup_git &&
130 + git p4 clone --dest="$git" //depot &&
131 + (
132 + cd "$cli" &&
133 + p4 open file1 &&
134 + echo line9 >>file1 &&
135 + p4 submit -d "line9 in file1"
136 + ) &&
137 + (
138 + cd "$git" &&
139 + git config git-p4.skipSubmitEdit true &&
140 + # this submit should cause a conflict
141 + echo line10 >>file1 &&
142 + git add file1 &&
143 + git commit -m "line10 in file1 will conflict" &&
144 + # but this commit is okay
145 + test_commit "okay_commit_after_auto_skip" &&
146 + test_expect_code 1 git p4 submit --conflict=skip >out &&
147 + test_i18ngrep "Applied only the commits" out
148 + )
149 +'
150 +
151 +test_expect_success 'conflict on first of two commits, --conflict=quit' '
152 + test_when_finished cleanup_git &&
153 + git p4 clone --dest="$git" //depot &&
154 + (
155 + cd "$cli" &&
156 + p4 open file1 &&
157 + echo line11 >>file1 &&
158 + p4 submit -d "line11 in file1"
159 + ) &&
160 + (
161 + cd "$git" &&
162 + git config git-p4.skipSubmitEdit true &&
163 + # this submit should cause a conflict
164 + echo line12 >>file1 &&
165 + git add file1 &&
166 + git commit -m "line12 in file1 will conflict" &&
167 + # but this commit is okay
168 + test_commit "okay_commit_after_auto_quit" &&
169 + test_expect_code 1 git p4 submit --conflict=quit >out &&
170 + test_i18ngrep "No commits applied" out
171 + )
172 +'
173 +
174 #
175 # Cleanup after submit fail, all cases. Some modifications happen
176 # before trying to apply the patch. Make sure these are unwound