Skip to content
Newer
Older
100755 137 lines (112 sloc) 3.07 KB
0ad12f0 @falconindy retroTag: initial commit. retroactive git tagging script
authored Aug 17, 2010
1 #!/bin/bash
2
3 #
4 # written for alex to retroactively tag his repos based on a VERSION file which
5 # was conveniently bumped for each of his "releases".
6 #
7
8 declare -a commits
f912c7e @falconindy retroTag: fix typo
authored Aug 18, 2010
9 declare -a existing_tags
0ad12f0 @falconindy retroTag: initial commit. retroactive git tagging script
authored Aug 18, 2010
10
11 die() {
12 local mesg=$1; shift
13 printf "\033[1;31m::\033[0m ${mesg}\n" "$@" >&2
14 }
15
16 warn() {
17 local mesg=$1; shift
18 printf "\033[1;33m::\033[0m ${mesg}\n" "$@" >&2
19 }
20
21 info() {
22 local mesg=$1; shift
23 printf " \033[1;34m::\033[1;0m\033[1;1m ${mesg}\033[1;0m\n" "$@"
24 }
25
26 msg() {
27 local mesg=$1; shift
28 printf " \033[1;32m==>\033[1;0m\033[1;1m ${mesg}\033[1;0m\n" "$@"
29 }
30
31 in_array() {
32 local item needle=$1; shift
33 [[ -z "$1" ]] && return 1 # Not Found
34 for item; do
35 [[ $item = "$needle" ]] && return 0 # Found
36 done
37 return 1 # Not Found
38 }
39
40 check_repo_sanity() {
41 if ! git rev-parse --quiet --verify HEAD &>/dev/null; then
42 die "error: Not in a git repo"
43 exit 1
44 fi
45 if ! git diff-index --quiet HEAD; then
46 die "error: repo is dirty. Please commit or stash your changes before running this script."
47 exit 1
48 fi
49 }
50
51 find_taggable_commits() {
52 local commit action file
53
54 while read -r line; do
55 [[ $line =~ ^$ ]] && continue
56 if [[ ! $line =~ ^: ]]; then
57 # current commit being examined
58 read commit <<< $line
59 continue
60 fi
61
62 # parse file change information
63 read -r _ _ _ _ action file <<< $line
64 if [[ $action =~ [AM] && $file == "VERSION" ]]; then
65 commits+=("$commit")
66 fi
67 done < <(git whatchanged --format="%H %ai")
68
69 if (( ${#commits[@]} == 0 )); then
70 die "error: No candidate commits were found for tagging" >&2
71 exit 1
72 fi
73 }
74
75 get_existing_tags() {
76 IFS=$'\n' read -r -d'\0' -a existing_tags < <(git tag)
77 }
78
366d70a @falconindy retroTag: review_commits() => review_candidates()
authored Aug 17, 2010
79 review_candidates() {
0ad12f0 @falconindy retroTag: initial commit. retroactive git tagging script
authored Aug 18, 2010
80 msg "Found ${#commits[@]} commits worthy of tagging. Press enter to review the commits."
81 read
82 for commit in "${commits[@]}"; do
83 read hash date <<< $commit
84 git show --stat $hash
85 done
86 }
87
88 ask_abort() {
89 read -N1 -p "Satisfied? Continue with tagging? (y/N) " reply
a4726de @falconindy s/echo/printf/ -- and some extra juju to go with
authored Dec 28, 2010
90 printf "\n"
91 [[ ! "$reply" =~ [Yy] ]] && { printf "Aborting...\n"; exit 1; }
0ad12f0 @falconindy retroTag: initial commit. retroactive git tagging script
authored Aug 18, 2010
92 }
93
94 tag_commits() {
95 local count=0
96
97 for commit in "${commits[@]}"; do
98 read hash date <<< $commit
99 [[ -z $hash || -z $date ]] && { die "Fatal error! Something is horribly wrong!"; exit 42; }
100
101 # make a new branch, rewound to the commit
102 git checkout $hash -b $hash &>/dev/null
103
104 read version < VERSION
105
106 # if the tag exists, skip tagging
107 if in_array $version "${existing_tags[@]}"; then
108 warn "Tag \"$version\" already exists. Skipping..."
109 else
110 GIT_COMMITTER_DATE="$date" git tag -a "$version" -m "tag as $version" &>/dev/null
111 info "${hash:0:8} => $version"
112 (( ++count ))
113 fi
114
115 # reset for next iteration
116 { git checkout master; git branch -d $hash; } &>/dev/null
117 unset hash date
118 done
119
120 if (( count > 0 )); then
a4726de @falconindy s/echo/printf/ -- and some extra juju to go with
authored Dec 29, 2010
121 printf "\n"
0ad12f0 @falconindy retroTag: initial commit. retroactive git tagging script
authored Aug 18, 2010
122 msg "Finished: Added $count new tags. Use \`git push --tags\` to update the remote."
123 else
a4726de @falconindy s/echo/printf/ -- and some extra juju to go with
authored Dec 29, 2010
124 printf "\n"
0ad12f0 @falconindy retroTag: initial commit. retroactive git tagging script
authored Aug 18, 2010
125 msg "Finished: No new tags were added."
126 fi
127 }
128
129 # main loop
130 check_repo_sanity
131 find_taggable_commits
132 get_existing_tags
366d70a @falconindy retroTag: review_commits() => review_candidates()
authored Aug 18, 2010
133 review_candidates
0ad12f0 @falconindy retroTag: initial commit. retroactive git tagging script
authored Aug 18, 2010
134 ask_abort
135 tag_commits
136
Something went wrong with that request. Please try again.