git-p4: parse marshal output "p4 -G" in p4 changes

The option -G of p4 (python marshal output) gives more context about the data being output. That's useful when using the command "change -o" as we can distinguish between warning/error line and real change description. This fixes the case where a p4 trigger for "p4 change" is set and the command git-p4 submit is run. Signed-off-by: Miguel Torroja <miguel.torroja@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Miguel Torroja committed Jul 13, 2017 at 09:00 UTC b596b3b920208acb775bb632288976377636ccd1
2 files changed +58 -29
git-p4.py
+57 -28
@@ -879,8 +879,12 @@ def p4ChangesForPaths(depotPaths, changeRange, requestedBlockSize):
879 cmd += ["%s...@%s" % (p, revisionRange)]
880
881 # Insert changes in chronological order
882 - for line in reversed(p4_read_pipe_lines(cmd)):
883 - changes.add(int(line.split(" ")[1]))
882 + for entry in reversed(p4CmdList(cmd)):
883 + if entry.has_key('p4ExitCode'):
884 + die('Error retrieving changes descriptions ({})'.format(entry['p4ExitCode']))
885 + if not entry.has_key('change'):
886 + continue
887 + changes.add(int(entry['change']))
888
889 if not block_size:
890 break
@@ -1526,37 +1530,62 @@ class P4Submit(Command, P4UserMap):
1530
1531 [upstream, settings] = findUpstreamBranchPoint()
1532
1529 - template = ""
1533 + template = """\
1534 +# A Perforce Change Specification.
1535 +#
1536 +# Change: The change number. 'new' on a new changelist.
1537 +# Date: The date this specification was last modified.
1538 +# Client: The client on which the changelist was created. Read-only.
1539 +# User: The user who created the changelist.
1540 +# Status: Either 'pending' or 'submitted'. Read-only.
1541 +# Type: Either 'public' or 'restricted'. Default is 'public'.
1542 +# Description: Comments about the changelist. Required.
1543 +# Jobs: What opened jobs are to be closed by this changelist.
1544 +# You may delete jobs from this list. (New changelists only.)
1545 +# Files: What opened files from the default changelist are to be added
1546 +# to this changelist. You may delete files from this list.
1547 +# (New changelists only.)
1548 +"""
1549 + files_list = []
1550 inFilesSection = False
1551 + change_entry = None
1552 args = ['change', '-o']
1553 if changelist:
1554 args.append(str(changelist))
1534 -
1535 - for line in p4_read_pipe_lines(args):
1536 - if line.endswith("\r\n"):
1537 - line = line[:-2] + "\n"
1538 - if inFilesSection:
1539 - if line.startswith("\t"):
1540 - # path starts and ends with a tab
1541 - path = line[1:]
1542 - lastTab = path.rfind("\t")
1543 - if lastTab != -1:
1544 - path = path[:lastTab]
1545 - if settings.has_key('depot-paths'):
1546 - if not [p for p in settings['depot-paths']
1547 - if p4PathStartsWith(path, p)]:
1548 - continue
1549 - else:
1550 - if not p4PathStartsWith(path, self.depotPath):
1551 - continue
1555 + for entry in p4CmdList(args):
1556 + if not entry.has_key('code'):
1557 + continue
1558 + if entry['code'] == 'stat':
1559 + change_entry = entry
1560 + break
1561 + if not change_entry:
1562 + die('Failed to decode output of p4 change -o')
1563 + for key, value in change_entry.iteritems():
1564 + if key.startswith('File'):
1565 + if settings.has_key('depot-paths'):
1566 + if not [p for p in settings['depot-paths']
1567 + if p4PathStartsWith(value, p)]:
1568 + continue
1569 else:
1553 - inFilesSection = False
1554 - else:
1555 - if line.startswith("Files:"):
1556 - inFilesSection = True
1557 -
1558 - template += line
1559 -
1570 + if not p4PathStartsWith(value, self.depotPath):
1571 + continue
1572 + files_list.append(value)
1573 + continue
1574 + # Output in the order expected by prepareLogMessage
1575 + for key in ['Change', 'Client', 'User', 'Status', 'Description', 'Jobs']:
1576 + if not change_entry.has_key(key):
1577 + continue
1578 + template += '\n'
1579 + template += key + ':'
1580 + if key == 'Description':
1581 + template += '\n'
1582 + for field_line in change_entry[key].splitlines():
1583 + template += '\t'+field_line+'\n'
1584 + if len(files_list) > 0:
1585 + template += '\n'
1586 + template += 'Files:\n'
1587 + for path in files_list:
1588 + template += '\t'+path+'\n'
1589 return template
1590
1591 def edit_template(self, template_file):
t/t9831-git-p4-triggers.sh
+1 -1
@@ -66,7 +66,7 @@ test_expect_failure 'import with extra info lines from verbose p4 trigger' '
66 )
67 '
68
69 -test_expect_failure 'submit description with extra info lines from verbose p4 change trigger' '
69 +test_expect_success 'submit description with extra info lines from verbose p4 change trigger' '
70 test_when_finished cleanup_git &&
71 (
72 p4 triggers -i <<-EOF