forked from plume-lib/plume-scripts
-
Notifications
You must be signed in to change notification settings - Fork 4
/
git-clone-related
executable file
·159 lines (144 loc) · 6.21 KB
/
git-clone-related
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
#!/bin/sh
###
### This script has been moved to the git-scripts repository:
### https://github.com/plume-lib/git-scripts
###
echo "Please use $(basename "$0") from https://github.com/plume-lib/git-scripts ."
echo "You are using $0,"
echo "which is an obsolete version from https://github.com/plume-lib/plume-scripts ."
# git-clone-related: clones a repository that is related to this one,
# or pulls it if it has already been cloned.
#
# Sometimes, two repositories are related: you need clones of both of them.
# When run from a clone of one (possibly in a fork and/or on a branch), this
# clones the other, attempting to find a matching fork and branch.
# This script also works in an Azure Pipelines, CircleCI, GitHub Actions, or
# Travis CI job; in a CI job, it uses (for example) the pull request's branch
# name even if the CI system uses a different branch name for its local clone.
# (On CircleCI, it depends on environment variable CIRCLE_COMPARE_URL;
# see documentation of `ci-info` script for details.)
#
# Usage: git-clone-related [ARGS] UPSTREAM_ORG REPO_NAME [DESTINATION] [GIT_CLONE_ARGS...]
# ARGS are:
# --upstream-branch FALLBACK_BRANCH
# the branch name to use if there is no branch matching this clone's
# branch name. If not specified (or if no branch of the given name
# exists), uses the default branch name (often "master" or "main").
# --debug print logging information
# UPSTREAM_ORG is, if this is a fork, the parent organization.
# REPO_NAME is the repository name without the organization.
# DESTINATION is the new clone (not its parent), by default ../REPO_NAME .
# If it exists, it is updated via "git pull", without changing its fork
# or branch. No error is issued if the pull fails.
# GIT_CLONE_ARGS is extra arguments to git clone. It defaults to
# "-q --single-branch --depth 1" (without the quotes).
# It is not used if the destination already exists.
#
# When invoked from within a clone of MYORG/MYREPO, at branch MYBRANCH,
# this script chooses the first of these that exists:
# branch ${MYBRANCH} of https://github.com/${MYORG}/${REPO_NAME}.git
# branch ${MYBRANCH} of https://github.com/${UPSTREAM_ORG}/${REPO_NAME}.git
# branch ${FALLBACK_BRANCH} of https://github.com/${UPSTREAM_ORG}/${REPO_NAME}.git
#
# Requires the `jq` program to be installed, when used in Azure Pipelines jobs.
# Do not attempt to add "--filter=blob:none" to the git command, as older git
# clients (apparently including GitHub, as of 2024-01-27) do not support it.
# Fail if any command fails.
set +e
if [ "$1" = "--debug" ] ; then
DEBUG=1
shift
set -x
fi
# FALLBACK_BRANCH may be unset.
if [ "$1" = "--upstream-branch" ] ; then
shift
FALLBACK_BRANCH=$1
shift
fi
if [ "$#" -lt 2 ]; then
echo "Usage: $0 UPSTREAM_ORG REPO [DESTINATION] [GIT_CLONE_ARGS...]" >&2
exit 1
fi
beginswith() { case $2 in "$1"*) true;; *) false;; esac; }
UPSTREAM_ORG=$1; shift
REPO_NAME=$1; shift
if [ "$#" -ne 0 ] && ! beginswith "-" "$1"; then
DESTINATION=$1; shift
if [ -d "$DESTINATION" ] && [ "$(pwd -P)" = "$(cd "$DESTINATION"; pwd -P)" ]; then
echo "git-clone-related: destination is same as current directory"
exit 1
fi
else
if [ "${REPO_NAME}" = "${PWD##*/}" ]; then
echo "git-clone-related: provide a destination argument"
exit 1
fi
DESTINATION=../${REPO_NAME}
fi
if [ "$#" -eq 0 ]; then
set -- -q --single-branch --depth 1
fi
if [ -n "$DEBUG" ] ; then
echo "Entering git-clone-related $UPSTREAM_ORG $REPO_NAME $DESTINATION $*"
fi
echo "In directory $(pwd) :"
if [ -d "${DESTINATION}" ]; then
echo "(cd ${DESTINATION} && git pull -q)"
# Use "cd" because older versions of git (eg, CircleCI) don't support the -C command-line option.
# In a Travis pull request, a repository can be in state "(HEAD detached at b475d58d)"
# and "git pull" fails.
(cd "${DESTINATION}" && (git pull -q || (git branch && true)))
else
SCRIPTDIR="$(cd "$(dirname "$0")" && pwd -P)"
CI_INFO="$SCRIPTDIR/../plume-scripts/ci-info"
if [ ! -f "$CI_INFO" ] ; then
CI_INFO="$SCRIPTDIR/../.plume-scripts/ci-info"
fi
if [ ! -f "$CI_INFO" ] ; then
CI_INFO="$SCRIPTDIR/.plume-scripts/ci-info"
fi
if [ ! -f "$CI_INFO" ] ; then
(cd "$SCRIPTDIR" && git clone --depth 1 https://github.com/plume-lib/plume-scripts .plume-scripts)
fi
if [ ! -f "$CI_INFO" ] ; then
echo "CI_INFO does not exist: $CI_INFO"
exit 1
fi
if [ -n "$DEBUG" ] ; then
echo "About to run ci-info --debug"
"${CI_INFO}" --debug "${UPSTREAM_ORG}"
echo "Ran ci-info --debug"
echo "About to run ci-info"
fi
eval "$("${CI_INFO}" "${UPSTREAM_ORG}")"
if [ -n "$DEBUG" ] ; then
echo "Finished running ci-info"
fi
UPSTREAM_REPO_URL="https://github.com/${UPSTREAM_ORG}/${REPO_NAME}.git"
if [ -n "$DEBUG" ] ; then
echo "About to run git-find-fork" "${CI_ORGANIZATION}" "${UPSTREAM_ORG}" "${REPO_NAME}"
fi
# REPO_URL is what will be cloned. It might be the same as UPSTREAM_REPO_URL.
REPO_URL=$("${SCRIPTDIR}"/git-find-fork "${CI_ORGANIZATION}" "${UPSTREAM_ORG}" "${REPO_NAME}")
if [ -n "$DEBUG" ] ; then
echo "git-find-fork ${CI_ORGANIZATION} ${UPSTREAM_ORG} ${REPO_NAME} => ${REPO_URL}"
fi
if [ -n "$DEBUG" ] ; then
echo "About to run git-find-branch" "${REPO_URL}" "${CI_BRANCH_NAME}" ${FALLBACK_BRANCH:+"$FALLBACK_BRANCH"}
fi
REPO_BRANCH=$("${SCRIPTDIR}"/git-find-branch "${REPO_URL}" "${CI_BRANCH_NAME}" ${FALLBACK_BRANCH:+"$FALLBACK_BRANCH"})
if [ -n "$DEBUG" ] ; then
echo "git-find-branch ${REPO_URL} ${CI_BRANCH_NAME} => ${REPO_BRANCH}"
fi
if [ "$UPSTREAM_REPO_URL" != "$REPO_URL" ] && [ "$REPO_BRANCH" != "$CI_BRANCH_NAME" ] ; then
## Don't use the fallback branch (e.g., master) of the downstream repo
REPO_URL="$UPSTREAM_REPO_URL"
REPO_BRANCH=$("${SCRIPTDIR}"/git-find-branch "${REPO_URL}" "${CI_BRANCH_NAME}" ${FALLBACK_BRANCH:+"$FALLBACK_BRANCH"})
fi
echo "git clone -b ${REPO_BRANCH} $* ${REPO_URL} ${DESTINATION}"
# Try twice in case of network lossage.
git clone --depth 1 -b "${REPO_BRANCH}" "$@" "${REPO_URL}" "${DESTINATION}" \
|| (sleep 60 && git clone --depth 1 -b "${REPO_BRANCH}" "$@" "${REPO_URL}" "${DESTINATION}")
fi
echo "Done in directory ${DESTINATION} : $(cd "${DESTINATION}" && git rev-parse HEAD)"