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>
This commit is contained in:
Pete Wyckoff 2012-09-09 16:16:13 -04:00 коммит произвёл Junio C Hamano
Родитель 728b7ad8bb
Коммит 6bbfd1372d
3 изменённых файлов: 105 добавлений и 5 удалений

Просмотреть файл

@ -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.

Просмотреть файл

@ -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

Просмотреть файл

@ -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