如何检查远程存储库是否已更改,是否需要进行拉取?

现在我使用这个简单的脚本:

git pull --dry-run | grep -q -v 'Already up-to-date.' && changed=1

但它相当重。

有没有更好的办法?理想的解决方案是检查所有远程分支,并返回已更改分支的名称以及每个分支中新提交的数量。


当前回答

如果你有一个上游分支

git fetch <remote>
git status

如果你没有上游分支

比较这两个分支:

git fetch <remote>
git log <local_branch_name>..<remote_branch_name> --oneline

例如:

git fetch origin

# See if there are any incoming changes
git log HEAD..origin/master --oneline

(我假设原点/主人是你的远程跟踪分支)

如果上面的输出中列出了任何提交,那么您就有了传入的更改——您需要合并。如果git日志中没有列出提交,那么就没有东西可以合并。

注意,即使你在一个没有跟踪远程的特性分支上,这也可以工作,因为if显式地引用了origin/master,而不是隐式地使用Git记住的上游分支。

其他回答

git ls-remote | cut -f1 | git cat-file --batch-check >&-

将列出所有在任何远程引用,不在你的回购。要捕捉你已经拥有的东西的远程引用更改(例如,重置到以前的提交)需要更多一点:

git pack-refs --all
mine=`mktemp`
sed '/^#/d;/^^/{G;s/.\(.*\)\n.* \(.*\)/\1 \2^{}/;};h' .git/packed-refs | sort -k2 >$mine
for r in `git remote`; do 
    echo Checking $r ...
    git ls-remote $r | sort -k2 | diff -b - $mine | grep ^\<
done

运行git fetch (remote)来更新你的远程引用,它会告诉你什么是新的。然后,当您签出本地分支时,它将显示它是否落后于上游。

我使用了一个基于Stephen Haberman回答的脚本版本:

if [ -n "$1" ]; then
    gitbin="git -C $1"
else
    gitbin="git"
fi

# Fetches from all the remotes, although --all can be replaced with origin
$gitbin fetch --all
if [ $($gitbin rev-parse HEAD) != $($gitbin rev-parse @{u}) ]; then
    $gitbin rebase @{u} --preserve-merges
fi

假设此脚本名为Git -fetch-and-rebase,可以使用本地Git存储库的可选参数目录名来调用它,以执行操作。如果调用脚本时不带参数,则假定当前目录是Git存储库的一部分。

例子:

# Operates on /abc/def/my-git-repo-dir
git-fetch-and-rebase /abc/def/my-git-repo-dir

# Operates on the Git repository which the current working directory is part of
git-fetch-and-rebase

这里也有。

如果你运行这个脚本,它将测试当前分支是否需要git拉:

#!/bin/bash

git fetch -v --dry-run 2>&1 |
    grep -qE "\[up\s+to\s+date\]\s+$(
        git branch 2>/dev/null |
           sed -n '/^\*/s/^\* //p' |
                sed -r 's:(\+|\*|\$):\\\1:g'
    )\s+" || {
        echo >&2 "Current branch need a 'git pull' before commit"
        exit 1
}

将它作为Git钩子预提交来避免非常方便

Merge branch 'foobar' of url:/path/to/git/foobar into foobar

当你承诺之前拉。

要将此代码用作钩子,只需复制/粘贴脚本即可

.git/hooks/pre-commit

and

chmod +x .git/hooks/pre-commit

我会按照布罗尔的建议去做。下面的一行脚本使用您最后提交的版本的SHA1,并将其与远程原始版本的SHA1进行比较,仅在它们不同时才进行更改。 基于git pull或git fetch的解决方案更加轻量级。

[ `git log --pretty=%H ...refs/heads/master^` != `git ls-remote origin
-h refs/heads/master |cut -f1` ] && git pull