Mercurial > hg
view contrib/hg-ssh @ 44805:02bf61bb4a70
copy: to find copy source, walk parent of revision we're marking copies in
As shown in the previous patch, `hg cp --after --at-rev . src dst`
fails if `src` is not in `.`. It seems obvious that you should always
walk the *parent* of the revision you're marking copies in, but that's
not how it was done for the working copy, and I didn't think to change
it when marking copies in a non-working-copy commit.
This patch fixes that by walking the parent commit instead, but only
if we're marking copies for a non-working-copy commit. We need to
leave the working-copy code unchanged because it depends on the weird
behavior of `workingctx.walk()`. With these changes, there's very
little overlap between the working-copy version and the
non-working-copy version of `walkpats()`, but I've refrained from
cleaning that up on the stable branch.
Differential Revision: https://phab.mercurial-scm.org/D8494
author | Martin von Zweigbergk <martinvonz@google.com> |
---|---|
date | Wed, 06 May 2020 10:33:56 -0700 |
parents | 99e231afc29c |
children | c102b704edb5 |
line wrap: on
line source
#!/usr/bin/env python # # Copyright 2005-2007 by Intevation GmbH <intevation@intevation.de> # # Author(s): # Thomas Arendsen Hein <thomas@intevation.de> # # This software may be used and distributed according to the terms of the # GNU General Public License version 2 or any later version. """ hg-ssh - a wrapper for ssh access to a limited set of mercurial repos To be used in ~/.ssh/authorized_keys with the "command" option, see sshd(8): command="hg-ssh path/to/repo1 /path/to/repo2 ~/repo3 ~user/repo4" ssh-dss ... (probably together with these other useful options: no-port-forwarding,no-X11-forwarding,no-agent-forwarding) This allows pull/push over ssh from/to the repositories given as arguments. If all your repositories are subdirectories of a common directory, you can allow shorter paths with: command="cd path/to/my/repositories && hg-ssh repo1 subdir/repo2" You can use pattern matching of your normal shell, e.g.: command="cd repos && hg-ssh user/thomas/* projects/{mercurial,foo}" You can also add a --read-only flag to allow read-only access to a key, e.g.: command="hg-ssh --read-only repos/*" """ from __future__ import absolute_import import os import shlex import sys # enable importing on demand to reduce startup time import hgdemandimport hgdemandimport.enable() from mercurial import ( dispatch, pycompat, ui as uimod, ) def main(): # Prevent insertion/deletion of CRs dispatch.initstdio() cwd = os.getcwd() readonly = False args = sys.argv[1:] while len(args): if args[0] == '--read-only': readonly = True args.pop(0) else: break allowed_paths = [ os.path.normpath(os.path.join(cwd, os.path.expanduser(path))) for path in args ] orig_cmd = os.getenv('SSH_ORIGINAL_COMMAND', '?') try: cmdargv = shlex.split(orig_cmd) except ValueError as e: sys.stderr.write('Illegal command "%s": %s\n' % (orig_cmd, e)) sys.exit(255) if cmdargv[:2] == ['hg', '-R'] and cmdargv[3:] == ['serve', '--stdio']: path = cmdargv[2] repo = os.path.normpath(os.path.join(cwd, os.path.expanduser(path))) if repo in allowed_paths: cmd = [b'-R', pycompat.fsencode(repo), b'serve', b'--stdio'] req = dispatch.request(cmd) if readonly: if not req.ui: req.ui = uimod.ui.load() req.ui.setconfig( b'hooks', b'pretxnopen.hg-ssh', b'python:__main__.rejectpush', b'hg-ssh', ) req.ui.setconfig( b'hooks', b'prepushkey.hg-ssh', b'python:__main__.rejectpush', b'hg-ssh', ) dispatch.dispatch(req) else: sys.stderr.write('Illegal repository "%s"\n' % repo) sys.exit(255) else: sys.stderr.write('Illegal command "%s"\n' % orig_cmd) sys.exit(255) def rejectpush(ui, **kwargs): ui.warn((b"Permission denied\n")) # mercurial hooks use unix process conventions for hook return values # so a truthy return means failure return True if __name__ == '__main__': main()