SmartGit 是否可以设置和自动增加版本号?
我阅读了一些关于标签的内容并将其设置在我的初始分支上(设置为“5.7.0”)。我需要手动设置这个标签,还是有一个插件可以在幕后为我处理版本控制?
SmartGit 是否可以设置和自动增加版本号?
我阅读了一些关于标签的内容并将其设置在我的初始分支上(设置为“5.7.0”)。我需要手动设置这个标签,还是有一个插件可以在幕后为我处理版本控制?
Git 不关心版本,只关心提交哈希。:-)
我的解决方案是编写一对用作过滤器的脚本。这些脚本查找 $Date$ 和 $Revision$ 关键字并分别使用日期和版本(标签)扩展它们。
在我的~/.gitconfig
文件中,我有以下内容;
[filter "kw"]
clean = kwclean
smudge = kwset
这些是脚本(用 Python 编写)
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
#
# Author: R.F. Smith <rsmith@xs4all.nl>
# $Date: 2013-10-25 23:52:42 +0200 $
#
# To the extent possible under law, Roland Smith has waived all copyright and
# related or neighboring rights to kwset.py. This work is published from
# the Netherlands. See http://creativecommons.org/publicdomain/zero/1.0/
"""Fill the Date and Revision keywords from the latest git commit and tag and
subtitutes them in the standard input."""
import os
import sys
import subprocess
import re
def gitdate():
"""Get the date from the latest commit in ISO8601 format.
"""
args = ['git', 'log', '-1', '--date=iso']
dline = [l for l in subprocess.check_output(args).splitlines()
if l.startswith('Date')]
try:
dat = dline[0][5:].strip()
return ''.join(['$', 'Date: ', dat, ' $'])
except IndexError:
raise ValueError('Date not found in git output')
def gitrev():
"""Get the latest tag and use it as the revision number. This presumes the
habit of using numerical tags. Use the short hash if no tag available.
"""
args = ['git', 'describe', '--tags', '--always']
try:
with open(os.devnull, 'w') as bb:
r = subprocess.check_output(args, stderr=bb)[:-1]
except subprocess.CalledProcessError:
return ''.join(['$', 'Revision', '$'])
return ''.join(['$', 'Revision: ', r, ' $'])
def main():
"""Main program.
"""
dre = re.compile(''.join([r'\$', r'Date:?\$']))
rre = re.compile(''.join([r'\$', r'Revision:?\$']))
currp = os.getcwd()
if not os.path.exists(currp+'/.git'):
print >> sys.stderr, 'This directory is not controlled by git!'
sys.exit(1)
date = gitdate()
rev = gitrev()
for line in sys.stdin:
line = dre.sub(date, line)
print rre.sub(rev, line),
if __name__ == '__main__':
main()
和
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
#
# Author: R.F. Smith <rsmith@xs4all.nl>
# $Date: 2013-07-23 16:14:31 +0200 $
#
# To the extent possible under law, Roland Smith has waived all copyright and
# related or neighboring rights to kwclean.py. This work is published from the
# Netherlands. See http://creativecommons.org/publicdomain/zero/1.0/
"""Remove the Date and Revision keyword contents from the standard input."""
import sys
import re
## This is the main program ##
if __name__ == '__main__':
dre = re.compile(''.join([r'\$', r'Date.*\$']))
drep = ''.join(['$', 'Date', '$'])
rre = re.compile(''.join([r'\$', r'Revision.*\$']))
rrep = ''.join(['$', 'Revision', '$'])
for line in sys.stdin:
line = dre.sub(drep, line)
print rre.sub(rrep, line),
在.gitattributes
存储库中的文件中,我指定哪些文件应该更新其关键字,例如:
*.py filter=kw
签入新版本后,我使用git tag
. 然后我运行一个脚本来更新所有有关键字的文件;
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
#
# Author: R.F. Smith <rsmith@xs4all.nl>
# $Date: 2013-10-25 23:52:42 +0200 $
# $Revision: e1e28c9 $
#
# To the extent possible under law, Roland Smith has waived all copyright and
# related or neighboring rights to update-all-keywords.py. This work is
# published from the Netherlands.
# See http://creativecommons.org/publicdomain/zero/1.0/
"""Remove and check out all files under git's control that contain keywords in
the current working directory."""
from __future__ import print_function, division
import os
import mmap
import sys
import subprocess
def checkfor(args):
"""Make sure that a program necessary for using this script is
available.
Arguments:
args -- string or list of strings of commands. A single string may
not contain spaces.
"""
if isinstance(args, str):
if ' ' in args:
raise ValueError('No spaces in single command allowed.')
args = [args]
try:
with open(os.devnull, 'w') as bb:
subprocess.check_call(args, stdout=bb, stderr=bb)
except subprocess.CalledProcessError:
print("Required program '{}' not found! exiting.".format(args[0]))
sys.exit(1)
def git_ls_files():
"""Find ordinary files that are controlled by git.
:returns: A list of files
"""
args = ['git', 'ls-files']
flist = subprocess.check_output(args).splitlines()
return flist
def git_not_checkedin():
"""Find files that are modified but are not checked in.
:returns: A list of modified files that are not checked in.
"""
lns = subprocess.check_output(['git', 'status', '-s']).splitlines()
lns = [l.split()[-1] for l in lns]
return lns
def keywordfiles(fns):
"""Filter those files that have keywords in them
:fns: A list of filenames
:returns: A list for filenames for files that contain keywords.
"""
# These lines are encoded otherwise they would be mangled if this file
# is checked in!
datekw = 'JERhdGU='.decode('base64')
revkw = 'JFJldmlzaW9u'.decode('base64')
rv = []
for fn in fns:
with open(fn, 'rb') as f:
try:
mm = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ)
if mm.find(datekw) > -1 or mm.find(revkw) > -1:
rv.append(fn)
mm.close()
except ValueError:
pass
return rv
def main(args):
"""Main program.
:args: command line arguments
"""
# Check if git is available.
checkfor(['git', '--version'])
# Check if .git exists
if not os.access('.git', os.F_OK):
print('No .git directory found!')
sys.exit(1)
# Get all files that are controlled by git.
files = git_ls_files()
# Remove those that aren't checked in
mod = git_not_checkedin()
if mod:
files = [f for f in files if not f in mod]
if not files:
print('{}: Only uncommitted changes, nothing to do.'.format(args[0]))
sys.exit(0)
files.sort()
# Find files that have keywords in them
kwfn = keywordfiles(files)
if kwfn:
print('{}: Updating all files.'.format(args[0]))
for fn in kwfn:
os.remove(fn)
args = ['git', 'checkout', '-f'] + kwfn
subprocess.call(args)
else:
print('{}: Nothing to update.'.format(args[0]))
if __name__ == '__main__':
main(sys.argv)