如何检查远程存储库是否已更改,是否需要进行拉取?
现在我使用这个简单的脚本:
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 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 ls-remote origin -h refs/heads/master
将列出远程上的当前头—您可以将其与以前的值进行比较,或者查看您的本地回购中是否有SHA。
下面是一个Bash一行代码,比较了当前分支的HEAD提交哈希和它的远程上游分支,不需要大量的git获取或git拉取——需要干运行操作:
[ $(git rev-parse HEAD) = $(git ls-remote $(git rev-parse --abbrev-ref @{u} | \
sed 's/\// /g') | cut -f1) ] && echo up to date || echo not up to date
以下是这条有点密集的线是如何被分解的:
Commands are grouped and nested using $(x) Bash command-substitution syntax. git rev-parse --abbrev-ref @{u} returns an abbreviated upstream ref (e.g. origin/master), which is then converted into space-separated fields by the piped sed command, e.g. origin master. This string is fed into git ls-remote which returns the head commit of the remote branch. This command will communicate with the remote repository. The piped cut command extracts just the first field (the commit hash), removing the tab-separated reference string. git rev-parse HEAD returns the local commit hash. The Bash syntax [ a = b ] && x || y completes the one-liner: this is a Bash string-comparison = within a test construct [ test ], followed by and-list and or-list constructs && true || false.
我基于@jberger的评论来解决这个问题。
if git checkout master &&
git fetch origin master &&
[ `git rev-list HEAD...origin/master --count` != 0 ] &&
git merge origin/master
then
echo 'Updated!'
else
echo 'Not updated.'
fi
如果这是一个脚本,你可以使用:
git fetch
$(git rev-parse HEAD) == $(git rev-parse @{u})
(注意:与之前的答案相比,这个答案的好处是您不需要单独的命令来获取当前的分支名称。“HEAD”和“@{u}”(当前分支的上游)负责处理它。详见“git rev-parse——help”。)
我会按照布罗尔的建议去做。下面的一行脚本使用您最后提交的版本的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