hgtouch /

# Copyright 2009  John Mulligan <>
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2, incorporated herein by reference.
# <>
"""create empty files and add them to the repository

The HG touch extension combines running the commands
"touch foo; hg add foo"  into one simple step.
If you do this often it can be a time saver.
Using the --subdirs switch allows a new path, including
directories to be created.

import os
from mercurial import util, commands
from mercurial.i18n import _

def touch(ui, repo, path, *paths, **opts):
    """touches a file and automatically adds it to the repository
    Specify one or more paths and those file names listed will be
    created and added to the repository if they do not already exist.
    If the --subdirs option is given, any missing directories along
    the path to the file will also be created.
    subdirs = opts.get('subdirs')
    paths = list(paths)
    paths.insert(0, path)
    for path in paths:
        touched = _touchfile(ui, repo.root, subdirs, path)
        if touched:
            commands.add(ui, repo, touched)
            ui.warn('already exists: %s\n' % path)

def _touchfile(ui, root ,subdirs, path):
    """touch a single file
    while path.startswith('/'):
        path = path[1:]
    apath = os.path.join(root, path)
    if os.path.exists(apath):
        # short circuit if file already exists
        return None

    if subdirs:
        # create any missing subdirs on the path
        dirpath = os.path.dirname(apath)
        if os.path.isdir(dirpath):
        elif os.path.exists(dirpath):
            raise util.Abort(_('%s exists and is not a directory') % dirpath)

    fp = open(apath, 'w')
    except (IOError, OSError), err:
        ui.debug('%s\n' % err)
        raise util.Abort(_('failed to touch: %s' % apath))
    return apath

cmdtable = {
    "touch": (touch, [
        ('s', 'subdirs', None, 'create any missing subdirectories'),
        ], "hg touch [-s] PATH [PATHS...]")