检查 Git 中是否需要 pull [英] Check if pull needed in Git

查看:26
本文介绍了检查 Git 中是否需要 pull的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何查看远程仓库是否发生变化需要拉取?

How do I check whether the remote repository has changed and I need to pull?

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

Now I use this simple script:

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

但它相当沉重.

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

Is there a better way? The ideal solution would check all the remote branches, and return names of the changed branches and the number of new commits in each one.

推荐答案

首先使用 git远程更新,使您的远程引用保持最新.然后,您可以执行以下几种操作之一,例如:

First use git remote update, to bring your remote refs up to date. Then you can do one of several things, such as:

  1. git status -uno 会告诉您正在跟踪的分支是在前面、后面还是已经发散.如果它什么也没说,本地和远程是一样的.

  1. git status -uno will tell you whether the branch you are tracking is ahead, behind or has diverged. If it says nothing, the local and remote are the same.

git show-branch *master 将向您显示名称以master"结尾的所有分支中的提交(例如 master起源/主).

git show-branch *master will show you the commits in all of the branches whose names end in 'master' (eg master and origin/master).

如果你使用 -vgit remote update (git remote -v update) 你可以看到哪些分支被更新了,所以你真的不需要任何进一步的命令.

If you use -v with git remote update (git remote -v update) you can see which branches got updated, so you don't really need any further commands.

但是,看起来您想在脚本或程序中执行此操作并以真/假值结束.如果是这样,有一些方法可以检查您当前的 HEAD 提交与您正在跟踪的分支的负责人之间的关系,尽管由于有四种可能的结果,您不能将其简化为是/没有答案.但是,如果您准备执行 pull --rebase ,那么您可以将local is behind"和local has diverged"视为need to pull",而将其他两个视为don不需要拉".

However, it looks like you want to do this in a script or program and end up with a true/false value. If so, there are ways to check the relationship between your current HEAD commit and the head of the branch you're tracking, although since there are four possible outcomes you can't reduce it to a yes/no answer. However, if you're prepared to do a pull --rebase then you can treat "local is behind" and "local has diverged" as "need to pull", and the other two as "don't need to pull".

您可以使用 git rev-parse <ref> 获取任何 ref 的提交 ID,因此您可以为 masterorigin/master 执行此操作 并比较它们.如果它们相等,则分支相同.如果它们不相等,您想知道哪个在另一个之前.使用 git merge-base master origin/master 会告诉你两个分支的共同祖先,如果他们没有分歧,这将与一个或另一个相同.如果你得到三个不同的 id,那么分支就已经发散了.

You can get the commit id of any ref using git rev-parse <ref>, so you can do this for master and origin/master and compare them. If they're equal, the branches are the same. If they're unequal, you want to know which is ahead of the other. Using git merge-base master origin/master will tell you the common ancestor of both branches, and if they haven't diverged this will be the same as one or the other. If you get three different ids, the branches have diverged.

要正确执行此操作,例如在脚本中,您需要能够引用当前分支以及它正在跟踪的远程分支./etc/bash_completion.d 中的 bash 提示设置函数有一些用于获取分支名称的有用代码.但是,您实际上可能并不需要获取名称.Git 有一些简洁的速记来引用分支和提交(如 git rev-parse --help 中所述).特别是,您可以将 @ 用于当前分支(假设您未处于分离头状态)和 @{u} 用于其上游分支(例如 <代码>起源/主).所以 git merge-base @ @{u} 将返回当前分支及其上游分支的(哈希)提交和 git rev-parse @git rev-parse @{u} 会给你两个提示的哈希值.这可以总结为以下脚本:

To do this properly, eg in a script, you need to be able to refer to the current branch, and the remote branch it's tracking. The bash prompt-setting function in /etc/bash_completion.d has some useful code for getting branch names. However, you probably don't actually need to get the names. Git has some neat shorthands for referring to branches and commits (as documented in git rev-parse --help). In particular, you can use @ for the current branch (assuming you're not in a detached-head state) and @{u} for its upstream branch (eg origin/master). So git merge-base @ @{u} will return the (hash of the) commit at which the current branch and its upstream diverge and git rev-parse @ and git rev-parse @{u} will give you the hashes of the two tips. This can be summarized in the following script:

#!/bin/sh

UPSTREAM=${1:-'@{u}'}
LOCAL=$(git rev-parse @)
REMOTE=$(git rev-parse "$UPSTREAM")
BASE=$(git merge-base @ "$UPSTREAM")

if [ $LOCAL = $REMOTE ]; then
    echo "Up-to-date"
elif [ $LOCAL = $BASE ]; then
    echo "Need to pull"
elif [ $REMOTE = $BASE ]; then
    echo "Need to push"
else
    echo "Diverged"
fi

注意: 旧版本的 git 本身不允许 @,因此您可能必须使用 @{0} 代替.

Note: older versions of git didn't allow @ on its own, so you may have to use @{0} instead.

UPSTREAM=${1:-'@{u}'} 允许您有选择地明确传递上游分支,以防您想检查与远程分支不同的远程分支为当前分支配置.这通常是 remotename/branchname 的形式.如果没有给出参数,则该值默认为@{u}.

The line UPSTREAM=${1:-'@{u}'} allows you optionally to pass an upstream branch explicitly, in case you want to check against a different remote branch than the one configured for the current branch. This would typically be of the form remotename/branchname. If no parameter is given, the value defaults to @{u}.

该脚本假定您已先执行了 git fetchgit remote update,以使跟踪分支保持最新.我没有将它构建到脚本中,因为能够将提取和比较作为单独的操作进行更灵活,例如,如果您想比较而不提取,因为您最近已经提取过.

The script assumes that you've done a git fetch or git remote update first, to bring the tracking branches up to date. I didn't build this into the script because it's more flexible to be able to do the fetching and the comparing as separate operations, for example if you want to compare without fetching because you already fetched recently.

这篇关于检查 Git 中是否需要 pull的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆