brew/Library/Homebrew/cmd/update-bash.sh

271 lines
7.1 KiB
Bash
Raw Normal View History

#!/bin/bash
2016-01-20 19:51:48 +08:00
if [[ -z "$HOMEBREW_BREW_FILE" ]]
then
# we don't use odie here, because it's only available when this script is called from brew.
echo "Error: $(basename "$0") must be called from brew!" >&2
exit 1
fi
brew() {
"$HOMEBREW_BREW_FILE" "$@"
}
which_git() {
local which_git
which_git="$(which git 2>/dev/null)"
2016-01-20 19:51:48 +08:00
if [[ -n "$which_git" && "/usr/bin/git" = "$which_git" ]]
then
local active_developer_dir
active_developer_dir="$('/usr/bin/xcode-select' -print-path 2>/dev/null)"
2016-01-20 19:51:48 +08:00
if [[ -n "$active_developer_dir" && -x "$active_developer_dir/usr/bin/git" ]]
then
which_git="$active_developer_dir/usr/bin/git"
else
which_git=""
fi
fi
echo "$which_git"
}
git_init_if_necessary() {
2016-01-20 19:51:48 +08:00
if [[ ! -d ".git" ]]
then
git init -q
git config --bool core.autocrlf false
git config remote.origin.url https://github.com/Homebrew/homebrew.git
git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
fi
2016-01-20 19:51:48 +08:00
if [[ "$(git remote show origin -n)" = *"mxcl/homebrew"* ]]
then
git remote set-url origin https://github.com/Homebrew/homebrew.git
git remote set-url --delete origin ".*mxcl\/homebrew.*"
fi
}
repo_var() {
echo "$1" |
sed -e "s|$HOMEBREW_PREFIX||g" \
-e 's|Library/Taps/||g' \
-e 's|[^a-z0-9]|_|g' |
tr "[:lower:]" "[:upper:]"
}
upstream_branch() {
local upstream_branch
upstream_branch="$(git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null)"
upstream_branch="${upstream_branch#refs/remotes/origin/}"
2016-01-20 19:51:48 +08:00
[[ -z "$upstream_branch" ]] && upstream_branch="master"
echo "$upstream_branch"
}
read_current_revision() {
git rev-parse -q --verify HEAD
}
# Don't warn about QUIET_ARGS; they need to be unquoted.
# shellcheck disable=SC2086
pop_stash() {
2016-01-20 19:51:48 +08:00
[[ -z "$STASHED" ]] && return
git stash pop $QUIET_ARGS
2016-01-20 19:51:48 +08:00
if [[ -n "$HOMEBREW_VERBOSE" ]]
then
echo "Restoring your stashed changes to $DIR:"
git status --short --untracked-files
fi
unset STASHED
}
pop_stash_message() {
2016-01-20 19:51:48 +08:00
[[ -z "$STASHED" ]] && return
echo "To restore the stashed changes to $DIR run:"
echo " 'cd $DIR && git stash pop'"
unset STASHED
}
# Don't warn about QUIET_ARGS; they need to be unquoted.
# shellcheck disable=SC2086
reset_on_interrupt() {
2016-01-20 19:51:48 +08:00
[[ -z "$INITIAL_BRANCH" ]] || git checkout "$INITIAL_BRANCH"
git reset --hard "$INITIAL_REVISION" $QUIET_ARGS
2016-01-20 19:51:48 +08:00
if [[ -n "$INITIAL_BRANCH" ]]
then
pop_stash
else
pop_stash_message
fi
}
# Don't warn about QUIET_ARGS; they need to be unquoted.
# shellcheck disable=SC2086
pull() {
local DIR="$1"
cd "$DIR" || return
TAP_VAR=$(repo_var "$DIR")
unset STASHED
# The upstream repository's default branch may not be master;
# check refs/remotes/origin/HEAD to see what the default
# origin branch name is, and use that. If not set, fall back to "master".
INITIAL_BRANCH="$(git symbolic-ref --short HEAD 2>/dev/null)"
UPSTREAM_BRANCH="$(upstream_branch)"
2016-01-20 19:51:48 +08:00
if [[ -n "$(git status --untracked-files=all --porcelain 2>/dev/null)" ]]
then
2016-01-20 19:51:48 +08:00
if [[ -n "$HOMEBREW_VERBOSE" ]]
then
echo "Stashing uncommitted changes to $DIR."
git status --short --untracked-files=all
fi
git -c "user.email=brew-update@localhost" \
-c "user.name=brew update" \
stash save --include-untracked $QUIET_ARGS
git reset --hard $QUIET_ARGS
STASHED="1"
fi
# Used for testing purposes, e.g., for testing formula migration after
# renaming it in the currently checked-out branch. To test run
# "brew update --simulate-from-current-branch"
2016-01-20 19:51:48 +08:00
if [[ -n "$HOMEBREW_SIMULATE_FROM_CURRENT_BRANCH" ]]
then
INITIAL_REVISION="$(git rev-parse -q --verify "$(upstream_branch)")"
CURRENT_REVISION="$(read_current_revision)"
export HOMEBREW_UPDATE_AFTER"$TAP_VAR"="$(git rev-parse "$UPSTREAM_BRANCH")"
if ! git merge-base --is-ancestor "$INITIAL_REVISION" "$CURRENT_REVISION"
then
odie "Your HEAD is not a descendant of $UPSTREAM_BRANCH!"
fi
return
fi
2016-01-20 19:51:48 +08:00
if [[ "$INITIAL_BRANCH" != "$UPSTREAM_BRANCH" && -n "$INITIAL_BRANCH" ]]
then
# Recreate and check out `#{upstream_branch}` if unable to fast-forward
# it to `origin/#{@upstream_branch}`. Otherwise, just check it out.
if git merge-base --is-ancestor "$UPSTREAM_BRANCH" "origin/$UPSTREAM_BRANCH" &>/dev/null
then
git checkout --force "$UPSTREAM_BRANCH" $QUIET_ARGS
else
git checkout --force -B "$UPSTREAM_BRANCH" "origin/$UPSTREAM_BRANCH" $QUIET_ARGS
fi
fi
INITIAL_REVISION="$(read_current_revision)"
# ensure we don't munge line endings on checkout
git config core.autocrlf false
trap reset_on_interrupt SIGINT
2016-01-20 19:51:48 +08:00
if [[ -n "$HOMEBREW_REBASE" ]]
then
git rebase $QUIET_ARGS "origin/$UPSTREAM_BRANCH"
else
git merge --no-edit --ff $QUIET_ARGS "origin/$UPSTREAM_BRANCH"
fi
trap - SIGINT
CURRENT_REVISION="$(read_current_revision)"
export HOMEBREW_UPDATE_AFTER"$TAP_VAR"="$(git rev-parse "$UPSTREAM_BRANCH")"
2016-01-20 19:51:48 +08:00
if [[ "$INITIAL_BRANCH" != "$UPSTREAM_BRANCH" && -n "$INITIAL_BRANCH" ]]
then
git checkout "$INITIAL_BRANCH" $QUIET_ARGS
pop_stash
else
pop_stash_message
fi
}
update-bash() {
2016-01-20 19:51:48 +08:00
if [[ -z "$HOMEBREW_DEVELOPER" ]]
then
odie "This command is currently only for Homebrew developers' use."
fi
for i in "$@"
do
case "$i" in
update|update-bash) shift ;;
--help) brew update --help; exit $? ;;
--verbose) HOMEBREW_VERBOSE=1 ;;
--debug) HOMEBREW_DEBUG=1;;
--rebase) HOMEBREW_REBASE=1 ;;
--simulate-from-current-branch) HOMEBREW_SIMULATE_FROM_CURRENT_BRANCH=1 ;;
--*) ;;
-*v*) HOMEBREW_VERBOSE=1 ;;
-*d*) HOMEBREW_DEBUG=1 ;;
-*) ;;
*)
odie <<-EOS
This command updates brew itself, and does not take formula names.
Use 'brew upgrade <formula>'.
EOS
;;
esac
done
2016-01-20 19:51:48 +08:00
if [[ -n "$HOMEBREW_DEBUG" ]]
then
set -x
fi
# check permissions
2016-01-20 19:51:48 +08:00
if [[ "$HOMEBREW_PREFIX" = "/usr/local" && ! -w /usr/local ]]
then
odie "/usr/local must be writable!"
fi
2016-01-20 19:51:48 +08:00
if [[ ! -w "$HOMEBREW_REPOSITORY" ]]
then
odie "$HOMEBREW_REPOSITORY must be writable!"
fi
2016-01-20 19:51:48 +08:00
if [[ -z "$(which_git)" ]]
then
brew install git
2016-01-20 19:51:48 +08:00
if [[ -z "$(which_git)" ]]
then
odie "Git must be installed and in your PATH!"
fi
fi
2016-01-20 19:51:48 +08:00
if [[ -z "$HOMEBREW_VERBOSE" ]]
then
QUIET_ARGS="-q"
fi
# ensure GIT_CONFIG is unset as we need to operate on .git/config
unset GIT_CONFIG
chdir "$HOMEBREW_REPOSITORY"
git_init_if_necessary
for DIR in "$HOMEBREW_REPOSITORY" "$HOMEBREW_LIBRARY"/Taps/*/*
do
2016-01-20 19:51:48 +08:00
[[ -d "$DIR/.git" ]] || continue
cd "$DIR" || continue
TAP_VAR=$(repo_var "$DIR")
export HOMEBREW_UPDATE_BEFORE"$TAP_VAR"="$(git rev-parse "$(upstream_branch)")"
UPSTREAM_BRANCH="$(upstream_branch)"
# the refspec ensures that the default upstream branch gets updated
git fetch $QUIET_ARGS origin \
"refs/heads/$UPSTREAM_BRANCH:refs/remotes/origin/$UPSTREAM_BRANCH" &
done
wait
for DIR in "$HOMEBREW_REPOSITORY" "$HOMEBREW_LIBRARY"/Taps/*/*
do
2016-01-20 19:51:48 +08:00
[[ -d "$DIR/.git" ]] || continue
pull "$DIR"
done
chdir "$HOMEBREW_REPOSITORY"
brew update-report "$@"
return $?
}