检查以确保在bash脚本

时间:2016-01-07 14:35:09

标签: git bash

我试图将一个函数写入一个bash脚本,以便它可以检查以确保作为脚本一部分获得rsynced的文件来自git的最新主副本。我发现this question似乎涵盖了这种情况。也许我误解了它应该做什么,但它似乎并没有像我希望的那样工作。

我注意到如果我在一个单独的分支上进行提交,然后合并到master中,当我将bask更改为master并忘记pull(我几乎总是忘记这样做)时,脚本没有注意到我在主人后面并允许rsync。任何人都可以建议为什么这个功能不能像我希望的那样工作?

startup_check() 
{
    # Check to make sure we are on the master branch
    CURRENTBRANCH=$(git status|awk 'NR==1{print $3}')

    if [ ! "$CURRENTBRANCH" == "master" ]; then
        echo -e "Not on master - cannot proceed, please change to master by using:\ngit checkout master"
        exit 1
    fi  

    # Check whether the current working branch is ahead, behind or diverged from remote master, and exit if we're not using the current remote master
    LOCAL=$(git rev-parse @)
    REMOTE=$(git rev-parse @{u})
    BASE=$(git merge-base @ @{u})

    if [ "$LOCAL" == "$REMOTE" ]; then
        echo "Working branch is up-to-date with remote master, proceeding...."
    elif [ "$LOCAL" == "$BASE" ]; then
        echo -e "Your working branch is behind the remote branch, you need to run:\ngit pull"
        exit 1
    elif [ "$REMOTE" == "$BASE" ]; then
        echo -e "Your working branch is ahead of the remote branch, you need to run:\ngit push origin master"
        exit 1
    else
        echo "Your working branch has diverged from the remote master, cannot continue"
        exit 1
    fi  
}

我正在使用git-2.6.2和bash-4.2

2 个答案:

答案 0 :(得分:1)

从我对OP的评论中,我看了一下git-bash-completion代码中的代码。现在回过头来看,如果我只是在方法的早期添加一个git fetch,我认为原始代码可能有效。

但是,我已经写了以下内容来做我想做的事情,我已经测试过,如果你没有掌握,并且有远程变化没有在本地反映,那么它是有效的,我相信其他部分会起作用:

startup_check() 
{
  # Need to do a git fecth first to download remote changes for us to compare against
  git fetch
  # Most of this code was taken from the __git_ps1_changes method of https://github.com/markgandolfo/git-bash-completion
  local branch_ref
  branch_ref="$(git symbolic-ref -q HEAD 2>/dev/null)";
  if [ -n "$branch_ref" ]; then
    local branch_origin
    branch_origin="$(git for-each-ref --format='%(upstream:short)' $branch_ref)";
    if [ -n "$branch_origin" ]; then
      local branch
      branch=${branch_ref##refs/heads/};

      if [ "$branch" != "master" ]; then
        echo "Not working on the master - cannot proceed"
        exit 1
      fi

      local unpush
      unpush=$(git rev-list $branch_origin..$branch --count);
      local unpull
      unpull=$(git rev-list $branch..$branch_origin --count);
      local staged
      staged=$(git diff --staged --name-status | wc -l);
      local uncommits
      uncommits=$(git status -s -uall --porcelain);

      if [[ $unpush -gt 0 ]]; then
        echo "There are changes which have not been pushed - cannot proceed. The following commits need to be pushed:"
        local unpushed
        unpushed=$(git rev-list $branch_origin..$branch);
        for commit in $unpushed; do
          git --no-pager log --pretty=format:"%H - %an, %ar : %s" -n 1 $commit
        done
        exit 1
      fi

      if [[ $unpull -gt 0 ]]; then
        echo "There are changes which have not been pulled - cannot proceed. The following commits have been added to master since your last pull:"
        local unpulled
        unpulled=$(git rev-list $branch..$branch_origin);
        for commit in $unpulled; do
          git --no-pager log --pretty=format:"%H - %an, %ar : %s" -n 1 $commit
        done
        exit 1
      fi

      if [[ $staged -gt 0 ]]; then
        local staging
        staging=$(git diff --staged --name-status);
        echo "There are changes which are staged but have been commited - cannot proceed"
        echo $staging
        exit 1
      fi

      local unstaged
      unstaged=$(echo "$uncommits" | grep -c "^ [A-Z]");
      if [[ $unstaged -gt 0 ]]; then
        echo "There are unstaged changes - cannot proceed"
        echo $(echo "$uncommits" | grep "^ [A-Z]")
        exit 1
      fi

      local untracked
      untracked=$(echo "$uncommits" | grep -c "^??");
      if [[ $untracked -gt 0 ]]; then
        echo "There are untracked changes - cannot proceed"
        echo $(echo "$uncommits" | grep "^??")
        exit 1
      fi
    fi
  else
    echo "Working folder isn't a git folder"
    exit 1
  fi
}

答案 1 :(得分:0)

首先你需要拉

修正了脚本

该脚本包含的空格会导致脚本在不同的unix风格上有不同的行为。

试试这个固定的。

#!/bin/sh

# Check to make sure we are on the master branch
CURRENTBRANCH=$(git status|awk 'NR==1{print $3}');

if [ ! "$CURRENTBRANCH"=="master" ]; then
    echo -e "Not on master - cannot proceed, please change to master by using:\ngit checkout master"
    exit 1
fi

# Check whether the current working branch is ahead, behind or diverged from remote master, and exit if we're not using the current remote master
LOCAL=$(git rev-parse @)
REMOTE=$(git rev-parse @{u})
BASE=$(git merge-base @ @{u})

if [ "$LOCAL"=="$REMOTE" ]; then
    echo "Working branch is up-to-date with remote master, proceeding...."
elif [ "$LOCAL"=="$BASE" ]; then
    echo -e "Your working branch is behind the remote branch, you need to run:\ngit pull"
    exit 1
elif [ "$REMOTE"=="$BASE" ]; then
    echo -e "Your working branch is ahead of the remote branch, you need to run:\ngit push origin master"
    exit 1
else
    echo "Your working branch has diverged from the remote master, cannot continue"
    exit 1
fi
相关问题