Repository navigation
Expand file tree
/
Copy pathgit_checkout_latest.zsh
More file actions
executable file
·104 lines (92 loc) · 4.29 KB
/
Copy pathgit_checkout_latest.zsh
File metadata and controls
executable file
·104 lines (92 loc) · 4.29 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
#!/bin/zsh
# Checks out latest tag into a branch
# Copyright (c) 2025 Maulik Mistry mistry01@gmail.com
# Please share support: https://www.paypal.com/paypalme/m1st0
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License included at LICENSE.TXT or
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Fetch all tags and branches from all remotes
printf "Fetching all tags and branches from all remotes...\n"
git fetch --tags --prune
git fetch --all
# Set the remote to check for updates.
# Tries to guess the user's remote name from the Git config.
# Defaults to 'origin' or 'upstream' if a custom name isn't found.
GIT_USER=$(git config --global user.name 2>/dev/null | tr -d '[:space:]')
if [[ -n "${GIT_USER}" ]] && git remote | grep -q "^${GIT_USER}$"; then
UPDATE_REMOTE="${GIT_USER}"
elif git remote | grep -q "^upstream$"; then
UPDATE_REMOTE="upstream"
else
UPDATE_REMOTE="origin"
fi
printf "Using remote: %s\n" "${UPDATE_REMOTE}"
# Function to safely check out or create a branch
safe_checkout() {
local branch_name=$1
local remote_branch=$2
# Check if local branch exists
if git show-ref --verify --quiet "refs/heads/${branch_name}"; then
printf "Local branch '${branch_name}' exists. Checking if update needed...\n"
# Switch to the branch first
git checkout "${branch_name}"
# Check if the local branch is up to date with remote
local local_commit=$(git rev-parse "${branch_name}")
local remote_commit=$(git rev-parse "${remote_branch}" 2>/dev/null)
if [[ "${local_commit}" == "${remote_commit}" ]]; then
printf "Branch '${branch_name}' is already up to date. No changes needed.\n"
return 0
else
printf "Branch '${branch_name}' needs updating...\n"
# Check for uncommitted changes
if ! git diff --quiet || ! git diff --cached --quiet; then
printf "WARNING: You have uncommitted changes. Please commit or stash them first.\n"
git status --short
return 1
fi
# Safe to update
git reset --hard "${remote_branch}"
fi
else
printf "Creating new branch '${branch_name}'...\n"
git checkout -b "${branch_name}" "${remote_branch}"
fi
}
# Check if user provided a specific tag as argument
if [[ $# -eq 1 ]]; then
provided_tag="$1"
# Verify the tag exists
if git tag | grep -q "^${provided_tag}$"; then
printf "Found specified tag: ${provided_tag}. Checking it out...\n"
safe_checkout "${provided_tag}" "tags/${provided_tag}"
exit 0
fi
# Otherwise check for a 'release/' branch on the specified remote
elif git branch -r | grep -q "${UPDATE_REMOTE}/release/"; then
release_branch=$(git branch -r | grep "${UPDATE_REMOTE}/release/" | sort -V | tail -n 1 | xargs)
release_branch_name=${release_branch#${UPDATE_REMOTE}/}
printf "Found a release branch on '${UPDATE_REMOTE}': ${release_branch_name}.\n"
safe_checkout "${release_branch_name}" "${release_branch}"
# Otherwise check for the absolute latest tag
elif latest_tag=$(git tag --sort=-v:refname | head -n 1 2>/dev/null); then
printf "No release branch found. Checking out the latest tag: ${latest_tag}.\n"
safe_checkout "${latest_tag}" "tags/${latest_tag}"
# Otherwise fall back to the default branch on the specified remote
else
default_branch=$(git remote show "${UPDATE_REMOTE}" | grep 'HEAD branch' | awk '{print $NF}' | xargs)
if [[ -n "${default_branch}" ]]; then
printf "No release branch or tags found. Checking out the default branch from '${UPDATE_REMOTE}': '${default_branch}'.\n"
safe_checkout "${default_branch}" "${UPDATE_REMOTE}/${default_branch}"
else
printf "Could not find a default branch on '${UPDATE_REMOTE}'. Please check the repository manually.\n"
exit 1
fi
fi