-
Notifications
You must be signed in to change notification settings - Fork 10
Expand file tree
/
Copy pathgit-add-tag
More file actions
executable file
·76 lines (64 loc) · 2.03 KB
/
git-add-tag
File metadata and controls
executable file
·76 lines (64 loc) · 2.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#!/bin/bash
#
# Usage: git-add-tag <commit range>
#
# Description:
# Append a tag (e.g. Reviewed-by, Acked-by) to every commit in a range.
# Opens $EDITOR for you to type the tag line(s), then amends each commit.
#
# Examples:
# git-add-tag HEAD~3 # tag the last 3 commits
# git-add-tag abc123.. # tag abc123 to HEAD
#
set -euo pipefail
usage () {
sed -n -e '/^#$/,/^$/s/^#[ ]\?//p' "${BASH_SOURCE[0]}"
}
if [ $# -ne 1 ] || [ "$1" = "--help" ]; then
usage
exit 1
fi
range="$1"
# Determine the base commit for rebase.
# "A..B" → base is A, "A.." → base is A, "A" (no dots) → treat as "A.."
if [[ "$range" == *..* ]]; then
base="${range%%.*}"
tip="${range##*..}"
tip="${tip:-HEAD}"
else
base="$range"
tip="HEAD"
fi
# If the range doesn't end at HEAD we need to detach first, rebase, then
# restore. For simplicity, only support ranges ending at HEAD (the common case).
if [ "$tip" != "HEAD" ]; then
echo "Error: ranges not ending at HEAD are not supported." >&2
echo "Check out the end of your range first, then re-run." >&2
exit 1
fi
# Fake a .git directory so the editor gets syntax highlighting for commit messages
readonly TMPDIR_TAG=$(mktemp -d)
trap 'rm -rf "$TMPDIR_TAG"' EXIT
readonly FAKE_GIT_DIR="$TMPDIR_TAG/.git"
readonly TAG_FILE="$FAKE_GIT_DIR/COMMIT_EDITMSG"
mkdir -p "$FAKE_GIT_DIR"
# Let the user type the tag(s) to append
"${EDITOR:-vi}" "$TAG_FILE"
if [ ! -s "$TAG_FILE" ]; then
echo "Empty tag file, aborting." >&2
exit 1
fi
# Use git rebase --exec to amend each commit in the range.
# We append a blank line + the tag to each commit message.
# The exec command must be a single line (git >= 2.49 rejects newlines),
# so we write a helper script and point --exec at it.
readonly EXEC_SCRIPT="$TMPDIR_TAG/amend.sh"
cat > "$EXEC_SCRIPT" <<'SCRIPT'
#!/bin/bash
set -e
tag_file="$1"
msg=$(git log --format=%B -n1)
printf '%s\n\n%s\n' "$msg" "$(cat "$tag_file")" | git commit --amend -F -
SCRIPT
chmod +x "$EXEC_SCRIPT"
git rebase "$base" --exec "$EXEC_SCRIPT $TAG_FILE"