hg status: do not crash when there is no .hgignore and a directory is not readable
If a repo has no .hgignore
(this happens frequently on repositories that come from a git clone, which tend to have a .gitignore
but no .hgignore
), and in the working copy there is a directory which is not readable by the current user (for example, for a ownership or persmission problem), hg-git causes a crash in hg status
instead of printing an error message.
An almost complete stack trace is:
$ hg status
...
Traceback (most recent call last):
File "/opt/mercurial/hg-git/hggit/gitdirstate.py", line 99, in _ignore
fp = open(files[0], 'rb')
FileNotFoundError: [Errno 2] No such file or directory: b'/tmp/example/.hgignore'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/opt/mercurial/hg-git/hggit/gitdirstate.py", line 182, in _finddotgitignores
entries = util.listdir(join(nd), stat=True, skip=skip)
PermissionError: [Errno 13] Permission denied: '/tmp/example/not_readable'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
[...]
File "/opt/mercurial/hg-git/hggit/gitdirstate.py", line 102, in _ignore
fns = self._finddotgitignores()
File "/opt/mercurial/hg-git/hggit/gitdirstate.py", line 185, in _finddotgitignores
fwarn(nd, inst.strerror)
File "/opt/mercurial/hg-git/hggit/gitdirstate.py", line 128, in fwarn
self._ui.warn(b'%s: %s\n' % (self.pathto(f), msg))
TypeError: %b requires a bytes-like object, or an object that implements __bytes__, not 'str'
After this change, the output of hg status
under such condition becomes:
$ hg status
not_readable: Permission denied
not_readable: Permission denied <-- duplicated!
? .gitignore
? dir/.gitignore
? dir/bar
? foo
? foobar
The "Permission denied" message is printed twice. This is probably a pre-existing bug that was masked by the crash and is now uncovered.
Tested on:
- Ubuntu 20.04
- Python 3.8.5
- mercurial 5.6.1
- hg-git 6e576b67d1ce.