1#!/bin/sh 2"""": # -*-python-*- 3# https://sourceware.org/bugzilla/show_bug.cgi?id=26034 4export "BUP_ARGV_0"="$0" 5arg_i=1 6for arg in "$@"; do 7 export "BUP_ARGV_${arg_i}"="$arg" 8 shift 9 arg_i=$((arg_i + 1)) 10done 11# Here to end of preamble replaced during install 12bup_python="$(dirname "$0")/../../config/bin/python" || exit $? 13exec "$bup_python" "$0" 14""" 15# end of bup preamble 16 17from __future__ import absolute_import 18from binascii import hexlify 19import os, sys 20 21sys.path[:0] = [os.path.dirname(os.path.realpath(__file__)) + '/..'] 22 23from bup import compat, git, options 24from bup.compat import argv_bytes 25from bup.helpers import debug1, handle_ctrl_c, log 26from bup.io import byte_stream, path_msg 27 28# FIXME: review for safe writes. 29 30handle_ctrl_c() 31 32optspec = """ 33bup tag 34bup tag [-f] <tag name> <commit> 35bup tag [-f] -d <tag name> 36-- 37d,delete= Delete a tag 38f,force Overwrite existing tag, or ignore missing tag when deleting 39""" 40 41o = options.Options(optspec) 42opt, flags, extra = o.parse(compat.argv[1:]) 43 44git.check_repo_or_die() 45 46tags = [t for sublist in git.tags().values() for t in sublist] 47 48if opt.delete: 49 # git.delete_ref() doesn't complain if a ref doesn't exist. We 50 # could implement this verification but we'd need to read in the 51 # contents of the tag file and pass the hash, and we already know 52 # about the tag's existance via "tags". 53 tag_name = argv_bytes(opt.delete) 54 if not opt.force and tag_name not in tags: 55 log("error: tag '%s' doesn't exist\n" % path_msg(tag_name)) 56 sys.exit(1) 57 tag_file = b'refs/tags/%s' % tag_name 58 git.delete_ref(tag_file) 59 sys.exit(0) 60 61if not extra: 62 for t in tags: 63 sys.stdout.flush() 64 out = byte_stream(sys.stdout) 65 out.write(t) 66 out.write(b'\n') 67 sys.exit(0) 68elif len(extra) != 2: 69 o.fatal('expected commit ref and hash') 70 71tag_name, commit = map(argv_bytes, extra[:2]) 72if not tag_name: 73 o.fatal("tag name must not be empty.") 74debug1("args: tag name = %s; commit = %s\n" 75 % (path_msg(tag_name), commit.decode('ascii'))) 76 77if tag_name in tags and not opt.force: 78 log("bup: error: tag '%s' already exists\n" % path_msg(tag_name)) 79 sys.exit(1) 80 81if tag_name.startswith(b'.'): 82 o.fatal("'%s' is not a valid tag name." % path_msg(tag_name)) 83 84try: 85 hash = git.rev_parse(commit) 86except git.GitError as e: 87 log("bup: error: %s" % e) 88 sys.exit(2) 89 90if not hash: 91 log("bup: error: commit %s not found.\n" % commit.decode('ascii')) 92 sys.exit(2) 93 94pL = git.PackIdxList(git.repo(b'objects/pack')) 95if not pL.exists(hash): 96 log("bup: error: commit %s not found.\n" % commit.decode('ascii')) 97 sys.exit(2) 98 99tag_file = git.repo(b'refs/tags/' + tag_name) 100try: 101 tag = open(tag_file, 'wb') 102except OSError as e: 103 log("bup: error: could not create tag '%s': %s" % (path_msg(tag_name), e)) 104 sys.exit(3) 105with tag as tag: 106 tag.write(hexlify(hash)) 107 tag.write(b'\n') 108