如何检查远程存储库是否已更改,是否需要进行拉取?
现在我使用这个简单的脚本:
git pull --dry-run | grep -q -v 'Already up-to-date.' && changed=1
但它相当重。
有没有更好的办法?理想的解决方案是检查所有远程分支,并返回已更改分支的名称以及每个分支中新提交的数量。
如何检查远程存储库是否已更改,是否需要进行拉取?
现在我使用这个简单的脚本:
git pull --dry-run | grep -q -v 'Already up-to-date.' && changed=1
但它相当重。
有没有更好的办法?理想的解决方案是检查所有远程分支,并返回已更改分支的名称以及每个分支中新提交的数量。
当前回答
我认为最好的方法是:
git diff remotes/origin/HEAD
假设您已经注册了this refspec。如果您已经克隆了存储库,则应该这样做,否则(例如,如果回购是在本地从头创建的,并推到远程),则需要显式地添加refspec。
其他回答
使用简单的regexp:
str=$(git status)
if [[ $str =~ .*Your\ branch\ is\ behind.*by.*commits,\ and\ can\ be\ fast-forwarded ]]; then
echo `date "+%Y-%m-%d %H:%M:%S"` "Needs pull"
else
echo "Code is up to date"
fi
运行git fetch (remote)来更新你的远程引用,它会告诉你什么是新的。然后,当您签出本地分支时,它将显示它是否落后于上游。
git ls-remote origin -h refs/heads/master
由brol给出的是检查遥控器中是否发生了变化的最简单的方法。
从局部头部开始:
$ git log -1 --oneline @
9e1ff307c779 (HEAD -> master, tag: v5.15-rc4, origin/master, origin/HEAD) Linux 5.15-rc4
我看到我拉的原点在那个标签处是最新的。Git状态也是这么说的。但这只是最新的本地数据,取数据后的(快进)合并。
检查远程HEAD是否去了某个地方,还有master,也许还有一些新标签:
$ git ls-remote origin HEAD master --tags 'v5.1[56]-rc[345]*'
84b3e42564accd94c2680e3ba42717c32c8b5fc4 HEAD
84b3e42564accd94c2680e3ba42717c32c8b5fc4 refs/heads/master
71a6dc2a869beafceef1ce46a9ebefd52288f1d7 refs/tags/v5.15-rc3
5816b3e6577eaa676ceb00a848f0fd65fe2adc29 refs/tags/v5.15-rc3^{}
f3cee05630e772378957a74a209aad059714cbd2 refs/tags/v5.15-rc4
9e1ff307c779ce1f0f810c7ecce3d95bbae40896 refs/tags/v5.15-rc4^{}
HEAD仍然在同一个分支上,但不再是同一个提交。本地@提交保留在v5.15-rc4标记中。这与kernel.org git的摘要表顶部的信息大致相同:
Branch: master <commit message> <author> age: 2 hours
只有ls-remote收集的信息更少-但只有我知道我是9e1ff…即v5.15-rc4。
除了命名引用(HEAD, master)或标签,还可以从任何repo中获得头部或分支的列表:
$ git ls-remote --heads git://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
af06aff2a0007976513134dfe993d55992dd866a refs/heads/akpm
20bcee8e95f783c11a7bea1b6a40c70a37873e0a refs/heads/akpm-base
a25006a77348ba06c7bc96520d331cd9dd370715 refs/heads/master
4d5a088c93cea1c821d02a2217c592391d9682e2 refs/heads/pending-fixes
4de593fb965fc2bd11a0b767e0c65ff43540a6e4 refs/heads/stable
这里用URL代替“origin”。
如何检查远程存储库是否已经更改,而我需要更改 拉?
如果你这么问,就拔。
我如何检查远程存储库是否最终完成了一些事情,我想要拉?
然后取回,检查,合并。
使用单个git命令:
$ git rev-list -1 master
9e1ff307c779ce1f0f810c7ecce3d95bbae40896
$ git rev-list -1 @
9e1ff307c779ce1f0f810c7ecce3d95bbae40896
这本身说明不了什么,但假设我知道我什么也没做,那么:
$ git ls-remote origin HEAD master
60a9483534ed0d99090a2ee1d4bb0b8179195f51 HEAD
60a9483534ed0d99090a2ee1d4bb0b8179195f51 refs/heads/master
会告诉我遥控器换了。自从上次编辑以来确实是这样。kernel.org说年龄:46分钟。关于最后一次在master上提交。
git取回后:
$ git rev-list -1 master
9e1ff307c779ce1f0f810c7ecce3d95bbae40896
$ git rev-list -1 FETCH_HEAD
60a9483534ed0d99090a2ee1d4bb0b8179195f51
$ git log --oneline ..FETCH_HEAD
60a9483534ed (origin/master, origin/HEAD) Merge tag 'warning-fixes-20211005' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs
f6274b06e326 Merge tag 'linux-kselftest-fixes-5.15-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest
ef31499a87cf fscache: Remove an unused static variable
d9e3f82279bf fscache: Fix some kerneldoc warnings shown up by W=1
bc868036569e 9p: Fix a bunch of kerneldoc warnings shown up by W=1
dcb442b13364 afs: Fix kerneldoc warning shown up by W=1
c0b27c486970 nfs: Fix kerneldoc warning shown up by W=1
84b3e42564ac Merge tag 'media/v5.15-3' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
b60be028fc1a Merge tag 'ovl-fixes-5.15-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs
df5c18838ea8 Merge tag 'mips-fixes_5.15_1' of git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux
206704a1fe0b media: atomisp: restore missing 'return' statement
740da9d7ca4e MIPS: Revert "add support for buggy MT7621S core detection"
1dc1eed46f9f ovl: fix IOCB_DIRECT if underlying fs doesn't support direct IO
2f9602870886 selftests: drivers/dma-buf: Fix implicit declaration warns
a295aef603e1 ovl: fix missing negative dentry check in ovl_rename()
现在我在本地拥有所有信息,但还没有合并。我还下载了所有的对象。git显示HASH或git diff HASH工作。
在这种情况下,合并几乎没有任何操作:快进到最后一次提交,没有额外的(真正的)合并,更不用说冲突了。这可以通过——ff-only来确保:
$ git merge --ff-only FETCH_HEAD
Updating 9e1ff307c779..60a9483534ed
Fast-forward
...
...
那我怎么知道什么时候拉呢?只要这两个散列是/将是不同的:更新9e1ff307c779..60 a9483534ed快进。它们不可能是一样的,那就是“没什么可更新的”。
最新的reflog提交也是这样说的:
$ git log -10 --oneline -g
60a9483534ed (HEAD -> master, origin/master, origin/HEAD) HEAD@{0}: merge 60a9483534ed0d99090a2ee1d4bb0b8179195f51: Fast-forward
9e1ff307c779 (tag: v5.15-rc4) HEAD@{1}: pull: Fast-forward
在这种情况下,新标签的出现可能是最好的触发器和目标;返回到git ls-remote origin——tags PATTERN。
...别告诉我git remote show是另一个方法:
show给出关于遥控器的一些信息。 使用-n选项,git ls-remote不会首先查询远程头;取而代之的是使用缓存信息。
首先使用git远程更新,使您的远程参考更新到最新。然后你可以做以下几件事中的一件,比如:
Git status -uno将告诉你你正在跟踪的分支是在前面、后面还是已经偏离。如果没有显示,则本地和远程是相同的。 Git show-branch *master会显示所有以master结尾的分支中的提交(例如master和origin/master)。
如果你在git远程更新(git remote -v update)中使用-v,你可以看到哪些分支被更新了,所以你真的不需要任何进一步的命令。
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 ("local is ahead" and "same") as "don't need to pull".
你可以使用git rev-parse <ref>获得任何ref的提交id,所以你可以对master和origin/master这样做并比较它们。如果它们相等,那么分支是相同的。如果它们不相等,你想知道哪个在前面。使用git merge-base master origin/master会告诉你两个分支的共同祖先,如果它们没有分叉,这将是一个或另一个相同的。如果您得到三个不同的id,则分支已经分离。
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}代替。
UPSTREAM=${1:-'@{u}'}允许你显式地传递一个上游分支,以防你想检查一个不同于当前分支配置的远程分支。这通常是remotename/branchname的形式。如果不指定参数,默认值为@{u}。
该脚本假设您已经首先进行了git获取或git远程更新,以使跟踪分支更新到最新。我没有把这个构建到脚本中,因为它更灵活,能够将抓取和比较作为单独的操作,例如,如果你想比较而不抓取,因为你最近已经获取了。
这一行在zsh中为我工作(来自@Stephen Haberman的回答)
git fetch; [ $(git rev-parse HEAD) = $(git rev-parse @{u}) ] \
&& echo "Up to date" || echo "Not up to date"