Something went wrong. Try again.
This repository has no description
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135#!/bin/bash# Usage: git sync## Fetches new objects from origin remote named either "upstream" or "origin",# then iterates over each local branch that corresponds to a remote branch and:## - If the local branch is outdated, fast-forward it;# - If the local branch contains unpushed work, warn about it;# - If the branch seems merged and its upstream branch was deleted, delete it.## If a local branch doesn't have any upstream configuration, but has a# same-named branch on the remote, assume that's its upstream branch.set -ewhile [ $# -gt 0 ]; do case "$1" in -h | --help ) sed -ne '/^#/!q;s/.\{1,2\}//;1d;p' < "$0" exit 0 ;; * ) "$0" --help >&2 exit 1 ;; esac shift 1doneGIT_DIR="$(git rev-parse --git-dir)"if [ -e "${GIT_DIR}/refs/remotes/upstream" ]; then ORIGIN="upstream"else ORIGIN="origin"fiif [ -t 1 ]; then RED=$'\e[31m' LIGHT_RED=$'\e[31;1m' GREEN=$'\e[32m' LIGHT_GREEN=$'\e[32;1m' RESET=$'\e[0m'else RED="" LIGHT_RED="" GREEN="" LIGHT_GREEN="" RESET=""fimain_branch() { local remote="$1" local head="$(cat "${GIT_DIR}/refs/remotes/${remote}/HEAD" 2>/dev/null)" if [[ $head == "ref: "* ]]; then echo "${head#ref: refs/remotes/${remote}/}" else return 1 fi}has_upstream_configuration() { local branch="$1" local remote="$(git config "branch.${branch}.remote")" [ "$remote" = "$ORIGIN" ] || return 1}upstream_branch() { local branch="$1" local resolved="" if resolved="$(git rev-parse --symbolic-full-name "${branch}@{upstream}" 2>/dev/null)"; then echo "$resolved" else return 1 fi}is_ancestor() { git merge-base --is-ancestor "$@" || ( merge_base=$(git merge-base "$@") && [[ $(git cherry $2 $(git commit-tree $(git rev-parse $1^{tree}) -p $merge_base -m _)) == "-"* ]] )}git fetch "$ORIGIN" --prune --quiet --progressMASTER="$(main_branch "$ORIGIN")" || MASTER="master"CURRENT_BRANCH="$(git symbolic-ref --short --quiet HEAD || true)"git branch --list | \ while read -r local_branch; do local_branch="${local_branch#* }" remote_branch="refs/remotes/${ORIGIN}/${local_branch}" gone="" if has_upstream_configuration "$local_branch"; then remote_branch="$(upstream_branch "$local_branch")" || gone=1 elif [ ! -e "${GIT_DIR}/${remote_branch}" ]; then remote_branch="" && gone=1 fi if [ -n "$remote_branch" ]; then shas=( `git rev-parse "$local_branch" "$remote_branch"` ) local_sha="${shas[0]}" remote_sha="${shas[1]}" if [ "$local_sha" = "$remote_sha" ]; then : # branch is up to date. elif is_ancestor "$local_branch" "$remote_branch"; then # Local branch is behind if [ "$local_branch" = "$CURRENT_BRANCH" ]; then git merge --ff-only --quiet "$remote_branch" else git update-ref "refs/heads/${local_branch}" "$remote_branch" fi echo "${GREEN}Updated branch ${LIGHT_GREEN}${local_branch}${RESET} (was ${local_sha:0:7})." else # Local branch is ahead or diverged. # TODO: Decide whether to try clean merge check + rebase here. echo "warning: \`$local_branch' seems to contain unpushed commits" >&2 fi elif [ -n "$gone" ]; then # Upstream branch got deleted if is_ancestor "$local_branch" "${ORIGIN}/${MASTER}"; then if [ "$local_branch" = "$CURRENT_BRANCH" ]; then git checkout --quiet "$MASTER" CURRENT_BRANCH="$MASTER" fi local_sha="$(git rev-parse "$local_branch")" git branch -D "$local_branch" >/dev/null echo "${RED}Deleted branch ${LIGHT_RED}${local_branch}${RESET} (was ${local_sha:0:7})." else echo "warning: \`$local_branch' is neither present on $ORIGIN nor merged into $MASTER. Have you pushed it yet?" >&2 fi fi done