##// END OF EJS Templates
phabricator: combine commit messages into the review when folding commits...
phabricator: combine commit messages into the review when folding commits No visible changes here, until an option to enable it is added to `phabsend`. This combines the Differential fields like Arcanist does, rather than simply concatenating the text blocks. Aside from populating everything properly in the web interface, Phabricator fails the review create/update if repeated fields are seen as would happen with simple concatenation. On the flip side, now that the Summary and Test Plan fields can contain data from multiple commits, we can't just join these fields together to determine if an amend is needed. If that were to happen, every single commit in the folded range would get amended with the combined commit message, which seems clearly wrong. Aside from making a minor assumption about the content of the Differential Revision field (it seems they allow some minor variances with spacing), this means that for folded reviews, you can't post it, go to the web page add a missing Test Plan, and then get it added to the commit message by re-posting it. I don't think that's a big deal. Differential Revision: https://phab.mercurial-scm.org/D8309

File last commit:

r43710:8a9e53b9 stable
r45134:dbe9182c default
Show More
state.py
150 lines | 4.7 KiB | text/x-python | PythonLexer
Martijn Pieters
fsmonitor: new experimental extension...
r28433 # state.py - fsmonitor persistent state
#
# Copyright 2013-2016 Facebook, Inc.
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
from __future__ import absolute_import
import errno
import os
import socket
import struct
Yuya Nishihara
py3: move up symbol imports to enforce import-checker rules...
r29205 from mercurial.i18n import _
Siddharth Agarwal
fsmonitor: don't write out state if identity has changed (issue5581)...
r32816 from mercurial import (
Gregory Szorc
fsmonitor: normalize hostname to bytes...
r43710 encoding,
Siddharth Agarwal
fsmonitor: don't write out state if identity has changed (issue5581)...
r32816 pathutil,
util,
)
Martijn Pieters
fsmonitor: new experimental extension...
r28433
_version = 4
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _versionformat = b">I"
Martijn Pieters
fsmonitor: new experimental extension...
r28433
Augie Fackler
formatting: blacken the codebase...
r43346
Martijn Pieters
fsmonitor: new experimental extension...
r28433 class state(object):
def __init__(self, repo):
Durham Goode
fsmonitor: remove use of repo.opener...
r31215 self._vfs = repo.vfs
Martijn Pieters
fsmonitor: new experimental extension...
r28433 self._ui = repo.ui
self._rootdir = pathutil.normasprefix(repo.root)
self._lastclock = None
Siddharth Agarwal
fsmonitor: don't write out state if identity has changed (issue5581)...
r32816 self._identity = util.filestat(None)
Martijn Pieters
fsmonitor: new experimental extension...
r28433
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.mode = self._ui.config(b'fsmonitor', b'mode')
Martijn Pieters
fsmonitor: new experimental extension...
r28433 self.walk_on_invalidate = self._ui.configbool(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'fsmonitor', b'walk_on_invalidate'
Augie Fackler
formatting: blacken the codebase...
r43346 )
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.timeout = float(self._ui.config(b'fsmonitor', b'timeout'))
Martijn Pieters
fsmonitor: new experimental extension...
r28433
def get(self):
try:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 file = self._vfs(b'fsmonitor.state', b'rb')
Martijn Pieters
fsmonitor: new experimental extension...
r28433 except IOError as inst:
Siddharth Agarwal
fsmonitor: don't write out state if identity has changed (issue5581)...
r32816 self._identity = util.filestat(None)
Martijn Pieters
fsmonitor: new experimental extension...
r28433 if inst.errno != errno.ENOENT:
raise
return None, None, None
Siddharth Agarwal
fsmonitor: don't write out state if identity has changed (issue5581)...
r32816 self._identity = util.filestat.fromfp(file)
Martijn Pieters
fsmonitor: new experimental extension...
r28433 versionbytes = file.read(4)
if len(versionbytes) < 4:
self._ui.log(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'fsmonitor',
b'fsmonitor: state file only has %d bytes, '
b'nuking state\n' % len(versionbytes),
Augie Fackler
formatting: blacken the codebase...
r43346 )
Martijn Pieters
fsmonitor: new experimental extension...
r28433 self.invalidate()
return None, None, None
try:
diskversion = struct.unpack(_versionformat, versionbytes)[0]
if diskversion != _version:
# different version, nuke state and start over
self._ui.log(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'fsmonitor',
b'fsmonitor: version switch from %d to '
b'%d, nuking state\n' % (diskversion, _version),
Augie Fackler
formatting: blacken the codebase...
r43346 )
Martijn Pieters
fsmonitor: new experimental extension...
r28433 self.invalidate()
return None, None, None
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 state = file.read().split(b'\0')
Martijn Pieters
fsmonitor: new experimental extension...
r28433 # state = hostname\0clock\0ignorehash\0 + list of files, each
# followed by a \0
Simon Farnsworth
fsmonitor: be robust in the face of bad state...
r30539 if len(state) < 3:
self._ui.log(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'fsmonitor',
b'fsmonitor: state file truncated (expected '
b'3 chunks, found %d), nuking state\n',
Augie Fackler
formatting: blacken the codebase...
r43346 len(state),
)
Simon Farnsworth
fsmonitor: be robust in the face of bad state...
r30539 self.invalidate()
return None, None, None
Martijn Pieters
fsmonitor: new experimental extension...
r28433 diskhostname = state[0]
Gregory Szorc
fsmonitor: normalize hostname to bytes...
r43710 hostname = encoding.strtolocal(socket.gethostname())
Martijn Pieters
fsmonitor: new experimental extension...
r28433 if diskhostname != hostname:
# file got moved to a different host
Augie Fackler
formatting: blacken the codebase...
r43346 self._ui.log(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'fsmonitor',
b'fsmonitor: stored hostname "%s" '
b'different from current "%s", nuking state\n'
Augie Fackler
formatting: blacken the codebase...
r43346 % (diskhostname, hostname),
)
Martijn Pieters
fsmonitor: new experimental extension...
r28433 self.invalidate()
return None, None, None
clock = state[1]
ignorehash = state[2]
# discard the value after the last \0
notefiles = state[3:-1]
finally:
file.close()
return clock, ignorehash, notefiles
def set(self, clock, ignorehash, notefiles):
if clock is None:
self.invalidate()
return
Siddharth Agarwal
fsmonitor: don't write out state if identity has changed (issue5581)...
r32816 # Read the identity from the file on disk rather than from the open file
# pointer below, because the latter is actually a brand new file.
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 identity = util.filestat.frompath(self._vfs.join(b'fsmonitor.state'))
Siddharth Agarwal
fsmonitor: don't write out state if identity has changed (issue5581)...
r32816 if identity != self._identity:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self._ui.debug(
b'skip updating fsmonitor.state: identity mismatch\n'
)
Siddharth Agarwal
fsmonitor: don't write out state if identity has changed (issue5581)...
r32816 return
Martijn Pieters
fsmonitor: new experimental extension...
r28433 try:
Augie Fackler
formatting: blacken the codebase...
r43346 file = self._vfs(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'fsmonitor.state', b'wb', atomictemp=True, checkambig=True
Augie Fackler
formatting: blacken the codebase...
r43346 )
Martijn Pieters
fsmonitor: new experimental extension...
r28433 except (IOError, OSError):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self._ui.warn(_(b"warning: unable to write out fsmonitor state\n"))
Martijn Pieters
fsmonitor: new experimental extension...
r28433 return
Simon Farnsworth
fsmonitor: be robust in the face of bad state...
r30539 with file:
Martijn Pieters
fsmonitor: new experimental extension...
r28433 file.write(struct.pack(_versionformat, _version))
Gregory Szorc
fsmonitor: normalize hostname to bytes...
r43710 file.write(encoding.strtolocal(socket.gethostname()) + b'\0')
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 file.write(clock + b'\0')
file.write(ignorehash + b'\0')
Martijn Pieters
fsmonitor: new experimental extension...
r28433 if notefiles:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 file.write(b'\0'.join(notefiles))
file.write(b'\0')
Martijn Pieters
fsmonitor: new experimental extension...
r28433
def invalidate(self):
try:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 os.unlink(os.path.join(self._rootdir, b'.hg', b'fsmonitor.state'))
Martijn Pieters
fsmonitor: new experimental extension...
r28433 except OSError as inst:
if inst.errno != errno.ENOENT:
raise
Siddharth Agarwal
fsmonitor: don't write out state if identity has changed (issue5581)...
r32816 self._identity = util.filestat(None)
Martijn Pieters
fsmonitor: new experimental extension...
r28433
def setlastclock(self, clock):
self._lastclock = clock
def getlastclock(self):
return self._lastclock