1#!/bin/bash
2# Copyright 2011 The Native Client Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6set -Ceu
7
8
9GiveUp() {
10  echo -n "*** "
11
12  if [[ -n "$1" ]]; then
13    # Print repo, do not output the trailing newline.
14    echo -n "$1: "
15  fi
16
17  if [[ -n "$2" ]]; then
18    # Print reason, do not output the trailing newline.
19    echo -n "$2 "
20  fi
21
22  echo "Please update manually! ***"
23  exit 0
24}
25
26
27# Go to repository.
28
29my_repo="$@"
30
31if [[ -n "$my_repo" ]]; then
32  cd "$my_repo"
33fi
34
35
36# Determine working branch.
37# We can't use 'git symbolic-ref HEAD' as it fails in detached HEAD state.
38
39status=`git status --branch --short --untracked-files=no`
40
41if [[ "$status" != "## HEAD (no branch)" ]]; then
42
43  my_branch_ref=`git symbolic-ref HEAD`
44  my_branch="${my_branch_ref#refs/heads/}"
45  my_commit=`git rev-parse $my_branch_ref`
46
47else
48
49  # Detached HEAD state - checkout branch that fits best.
50  # In general, we can walk all suitable branches and pick one that is closer
51  # to the commit we are at, or give up if ambiguity.
52  # However, what we actually need most of the times is to change from the
53  # pinned revision to master - try it.
54
55  my_branch_ref="refs/heads/master"
56  my_branch="master"
57  my_commit=`git rev-parse $my_branch_ref`
58
59  if [[ -z "$my_commit" ]]; then
60    # No branch master?
61    GiveUp "$my_repo" "Failed to pick a branch to change from detached HEAD."
62  fi
63
64  prev_commit=`git rev-parse HEAD`
65  merge_base=`git merge-base $prev_commit $my_commit`
66
67  if [[ "$merge_base" != "$prev_commit" ]]; then
68    # HEAD and master have diverged?
69    GiveUp "$my_repo" "Failed to pick a branch to change from detached HEAD."
70  fi
71
72  # Branch seems to fit, check it out.
73  git checkout "$my_branch"
74
75fi
76
77
78# Now determine upstream branch and check tracking.
79
80upstream_branch_ref=`git for-each-ref --format='%(upstream)' $my_branch_ref`
81
82if [[ -z "$upstream_branch_ref" ]]; then
83  GiveUp "$my_repo" "Failed to determine upstream branch."
84fi
85
86upstream_branch="${upstream_branch_ref#refs/remotes/}"
87upstream_commit=`git rev-parse $upstream_branch_ref`
88merge_base=`git merge-base $my_commit $upstream_commit`
89
90if [[ "$merge_base" = "$upstream_commit" ]]; then
91  # We are on the tip of the remote branch already.
92  exit 0
93fi
94
95if [[ "$merge_base" = "$my_commit" ]]; then
96  # We can fast-forward - do it.
97  git rebase "$upstream_branch" "$my_branch"
98  exit 0
99fi
100
101# Need to resolve manually.
102GiveUp "$my_repo" "Working branch and upstream branch have diverged."
103