我试图将一个函数写入一个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
答案 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