gpt4 book ai didi

git - git:如何以编程方式确定是否需要 pull 或 push ?

转载 作者:行者123 更新时间:2023-12-02 03:16:46 24 4
gpt4 key购买 nike

我正在编写一个程序,用于检查几个克隆的git存储库的状态。

如何确定我的存储库是否需要“ git pull”或“ git push”?

最佳答案

首先,pull只是fetch,然后是merge(或rebase)。这很重要,因为您首先想要的是一个相关的,更简单的问题的答案:与某些远程存储库相比,本地存储库领先和/或落后多远? (对于TL; DR答案,请跳到下面的第一个标头部分。)

还有其他潜在的复杂性,但是这里要做的简单的事情是对照其他一些git存储库检查分支提示。让我们给它们起一些名字以供说明。我们可以将您的存储库称为“ L”(对于本地),假设还有两个附加存储库“ RA”(远程A)和“ RB”,它们的URL以远程名称RA和RB存储在本地存储库L中。

一次获得您可能需要的所有内容的简单方法是在RA和RB上同时运行git fetch(或git remote update)。 (尽管我不确定其中是否有任何实际价值,但我们稍后会看到一种推迟获取的方法。)

给定一个典型的设置,同时获取两个遥控器将复制其本地分支为您自己的“远程分支”。假设RA具有masterdev,而RB具有masterfeature,因此在获取完成之后:

L$ git rev-parse --short refs/remotes/RA/master
feedbee
L$ git rev-parse --short refs/remotes/RA/dev
feedbee
L$ git rev-parse --short refs/remotes/RB/master
badf00d
L$ git rev-parse --short refs/remotes/RB/feature
c0ffee1


(这些数字是虚构的,但仅用于说明。此外,如果您使用真实代码执行此操作,则不需要 --short。而且,您可以缩写分支名称,而忽略 refs/remotes/-在下面, refs/heads/ —只要它们没有歧义。不过,如果您正在编写脚本,则以防万一,使用全名可能更明智。

现在,让我们检查一下您自己的本地分支机构的提示:

L$ git rev-parse --short refs/heads/master
feedbee


这意味着您的 master与RA的 master与其 dev同步。因此,那里没有任何要推送或获取的内容(尽管您已经为了获取该内容而已经获取了内容),因此也没有要合并或变基的内容。

另一方面,远程RB由于其 master指向提交 badf00d而未同步。这是否意味着您需要合并或推送?也许(也许不是):这是带来复杂性的地方。如果需要手动合并,Git并不能提供太多帮助,但是您可以通过查看提交如何确定RB是否处于“领先”,“处于落后”或两者兼而有之。图相互堆叠。

如果repo L严格位于repo RB的“前面”,即您拥有可以推送的内容,则图形片段必须类似于以下内容:

... - o           <-- RB/master: tip-most commit = badf00d
\
o - o <-- master: tip commit = feedbee


git status给您的术语中,L是回购RB所在的位置“前面2”。如果您对RB进行了推送,则git会将最后两次提交交给RB,并告诉它请将其 master设置为 feedbee,这将使其赶上来。

如果repo L严格位于RB的“后面”,则图形片段将看起来相同,但标签将颠倒:

... - o           <-- master
\
o - o <-- RB/master


在这种情况下,如果您进行合并以将 RB/master带入 master,则git会看到一个快进操作,并将您的master设置为 badf00d。此时,回购RA可能会落后,您可能希望将其推到那里。

不过,还有两种可能性。例如,L可以在后面,也可以在后面:

... - o - o       <-- master
\
o - o <-- RB/master


这需要一个rebase或一个真正的合并,如果git不能单独组合各种更改(或者即使可以合并,则可能会出错),这两者都可能需要手动操作。

最后,这两个分支技巧可能(尽管不太可能)是完全不相关的(在 ...部分中没有共同的祖先):

... - o   <-- master

... - o <-- RB/master


这是最棘手的问题,因为我在下面描述的内容提供了错误的前后计数。 (如果某人已经去掉并重写了其中一个克隆的所有历史记录,那么它也只能在克隆的仓库中发生。为这种情况添加一个偏执检查,例如使用 git merge-base可能是合理的。但是我会请从现在开始忽略它。)

寻找领先和落后

解决了所有这些问题之后,这是一种快速方法,可以找到您知道相关的两个分支(一个本地,一个远程)的“提前”和“后退”计数。我将切换到远程“起源”,这是(单个)克隆源的常用名称,并使用分支名称的缩写形式:

$ ahead=$(git rev-list --count origin/master..master)
$ behind=$(git rev-list --count master..origin/master)


它们使用 gitrevisions range syntax选择本地分支提示(由 master标识的提交)可访问的修订版本,而不是远程分支提示(由 origin/master标识)的可达版本。

如果您领先但又不落后,您可以放心地 git push。如果您不落后,但可以安全地 git merge快速前进(此时,使用 pull是没有意义的,因为您已经完成了 fetch步骤)。如果您同时处于领先地位和落后地位,以至于两个计数都不为零,则必须决定是合并还是变基,以及如果合并或变基失败,该怎么办。当然,如果两个计数都为零,则两个分支提示将标识相同的SHA-1,因此无需执行任何操作。

如果您不想使用 git fetch怎么办?

最终,您必须使用 git fetch。但是,如果愿意,可以从 git ls-remote开始,它会列出SHA-1和refname的列表:

$ git ls-remote
From [url redacted]
a17c56c056d5fea0843b429132904c429a900229 HEAD
ca00f80b58d679e59fc271650f68cd25cdb72b09 refs/heads/maint
a17c56c056d5fea0843b429132904c429a900229 refs/heads/master
0029c496ce1b91f10b75ade16604b8e9f5d8d20b refs/heads/next
fcd56459647e0c41f2ea9c5b7e2ed827f701fc95 refs/heads/pu
e8f6847178db882bd42d5572439333ca4cb3222e refs/heads/todo
d5aef6e4d58cfe1549adef5b436f3ace984e8c86 refs/tags/gitgui-0.10.0
3d654be48f65545c4d3e35f5d3bbed5489820930 refs/tags/gitgui-0.10.0^{}
[mass snippage]


如果远程计算机上的SHA-1与本地SHA-1不同,则这些SHA-1不会携带您需要的所有图形信息,但是,如果您关心的SHA-1匹配,那么您就可以知道没有要获取的图形信息。推。此外,如果它们不同,则可以查看是否具有相应的SHA-1。例如,上面显示了远程服务器的 master指向提交 a17c56c056d5fea0843b429132904c429a900229。如果有(我没有),我可以将其用作 git rev-list --count中的指定符之一,以找出距遥控器多远的距离。因为我没有,所以我几乎可以肯定落后了:我不知道多少,但是我需要获取,然后合并或变基(我不知道自己是否也领先于我取)。

您怎么知道要看哪个分支?

最好事先确定,而不是仅遍历所有可能的分支。但是,如果您确实想遍历分支,则此工具为 git for-each-ref,它需要使用很多参数。例如,要找到自己的本地分支机构:

$ git for-each-ref --format='%(refname)' refs/heads
refs/heads/master
refs/heads/precious
refs/heads/stash-exp


查找远程 origin的分支:

$ git for-each-ref --format='%(refname)' refs/remotes/origin
refs/remotes/origin/maint
refs/remotes/origin/master
refs/remotes/origin/next
refs/remotes/origin/pu
refs/remotes/origin/todo


剥离掉足够多的字符串并匹配分支名称很容易,以便能够进行比较。如果您要检查(并跳过)匹配的SHA-1,则可以使用其他选项同时获得分支名称和SHA-1,这显然会使前和后计数为零。

关于git - git:如何以编程方式确定是否需要 pull 或 push ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31666641/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com