forked from eisop-plume-lib/plume-scripts
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgit-clone-related
executable file
·129 lines (118 loc) · 5.19 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
#!/bin/sh
# 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.
# 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
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)"
if [ -n "$DEBUG" ] ; then
echo "About to run ci-info --debug"
"${SCRIPTDIR}/ci-info" --debug "${UPSTREAM_ORG}"
echo "Ran ci-info --debug"
echo "About to run ci-info"
fi
eval "$("${SCRIPTDIR}"/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 -b "${REPO_BRANCH}" "$@" "${REPO_URL}" "${DESTINATION}" \
|| git clone -b "${REPO_BRANCH}" "$@" "${REPO_URL}" "${DESTINATION}"
fi
echo "Done in directory ${DESTINATION} : $(cd "${DESTINATION}" && git rev-parse HEAD)"