def main():
    global TAB_WIDTH

    git_exec = Git()
    output = git_exec.rev_parse('--show-toplevel', with_extended_output=True,
                                with_exceptions=False)
    err_no, git_root, err_msg = output
    if err_no:
        print >> sys.stderr, err_msg
        sys.exit(1)

    git_repo = Repo(git_root)
    git_config = git_repo.config_reader()

    ws_config = {
        'blank-at-eol': True,
        'space-before-tab': True,
        'indent-with-non-tab': False,
        'tab-in-indent': False,
        'blank-at-eof': False,
        'trailing-space': False,
        'cr-at-eol': False,
    }
    try:
        _config_whitespace = git_config.get('core', 'whitespace')
        for c in _config_whitespace.split(','):
            c = c.strip()

            if 'tabwidth' in c:
                ws_config['tabwidth'] = int(c.split('=').pop())
            else:
                if c[0] == '-':  # e.g. -tab-in-indent
                    ws_config[c[1:]] = False
                else:
                    ws_config[c] = True
    except:
        pass

    if ws_config.get('tab-in-indent', False) and \
       ws_config.get('indent-with-non-tab', False):
        print >> sys.stderr, \
                 'Cannot enforce both tab-in-indent and indent-with-non-tab.'
        sys.exit(1)

    TAB_WIDTH = ws_config.get('tabwidth')
    sanitizers = []

    if ws_config.get('trailing-space', False):
        ws_config['blank-at-eol'] = True
        ws_config['blank-at-eof'] = True

    # Allow overrides gitconfig by cli argument
    arg_parser = argparse.ArgumentParser()
    arg_parser.set_defaults(**ws_config)

    arg_parser.add_argument('--trailing-space', dest='trailing-space',
                            type=ast.literal_eval, metavar='True|False',
                            help='trailing-space is a short-hand to cover '
                                 'both blank-at-eol and blank-at-eof')
    arg_parser.add_argument('--blank-at-eol', dest='blank-at-eol',
                            type=ast.literal_eval, metavar='True|False',
                            help='treats trailing whitespaces at the end of '
                                 'the line as an error')
    arg_parser.add_argument('--space-before-tab', dest='space-before-tab',
                            type=ast.literal_eval, metavar='True|False',
                            help='treats a space character that appears '
                                 'immediately before a tab character in the '
                                 'initial indent part of the line as an error')
    arg_parser.add_argument('--indent-with-non-tab',
                            dest='indent-with-non-tab',
                            type=ast.literal_eval, metavar='True|False',
                            help='treats a line that is indented with 8 or '
                                 'more space characters as an error')
    arg_parser.add_argument('--tab-in-indent', dest='tab-in-indent',
                            type=ast.literal_eval, metavar='True|False',
                            help='treats a tab character in the initial '
                                 'indent part of the line as an error')
#    arg_parser.add_argument('--blank-at-eof', dest='blank-at-eof',
#                            type=ast.literal_eval, metavar='True|False',
#                            help='treats blank lines added at the end of '
#                                 'file as an error')
    arg_parser.add_argument('--cr-at-eol', dest='cr-at-eol',
                            type=ast.literal_eval, metavar='True|False',
                            help='treats a carriage-return at the end of '
                                 'line as part of the line terminator, i.e. '
                                 'with it, trailing-space does not trigger '
                                 'if the character before such a '
                                 'carriage-return is not a whitespace')
    arg_parser.add_argument('--tabwidth', type=int, metavar='',
                            help='tells how many character positions a tab '
                                 'occupies; this is relevant for '
                                 'indent-with-non-tab and when git fixes '
                                 'tab-in-indent errors. The default tab '
                                 'width is 8.')

    arg_parser.add_argument('-d', '--debug', action='store_true',
                            help='Print the whitespace config')

    args = arg_parser.parse_args()
    ws_config = vars(args)

    if args.debug:
        import pprint
        pp = pprint.PrettyPrinter()
        pp.pprint(ws_config)

    # Prepare appropriate sanitizers
    if ws_config.get('blank-at-eol', False):
        sanitizers.append(blank_at_eol_sanitizer)

    if ws_config.get('space-before-tab', False):
        sanitizers.append(space_before_tab_sanitizer)

    if ws_config.get('indent-with-non-tab', False):
        sanitizers.append(indent_with_non_tab_sanitizer)

    if ws_config.get('tab-in-indent', False):
        sanitizers.append(tab_in_indent_sanitizer)

#    if ws_config.get('blank-at-eof', False):
#        sanitizers.append(blank_at_eof_sanitizer)

    if ws_config.get('cr-at-eol', False):
        sanitizers.append(cr_at_eol_sanitizer)

    head_diff = git_repo.head.commit.diff(create_patch=True)
    head_diff_add = head_diff.iter_change_type('A')
    head_diff_modify = head_diff.iter_change_type('M')

    map(lambda i: sanitize_diff(i, git_root, sanitizers),
        itertools.chain(head_diff_add, head_diff_modify))