annotate mercurial/scmposix.py @ 43913:4b7d5d10c45d

exchange: ensure all outgoing subrepo references are present before pushing We've run into occasional problems with people committing a repo, and then amending or rebasing in the subrepo. That makes it so that the revision in the parent can't be checked out, and the problem gets propagated on push. Mercurial already tries to defend against this sort of dangling reference by pushing *all* subrepo revisions first. This reuses the checks that trigger warnings in `hg verify` to bail on the push unless using `--force`. I thought about putting this on the server side, but at that point, all of the data has been transferred, only to bail out. Additionally, SCM Manager hosts subrepos in a location that isn't nested in the parent, so normal subrepo code would complain that the subrepo is missing when run on the server. Because the push command pushes subrepos before calling this exchange code, a subrepo will be pushed before the parent is verified. Not great, but no dangling references are exchanged, so it solves the problem. This code isn't in the loop that pushes the subrepos because: 1) the list of outgoing revisions is needed to limit the scope of the check 2) the loop only accesses the current revision, and therefore can miss subrepos that were dropped in previous commits 3) this code is called when pushing a subrepo, so the protection is recursive I'm not sure if there's a cheap check for the list of files in the outgoing bundle. If there is, that would provide a fast path to bypass this check for people not using subrepos (or if no subrepo changes were made). There's probably also room for verifying other references like tags. But since that doesn't break checkouts, it's much less of a problem. Differential Revision: https://phab.mercurial-scm.org/D7616
author Matt Harbison <matt_harbison@yahoo.com>
date Thu, 12 Dec 2019 12:30:15 -0500
parents 9f70512ae2cf
children 9ac96b9fa76e
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
27483
39087ee88835 scmposix: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22583
diff changeset
1 from __future__ import absolute_import
39087ee88835 scmposix: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22583
diff changeset
2
30311
80708959161a scmutil: narrow ImportError handling in termwidth()
Yuya Nishihara <yuya@tcha.org>
parents: 30310
diff changeset
3 import array
30309
4b1af1c867fa scmutil: move util.termwidth()
Yuya Nishihara <yuya@tcha.org>
parents: 30276
diff changeset
4 import errno
4b1af1c867fa scmutil: move util.termwidth()
Yuya Nishihara <yuya@tcha.org>
parents: 30276
diff changeset
5 import fcntl
27483
39087ee88835 scmposix: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22583
diff changeset
6 import os
39087ee88835 scmposix: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22583
diff changeset
7 import sys
39087ee88835 scmposix: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22583
diff changeset
8
43089
c59eb1560c44 py3: manually import getattr where it is needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43077
diff changeset
9 from .pycompat import getattr
27483
39087ee88835 scmposix: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22583
diff changeset
10 from . import (
30276
c90a05124fae py3: make scmposix.userrcpath() return bytes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 27483
diff changeset
11 encoding,
30467
5b0baa9f3362 py3: use pycompat.sysargv in scmposix.systemrcpath()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30314
diff changeset
12 pycompat,
32208
d74b0cff94a9 osutil: proxy through util (and platform) modules (API)
Yuya Nishihara <yuya@tcha.org>
parents: 32078
diff changeset
13 util,
27483
39087ee88835 scmposix: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22583
diff changeset
14 )
18690
4c6f7f0dadab scmutil: split platform-specific bits into their own modules
Kevin Bullock <kbullock@ringworld.org>
parents:
diff changeset
15
32078
bf5e13e38390 pager: use less as a fallback on Unix
Yuya Nishihara <yuya@tcha.org>
parents: 31339
diff changeset
16 # BSD 'more' escapes ANSI color sequences by default. This can be disabled by
bf5e13e38390 pager: use less as a fallback on Unix
Yuya Nishihara <yuya@tcha.org>
parents: 31339
diff changeset
17 # $MORE variable, but there's no compatible option with Linux 'more'. Given
bf5e13e38390 pager: use less as a fallback on Unix
Yuya Nishihara <yuya@tcha.org>
parents: 31339
diff changeset
18 # OS X is widely used and most modern Unix systems would have 'less', setting
bf5e13e38390 pager: use less as a fallback on Unix
Yuya Nishihara <yuya@tcha.org>
parents: 31339
diff changeset
19 # 'less' as the default seems reasonable.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43075
diff changeset
20 fallbackpager = b'less'
32078
bf5e13e38390 pager: use less as a fallback on Unix
Yuya Nishihara <yuya@tcha.org>
parents: 31339
diff changeset
21
43075
57875cf423c9 style: run a patched black on a subset of mercurial
Augie Fackler <augie@google.com>
parents: 34647
diff changeset
22
18690
4c6f7f0dadab scmutil: split platform-specific bits into their own modules
Kevin Bullock <kbullock@ringworld.org>
parents:
diff changeset
23 def _rcfiles(path):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43075
diff changeset
24 rcs = [os.path.join(path, b'hgrc')]
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43075
diff changeset
25 rcdir = os.path.join(path, b'hgrc.d')
18690
4c6f7f0dadab scmutil: split platform-specific bits into their own modules
Kevin Bullock <kbullock@ringworld.org>
parents:
diff changeset
26 try:
43075
57875cf423c9 style: run a patched black on a subset of mercurial
Augie Fackler <augie@google.com>
parents: 34647
diff changeset
27 rcs.extend(
57875cf423c9 style: run a patched black on a subset of mercurial
Augie Fackler <augie@google.com>
parents: 34647
diff changeset
28 [
57875cf423c9 style: run a patched black on a subset of mercurial
Augie Fackler <augie@google.com>
parents: 34647
diff changeset
29 os.path.join(rcdir, f)
57875cf423c9 style: run a patched black on a subset of mercurial
Augie Fackler <augie@google.com>
parents: 34647
diff changeset
30 for f, kind in util.listdir(rcdir)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43075
diff changeset
31 if f.endswith(b".rc")
43075
57875cf423c9 style: run a patched black on a subset of mercurial
Augie Fackler <augie@google.com>
parents: 34647
diff changeset
32 ]
57875cf423c9 style: run a patched black on a subset of mercurial
Augie Fackler <augie@google.com>
parents: 34647
diff changeset
33 )
18690
4c6f7f0dadab scmutil: split platform-specific bits into their own modules
Kevin Bullock <kbullock@ringworld.org>
parents:
diff changeset
34 except OSError:
4c6f7f0dadab scmutil: split platform-specific bits into their own modules
Kevin Bullock <kbullock@ringworld.org>
parents:
diff changeset
35 pass
4c6f7f0dadab scmutil: split platform-specific bits into their own modules
Kevin Bullock <kbullock@ringworld.org>
parents:
diff changeset
36 return rcs
4c6f7f0dadab scmutil: split platform-specific bits into their own modules
Kevin Bullock <kbullock@ringworld.org>
parents:
diff changeset
37
43075
57875cf423c9 style: run a patched black on a subset of mercurial
Augie Fackler <augie@google.com>
parents: 34647
diff changeset
38
18690
4c6f7f0dadab scmutil: split platform-specific bits into their own modules
Kevin Bullock <kbullock@ringworld.org>
parents:
diff changeset
39 def systemrcpath():
4c6f7f0dadab scmutil: split platform-specific bits into their own modules
Kevin Bullock <kbullock@ringworld.org>
parents:
diff changeset
40 path = []
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43075
diff changeset
41 if pycompat.sysplatform == b'plan9':
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43075
diff changeset
42 root = b'lib/mercurial'
18690
4c6f7f0dadab scmutil: split platform-specific bits into their own modules
Kevin Bullock <kbullock@ringworld.org>
parents:
diff changeset
43 else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43075
diff changeset
44 root = b'etc/mercurial'
18690
4c6f7f0dadab scmutil: split platform-specific bits into their own modules
Kevin Bullock <kbullock@ringworld.org>
parents:
diff changeset
45 # old mod_python does not set sys.argv
4c6f7f0dadab scmutil: split platform-specific bits into their own modules
Kevin Bullock <kbullock@ringworld.org>
parents:
diff changeset
46 if len(getattr(sys, 'argv', [])) > 0:
30467
5b0baa9f3362 py3: use pycompat.sysargv in scmposix.systemrcpath()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30314
diff changeset
47 p = os.path.dirname(os.path.dirname(pycompat.sysargv[0]))
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43075
diff changeset
48 if p != b'/':
22583
23c995ed466b config: don't read the same config file twice
Mads Kiilerich <madski@unity3d.com>
parents: 18690
diff changeset
49 path.extend(_rcfiles(os.path.join(p, root)))
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43075
diff changeset
50 path.extend(_rcfiles(b'/' + root))
18690
4c6f7f0dadab scmutil: split platform-specific bits into their own modules
Kevin Bullock <kbullock@ringworld.org>
parents:
diff changeset
51 return path
4c6f7f0dadab scmutil: split platform-specific bits into their own modules
Kevin Bullock <kbullock@ringworld.org>
parents:
diff changeset
52
43075
57875cf423c9 style: run a patched black on a subset of mercurial
Augie Fackler <augie@google.com>
parents: 34647
diff changeset
53
18690
4c6f7f0dadab scmutil: split platform-specific bits into their own modules
Kevin Bullock <kbullock@ringworld.org>
parents:
diff changeset
54 def userrcpath():
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43075
diff changeset
55 if pycompat.sysplatform == b'plan9':
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43075
diff changeset
56 return [encoding.environ[b'home'] + b'/lib/hgrc']
34647
dacfcdd8b94e codemod: use pycompat.isdarwin
Jun Wu <quark@fb.com>
parents: 32208
diff changeset
57 elif pycompat.isdarwin:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43075
diff changeset
58 return [os.path.expanduser(b'~/.hgrc')]
18690
4c6f7f0dadab scmutil: split platform-specific bits into their own modules
Kevin Bullock <kbullock@ringworld.org>
parents:
diff changeset
59 else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43075
diff changeset
60 confighome = encoding.environ.get(b'XDG_CONFIG_HOME')
30941
354020079723 hg: allow usage of XDG_CONFIG_HOME/hg/hgrc
David Demelier <demelier.david@gmail.com>
parents: 30641
diff changeset
61 if confighome is None or not os.path.isabs(confighome):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43075
diff changeset
62 confighome = os.path.expanduser(b'~/.config')
30941
354020079723 hg: allow usage of XDG_CONFIG_HOME/hg/hgrc
David Demelier <demelier.david@gmail.com>
parents: 30641
diff changeset
63
43075
57875cf423c9 style: run a patched black on a subset of mercurial
Augie Fackler <augie@google.com>
parents: 34647
diff changeset
64 return [
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43075
diff changeset
65 os.path.expanduser(b'~/.hgrc'),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43075
diff changeset
66 os.path.join(confighome, b'hg', b'hgrc'),
43075
57875cf423c9 style: run a patched black on a subset of mercurial
Augie Fackler <augie@google.com>
parents: 34647
diff changeset
67 ]
57875cf423c9 style: run a patched black on a subset of mercurial
Augie Fackler <augie@google.com>
parents: 34647
diff changeset
68
30309
4b1af1c867fa scmutil: move util.termwidth()
Yuya Nishihara <yuya@tcha.org>
parents: 30276
diff changeset
69
30314
365812902904 scmutil: extend termwidth() to return terminal height, renamed to termsize()
Yuya Nishihara <yuya@tcha.org>
parents: 30312
diff changeset
70 def termsize(ui):
30309
4b1af1c867fa scmutil: move util.termwidth()
Yuya Nishihara <yuya@tcha.org>
parents: 30276
diff changeset
71 try:
4b1af1c867fa scmutil: move util.termwidth()
Yuya Nishihara <yuya@tcha.org>
parents: 30276
diff changeset
72 import termios
43075
57875cf423c9 style: run a patched black on a subset of mercurial
Augie Fackler <augie@google.com>
parents: 34647
diff changeset
73
30311
80708959161a scmutil: narrow ImportError handling in termwidth()
Yuya Nishihara <yuya@tcha.org>
parents: 30310
diff changeset
74 TIOCGWINSZ = termios.TIOCGWINSZ # unavailable on IRIX (issue3449)
80708959161a scmutil: narrow ImportError handling in termwidth()
Yuya Nishihara <yuya@tcha.org>
parents: 30310
diff changeset
75 except (AttributeError, ImportError):
30314
365812902904 scmutil: extend termwidth() to return terminal height, renamed to termsize()
Yuya Nishihara <yuya@tcha.org>
parents: 30312
diff changeset
76 return 80, 24
30312
1ad1c5017043 scmutil: remove superfluous indent from termwidth()
Yuya Nishihara <yuya@tcha.org>
parents: 30311
diff changeset
77
1ad1c5017043 scmutil: remove superfluous indent from termwidth()
Yuya Nishihara <yuya@tcha.org>
parents: 30311
diff changeset
78 for dev in (ui.ferr, ui.fout, ui.fin):
1ad1c5017043 scmutil: remove superfluous indent from termwidth()
Yuya Nishihara <yuya@tcha.org>
parents: 30311
diff changeset
79 try:
30309
4b1af1c867fa scmutil: move util.termwidth()
Yuya Nishihara <yuya@tcha.org>
parents: 30276
diff changeset
80 try:
30312
1ad1c5017043 scmutil: remove superfluous indent from termwidth()
Yuya Nishihara <yuya@tcha.org>
parents: 30311
diff changeset
81 fd = dev.fileno()
1ad1c5017043 scmutil: remove superfluous indent from termwidth()
Yuya Nishihara <yuya@tcha.org>
parents: 30311
diff changeset
82 except AttributeError:
1ad1c5017043 scmutil: remove superfluous indent from termwidth()
Yuya Nishihara <yuya@tcha.org>
parents: 30311
diff changeset
83 continue
1ad1c5017043 scmutil: remove superfluous indent from termwidth()
Yuya Nishihara <yuya@tcha.org>
parents: 30311
diff changeset
84 if not os.isatty(fd):
1ad1c5017043 scmutil: remove superfluous indent from termwidth()
Yuya Nishihara <yuya@tcha.org>
parents: 30311
diff changeset
85 continue
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43075
diff changeset
86 arri = fcntl.ioctl(fd, TIOCGWINSZ, b'\0' * 8)
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43480
diff changeset
87 height, width = array.array('h', arri)[:2]
30314
365812902904 scmutil: extend termwidth() to return terminal height, renamed to termsize()
Yuya Nishihara <yuya@tcha.org>
parents: 30312
diff changeset
88 if width > 0 and height > 0:
365812902904 scmutil: extend termwidth() to return terminal height, renamed to termsize()
Yuya Nishihara <yuya@tcha.org>
parents: 30312
diff changeset
89 return width, height
30312
1ad1c5017043 scmutil: remove superfluous indent from termwidth()
Yuya Nishihara <yuya@tcha.org>
parents: 30311
diff changeset
90 except ValueError:
1ad1c5017043 scmutil: remove superfluous indent from termwidth()
Yuya Nishihara <yuya@tcha.org>
parents: 30311
diff changeset
91 pass
1ad1c5017043 scmutil: remove superfluous indent from termwidth()
Yuya Nishihara <yuya@tcha.org>
parents: 30311
diff changeset
92 except IOError as e:
43480
667f56d73ceb scmposix: another suppression on IOError subscripting
Augie Fackler <augie@google.com>
parents: 43089
diff changeset
93 if e[0] == errno.EINVAL: # pytype: disable=unsupported-operands
30309
4b1af1c867fa scmutil: move util.termwidth()
Yuya Nishihara <yuya@tcha.org>
parents: 30276
diff changeset
94 pass
30312
1ad1c5017043 scmutil: remove superfluous indent from termwidth()
Yuya Nishihara <yuya@tcha.org>
parents: 30311
diff changeset
95 else:
1ad1c5017043 scmutil: remove superfluous indent from termwidth()
Yuya Nishihara <yuya@tcha.org>
parents: 30311
diff changeset
96 raise
30314
365812902904 scmutil: extend termwidth() to return terminal height, renamed to termsize()
Yuya Nishihara <yuya@tcha.org>
parents: 30312
diff changeset
97 return 80, 24