如何知道git存储库是否有尚未与服务器(源)同步的更改?

发布于 2024-11-09 13:05:53 字数 211 浏览 0 评论 0原文

我在 Git 中设置了大量项目,这些项目以前是在 CVS 中管理的。 Tortoise CVS 和 Eclipse 都可以让我很容易地看到(通过图标覆盖)我是否对存储库进行了尚未发送到中央服务器的更改。

有没有一种方便的方法可以用 Git 来实现这一点?我实际上并不需要图标覆盖——我只需要知道在将我的分支与原始分支进行比较时是否有显着的更改。我不介意使用某种脚本来查询所有 Git 存储库。

I have a large number of projects setup in Git that were previously managed in CVS. Tortoise CVS as well as Eclipse both made it very easy to see (via icon overlays) if I had made changes to the repository that had not yet been sent to the central server.

Is there a convenient way to achieve this with Git? I don't really need the icon overlays -- I just need to know if I have outstanding changes when comparing my branches to those in origin. I don't mind using a script of some kind to query all the Git repos.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

荒人说梦 2024-11-16 13:05:53

像 git log origin/master..master 这样的东西应该给你已经完成但未推送的提交。如果你获取 origin 然后执行 git log master..origin/master ,你可以看到远程 master 中的提交。您还可以执行 git log origin/master...master 来查看本地和远程的新提交。

您可以将 git log 替换为 git rev-list,并根据需要轻松确定是否以及未推送到脚本中的内容。

Something like git log origin/master..master should give you the commits that you have done and not pushed. If you fetch origin and then do git log master..origin/master you can see commits in remote master. You can also do git log origin/master...master to see new commits both locally and remote.

You can replace git log with git rev-list and easily figure out if and what is not pushed in a script if needed.

不疑不惑不回忆 2024-11-16 13:05:53

以下示例仅涉及单个存储库。在周围脚本中使用循环在多个存储库上运行它们。

在使用以下命令之前,您可能需要运行(例如) git fetch origin 来更新本地远程跟踪分支(以便您检查上游的最新提示)分支机构)。

如果您只关心当前签出的分支:

git status -sb

如果第一行报告“ahead”,则当前分支的提交不属于其上游分支。该命令的输出不适合程序直接使用(它是一个“瓷器”命令)。对于程序化使用,请使用“plumbing”命令列出“前方”提交:

git rev-list HEAD@{upstream}..HEAD

您可以将其通过管道传输到 wc -l 来获取计数。如果您只对“领先”状态感兴趣(而不是确切的计数),则 test -n "$(git rev-list -n 1 HEAD@{upstream}..HEAD)" 可能会快一点。

如果您想检查存储库的所有分支:

git branch -v

同样,您将看到“ahead”分支的提交不属于其上游分支。这也是一个“瓷器”命令,因此如果您想可靠地检测程序中的状态,那么您将需要使用一些“管道”命令:

git for-each-ref --shell --format='
    b=%(refname:short)
    u=${b}'@{upstream}'
    if git rev-parse --verify --quiet "$u" >/dev/null 2>&1; then
        test -n "$(git rev-list -n 1 "$u..$b")" &&
        echo "$b: has unpushed commits"
    else
        echo "$b: no upstream configuration" >&2
    fi
' refs/heads | sh

调整 echo 语句(或将其替换为其他命令)以满足您的目的。

The following examples only deal with a single repository. Use a loop in a surrounding script to run them on multiple repositories.

You will probably want to run (e.g.) git fetch origin to update your local remote-tracking branches before using the following commands (so that you are checking against the most up-to-date tips of the upstream branches).

If you are only concerned with the branch that is currently checked out:

git status -sb

If the first line reports “ahead”, then the current branch has commits that are not part of its upstream branch. The output of this command is not suitable for consumption directly by a program (it is a “porcelain” command). For programatic consumption use a “plumbing” command to list the “ahead” commits:

git rev-list HEAD@{upstream}..HEAD

You can pipe that to wc -l to get a count. If you are only interested in the “ahead” status (not the exact count), then test -n "$(git rev-list -n 1 HEAD@{upstream}..HEAD)" may be faster.

If you want to check on all the branches of a repository:

git branch -v

Again, you will see “ahead” for branches with commits that are not part of their upstream branch. This is also a “porcelain” command, so if you want to reliably detect the state in a program, then you will want to use some “plumbing” commands:

git for-each-ref --shell --format='
    b=%(refname:short)
    u=${b}'@{upstream}'
    if git rev-parse --verify --quiet "$u" >/dev/null 2>&1; then
        test -n "$(git rev-list -n 1 "$u..$b")" &&
        echo "$b: has unpushed commits"
    else
        echo "$b: no upstream configuration" >&2
    fi
' refs/heads | sh

Adjust the echo statements (or replace them with other commands) to suit your purposes.

明月夜 2024-11-16 13:05:53

如果您有一个名为 origin 的远程设备,请尝试运行此命令:

git remote show origin

这将为您提供一个很好的摘要。

例如,这就是我得到的结果

git % git remote show origin
* remote origin
  Fetch URL: git://git.kernel.org/pub/scm/git/git.git
  Push  URL: git://git.kernel.org/pub/scm/git/git.git
  HEAD branch: master
  Remote branches:
    html   tracked
    maint  tracked
    man    tracked
    master tracked
    next   tracked
    pu     tracked
    todo   tracked
  Local branches configured for 'git pull':
    html   merges with remote html
    master merges with remote master
  Local refs configured for 'git push':
    html   pushes to html   (local out of date)
    master pushes to master (local out of date)

,表明我的本地分支 htmlmaster 已过期。如果我的远程提交不在我的本地存储库中 - 它将显示在为 git pull 配置的分支部分中。

origin 替换为任何远程存储库的名称。

如果您不知道您的来源的名称是什么,或者它们的 URL,请尝试以下操作:

git remote -v

这将为您提供遥控器及其 URL 的列表。

编辑添加

如果您有很多子模块,您可以使用git submodule foreach,正如我所描述的此处。您可以重定向输出并解析它以获得您需要的内容。

If you have a remote named, say, origin, - try running this:

git remote show origin

This will give you a nice summary.

For example this is what I get

git % git remote show origin
* remote origin
  Fetch URL: git://git.kernel.org/pub/scm/git/git.git
  Push  URL: git://git.kernel.org/pub/scm/git/git.git
  HEAD branch: master
  Remote branches:
    html   tracked
    maint  tracked
    man    tracked
    master tracked
    next   tracked
    pu     tracked
    todo   tracked
  Local branches configured for 'git pull':
    html   merges with remote html
    master merges with remote master
  Local refs configured for 'git push':
    html   pushes to html   (local out of date)
    master pushes to master (local out of date)

which shows that my local branches html and master are out of date. If my remote had commits that were not in my local repo - it would show in the section of branches configured for git pull.

replace origin with the name of any remote repository.

If you don't know what the names of your origins are, or their URLs try this:

git remote -v

which will give you a list of your remotes and their URLs.

Edited to add

If you have many submodule you could use git submodule foreach as I've described here. You could redirect the output and parse it to get what you need.

情未る 2024-11-16 13:05:53

昨天我尝试推出自己的解决方案。这是我想到的(对于单个存储库):

#!/bin/sh

for ref in $(git for-each-ref --format='%(refname)' refs/remotes/); do
    ending=${ref#refs/remotes/}
    remote=${ending%/*}
    branch=${ending#*/}
    if [ "${branch}" == "HEAD" ]; then continue; fi
    echo -e "\e[1;34m$branch on $remote\e[0m"
    echo "AHEAD by:"
    git log --oneline $branch ^$remote/$branch
    echo "BEHIND by:"
    git log --oneline $remote/$branch ^$branch
done

这是基于我提取的多个来源(包括此处的答案)的信息。考虑到我提供的参数,我仍然对“git log”命令正在做什么感到有点怀疑——但它似乎吐出了我想要的信息。

Yesterday I tried to roll my own solution. Here's what I came up with (for a single repository):

#!/bin/sh

for ref in $(git for-each-ref --format='%(refname)' refs/remotes/); do
    ending=${ref#refs/remotes/}
    remote=${ending%/*}
    branch=${ending#*/}
    if [ "${branch}" == "HEAD" ]; then continue; fi
    echo -e "\e[1;34m$branch on $remote\e[0m"
    echo "AHEAD by:"
    git log --oneline $branch ^$remote/$branch
    echo "BEHIND by:"
    git log --oneline $remote/$branch ^$branch
done

This was based off info I've pulled several sources including answers here. I'm still a bit shady on what the 'git log' command is doing given the parameters I'm providing -- but it seems to spit out the kind of info I want.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文