diff --git a/pre_commit/main.py b/pre_commit/main.py
index 8a77316..baaf84b 100644
--- a/pre_commit/main.py
+++ b/pre_commit/main.py
@@ -1,6 +1,7 @@
 from __future__ import unicode_literals
 
 import argparse
+import logging
 import os
 import sys
 
@@ -20,6 +21,8 @@ from pre_commit.logging_handler import add_logging_handler
 from pre_commit.runner import Runner
 
 
+logger = logging.getLogger('pre_commit')
+
 # https://github.com/pre-commit/pre-commit/issues/217
 # On OSX, making a virtualenv using pyvenv at . causes `virtualenv` and `pip`
 # to install packages to the wrong place.  We don't want anything to deal with
@@ -117,7 +120,14 @@ def main(argv=None):
     _add_color_option(autoupdate_parser)
     _add_config_option(autoupdate_parser)
     autoupdate_parser.add_argument(
-        '--tags-only', action='store_true', help='Update to tags only.',
+        '--tags-only', action='store_true', help='LEGACY: for compatibility',
+    )
+    autoupdate_parser.add_argument(
+        '--bleeding-edge', action='store_true',
+        help=(
+            'Update to the bleeding edge of `master` instead of the latest '
+            'tagged version (the default behavior).'
+        ),
     )
 
     run_parser = subparsers.add_parser('run', help='Run hooks.')
@@ -209,7 +219,9 @@ def main(argv=None):
         elif args.command == 'clean':
             return clean(runner)
         elif args.command == 'autoupdate':
-            return autoupdate(runner, args.tags_only)
+            if args.tags_only:
+                logger.warning('--tags-only is the default')
+            return autoupdate(runner, tags_only=not args.bleeding_edge)
         elif args.command == 'run':
             return run(runner, args)
         elif args.command == 'sample-config':

[RFC] Make the default of `pre-commit autoupdate` use `--tags-only`?
I find that `--tags-only` to be much better than the default.

My proposal:

- Make the `--tags-only` behaviour the default behaviour
- Make `--tags-only` a noop argument which produces a warning and does the default
- Add a `--bleeding-edge` which does the current default behaviour

@chriskuehl  thoughts?
diff --git a/tests/conftest.py b/tests/conftest.py
index 23eddb5..140463b 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -186,3 +186,12 @@ def cap_out():
     with mock.patch.object(output, 'write', write):
         with mock.patch.object(output, 'write_line', write_line):
             yield Fixture(stream)
+
+
+@pytest.yield_fixture
+def fake_log_handler():
+    handler = mock.Mock(level=logging.INFO)
+    logger = logging.getLogger('pre_commit')
+    logger.addHandler(handler)
+    yield handler
+    logger.removeHandler(handler)
diff --git a/tests/main_test.py b/tests/main_test.py
index 8cc6121..0425b8d 100644
--- a/tests/main_test.py
+++ b/tests/main_test.py
@@ -127,3 +127,8 @@ def test_expected_fatal_error_no_git_repo(
         'Is it installed, and are you in a Git repository directory?\n'
         'Check the log at ~/.pre-commit/pre-commit.log\n'
     )
+
+
+def test_warning_on_tags_only(mock_commands, cap_out):
+    main.main(('autoupdate', '--tags-only'))
+    assert '--tags-only is the default' in cap_out.get()
diff --git a/tests/repository_test.py b/tests/repository_test.py
index 4cb2e4e..f91642e 100644
--- a/tests/repository_test.py
+++ b/tests/repository_test.py
@@ -2,7 +2,6 @@ from __future__ import absolute_import
 from __future__ import unicode_literals
 
 import io
-import logging
 import os.path
 import re
 import shutil
@@ -680,15 +679,6 @@ def test_local_python_repo(store):
     assert ret[1].replace(b'\r\n', b'\n') == b"['filename']\nHello World\n"
 
 
-@pytest.yield_fixture
-def fake_log_handler():
-    handler = mock.Mock(level=logging.INFO)
-    logger = logging.getLogger('pre_commit')
-    logger.addHandler(handler)
-    yield handler
-    logger.removeHandler(handler)
-
-
 def test_hook_id_not_present(tempdir_factory, store, fake_log_handler):
     path = make_repo(tempdir_factory, 'script_hooks_repo')
     config = make_config_from_repo(path)

pip install -e .[dev]
parse_log_pytest
requirements.txt
pytest
apt-get update apt-get install -y gcc
3.9
requirements-dev.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
aspy.yaml==1.3.0
cached-property==2.0.1
coverage==7.8.0
distlib==0.3.9
exceptiongroup==1.2.2
filelock==3.18.0
flake8==7.2.0
iniconfig==2.1.0
mccabe==0.7.0
mock==5.2.0
nodeenv==1.9.1
packaging==24.2
platformdirs==4.3.7
pluggy==1.5.0
-e git+https://github.com/pre-commit/pre-commit.git@1be4e4f82e31336fa5fca096c962c72ac0041537#egg=pre_commit
pycodestyle==2.13.0
pyflakes==3.3.1
pytest==8.3.5
pytest-env==1.1.5
PyYAML==6.0.2
six==1.17.0
tomli==2.2.1
virtualenv==20.29.3

name: pre-commit
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=3.0.16=h5eee18b_0
  - pip=25.0=py39h06a4308_0
  - python=3.9.21=he870216_1
  - readline=8.2=h5eee18b_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tzdata=2025a=h04d1e81_0
  - wheel=0.45.1=py39h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - aspy-yaml==1.3.0
      - cached-property==2.0.1
      - coverage==7.8.0
      - distlib==0.3.9
      - exceptiongroup==1.2.2
      - filelock==3.18.0
      - flake8==7.2.0
      - iniconfig==2.1.0
      - mccabe==0.7.0
      - mock==5.2.0
      - nodeenv==1.9.1
      - packaging==24.2
      - platformdirs==4.3.7
      - pluggy==1.5.0
      - pycodestyle==2.13.0
      - pyflakes==3.3.1
      - pytest==8.3.5
      - pytest-env==1.1.5
      - pyyaml==6.0.2
      - setuptools==18.4
      - six==1.17.0
      - tomli==2.2.1
      - virtualenv==20.29.3
prefix: /opt/conda/envs/pre-commit

tests/main_test.py::test_warning_on_tags_only
tests/repository_test.py::test_switch_language_versions_doesnt_clobber tests/repository_test.py::test_versioned_python_hook tests/repository_test.py::test_run_a_ruby_hook tests/repository_test.py::test_run_versioned_ruby_hook tests/repository_test.py::test_run_ruby_hook_with_disable_shared_gems tests/repository_test.py::test_golang_hook tests/repository_test.py::test_additional_ruby_dependencies_installed tests/repository_test.py::test_additional_golang_dependencies_installed
tests/main_test.py::test_overall_help tests/main_test.py::test_help_command tests/main_test.py::test_help_other_command tests/main_test.py::test_install_command[autoupdate] tests/main_test.py::test_install_command[clean] tests/main_test.py::test_install_command[install] tests/main_test.py::test_install_command[install-hooks] tests/main_test.py::test_install_command[run] tests/main_test.py::test_install_command[sample-config] tests/main_test.py::test_install_command[uninstall] tests/main_test.py::test_help_cmd_in_empty_directory tests/main_test.py::test_expected_fatal_error_no_git_repo tests/repository_test.py::test_python_hook tests/repository_test.py::test_python_hook_args_with_spaces tests/repository_test.py::test_python_hook_weird_setup_cfg tests/repository_test.py::test_run_a_node_hook tests/repository_test.py::test_run_versioned_node_hook tests/repository_test.py::test_system_hook_with_spaces tests/repository_test.py::test_repo_with_legacy_hooks_yaml tests/repository_test.py::test_missing_executable tests/repository_test.py::test_missing_pcre_support tests/repository_test.py::test_run_a_script_hook tests/repository_test.py::test_run_hook_with_spaced_args tests/repository_test.py::test_run_hook_with_curly_braced_arguments tests/repository_test.py::test_pcre_hook_no_match tests/repository_test.py::test_pcre_hook_matching tests/repository_test.py::test_pcre_hook_case_insensitive_option tests/repository_test.py::test_pcre_many_files tests/repository_test.py::test_cwd_of_hook tests/repository_test.py::test_lots_of_files tests/repository_test.py::test_venvs tests/repository_test.py::test_additional_dependencies tests/repository_test.py::test_additional_dependencies_duplicated tests/repository_test.py::test_additional_python_dependencies_installed tests/repository_test.py::test_additional_dependencies_roll_forward tests/repository_test.py::test_additional_node_dependencies_installed tests/repository_test.py::test_reinstall tests/repository_test.py::test_control_c_control_c_on_install tests/repository_test.py::test_really_long_file_paths tests/repository_test.py::test_config_overrides_repo_specifics tests/repository_test.py::test_tags_on_repositories tests/repository_test.py::test_local_repository tests/repository_test.py::test_local_python_repo tests/repository_test.py::test_hook_id_not_present tests/repository_test.py::test_too_new_version tests/repository_test.py::test_versions_ok[0.1.0] tests/repository_test.py::test_versions_ok[0.13.6]
pre_commit/main.py
pre_commit/main.py