filter-repo: add a --version option

Note that this isn't a version *number* or even the more generalized
version string that folks are used to seeing, but a version hash (or
leading portion thereof).

A few import points:

  * These version hashes are not strictly monotonically increasing
    values.  Like I said, these aren't version numbers.  If that
    bothers you, read on...

  * This scheme has incredibly nice semantics satisfying a pair of
    properties that most version schemes would assume are mutually
    incompatible:
       This scheme works even if the user doesn't have a clone of
       filter-repo and doesn't require any build step to inject the
       version into the program; it works even if people just download
       git-filter-repo.py off GitHub without any of the other sources.
    And:
       This scheme means that a user is running precisely version X of
       the code, with the version not easily faked or misrepresented
       when third parties edit the code.
    Given the wonderful semantics provided by satisfying this pair of
    properties that all other versioning schemes seem to miss out on, I
    think I should name this scheme.  How about "Semantic Versioning"?
    (Hehe...)

  * The version hash is super easy to use; I just go to my own clone of
    filter-repo and run either:
        git show $VERSION_HASH
    or
        git describe $VERSION_HASH

  * A human consumable version might suggest to folks that this software
    is something they might frequently use and upgrade.  This program
    should only be used in exceptional cases (because rewriting history
    is not for the faint of heart).

  * A human consumable version (i.e. a version number or even the
    more relaxed version strings in more common use) might suggest to
    folks that they can rely on strict backward compatibility.  It's
    nice to subtly undercut any such assumption.

  * Despite all that, I will make releases (downloadable tarballs with
    real version numbers in the tarball name; I'm just going to re-use
    whatever version git is released with at the time).  But those
    version numbers won't be used by the --version option; instead the
    version hash will.

Signed-off-by: Elijah Newren <newren@gmail.com>
This commit is contained in:
Elijah Newren 2019-10-18 09:07:46 -07:00
parent 1e21d6e2ec
commit e6dd613e3f
2 changed files with 24 additions and 0 deletions

View File

@ -1546,6 +1546,19 @@ class GitUtils(object):
return file_changes
@staticmethod
def print_my_version():
with open(sys.argv[0], 'br') as f:
contents = f.read()
# If people replaced @@LOCALEDIR@@ string to point at their local
# directory, undo it so we can get original source version.
contents = re.sub(br'(\("GIT_TEXTDOMAINDIR"\) or ").*"',
br'\1@@LOCALEDIR@@"', contents)
cmd = 'git hash-object --stdin'.split()
version = subprocess.check_output(cmd, input=contents).strip()
print(decode(version[0:12]))
class FilteringOptions(object):
class AppendFilter(argparse.Action):
def __call__(self, parser, namespace, values, option_string=None):
@ -1856,6 +1869,8 @@ EXAMPLES
misc = parser.add_argument_group(title=_("Miscellaneous options"))
misc.add_argument('--help', '-h', action='store_true',
help=_("Show this help message and exit."))
misc.add_argument('--version', action='store_true',
help=_("Display filter-repo's version and exit."))
misc.add_argument('--force', '-f', action='store_true',
help=_("Rewrite history even if the current repo does not look "
"like a fresh clone."))
@ -2075,6 +2090,9 @@ EXAMPLES
if args.help:
parser.print_help()
raise SystemExit()
if args.version:
GitUtils.print_my_version()
raise SystemExit()
FilteringOptions.sanity_check_args(args)
if args.mailmap:
args.mailmap = MailmapInfo(args.mailmap)

View File

@ -1352,4 +1352,10 @@ test_expect_success 'tweaking just a tag' '
)
'
test_expect_success '--version' '
git filter-repo --version >actual &&
git hash-object ../../git-filter-repo | colrm 13 >expect &&
test_cmp expect actual
'
test_done