#!/bin/bash # Copyright 2011 The Native Client Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. set -Ceu GiveUp() { echo -n "*** " if [[ -n "$1" ]]; then # Print repo, do not output the trailing newline. echo -n "$1: " fi if [[ -n "$2" ]]; then # Print reason, do not output the trailing newline. echo -n "$2 " fi echo "Please update manually! ***" exit 0 } # Go to repository. my_repo="$@" if [[ -n "$my_repo" ]]; then cd "$my_repo" fi # Determine working branch. # We can't use 'git symbolic-ref HEAD' as it fails in detached HEAD state. status=`git status --branch --short --untracked-files=no` if [[ "$status" != "## HEAD (no branch)" ]]; then my_branch_ref=`git symbolic-ref HEAD` my_branch="${my_branch_ref#refs/heads/}" my_commit=`git rev-parse $my_branch_ref` else # Detached HEAD state - checkout branch that fits best. # In general, we can walk all suitable branches and pick one that is closer # to the commit we are at, or give up if ambiguity. # However, what we actually need most of the times is to change from the # pinned revision to master - try it. my_branch_ref="refs/heads/master" my_branch="master" my_commit=`git rev-parse $my_branch_ref` if [[ -z "$my_commit" ]]; then # No branch master? GiveUp "$my_repo" "Failed to pick a branch to change from detached HEAD." fi prev_commit=`git rev-parse HEAD` merge_base=`git merge-base $prev_commit $my_commit` if [[ "$merge_base" != "$prev_commit" ]]; then # HEAD and master have diverged? GiveUp "$my_repo" "Failed to pick a branch to change from detached HEAD." fi # Branch seems to fit, check it out. git checkout "$my_branch" fi # Now determine upstream branch and check tracking. upstream_branch_ref=`git for-each-ref --format='%(upstream)' $my_branch_ref` if [[ -z "$upstream_branch_ref" ]]; then GiveUp "$my_repo" "Failed to determine upstream branch." fi upstream_branch="${upstream_branch_ref#refs/remotes/}" upstream_commit=`git rev-parse $upstream_branch_ref` merge_base=`git merge-base $my_commit $upstream_commit` if [[ "$merge_base" = "$upstream_commit" ]]; then # We are on the tip of the remote branch already. exit 0 fi if [[ "$merge_base" = "$my_commit" ]]; then # We can fast-forward - do it. git rebase "$upstream_branch" "$my_branch" exit 0 fi # Need to resolve manually. GiveUp "$my_repo" "Working branch and upstream branch have diverged."