From 11116c2467710c9b3df37164dce2bb012a205d33 Mon Sep 17 00:00:00 2001 From: Mike McQuaid <mike@mikemcquaid.com> Date: Wed, 10 Aug 2016 09:33:47 +0100 Subject: [PATCH] update.sh: further speed up `brew update`. Tweak the logic further to make the no-op case even faster. Before: ``` brew update 1.10s user 1.05s system 92% cpu 2.325 total brew update --preinstall 0.60s user 0.77s system 96% cpu 1.433 total ``` After: ``` brew update 0.60s user 0.34s system 83% cpu 1.132 total brew update --preinstall 0.29s user 0.24s system 62% cpu 0.860 total ``` These times are now fast enough to avoid any further special-casing for `--preinstall`, roll it out to users by default and not print a message unless we've actually found some updates. --- Library/Homebrew/cmd/update.sh | 113 +++++++++++++++++++++------------ 1 file changed, 74 insertions(+), 39 deletions(-) diff --git a/Library/Homebrew/cmd/update.sh b/Library/Homebrew/cmd/update.sh index 4121078e14..2e40d1d428 100644 --- a/Library/Homebrew/cmd/update.sh +++ b/Library/Homebrew/cmd/update.sh @@ -166,7 +166,35 @@ reset_on_interrupt() { exit 130 } -pull() { +# 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" +simulate_from_current_branch() { + local DIR + local TAP_VAR + local UPSTREAM_BRANCH + local CURRENT_REVISION + + DIR="$1" + cd "$DIR" || return + TAP_VAR="$2" + UPSTREAM_BRANCH="$3" + CURRENT_REVISION="$4" + + INITIAL_REVISION="$(git rev-parse -q --verify "$UPSTREAM_BRANCH")" + export HOMEBREW_UPDATE_BEFORE"$TAP_VAR"="$INITIAL_REVISION" + export HOMEBREW_UPDATE_AFTER"$TAP_VAR"="$CURRENT_REVISION" + if [[ "$INITIAL_REVISION" != "$CURRENT_REVISION" ]] + then + HOMEBREW_UPDATED="1" + fi + if ! git merge-base --is-ancestor "$INITIAL_REVISION" "$CURRENT_REVISION" + then + odie "Your $DIR HEAD is not a descendant of $UPSTREAM_BRANCH!" + fi +} + +merge_or_rebase() { if [[ -n "$HOMEBREW_VERBOSE" ]] then echo "Updating $DIR..." @@ -174,38 +202,14 @@ pull() { local DIR local TAP_VAR + local UPSTREAM_BRANCH DIR="$1" cd "$DIR" || return - TAP_VAR=$(repo_var "$DIR") + TAP_VAR="$2" + UPSTREAM_BRANCH="$3" 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)" - - # 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" - 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_BEFORE"$TAP_VAR"="$INITIAL_REVISION" - export HOMEBREW_UPDATE_AFTER"$TAP_VAR"="$CURRENT_REVISION" - if [[ "$INITIAL_REVISION" != "$CURRENT_REVISION" ]] - then - HOMEBREW_UPDATED="1" - fi - if ! git merge-base --is-ancestor "$INITIAL_REVISION" "$CURRENT_REVISION" - then - odie "Your $DIR HEAD is not a descendant of $UPSTREAM_BRANCH!" - fi - return - fi - trap reset_on_interrupt SIGINT if [[ -n "$(git status --untracked-files=all --porcelain 2>/dev/null)" ]] @@ -223,6 +227,7 @@ pull() { STASHED="1" fi + INITIAL_BRANCH="$(git symbolic-ref --short HEAD 2>/dev/null)" if [[ "$INITIAL_BRANCH" != "$UPSTREAM_BRANCH" && -n "$INITIAL_BRANCH" ]] then # Recreate and check out `#{upstream_branch}` if unable to fast-forward @@ -329,11 +334,6 @@ user account: EOS fi - if [[ -n "$HOMEBREW_UPDATE_PREINSTALL" ]] - then - echo "Checking for Homebrew updates..." - fi - if ! git --version >/dev/null 2>&1 then # we cannot install brewed git if homebrew/core is unavailable. @@ -378,19 +378,34 @@ EOS for DIR in "$HOMEBREW_REPOSITORY" "$HOMEBREW_LIBRARY"/Taps/*/* do [[ -d "$DIR/.git" ]] || continue + cd "$DIR" || continue + + TAP_VAR="$(repo_var "$DIR")" + declare PREFETCH_REVISION"$TAP_VAR"="$(read_current_revision)" + [[ -n "$SKIP_FETCH_BREW_REPOSITORY" && "$DIR" = "$HOMEBREW_REPOSITORY" ]] && continue [[ -n "$SKIP_FETCH_CORE_REPOSITORY" && "$DIR" = "$HOMEBREW_LIBRARY/Taps/homebrew/homebrew-core" ]] && continue - cd "$DIR" || continue + + # 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". UPSTREAM_BRANCH="$(upstream_branch)" + declare UPSTREAM_BRANCH"$TAP_VAR"="$UPSTREAM_BRANCH" + # the refspec ensures that the default upstream branch gets updated ( if [[ -n "$HOMEBREW_UPDATE_PREINSTALL" ]] then # Skip taps checked/fetched recently - [[ -n "$(find "$DIR/.git/FETCH_HEAD" -type f -mmin -1 2>/dev/null)" ]] && exit - # Skip taps without formulae. - FORMULAE="$(find "$DIR" -maxdepth 1 \( -name "*.rb" -or -name Formula -or -name HomebrewFormula \) -print -quit)" - [[ -z "$FORMULAE" ]] && exit + [[ -n "$(find "$DIR/.git/FETCH_HEAD" -type f -mtime -60s 2>/dev/null)" ]] && exit + + # Skip taps without formulae (but always update Homebrew/brew and Homebrew/homebrew-core) + if [[ "$DIR" != "$HOMEBREW_REPOSITORY" && + "$DIR" != "$HOMEBREW_LIBRARY/Taps/homebrew/homebrew-core" ]] + then + FORMULAE="$(find "$DIR" -maxdepth 1 \( -name "*.rb" -or -name Formula -or -name HomebrewFormula \) -print -quit)" + [[ -z "$FORMULAE" ]] && exit + fi fi UPSTREAM_REPOSITORY_URL="$(git config remote.origin.url)" @@ -448,7 +463,27 @@ EOS for DIR in "$HOMEBREW_REPOSITORY" "$HOMEBREW_LIBRARY"/Taps/*/* do [[ -d "$DIR/.git" ]] || continue - pull "$DIR" + cd "$DIR" || continue + + TAP_VAR="$(repo_var "$DIR")" + UPSTREAM_BRANCH_VAR="UPSTREAM_BRANCH$TAP_VAR" + UPSTREAM_BRANCH="${!UPSTREAM_BRANCH_VAR}" + CURRENT_REVISION="$(read_current_revision)" + + PREFETCH_REVISION_VAR="PREFETCH_REVISION$TAP_VAR" + PREFETCH_REVISION="${!PREFETCH_REVISION_VAR}" + + if [[ -n "$HOMEBREW_SIMULATE_FROM_CURRENT_BRANCH" ]] + then + simulate_from_current_branch "$DIR" "$TAP_VAR" "$UPSTREAM_BRANCH" "$CURRENT_REVISION" + elif [[ "$PREFETCH_REVISION" = "$CURRENT_REVISION" ]] + then + export HOMEBREW_UPDATE_BEFORE"$TAP_VAR"="$CURRENT_REVISION" + export HOMEBREW_UPDATE_AFTER"$TAP_VAR"="$CURRENT_REVISION" + else + merge_or_rebase "$DIR" "$TAP_VAR" "$UPSTREAM_BRANCH" + fi + [[ -n "$HOMEBREW_VERBOSE" ]] && echo done -- GitLab