-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgit-find-branch-from-commit
More file actions
executable file
·168 lines (143 loc) · 5.64 KB
/
git-find-branch-from-commit
File metadata and controls
executable file
·168 lines (143 loc) · 5.64 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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
#!/bin/bash
# git-find-branch-from-commit: Find all branches that contain a specific commit
# Usage: git-find-branch-from-commit <commit-sha>
# The commit SHA must be at least 8 characters long.
# Bash completion function
_git_find_branch_from_commit_completion() {
local cur prev
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
# If we're completing the first argument, try to complete commit SHAs
if [ $COMP_CWORD -eq 1 ]; then
# Try to complete partial commit SHA
if [[ ${cur} =~ ^[0-9a-fA-F]+$ ]] && [ ${#cur} -ge 4 ]; then
# Get matching commit SHAs
local commits=$(git log --oneline --format="%h" 2>/dev/null | grep "^${cur}" | head -20)
if [ -n "$commits" ]; then
COMPREPLY=($(compgen -W "${commits}" -- "${cur}"))
fi
fi
fi
return 0
}
# If script is being sourced (for completion), register completion and return
if [[ "${BASH_SOURCE[0]}" != "${0}" ]]; then
# Script is being sourced
complete -F _git_find_branch_from_commit_completion git-find-branch-from-commit
complete -F _git_find_branch_from_commit_completion ./git-find-branch-from-commit
# Also register for git alias if it exists
complete -F _git_find_branch_from_commit_completion git find-branch-from-commit 2>/dev/null || true
return 0
fi
# Color codes
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
MAGENTA='\033[0;35m'
NC='\033[0m' # No Color
# Check if commit SHA argument is provided
if [ $# -eq 0 ]; then
echo -e "${RED}Error: Commit SHA is required.${NC}"
echo ""
echo "Usage: $0 <commit-sha>"
echo ""
echo " <commit-sha> : The commit SHA to search for (minimum 8 characters)"
echo ""
echo "Examples:"
echo " $0 abc12345"
echo " $0 abc1234567890def"
echo ""
exit 1
fi
COMMIT_SHA="$1"
# Validate commit SHA length (minimum 8 characters)
if [ ${#COMMIT_SHA} -lt 8 ]; then
echo -e "${RED}Error: Commit SHA must be at least 8 characters long.${NC}"
echo ""
echo "You provided: ${COMMIT_SHA} (${#COMMIT_SHA} characters)"
echo "Please provide at least 8 characters of the commit SHA."
echo ""
exit 1
fi
# Validate commit SHA format (should be hexadecimal)
if ! [[ "$COMMIT_SHA" =~ ^[0-9a-fA-F]+$ ]]; then
echo -e "${RED}Error: Invalid commit SHA format. Commit SHA must contain only hexadecimal characters (0-9, a-f, A-F).${NC}"
echo ""
exit 1
fi
# Check if the commit exists in the repository
if ! git rev-parse --verify "$COMMIT_SHA" >/dev/null 2>&1; then
echo -e "${RED}Error: Commit '$COMMIT_SHA' not found in this repository.${NC}"
echo ""
echo "Please verify:"
echo " 1. The commit SHA is correct"
echo " 2. You are in a git repository"
echo " 3. The commit exists in the repository (you may need to fetch from remote)"
echo ""
exit 1
fi
# Get the full commit SHA for display
FULL_COMMIT_SHA=$(git rev-parse "$COMMIT_SHA")
SHORT_SHA=$(git rev-parse --short "$COMMIT_SHA")
echo -e "${CYAN}Searching for branches containing commit: ${SHORT_SHA}${NC}"
echo -e "${CYAN}Full SHA: ${FULL_COMMIT_SHA}${NC}"
echo ""
# Get commit information
COMMIT_SUBJECT=$(git log -1 --format="%s" "$COMMIT_SHA" 2>/dev/null)
COMMIT_AUTHOR=$(git log -1 --format="%an" "$COMMIT_SHA" 2>/dev/null)
COMMIT_DATE=$(git log -1 --format="%ai" "$COMMIT_SHA" 2>/dev/null)
echo -e "${YELLOW}Commit Information:${NC}"
echo -e " Subject: ${COMMIT_SUBJECT}"
echo -e " Author: ${COMMIT_AUTHOR}"
echo -e " Date: ${COMMIT_DATE}"
echo ""
# Create temporary file for branches
TEMP_FILE=$(mktemp)
trap "rm -f $TEMP_FILE" EXIT
echo -e "${CYAN}Scanning all branches...${NC}"
# Get all branches (local and remote)
BRANCH_COUNT=0
while IFS= read -r branch; do
# Check if this branch contains the commit
if git branch --contains "$COMMIT_SHA" --all 2>/dev/null | grep -q "^[ *]*${branch}$" || \
git branch -r --contains "$COMMIT_SHA" 2>/dev/null | grep -q "${branch}"; then
# Normalize branch name: remove 'remotes/' and remote name, keep only branch name
normalized_branch=$(echo "$branch" | sed 's/^remotes\/[^/]*\///' | sed 's/^\*\? *//')
echo "$normalized_branch" >> "$TEMP_FILE"
((BRANCH_COUNT++))
fi
done < <(git branch -a | grep -v HEAD | sed 's/^\*\? *//' | sort -u)
# Alternative method: use git branch --contains directly
# This is more reliable
git branch -a --contains "$COMMIT_SHA" 2>/dev/null | grep -v HEAD | sed 's/^\*\? *//' | sed 's/^remotes\/[^/]*\///' | sort -u > "$TEMP_FILE" 2>/dev/null
# Count unique branches
BRANCH_COUNT=$(sort -u "$TEMP_FILE" | wc -l | tr -d ' ')
if [ "$BRANCH_COUNT" -eq 0 ] || [ ! -s "$TEMP_FILE" ]; then
echo -e "${YELLOW}No branches found containing commit ${SHORT_SHA}.${NC}"
echo ""
echo "This could mean:"
echo " - The commit exists but is not in any branch"
echo " - The commit is in a detached HEAD state"
echo " - You may need to fetch from remote repositories"
echo ""
exit 0
fi
echo -e "${GREEN}Found ${BRANCH_COUNT} branch(es) containing commit ${SHORT_SHA}:${NC}"
echo ""
# Display branches
while IFS= read -r branch; do
if [ -n "$branch" ]; then
# Check if it's a local or remote branch
if git show-ref --verify --quiet refs/heads/"$branch" 2>/dev/null; then
echo -e " ${GREEN}*${NC} ${branch} ${CYAN}(local)${NC}"
elif git show-ref --verify --quiet refs/remotes/*/"$branch" 2>/dev/null; then
echo -e " ${YELLOW}*${NC} ${branch} ${CYAN}(remote)${NC}"
else
echo -e " ${YELLOW}*${NC} ${branch}"
fi
fi
done < <(sort -u "$TEMP_FILE")
echo ""