Merge branch 'pw/p4-submit-conflicts'
Add '--conflict' option to git-p4 subcommand to specify what action to take when conflicts are found during 'p4 submit'. * pw/p4-submit-conflicts: git-p4: add submit --conflict option and config varaiable git p4: add submit --prepare-p4-only option git p4: add submit --dry-run option git p4: accept -v for --verbose git p4: revert deleted files after submit cancel git p4: rearrange submit template construction git p4: test clean-up after failed submit, fix added files git p4: standardize submit cancel due to unchanged template git p4: move conflict prompt into run, add [q]uit input git p4: remove submit failure options [a]pply and [w]rite git p4: gracefully fail if some commits could not be applied git p4 test: remove bash-ism of combined export/assignmentmaint
commit
8db3865936
|
@ -163,7 +163,7 @@ All commands except clone accept these options.
|
||||||
--git-dir <dir>::
|
--git-dir <dir>::
|
||||||
Set the 'GIT_DIR' environment variable. See linkgit:git[1].
|
Set the 'GIT_DIR' environment variable. See linkgit:git[1].
|
||||||
|
|
||||||
--verbose::
|
--verbose, -v::
|
||||||
Provide more progress information.
|
Provide more progress information.
|
||||||
|
|
||||||
Sync options
|
Sync options
|
||||||
|
@ -269,6 +269,24 @@ These options can be used to modify 'git p4 submit' behavior.
|
||||||
Export tags from git as p4 labels. Tags found in git are applied
|
Export tags from git as p4 labels. Tags found in git are applied
|
||||||
to the perforce working directory.
|
to the perforce working directory.
|
||||||
|
|
||||||
|
--dry-run, -n::
|
||||||
|
Show just what commits would be submitted to p4; do not change
|
||||||
|
state in git or p4.
|
||||||
|
|
||||||
|
--prepare-p4-only::
|
||||||
|
Apply a commit to the p4 workspace, opening, adding and deleting
|
||||||
|
files in p4 as for a normal submit operation. Do not issue the
|
||||||
|
final "p4 submit", but instead print a message about how to
|
||||||
|
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
|
Rebase options
|
||||||
~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~
|
||||||
These options can be used to modify 'git p4 rebase' behavior.
|
These options can be used to modify 'git p4 rebase' behavior.
|
||||||
|
@ -519,6 +537,10 @@ git-p4.labelExportRegexp::
|
||||||
Only p4 labels matching this regular expression will be exported. The
|
Only p4 labels matching this regular expression will be exported. The
|
||||||
default value is '[a-zA-Z0-9_\-.]+$'.
|
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
|
IMPLEMENTATION DETAILS
|
||||||
----------------------
|
----------------------
|
||||||
* Changesets from p4 are imported using git fast-import.
|
* Changesets from p4 are imported using git fast-import.
|
||||||
|
|
239
git-p4.py
239
git-p4.py
|
@ -844,6 +844,9 @@ class P4RollBack(Command):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
class P4Submit(Command, P4UserMap):
|
class P4Submit(Command, P4UserMap):
|
||||||
|
|
||||||
|
conflict_behavior_choices = ("ask", "skip", "quit")
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
Command.__init__(self)
|
Command.__init__(self)
|
||||||
P4UserMap.__init__(self)
|
P4UserMap.__init__(self)
|
||||||
|
@ -853,12 +856,19 @@ class P4Submit(Command, P4UserMap):
|
||||||
# preserve the user, requires relevant p4 permissions
|
# preserve the user, requires relevant p4 permissions
|
||||||
optparse.make_option("--preserve-user", dest="preserveUser", action="store_true"),
|
optparse.make_option("--preserve-user", dest="preserveUser", action="store_true"),
|
||||||
optparse.make_option("--export-labels", dest="exportLabels", action="store_true"),
|
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.description = "Submit changes from git to the perforce depot."
|
||||||
self.usage += " [name of git branch to submit into perforce depot]"
|
self.usage += " [name of git branch to submit into perforce depot]"
|
||||||
self.origin = ""
|
self.origin = ""
|
||||||
self.detectRenames = False
|
self.detectRenames = False
|
||||||
self.preserveUser = gitConfig("git-p4.preserveUser").lower() == "true"
|
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.isWindows = (platform.system() == "Windows")
|
||||||
self.exportLabels = False
|
self.exportLabels = False
|
||||||
self.p4HasMoveCommand = p4_has_command("move")
|
self.p4HasMoveCommand = p4_has_command("move")
|
||||||
|
@ -1088,7 +1098,10 @@ class P4Submit(Command, P4UserMap):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def applyCommit(self, id):
|
def applyCommit(self, id):
|
||||||
print "Applying %s" % (read_pipe("git log --max-count=1 --pretty=oneline %s" % id))
|
"""Apply one commit, return True if it succeeded."""
|
||||||
|
|
||||||
|
print "Applying", read_pipe(["git", "show", "-s",
|
||||||
|
"--format=format:%h %s", id])
|
||||||
|
|
||||||
(p4User, gitEmail) = self.p4UserForCommit(id)
|
(p4User, gitEmail) = self.p4UserForCommit(id)
|
||||||
|
|
||||||
|
@ -1195,34 +1208,13 @@ class P4Submit(Command, P4UserMap):
|
||||||
patch_succeeded = True
|
patch_succeeded = True
|
||||||
|
|
||||||
if not patch_succeeded:
|
if not patch_succeeded:
|
||||||
print "What do you want to do?"
|
for f in editedFiles:
|
||||||
response = "x"
|
p4_revert(f)
|
||||||
while response != "s" and response != "a" and response != "w":
|
return False
|
||||||
response = raw_input("[s]kip this patch / [a]pply the patch forcibly "
|
|
||||||
"and with .rej files / [w]rite the patch to a file (patch.txt) ")
|
|
||||||
if response == "s":
|
|
||||||
print "Skipping! Good luck with the next patches..."
|
|
||||||
for f in editedFiles:
|
|
||||||
p4_revert(f)
|
|
||||||
for f in filesToAdd:
|
|
||||||
os.remove(f)
|
|
||||||
return
|
|
||||||
elif response == "a":
|
|
||||||
os.system(applyPatchCmd)
|
|
||||||
if len(filesToAdd) > 0:
|
|
||||||
print "You may also want to call p4 add on the following files:"
|
|
||||||
print " ".join(filesToAdd)
|
|
||||||
if len(filesToDelete):
|
|
||||||
print "The following files should be scheduled for deletion with p4 delete:"
|
|
||||||
print " ".join(filesToDelete)
|
|
||||||
die("Please resolve and submit the conflict manually and "
|
|
||||||
+ "continue afterwards with git p4 submit --continue")
|
|
||||||
elif response == "w":
|
|
||||||
system(diffcmd + " > patch.txt")
|
|
||||||
print "Patch saved to patch.txt in %s !" % self.clientPath
|
|
||||||
die("Please resolve and submit the conflict manually and "
|
|
||||||
"continue afterwards with git p4 submit --continue")
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Apply the patch for real, and do add/delete/+x handling.
|
||||||
|
#
|
||||||
system(applyPatchCmd)
|
system(applyPatchCmd)
|
||||||
|
|
||||||
for f in filesToAdd:
|
for f in filesToAdd:
|
||||||
|
@ -1236,6 +1228,10 @@ class P4Submit(Command, P4UserMap):
|
||||||
mode = filesToChangeExecBit[f]
|
mode = filesToChangeExecBit[f]
|
||||||
setP4ExecBit(f, mode)
|
setP4ExecBit(f, mode)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Build p4 change description, starting with the contents
|
||||||
|
# of the git commit message.
|
||||||
|
#
|
||||||
logMessage = extractLogMessageFromGitCommit(id)
|
logMessage = extractLogMessageFromGitCommit(id)
|
||||||
logMessage = logMessage.strip()
|
logMessage = logMessage.strip()
|
||||||
(logMessage, jobs) = self.separate_jobs_from_description(logMessage)
|
(logMessage, jobs) = self.separate_jobs_from_description(logMessage)
|
||||||
|
@ -1244,8 +1240,16 @@ class P4Submit(Command, P4UserMap):
|
||||||
submitTemplate = self.prepareLogMessage(template, logMessage, jobs)
|
submitTemplate = self.prepareLogMessage(template, logMessage, jobs)
|
||||||
|
|
||||||
if self.preserveUser:
|
if self.preserveUser:
|
||||||
submitTemplate = submitTemplate + ("\n######## Actual user %s, modified after commit\n" % p4User)
|
submitTemplate += "\n######## Actual user %s, modified after commit\n" % p4User
|
||||||
|
|
||||||
|
if self.checkAuthorship and not self.p4UserIsMe(p4User):
|
||||||
|
submitTemplate += "######## git author %s does not match your p4 account.\n" % gitEmail
|
||||||
|
submitTemplate += "######## Use option --preserve-user to modify authorship.\n"
|
||||||
|
submitTemplate += "######## Variable git-p4.skipUserNameCheck hides this message.\n"
|
||||||
|
|
||||||
|
separatorLine = "######## everything below this line is just the diff #######\n"
|
||||||
|
|
||||||
|
# diff
|
||||||
if os.environ.has_key("P4DIFF"):
|
if os.environ.has_key("P4DIFF"):
|
||||||
del(os.environ["P4DIFF"])
|
del(os.environ["P4DIFF"])
|
||||||
diff = ""
|
diff = ""
|
||||||
|
@ -1253,6 +1257,7 @@ class P4Submit(Command, P4UserMap):
|
||||||
diff += p4_read_pipe(['diff', '-du',
|
diff += p4_read_pipe(['diff', '-du',
|
||||||
wildcard_encode(editedFile)])
|
wildcard_encode(editedFile)])
|
||||||
|
|
||||||
|
# new file diff
|
||||||
newdiff = ""
|
newdiff = ""
|
||||||
for newFile in filesToAdd:
|
for newFile in filesToAdd:
|
||||||
newdiff += "==== new file ====\n"
|
newdiff += "==== new file ====\n"
|
||||||
|
@ -1263,13 +1268,7 @@ class P4Submit(Command, P4UserMap):
|
||||||
newdiff += "+" + line
|
newdiff += "+" + line
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
if self.checkAuthorship and not self.p4UserIsMe(p4User):
|
# change description file: submitTemplate, separatorLine, diff, newdiff
|
||||||
submitTemplate += "######## git author %s does not match your p4 account.\n" % gitEmail
|
|
||||||
submitTemplate += "######## Use option --preserve-user to modify authorship.\n"
|
|
||||||
submitTemplate += "######## Variable git-p4.skipUserNameCheck hides this message.\n"
|
|
||||||
|
|
||||||
separatorLine = "######## everything below this line is just the diff #######\n"
|
|
||||||
|
|
||||||
(handle, fileName) = tempfile.mkstemp()
|
(handle, fileName) = tempfile.mkstemp()
|
||||||
tmpFile = os.fdopen(handle, "w+")
|
tmpFile = os.fdopen(handle, "w+")
|
||||||
if self.isWindows:
|
if self.isWindows:
|
||||||
|
@ -1279,8 +1278,47 @@ class P4Submit(Command, P4UserMap):
|
||||||
tmpFile.write(submitTemplate + separatorLine + diff + newdiff)
|
tmpFile.write(submitTemplate + separatorLine + diff + newdiff)
|
||||||
tmpFile.close()
|
tmpFile.close()
|
||||||
|
|
||||||
|
if self.prepare_p4_only:
|
||||||
|
#
|
||||||
|
# Leave the p4 tree prepared, and the submit template around
|
||||||
|
# and let the user decide what to do next
|
||||||
|
#
|
||||||
|
print
|
||||||
|
print "P4 workspace prepared for submission."
|
||||||
|
print "To submit or revert, go to client workspace"
|
||||||
|
print " " + self.clientPath
|
||||||
|
print
|
||||||
|
print "To submit, use \"p4 submit\" to write a new description,"
|
||||||
|
print "or \"p4 submit -i %s\" to use the one prepared by" \
|
||||||
|
" \"git p4\"." % fileName
|
||||||
|
print "You can delete the file \"%s\" when finished." % fileName
|
||||||
|
|
||||||
|
if self.preserveUser and p4User and not self.p4UserIsMe(p4User):
|
||||||
|
print "To preserve change ownership by user %s, you must\n" \
|
||||||
|
"do \"p4 change -f <change>\" after submitting and\n" \
|
||||||
|
"edit the User field."
|
||||||
|
if pureRenameCopy:
|
||||||
|
print "After submitting, renamed files must be re-synced."
|
||||||
|
print "Invoke \"p4 sync -f\" on each of these files:"
|
||||||
|
for f in pureRenameCopy:
|
||||||
|
print " " + f
|
||||||
|
|
||||||
|
print
|
||||||
|
print "To revert the changes, use \"p4 revert ...\", and delete"
|
||||||
|
print "the submit template file \"%s\"" % fileName
|
||||||
|
if filesToAdd:
|
||||||
|
print "Since the commit adds new files, they must be deleted:"
|
||||||
|
for f in filesToAdd:
|
||||||
|
print " " + f
|
||||||
|
print
|
||||||
|
return True
|
||||||
|
|
||||||
|
#
|
||||||
|
# Let the user edit the change description, then submit it.
|
||||||
|
#
|
||||||
if self.edit_template(fileName):
|
if self.edit_template(fileName):
|
||||||
# read the edited message and submit
|
# read the edited message and submit
|
||||||
|
ret = True
|
||||||
tmpFile = open(fileName, "rb")
|
tmpFile = open(fileName, "rb")
|
||||||
message = tmpFile.read()
|
message = tmpFile.read()
|
||||||
tmpFile.close()
|
tmpFile.close()
|
||||||
|
@ -1304,14 +1342,18 @@ class P4Submit(Command, P4UserMap):
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# skip this patch
|
# skip this patch
|
||||||
|
ret = False
|
||||||
print "Submission cancelled, undoing p4 changes."
|
print "Submission cancelled, undoing p4 changes."
|
||||||
for f in editedFiles:
|
for f in editedFiles:
|
||||||
p4_revert(f)
|
p4_revert(f)
|
||||||
for f in filesToAdd:
|
for f in filesToAdd:
|
||||||
p4_revert(f)
|
p4_revert(f)
|
||||||
os.remove(f)
|
os.remove(f)
|
||||||
|
for f in filesToDelete:
|
||||||
|
p4_revert(f)
|
||||||
|
|
||||||
os.remove(fileName)
|
os.remove(fileName)
|
||||||
|
return ret
|
||||||
|
|
||||||
# Export git tags as p4 labels. Create a p4 label and then tag
|
# Export git tags as p4 labels. Create a p4 label and then tag
|
||||||
# with that.
|
# with that.
|
||||||
|
@ -1369,14 +1411,20 @@ class P4Submit(Command, P4UserMap):
|
||||||
for mapping in clientSpec.mappings:
|
for mapping in clientSpec.mappings:
|
||||||
labelTemplate += "\t%s\n" % mapping.depot_side.path
|
labelTemplate += "\t%s\n" % mapping.depot_side.path
|
||||||
|
|
||||||
p4_write_pipe(["label", "-i"], labelTemplate)
|
if self.dry_run:
|
||||||
|
print "Would create p4 label %s for tag" % name
|
||||||
|
elif self.prepare_p4_only:
|
||||||
|
print "Not creating p4 label %s for tag due to option" \
|
||||||
|
" --prepare-p4-only" % name
|
||||||
|
else:
|
||||||
|
p4_write_pipe(["label", "-i"], labelTemplate)
|
||||||
|
|
||||||
# Use the label
|
# Use the label
|
||||||
p4_system(["tag", "-l", name] +
|
p4_system(["tag", "-l", name] +
|
||||||
["%s@%s" % (mapping.depot_side.path, changelist) for mapping in clientSpec.mappings])
|
["%s@%s" % (mapping.depot_side.path, changelist) for mapping in clientSpec.mappings])
|
||||||
|
|
||||||
if verbose:
|
if verbose:
|
||||||
print "created p4 label for tag %s" % name
|
print "created p4 label for tag %s" % name
|
||||||
|
|
||||||
def run(self, args):
|
def run(self, args):
|
||||||
if len(args) == 0:
|
if len(args) == 0:
|
||||||
|
@ -1403,6 +1451,16 @@ class P4Submit(Command, P4UserMap):
|
||||||
if not self.canChangeChangelists():
|
if not self.canChangeChangelists():
|
||||||
die("Cannot preserve user names without p4 super-user or admin permissions")
|
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:
|
if self.verbose:
|
||||||
print "Origin branch is " + self.origin
|
print "Origin branch is " + self.origin
|
||||||
|
|
||||||
|
@ -1435,12 +1493,15 @@ class P4Submit(Command, P4UserMap):
|
||||||
os.makedirs(self.clientPath)
|
os.makedirs(self.clientPath)
|
||||||
|
|
||||||
chdir(self.clientPath)
|
chdir(self.clientPath)
|
||||||
print "Synchronizing p4 checkout..."
|
if self.dry_run:
|
||||||
if new_client_dir:
|
print "Would synchronize p4 checkout in %s" % self.clientPath
|
||||||
# old one was destroyed, and maybe nobody told p4
|
|
||||||
p4_sync("...", "-f")
|
|
||||||
else:
|
else:
|
||||||
p4_sync("...")
|
print "Synchronizing p4 checkout..."
|
||||||
|
if new_client_dir:
|
||||||
|
# old one was destroyed, and maybe nobody told p4
|
||||||
|
p4_sync("...", "-f")
|
||||||
|
else:
|
||||||
|
p4_sync("...")
|
||||||
self.check()
|
self.check()
|
||||||
|
|
||||||
commits = []
|
commits = []
|
||||||
|
@ -1487,14 +1548,64 @@ class P4Submit(Command, P4UserMap):
|
||||||
if gitConfig("git-p4.detectCopiesHarder", "--bool") == "true":
|
if gitConfig("git-p4.detectCopiesHarder", "--bool") == "true":
|
||||||
self.diffOpts += " --find-copies-harder"
|
self.diffOpts += " --find-copies-harder"
|
||||||
|
|
||||||
while len(commits) > 0:
|
#
|
||||||
commit = commits[0]
|
# Apply the commits, one at a time. On failure, ask if should
|
||||||
commits = commits[1:]
|
# continue to try the rest of the patches, or quit.
|
||||||
self.applyCommit(commit)
|
#
|
||||||
|
if self.dry_run:
|
||||||
|
print "Would apply"
|
||||||
|
applied = []
|
||||||
|
last = len(commits) - 1
|
||||||
|
for i, commit in enumerate(commits):
|
||||||
|
if self.dry_run:
|
||||||
|
print " ", read_pipe(["git", "show", "-s",
|
||||||
|
"--format=format:%h %s", commit])
|
||||||
|
ok = True
|
||||||
|
else:
|
||||||
|
ok = self.applyCommit(commit)
|
||||||
|
if ok:
|
||||||
|
applied.append(commit)
|
||||||
|
else:
|
||||||
|
if self.prepare_p4_only and i < last:
|
||||||
|
print "Processing only the first commit due to option" \
|
||||||
|
" --prepare-p4-only"
|
||||||
|
break
|
||||||
|
if i < last:
|
||||||
|
quit = False
|
||||||
|
while True:
|
||||||
|
# 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 len(commits) == 0:
|
if response[0] == "s":
|
||||||
print "All changes applied!"
|
print "Skipping this commit, but applying the rest"
|
||||||
chdir(self.oldWorkingDirectory)
|
break
|
||||||
|
if response[0] == "q":
|
||||||
|
print "Quitting"
|
||||||
|
quit = True
|
||||||
|
break
|
||||||
|
if quit:
|
||||||
|
break
|
||||||
|
|
||||||
|
chdir(self.oldWorkingDirectory)
|
||||||
|
|
||||||
|
if self.dry_run:
|
||||||
|
pass
|
||||||
|
elif self.prepare_p4_only:
|
||||||
|
pass
|
||||||
|
elif len(commits) == len(applied):
|
||||||
|
print "All commits applied!"
|
||||||
|
|
||||||
sync = P4Sync()
|
sync = P4Sync()
|
||||||
sync.run([])
|
sync.run([])
|
||||||
|
@ -1502,6 +1613,20 @@ class P4Submit(Command, P4UserMap):
|
||||||
rebase = P4Rebase()
|
rebase = P4Rebase()
|
||||||
rebase.rebase()
|
rebase.rebase()
|
||||||
|
|
||||||
|
else:
|
||||||
|
if len(applied) == 0:
|
||||||
|
print "No commits applied."
|
||||||
|
else:
|
||||||
|
print "Applied only the commits marked with '*':"
|
||||||
|
for c in commits:
|
||||||
|
if c in applied:
|
||||||
|
star = "*"
|
||||||
|
else:
|
||||||
|
star = " "
|
||||||
|
print star, read_pipe(["git", "show", "-s",
|
||||||
|
"--format=format:%h %s", c])
|
||||||
|
print "You will have to do 'git p4 sync' and rebase."
|
||||||
|
|
||||||
if gitConfig("git-p4.exportLabels", "--bool") == "true":
|
if gitConfig("git-p4.exportLabels", "--bool") == "true":
|
||||||
self.exportLabels = True
|
self.exportLabels = True
|
||||||
|
|
||||||
|
@ -1512,6 +1637,10 @@ class P4Submit(Command, P4UserMap):
|
||||||
missingGitTags = gitTags - p4Labels
|
missingGitTags = gitTags - p4Labels
|
||||||
self.exportGitTags(missingGitTags)
|
self.exportGitTags(missingGitTags)
|
||||||
|
|
||||||
|
# exit with error unless everything applied perfecly
|
||||||
|
if len(commits) != len(applied):
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
class View(object):
|
class View(object):
|
||||||
|
@ -3015,7 +3144,7 @@ def main():
|
||||||
|
|
||||||
args = sys.argv[2:]
|
args = sys.argv[2:]
|
||||||
|
|
||||||
options.append(optparse.make_option("--verbose", dest="verbose", action="store_true"))
|
options.append(optparse.make_option("--verbose", "-v", dest="verbose", action="store_true"))
|
||||||
if cmd.needsGit:
|
if cmd.needsGit:
|
||||||
options.append(optparse.make_option("--git-dir", dest="gitdir"))
|
options.append(optparse.make_option("--git-dir", dest="gitdir"))
|
||||||
|
|
||||||
|
|
|
@ -26,9 +26,10 @@ testid=${this_test#t}
|
||||||
git_p4_test_start=9800
|
git_p4_test_start=9800
|
||||||
P4DPORT=$((10669 + ($testid - $git_p4_test_start)))
|
P4DPORT=$((10669 + ($testid - $git_p4_test_start)))
|
||||||
|
|
||||||
export P4PORT=localhost:$P4DPORT
|
P4PORT=localhost:$P4DPORT
|
||||||
export P4CLIENT=client
|
P4CLIENT=client
|
||||||
export P4EDITOR=:
|
P4EDITOR=:
|
||||||
|
export P4PORT P4CLIENT P4EDITOR
|
||||||
|
|
||||||
db="$TRASH_DIRECTORY/db"
|
db="$TRASH_DIRECTORY/db"
|
||||||
cli=$(test-path-utils real_path "$TRASH_DIRECTORY/cli")
|
cli=$(test-path-utils real_path "$TRASH_DIRECTORY/cli")
|
||||||
|
|
|
@ -38,7 +38,7 @@ test_expect_success 'no config, unedited, say no' '
|
||||||
cd "$git" &&
|
cd "$git" &&
|
||||||
echo line >>file1 &&
|
echo line >>file1 &&
|
||||||
git commit -a -m "change 3 (not really)" &&
|
git commit -a -m "change 3 (not really)" &&
|
||||||
printf "bad response\nn\n" | git p4 submit &&
|
printf "bad response\nn\n" | test_expect_code 1 git p4 submit &&
|
||||||
p4 changes //depot/... >wc &&
|
p4 changes //depot/... >wc &&
|
||||||
test_line_count = 2 wc
|
test_line_count = 2 wc
|
||||||
)
|
)
|
||||||
|
|
|
@ -54,6 +54,47 @@ test_expect_success 'submit --origin' '
|
||||||
)
|
)
|
||||||
'
|
'
|
||||||
|
|
||||||
|
test_expect_success 'submit --dry-run' '
|
||||||
|
test_when_finished cleanup_git &&
|
||||||
|
git p4 clone --dest="$git" //depot &&
|
||||||
|
(
|
||||||
|
cd "$git" &&
|
||||||
|
test_commit "dry-run1" &&
|
||||||
|
test_commit "dry-run2" &&
|
||||||
|
git p4 submit --dry-run >out &&
|
||||||
|
test_i18ngrep "Would apply" out
|
||||||
|
) &&
|
||||||
|
(
|
||||||
|
cd "$cli" &&
|
||||||
|
test_path_is_missing "dry-run1.t" &&
|
||||||
|
test_path_is_missing "dry-run2.t"
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'submit --dry-run --export-labels' '
|
||||||
|
test_when_finished cleanup_git &&
|
||||||
|
git p4 clone --dest="$git" //depot &&
|
||||||
|
(
|
||||||
|
cd "$git" &&
|
||||||
|
echo dry-run1 >dry-run1 &&
|
||||||
|
git add dry-run1 &&
|
||||||
|
git commit -m "dry-run1" dry-run1 &&
|
||||||
|
git config git-p4.skipSubmitEdit true &&
|
||||||
|
git p4 submit &&
|
||||||
|
echo dry-run2 >dry-run2 &&
|
||||||
|
git add dry-run2 &&
|
||||||
|
git commit -m "dry-run2" dry-run2 &&
|
||||||
|
git tag -m "dry-run-tag1" dry-run-tag1 HEAD^ &&
|
||||||
|
git p4 submit --dry-run --export-labels >out &&
|
||||||
|
test_i18ngrep "Would create p4 label" out
|
||||||
|
) &&
|
||||||
|
(
|
||||||
|
cd "$cli" &&
|
||||||
|
test_path_is_file "dry-run1" &&
|
||||||
|
test_path_is_missing "dry-run2"
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
test_expect_success 'submit with allowSubmit' '
|
test_expect_success 'submit with allowSubmit' '
|
||||||
test_when_finished cleanup_git &&
|
test_when_finished cleanup_git &&
|
||||||
git p4 clone --dest="$git" //depot &&
|
git p4 clone --dest="$git" //depot &&
|
||||||
|
@ -334,6 +375,30 @@ test_expect_success 'description with Jobs section and bogus following text' '
|
||||||
make_job $(cat jobname) &&
|
make_job $(cat jobname) &&
|
||||||
test_must_fail git p4 submit 2>err &&
|
test_must_fail git p4 submit 2>err &&
|
||||||
test_i18ngrep "Unknown field name" err
|
test_i18ngrep "Unknown field name" err
|
||||||
|
) &&
|
||||||
|
(
|
||||||
|
cd "$cli" &&
|
||||||
|
p4 revert desc6 &&
|
||||||
|
rm desc6
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'submit --prepare-p4-only' '
|
||||||
|
test_when_finished cleanup_git &&
|
||||||
|
git p4 clone --dest="$git" //depot &&
|
||||||
|
(
|
||||||
|
cd "$git" &&
|
||||||
|
echo prep-only-add >prep-only-add &&
|
||||||
|
git add prep-only-add &&
|
||||||
|
git commit -m "prep only add" &&
|
||||||
|
git p4 submit --prepare-p4-only >out &&
|
||||||
|
test_i18ngrep "prepared for submission" out &&
|
||||||
|
test_i18ngrep "must be deleted" out
|
||||||
|
) &&
|
||||||
|
(
|
||||||
|
cd "$cli" &&
|
||||||
|
test_path_is_file prep-only-add &&
|
||||||
|
p4 fstat -T action prep-only-add | grep -w add
|
||||||
)
|
)
|
||||||
'
|
'
|
||||||
|
|
||||||
|
|
|
@ -160,9 +160,6 @@ test_expect_success 'cleanup after failure' '
|
||||||
# the cli file so that submit will get a conflict. Make sure that
|
# the cli file so that submit will get a conflict. Make sure that
|
||||||
# scrubbing doesn't make a mess of things.
|
# scrubbing doesn't make a mess of things.
|
||||||
#
|
#
|
||||||
# Assumes that git-p4 exits leaving the p4 file open, with the
|
|
||||||
# conflict-generating patch unapplied.
|
|
||||||
#
|
|
||||||
# This might happen only if the git repo is behind the p4 repo at
|
# This might happen only if the git repo is behind the p4 repo at
|
||||||
# submit time, and there is a conflict.
|
# submit time, and there is a conflict.
|
||||||
#
|
#
|
||||||
|
@ -181,14 +178,11 @@ test_expect_success 'do not scrub plain text' '
|
||||||
sed -i "s/^line5/line5 p4 edit/" file_text &&
|
sed -i "s/^line5/line5 p4 edit/" file_text &&
|
||||||
p4 submit -d "file5 p4 edit"
|
p4 submit -d "file5 p4 edit"
|
||||||
) &&
|
) &&
|
||||||
! git p4 submit &&
|
echo s | test_expect_code 1 git p4 submit &&
|
||||||
(
|
(
|
||||||
# exepct something like:
|
# make sure the file is not left open
|
||||||
# file_text - file(s) not opened on this client
|
|
||||||
# but not copious diff output
|
|
||||||
cd "$cli" &&
|
cd "$cli" &&
|
||||||
p4 diff file_text >wc &&
|
! p4 fstat -T action file_text
|
||||||
test_line_count = 1 wc
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
'
|
'
|
||||||
|
@ -343,44 +337,6 @@ test_expect_failure 'Add keywords in git which do not match the default p4 value
|
||||||
)
|
)
|
||||||
'
|
'
|
||||||
|
|
||||||
# Check that the existing merge conflict handling still works.
|
|
||||||
# Modify kwfile1.c in git, and delete in p4. We should be able
|
|
||||||
# to skip the git commit.
|
|
||||||
#
|
|
||||||
test_expect_success 'merge conflict handling still works' '
|
|
||||||
test_when_finished cleanup_git &&
|
|
||||||
(
|
|
||||||
cd "$cli" &&
|
|
||||||
echo "Hello:\$Id\$" >merge2.c &&
|
|
||||||
echo "World" >>merge2.c &&
|
|
||||||
p4 add -t ktext merge2.c &&
|
|
||||||
p4 submit -d "add merge test file"
|
|
||||||
) &&
|
|
||||||
git p4 clone --dest="$git" //depot &&
|
|
||||||
(
|
|
||||||
cd "$git" &&
|
|
||||||
sed -e "/Hello/d" merge2.c >merge2.c.tmp &&
|
|
||||||
mv merge2.c.tmp merge2.c &&
|
|
||||||
git add merge2.c &&
|
|
||||||
git commit -m "Modifying merge2.c"
|
|
||||||
) &&
|
|
||||||
(
|
|
||||||
cd "$cli" &&
|
|
||||||
p4 delete merge2.c &&
|
|
||||||
p4 submit -d "remove merge test file"
|
|
||||||
) &&
|
|
||||||
(
|
|
||||||
cd "$git" &&
|
|
||||||
test -f merge2.c &&
|
|
||||||
git config git-p4.skipSubmitEdit true &&
|
|
||||||
git config git-p4.attemptRCSCleanup true &&
|
|
||||||
!(echo "s" | git p4 submit) &&
|
|
||||||
git rebase --skip &&
|
|
||||||
! test -f merge2.c
|
|
||||||
)
|
|
||||||
'
|
|
||||||
|
|
||||||
|
|
||||||
test_expect_success 'kill p4d' '
|
test_expect_success 'kill p4d' '
|
||||||
kill_p4d
|
kill_p4d
|
||||||
'
|
'
|
||||||
|
|
|
@ -0,0 +1,429 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
test_description='git p4 submit failure handling'
|
||||||
|
|
||||||
|
. ./lib-git-p4.sh
|
||||||
|
|
||||||
|
test_expect_success 'start p4d' '
|
||||||
|
start_p4d
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'init depot' '
|
||||||
|
(
|
||||||
|
cd "$cli" &&
|
||||||
|
p4 client -o | sed "/LineEnd/s/:.*/:unix/" | p4 client -i &&
|
||||||
|
echo line1 >file1 &&
|
||||||
|
p4 add file1 &&
|
||||||
|
p4 submit -d "line1 in file1"
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'conflict on one commit' '
|
||||||
|
test_when_finished cleanup_git &&
|
||||||
|
git p4 clone --dest="$git" //depot &&
|
||||||
|
(
|
||||||
|
cd "$cli" &&
|
||||||
|
p4 open file1 &&
|
||||||
|
echo line2 >>file1 &&
|
||||||
|
p4 submit -d "line2 in file1"
|
||||||
|
) &&
|
||||||
|
(
|
||||||
|
# now this commit should cause a conflict
|
||||||
|
cd "$git" &&
|
||||||
|
git config git-p4.skipSubmitEdit true &&
|
||||||
|
echo line3 >>file1 &&
|
||||||
|
git add file1 &&
|
||||||
|
git commit -m "line3 in file1 will conflict" &&
|
||||||
|
test_expect_code 1 git p4 submit >out &&
|
||||||
|
test_i18ngrep "No commits applied" out
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'conflict on second of two commits' '
|
||||||
|
test_when_finished cleanup_git &&
|
||||||
|
git p4 clone --dest="$git" //depot &&
|
||||||
|
(
|
||||||
|
cd "$cli" &&
|
||||||
|
p4 open file1 &&
|
||||||
|
echo line3 >>file1 &&
|
||||||
|
p4 submit -d "line3 in file1"
|
||||||
|
) &&
|
||||||
|
(
|
||||||
|
cd "$git" &&
|
||||||
|
git config git-p4.skipSubmitEdit true &&
|
||||||
|
# this commit is okay
|
||||||
|
test_commit "first_commit_okay" &&
|
||||||
|
# now this submit should cause a conflict
|
||||||
|
echo line4 >>file1 &&
|
||||||
|
git add file1 &&
|
||||||
|
git commit -m "line4 in file1 will conflict" &&
|
||||||
|
test_expect_code 1 git p4 submit >out &&
|
||||||
|
test_i18ngrep "Applied only the commits" out
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'conflict on first of two commits, skip' '
|
||||||
|
test_when_finished cleanup_git &&
|
||||||
|
git p4 clone --dest="$git" //depot &&
|
||||||
|
(
|
||||||
|
cd "$cli" &&
|
||||||
|
p4 open file1 &&
|
||||||
|
echo line4 >>file1 &&
|
||||||
|
p4 submit -d "line4 in file1"
|
||||||
|
) &&
|
||||||
|
(
|
||||||
|
cd "$git" &&
|
||||||
|
git config git-p4.skipSubmitEdit true &&
|
||||||
|
# this submit should cause a conflict
|
||||||
|
echo line5 >>file1 &&
|
||||||
|
git add file1 &&
|
||||||
|
git commit -m "line5 in file1 will conflict" &&
|
||||||
|
# but this commit is okay
|
||||||
|
test_commit "okay_commit_after_skip" &&
|
||||||
|
echo s | test_expect_code 1 git p4 submit >out &&
|
||||||
|
test_i18ngrep "Applied only the commits" out
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'conflict on first of two commits, quit' '
|
||||||
|
test_when_finished cleanup_git &&
|
||||||
|
git p4 clone --dest="$git" //depot &&
|
||||||
|
(
|
||||||
|
cd "$cli" &&
|
||||||
|
p4 open file1 &&
|
||||||
|
echo line7 >>file1 &&
|
||||||
|
p4 submit -d "line7 in file1"
|
||||||
|
) &&
|
||||||
|
(
|
||||||
|
cd "$git" &&
|
||||||
|
git config git-p4.skipSubmitEdit true &&
|
||||||
|
# this submit should cause a conflict
|
||||||
|
echo line8 >>file1 &&
|
||||||
|
git add file1 &&
|
||||||
|
git commit -m "line8 in file1 will conflict" &&
|
||||||
|
# but this commit is okay
|
||||||
|
test_commit "okay_commit_after_quit" &&
|
||||||
|
echo q | test_expect_code 1 git p4 submit >out &&
|
||||||
|
test_i18ngrep "No commits applied" out
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
|
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
|
||||||
|
# properly. Put each one in a diff along with something that will
|
||||||
|
# obviously conflict. Make sure it is back to normal after.
|
||||||
|
#
|
||||||
|
|
||||||
|
test_expect_success 'cleanup edit p4 populate' '
|
||||||
|
(
|
||||||
|
cd "$cli" &&
|
||||||
|
echo text file >text &&
|
||||||
|
p4 add text &&
|
||||||
|
echo text+x file >text+x &&
|
||||||
|
chmod 755 text+x &&
|
||||||
|
p4 add text+x &&
|
||||||
|
p4 submit -d "populate p4"
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
|
setup_conflict() {
|
||||||
|
# clone before modifying file1 to force it to conflict
|
||||||
|
test_when_finished cleanup_git &&
|
||||||
|
git p4 clone --dest="$git" //depot &&
|
||||||
|
# ticks outside subshells
|
||||||
|
test_tick &&
|
||||||
|
(
|
||||||
|
cd "$cli" &&
|
||||||
|
p4 open file1 &&
|
||||||
|
echo $test_tick >>file1 &&
|
||||||
|
p4 submit -d "$test_tick in file1"
|
||||||
|
) &&
|
||||||
|
test_tick &&
|
||||||
|
(
|
||||||
|
cd "$git" &&
|
||||||
|
git config git-p4.skipSubmitEdit true &&
|
||||||
|
# easy conflict
|
||||||
|
echo $test_tick >>file1 &&
|
||||||
|
git add file1
|
||||||
|
# caller will add more and submit
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
test_expect_success 'cleanup edit after submit fail' '
|
||||||
|
setup_conflict &&
|
||||||
|
(
|
||||||
|
cd "$git" &&
|
||||||
|
echo another line >>text &&
|
||||||
|
git add text &&
|
||||||
|
git commit -m "conflict" &&
|
||||||
|
test_expect_code 1 git p4 submit
|
||||||
|
) &&
|
||||||
|
(
|
||||||
|
cd "$cli" &&
|
||||||
|
# make sure it is not open
|
||||||
|
! p4 fstat -T action text
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'cleanup add after submit fail' '
|
||||||
|
setup_conflict &&
|
||||||
|
(
|
||||||
|
cd "$git" &&
|
||||||
|
echo new file >textnew &&
|
||||||
|
git add textnew &&
|
||||||
|
git commit -m "conflict" &&
|
||||||
|
test_expect_code 1 git p4 submit
|
||||||
|
) &&
|
||||||
|
(
|
||||||
|
cd "$cli" &&
|
||||||
|
# make sure it is not there
|
||||||
|
# and that p4 thinks it is not added
|
||||||
|
# P4 returns 0 both for "not there but added" and
|
||||||
|
# "not there", so grep.
|
||||||
|
test_path_is_missing textnew &&
|
||||||
|
p4 fstat -T action textnew 2>&1 | grep "no such file"
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'cleanup delete after submit fail' '
|
||||||
|
setup_conflict &&
|
||||||
|
(
|
||||||
|
cd "$git" &&
|
||||||
|
git rm text+x &&
|
||||||
|
git commit -m "conflict" &&
|
||||||
|
test_expect_code 1 git p4 submit
|
||||||
|
) &&
|
||||||
|
(
|
||||||
|
cd "$cli" &&
|
||||||
|
# make sure it is there
|
||||||
|
test_path_is_file text+x &&
|
||||||
|
! p4 fstat -T action text+x
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'cleanup copy after submit fail' '
|
||||||
|
setup_conflict &&
|
||||||
|
(
|
||||||
|
cd "$git" &&
|
||||||
|
cp text text2 &&
|
||||||
|
git add text2 &&
|
||||||
|
git commit -m "conflict" &&
|
||||||
|
git config git-p4.detectCopies true &&
|
||||||
|
git config git-p4.detectCopiesHarder true &&
|
||||||
|
# make sure setup is okay
|
||||||
|
git diff-tree -r -C --find-copies-harder HEAD | grep text2 | grep C100 &&
|
||||||
|
test_expect_code 1 git p4 submit
|
||||||
|
) &&
|
||||||
|
(
|
||||||
|
cd "$cli" &&
|
||||||
|
test_path_is_missing text2 &&
|
||||||
|
p4 fstat -T action text2 2>&1 | grep "no such file"
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'cleanup rename after submit fail' '
|
||||||
|
setup_conflict &&
|
||||||
|
(
|
||||||
|
cd "$git" &&
|
||||||
|
git mv text text2 &&
|
||||||
|
git commit -m "conflict" &&
|
||||||
|
git config git-p4.detectRenames true &&
|
||||||
|
# make sure setup is okay
|
||||||
|
git diff-tree -r -M HEAD | grep text2 | grep R100 &&
|
||||||
|
test_expect_code 1 git p4 submit
|
||||||
|
) &&
|
||||||
|
(
|
||||||
|
cd "$cli" &&
|
||||||
|
test_path_is_missing text2 &&
|
||||||
|
p4 fstat -T action text2 2>&1 | grep "no such file"
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
|
#
|
||||||
|
# Cleanup after deciding not to submit during editTemplate. This
|
||||||
|
# involves unwinding more work, because files have been added, deleted
|
||||||
|
# and chmod-ed now. Same approach as above.
|
||||||
|
#
|
||||||
|
|
||||||
|
test_expect_success 'cleanup edit after submit cancel' '
|
||||||
|
test_when_finished cleanup_git &&
|
||||||
|
git p4 clone --dest="$git" //depot &&
|
||||||
|
(
|
||||||
|
cd "$git" &&
|
||||||
|
echo line >>text &&
|
||||||
|
git add text &&
|
||||||
|
git commit -m text &&
|
||||||
|
echo n | test_expect_code 1 git p4 submit &&
|
||||||
|
git reset --hard HEAD^
|
||||||
|
) &&
|
||||||
|
(
|
||||||
|
cd "$cli" &&
|
||||||
|
! p4 fstat -T action text &&
|
||||||
|
test_cmp "$git"/text text
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'cleanup add after submit cancel' '
|
||||||
|
test_when_finished cleanup_git &&
|
||||||
|
git p4 clone --dest="$git" //depot &&
|
||||||
|
(
|
||||||
|
cd "$git" &&
|
||||||
|
echo line >textnew &&
|
||||||
|
git add textnew &&
|
||||||
|
git commit -m textnew &&
|
||||||
|
echo n | test_expect_code 1 git p4 submit
|
||||||
|
) &&
|
||||||
|
(
|
||||||
|
cd "$cli" &&
|
||||||
|
test_path_is_missing textnew &&
|
||||||
|
p4 fstat -T action textnew 2>&1 | grep "no such file"
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'cleanup delete after submit cancel' '
|
||||||
|
test_when_finished cleanup_git &&
|
||||||
|
git p4 clone --dest="$git" //depot &&
|
||||||
|
(
|
||||||
|
cd "$git" &&
|
||||||
|
git rm text &&
|
||||||
|
git commit -m "rm text" &&
|
||||||
|
echo n | test_expect_code 1 git p4 submit
|
||||||
|
) &&
|
||||||
|
(
|
||||||
|
cd "$cli" &&
|
||||||
|
test_path_is_file text &&
|
||||||
|
! p4 fstat -T action text
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'cleanup copy after submit cancel' '
|
||||||
|
test_when_finished cleanup_git &&
|
||||||
|
git p4 clone --dest="$git" //depot &&
|
||||||
|
(
|
||||||
|
cd "$git" &&
|
||||||
|
cp text text2 &&
|
||||||
|
git add text2 &&
|
||||||
|
git commit -m text2 &&
|
||||||
|
git config git-p4.detectCopies true &&
|
||||||
|
git config git-p4.detectCopiesHarder true &&
|
||||||
|
git diff-tree -r -C --find-copies-harder HEAD | grep text2 | grep C100 &&
|
||||||
|
echo n | test_expect_code 1 git p4 submit
|
||||||
|
) &&
|
||||||
|
(
|
||||||
|
cd "$cli" &&
|
||||||
|
test_path_is_missing text2 &&
|
||||||
|
p4 fstat -T action text2 2>&1 | grep "no such file"
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'cleanup rename after submit cancel' '
|
||||||
|
test_when_finished cleanup_git &&
|
||||||
|
git p4 clone --dest="$git" //depot &&
|
||||||
|
(
|
||||||
|
cd "$git" &&
|
||||||
|
git mv text text2 &&
|
||||||
|
git commit -m text2 &&
|
||||||
|
git config git-p4.detectRenames true &&
|
||||||
|
git diff-tree -r -M HEAD | grep text2 | grep R100 &&
|
||||||
|
echo n | test_expect_code 1 git p4 submit
|
||||||
|
) &&
|
||||||
|
(
|
||||||
|
cd "$cli" &&
|
||||||
|
test_path_is_missing text2 &&
|
||||||
|
p4 fstat -T action text2 2>&1 | grep "no such file"
|
||||||
|
test_path_is_file text &&
|
||||||
|
! p4 fstat -T action text
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'cleanup chmod after submit cancel' '
|
||||||
|
test_when_finished cleanup_git &&
|
||||||
|
git p4 clone --dest="$git" //depot &&
|
||||||
|
(
|
||||||
|
cd "$git" &&
|
||||||
|
chmod u+x text &&
|
||||||
|
chmod u-x text+x &&
|
||||||
|
git add text text+x &&
|
||||||
|
git commit -m "chmod texts" &&
|
||||||
|
echo n | test_expect_code 1 git p4 submit
|
||||||
|
) &&
|
||||||
|
(
|
||||||
|
cd "$cli" &&
|
||||||
|
test_path_is_file text &&
|
||||||
|
! p4 fstat -T action text &&
|
||||||
|
stat --format=%A text | egrep ^-r-- &&
|
||||||
|
test_path_is_file text+x &&
|
||||||
|
! p4 fstat -T action text+x &&
|
||||||
|
stat --format=%A text+x | egrep ^-r-x
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'kill p4d' '
|
||||||
|
kill_p4d
|
||||||
|
'
|
||||||
|
|
||||||
|
test_done
|
Loading…
Reference in New Issue