ChatGPT解决这个技术问题 Extra ChatGPT

查看未推送的 Git 提交

如何查看我所做的任何本地提交,但尚未推送到远程存储库?有时,git status 会打印出我的分支是在 origin/master 之前提交 X 次,但并非总是如此。

这是我安装 Git 的错误,还是我遗漏了什么?

从 Git 2.5+(2015 年第二季度)开始,实际答案是 git log @{push}..。在 my answer below 中查看新的快捷方式 @{push}(引用您要推送到的远程跟踪分支)
@Torek - Git 使另一个简单的任务变得困难。每当一个 Git 问题以成百上千的点赞数和数百万的浏览量出现时,就会有人会想:哇,我们真的搞砸了这个工作流程。唉,Git 开发者在开发生命周期中省略了反馈步骤,因此没有纳入反馈。相反,他们一遍又一遍地犯同样的错误。对于这个问题,git status --all 应该出现在 2010 年;或 git status -v 实际上应该提供包含额外信息的详细输出。
我不同意“git status -v”应该提供此信息,因为它旨在提供有关工作树的状态,因为它仅与签出分支有关。但是,请参阅下面关于“git branch -v”的答案,我认为这应该是公认的答案
这个特定的 StackOverflow 问题具有最多的正确答案,所有这些都有效但没有任何意义。
@jww:我同意。在使用 mercurial 之后,我又回到了使用 git。与 mercurial 的易用性和优雅相比,git 是一团糟

E
Epeli
git log origin/master..HEAD

您还可以使用相同的语法查看差异

git diff origin/master..HEAD

这为我做到了-出于某种原因 git log origin.. 本身就引发了错误。看起来我的本地分支的配置方式也有问题 - 一旦我进行了我在这里找到的更改:wincent.com/blog/… ...问题已解决,我可以再次使用 git status 来查看我想要的内容。
无价之宝:所以我做了git config --global alias.ahead "log origin/master..HEAD --oneline",这样我就可以快速找到我在哪里。更多糖果:for i in *; do echo $i && git ahead 2>/dev/null; done
git log --stat origin/master..HEAD 额外的精彩
这不是最好的解决方案。 Origin/master 可能并不总是上游分支。更好的解决方案是使用@{u} 而不是“origin/master”来指示上游分支。由于默认情况下暗示了 HEAD,因此也可以将其省略。请参阅@Ben Ling 的回答。传出更改:git log @{u}.. 传入更改:git log ..@{u}
@Nocturne 我只想指出,发布此答案时,@{u} 语法尚不可用,仅在 February 12, 2010 上可用。此外,如果本地分支未配置上游,@{u} 将不起作用。最后,@{u} 目前不支持制表符补全,具有制表符补全的 <remote>/<branch> 仍然是获取此信息的最快方法之一,无论是否配置了上游,它都可以工作。
a
alex

如果您想查看尚未推送的所有分支上的所有提交,您可能正在寻找类似这样的内容:

git log --branches --not --remotes

如果您只想查看每个分支上的最新提交以及分支名称,则:

git log --branches --not --remotes --simplify-by-decoration --decorate --oneline

这太棒了。在一个相关的场景中,我有两个本地分支和两个上游分支,并且一只本地手被合并到另一只手中。我想知道哪些提交可以安全地变基,但正常的 git log master..HEAD 不起作用,因为有多个上游。这篇文章将我带到 git log MyBranch --not --remotes,以在单个分支中显示尚未推送到任何上游的所有提交。
我知道您的第二个命令还列出了尚未推送的提交,只是每个分支只显示一个。
--decorate 也显示了分支。 --graph 使其更加明显。
请注意,这些命令仅列出尚未在任何分支中推送的提交。例子:假设你有分支开发分支feat-NewThing。您在本地对 feat-NewThing 进行更改。 (日志有变化。)然后你将 feat-newThing 推送到它的远程分支。 (日志为空)。您合并本地专长新事物以在本地开发。假设快进,日志仍然没有变化。
这是实际的解决方案。唯一一个不需要指定分支或需要定义上游的通常工作的。
B
Ben Lings

您可以显示您在本地但不是上游的所有提交

git log @{u}..

@{u}@{upstream} 表示当前分支的上游分支(详见 git rev-parse --helpgit help revisions)。


在 Windows 上,我需要将最后一个参数括在引号中,例如: git log "@{u}.."
git log @{u}.. -p 最有用的选项之一是 -p,它显示了每次确认中引入的差异。
可能更好 git log @{push}.. ,请参阅 another answer
我发现这是最好的答案。我还发现,如果没有备忘单,我就无法在地球上记住它。为什么 git 开发人员没有选择明显的、符合 git status 的东西,因为我们想知道一个情况的 statusgit status -v 会更有意义。
C
Christian Vielma

这对我有用:

git cherry -v 

Git: See all unpushed commits or commits that are not in another branch 所示。


我认为这应该是主要答案,因为它提供了更简洁的提交列表,而不是所有文件中难以阅读的冗长差异!
git-cherry - “查找尚未应用于上游的提交”,似乎提供了 OP 所要求的内容,但只有提交主题而不是整个提交消息。
值得注意的是,这只会告诉您当前签出的分支上是否有未推送的提交。它不会告诉您是否有未推送提交的本地分支(当前未签出)。
G
Greg Hewgill

您可以使用 git log 执行此操作:

git log origin/master..

这假定 origin 是您的上游远程的名称,而 master 是您的上游分支的名称。在 .. 之后省略任何修订名称意味着 HEAD,它列出了尚未推送的新提交。


每当我看到带有 git log 和“2-dots-not-3”的答案时,它总是让我想起 stackoverflow.com/questions/53569/… ;)
只是将其添加到答案中 - 如果没有上游设置,此命令会导致说没有设置上游。如果您倾向于使用此命令查看暂存的提交,请运行 git branch --set-upstream master origin/<branch> 以设置上游。
这将与源中的默认分支进行比较,而不是当前的远程分支。
致命:模棱两可的参数“起源..”:未知修订版或路径不在工作树中。
不,它显示了所有不同的最新提交,但不回答原始 Q。
V
VonC

所有其他答案都谈论“上游”(您从中提取的分支)。但是本地分支可以推送到与其拉出的分支不同的分支。

master 可能不会推送到远程跟踪分支“origin/master”。
masterupstream 分支可能是 origin/master,但它可以推送到远程跟踪分支 origin/xxx 甚至 anotherUpstreamRepo/yyy
这些是由 branch.*.pushremote 为当前分支以及 global remote.pushDefault 值设置的。

远程跟踪分支在寻找未推送的提交时计数:跟踪 本地分支 将被推送到的 branch at the remote 的分支。
{ 1} 也可以是 origin/xxx 甚至是 anotherUpstreamRepo/yyy

Git 2.5+(2015 年第二季度)为此引入了一个新的快捷方式:@{push}

请参阅 commit 29bc885commit 3dbe9dbcommit adfe5d0commit 48c5847commit a1ad0ebcommit e291c75commit 979cb24commit 1ca41a1commit 3a429d0commit a9f9f8ccommit 8770e6fcommit da66b27、{ 13}、commit 9e3751dcommit ee2499f [全部从 2015 年 5 月 21 日] 和 commit e41bf35 [2015 年 5 月 1 日] 由 Jeff King (peff) 提供。
(由 commit c4a8354 中的 Junio C Hamano -- gitster -- 合并,05 2015 年 6 月)

Commit adfe5d0 解释:

sha1_name:实现@{push} 简写

在三角工作流中,每个分支可能有两个不同的兴趣点:您通常从中提取的 @{upstream} 和您通常推送到的目的地。后者没有简写,但它很有用。例如,您可能想知道您尚未推送哪些提交: git log @{push}.. 或者作为一个更复杂的示例,假设您通常从 origin/master 拉取更改(您将其设置为您的 @{ upstream}),并将更改推送到您的 fork(例如,作为 myfork/topic)。您可以从多台机器推送到您的分支,这需要您从推送目的地而不是上游集成更改。有了这个补丁,你可以这样做: git rebase @{push} 而不是输入全名。

Commit 29bc885 补充说:

for-each-ref: 接受 "%(push)" 格式

就像我们有 "%(upstream)" 来报告每个 ref 的 "@{upstream}" 一样,这个补丁添加了 "%(push)" 来匹配 "@{push}"。它支持与上游相同的跟踪格式修饰符(因为您可能想知道,例如,哪些分支有提交要推送)。

如果您想查看与您要推送到的分支相比,您的本地分支领先/落后有多少提交:

git for-each-ref --format="%(refname:short) %(push:track)" refs/heads

S
Sunil Garg

我之前有一个提交,没有推送到任何分支,也没有远程或本地。只是提交。其他答案中没有任何东西对我有用,但是:

git reflog

在那里我找到了我的承诺。


如此链接 git-scm.com/docs/git-reflog 中所述,引用日志或“reflogs”记录本地存储库中分支和其他引用的提示何时更新。就我而言,我克隆了一个 repo,创建了一个新分支,删除了该分支,创建了一个新分支,创建了一个提交并更改了提交。所有这些步骤都记录为 HEAD@{0}: commit (amend) : .. HEAD@git-scm.com/docs/git-reflog: commit: ... HEAD@{2}: checkout: 从...移动到 ... HEAD@{ 3}:签出:从...移动到... HEAD@{4}:克隆:来自#sorry格式,显然不允许在评论中使用多行
这也包括原始提交,最好的解决方案是使用@PlagueHammer (stackoverflow.com/a/2016954/624048) 提供的命令
D
Dag Høidahl

方便的 git 别名,用于在当前分支中查找未推送的提交:

alias unpushed = !GIT_CURRENT_BRANCH=$(git name-rev --name-only HEAD) && git log origin/$GIT_CURRENT_BRANCH..$GIT_CURRENT_BRANCH --oneline

这基本上是做什么的:

git log origin/branch..branch

但也确定当前分支名称。


这太棒了!对于那些不熟悉别名的人,只需将它们添加到您的 ~/.gitconfig 文件中的 [alias] 部分。
在 bash 中复制/粘贴不起作用,但该脚本非常有用且易于理解
正如@GaryHaran 指出的那样,这不是 bash 别名。还有一个用于添加别名的 git 命令:git alias <alias-name> <command> 在这种情况下,该命令应该用单引号引起来,以便从 shell 中转义特殊字符。
那将是:git config --global alias.unpushed '!GIT_CURRENT_BRANCH=$(git name-rev --name-only HEAD) && git log origin/$GIT_CURRENT_BRANCH..$GIT_CURRENT_BRANCH --oneline'
不过,这似乎与 git log @{u}.. 基本相同 - 请参阅 another answer
J
Justin Ohms

你可以试试……

gitk

我知道它不是一个纯粹的命令行选项,但如果你安装了它并且在一个 GUI 系统上,这是一个很好的方式来准确地看到你在寻找什么以及更多。

(实际上我有点惊讶到目前为止没有人提到它。)


gitk --all 查看所有分支。
tig 是 ncurses 替代方案。
@justin-ohms gitk 太棒了!从来不知道这存在!方便在漂亮的 UI 中浏览更改。
@ray tig 在“仅限终端”的情况下最有用 - 您无法访问桌面 GUI。第一次了解它!有趣:tiggit 的倒数!
A
Aurelien

git branch -v 将针对每个本地分支显示它是否“领先”。


是的,如果分支 devel 上存在未推送的提交,则相应的行将是 * devel 8a12fc0 [ahead 1] commit msg* 将仅在与签出分支对应的行上)。 ahead 1 表示“提前一个提交”,即有一个未推送的提交。
不是git branch -vv吗?参照。 docs:“如果给出两次,也打印上游分支的名称(另见 git remote show <remote>)。”
这不是要打印上游分支的名称,而是要为每个本地分支打印 behind 和/或 ahead,这足以解决 OP 的问题(检测未推送的提交)。 git branch -v 就足够了,刚刚用 Git 2.16.2 再次测试 :)
-vv 很有用,因为它显示了与远程同步的分支和根本未推送的分支之间的差异。 (只有一个 -v,它们在显示中的显示相同。)
C
CCC

我使用以下别名仅获取已提交但尚未推送的文件列表(和状态)(对于当前分支)

git config --global alias.unpushed \
"diff origin/$(git name-rev --name-only HEAD)..HEAD --name-status"

然后做:

git unpushed

看起来很有趣,但在我的情况下 $(git name-rev --name-only HEAD) 是“未定义的”
我不得不将 diff 更改为 git diff,因为它默认使用 diff (GNU diffutils) 3.7
您可以改用“FETCH_HEAD”参考: git config --global alias.unpushed "log FETCH_HEAD..HEAD"
G
Giorgos Kylafas

我相信最典型的方法是运行类似的东西:

git cherry --abbrev=7 -v @{upstream}

但是,我个人更喜欢跑步:

git log --graph --decorate --pretty=oneline --abbrev-commit --all @{upstream}^..

它显示了来自 all 分支的提交,这些分支未在上游合并,加上上游的最后一个提交(显示为所有其他提交的根节点)。我经常使用它,因此我为它创建了别名 noup

git config --global alias.noup \
'log --graph --decorate --pretty=oneline --abbrev-commit --all @{upstream}^..'

a
adswebwork
git cherry -v

这将列出您的本地评论历史记录(尚未推送)以及相应的消息


B
Bruno Adelé

我建议你去看看脚本 https://github.com/badele/gitcheck,我已经编写了这个脚本,以便一次性检查你所有的 git 存储库,它会显示谁没有提交和谁没有推/拉。

https://i.stack.imgur.com/JCu9O.png


你能解释一下如何让这个插件在 Windows 机器上工作吗?我正在尝试运行 pip,但命令行中缺少该命令。我安装了 Python,但我不确定它是否足够。
@KonradSzałwiński 我没有 Windows 机器,但在这个主题( stackoverflow.com/questions/4750806/… )中,用户似乎回答了你的问题:)。但我没有在 Windows 中测试过,我不确定它是否有效。
@KonradSzałwiński ChristianTremblay github 贡献者添加了 Windows 支持。现在 gitcheck 在 Windows 上工作。您可以在 github.com/badele/gitcheck 上下载它
现在,您还可以直接从 docker 容器中使用 gitcheck(文件在您的主机中)有关更多信息,请参阅 gitcheck github 项目
感谢您发布此信息,它似乎真的很有用。我尝试安装,但安装后我找不到运行它的脚本的位置。 $ pip install git+git://github.com/badele/gitcheck.git 收集 git+git://github.com/badele/gitcheck.git 克隆 git://github.com/badele/gitcheck.git 到 c :\users\u6041501\appdata\local\temp\pip-bxt472z_-build 安装收集的包:gitcheck 运行 setup.py install for gitcheck:开始 运行 setup.py install for gitcheck:完成状态 'done' 成功安装 gitcheck-0.3 .22
I
Igor Zevaka

这不是一个错误。您可能看到的是自动合并失败后的 git 状态,其中从远程获取更改但尚未合并。

要查看本地 repo 和远程之间的提交,请执行以下操作:

git fetch

这是 100% 安全的,不会模拟您的工作副本。如果有更改,git status 将显示 X commits ahead of origin/master

您现在可以显示远程但不在本地的提交日志:

git log HEAD..origin

V
VaTo

这对我来说效果更好:

git log --oneline @{upstream}..

或者:

git log --oneline origin/(remotebranch)..

对于其他想知道的人,@{upstream} 是字面意思(upstream 是一个神奇的词),而 remotebranch 只是您的分支的名称。
n
nailgun

有一个名为 unpushed 的工具,它扫描指定工作目录中的所有 Git、Mercurial 和 Subversion 存储库,并显示未提交文件和未推送提交的列表。 Linux下安装很简单:

$ easy_install --user unpushed

或者

$ sudo easy_install unpushed

在系统范围内安装。

用法也很简单:

$ unpushed ~/workspace
* /home/nailgun/workspace/unpushed uncommitted (Git)
* /home/nailgun/workspace/unpushed:master unpushed (Git)
* /home/nailgun/workspace/python:new-syntax unpushed (Git)

有关详细信息,请参阅 unpushed --helpofficial description。它还有一个 cronjob 脚本 unpushed-notify,用于在屏幕上通知未提交和未推送的更改。


M
Mohsen Kashi

要轻松列出所有分支中的所有未推送提交,您可以使用以下命令:

 git log --branches  @{u}..

K
Kaz

如果尚未推出的提交数是个位数,通常是这样,最简单的方法是:

$ git checkout

git 通过告诉您相对于您的来源您“提前 N 次提交”来响应。所以现在在查看日志时记住这个数字。如果您“领先 3 次提交”,则历史上的前 3 次提交仍然是私有的。


C
Christophe Roussy

类似:查看未合并的分支:

git branch --all --no-merged

那些可能是可疑的,但我推荐 cxreg 的答案


A
Alexander Oh

一种处理方式是列出在一个分支上可用但在另一个分支上不可用的提交。

git log ^origin/master master

'^' 字符有什么作用?
@AranMulholland 它代表不在这里。
D
Daniel B

我真的迟到了,我不确定它是什么时候实施的,但要看看 git push 会做什么,只需使用 --dry-run option

$ git push --dry-run
To ssh://bitbucket.local.lan:7999/qarepo/controller.git
   540152d1..21bd921c  imaging -> imaging

v
vrnair24

如上所述:

git diff origin/master..HEAD

但是如果你使用 git gui

打开gui界面后,选择“Repository”->“Visualize History”下

注意:有些人喜欢使用 CMD Prompt/Terminal 而有些人喜欢使用 Git GUI(为简单起见)


git gui 中的可视化选项就是其中之一。
A
Aidin

如果你有 git 子模块...

无论您使用 git cherry -v 还是 git logs @{u}.. -p,都不要忘记通过 git submodule foreach --recursive 'git logs @{u}..' 包含您的子模块

我正在使用以下 bash 脚本来检查所有这些:

    unpushedCommitsCmd="git log @{u}.."; # Source: https://stackoverflow.com/a/8182309

    # check if there are unpushed changes
    if [ -n "$($getGitUnpushedCommits)" ]; then # Check Source: https://stackoverflow.com/a/12137501
        echo "You have unpushed changes.  Push them first!"
        $getGitUnpushedCommits;
        exit 2
    fi

    unpushedInSubmodules="git submodule foreach --recursive --quiet ${unpushedCommitsCmd}"; # Source: https://stackoverflow.com/a/24548122
    # check if there are unpushed changes in submodules
    if [ -n "$($unpushedInSubmodules)" ]; then
        echo "You have unpushed changes in submodules.  Push them first!"
        git submodule foreach --recursive ${unpushedCommitsCmd} # not "--quiet" this time, to display details
        exit 2
    fi

b
bimlas

这是我的便携式解决方案(无需额外安装也可以在 Windows 上运行的 shell 脚本),它显示了所有分支与原点的差异:git-fetch-log

示例输出:

==== branch [behind 1]

> commit 652b883 (origin/branch)
| Author: BimbaLaszlo <bimbalaszlo@gmail.com>
| Date:   2016-03-10 09:11:11 +0100
|
|     Commit on remote
|
o commit 2304667 (branch)
  Author: BimbaLaszlo <bimbalaszlo@gmail.com>
  Date:   2015-08-28 13:21:13 +0200

      Commit on local

==== master [ahead 1]

< commit 280ccf8 (master)
| Author: BimbaLaszlo <bimbalaszlo@gmail.com>
| Date:   2016-03-25 21:42:55 +0100
|
|     Commit on local
|
o commit 2369465 (origin/master, origin/HEAD)
  Author: BimbaLaszlo <bimbalaszlo@gmail.com>
  Date:   2016-03-10 09:02:52 +0100

      Commit on remote

==== test [ahead 1, behind 1]

< commit 83a3161 (test)
| Author: BimbaLaszlo <bimbalaszlo@gmail.com>
| Date:   2016-03-25 22:50:00 +0100
|
|     Diverged from remote
|
| > commit 4aafec7 (origin/test)
|/  Author: BimbaLaszlo <bimbalaszlo@gmail.com>
|   Date:   2016-03-14 10:34:28 +0100
|
|       Pushed remote
|
o commit 0fccef3
  Author: BimbaLaszlo <bimbalaszlo@gmail.com>
  Date:   2015-09-03 10:33:39 +0200

      Last common commit

可以使用为日志传递的参数,例如 --oneline--patch


t
the Tin Man
git show

将显示本地提交中的所有差异。

git show --name-only

将显示本地提交 ID 和提交的名称。


git show 只显示最近的提交,无论它是否被推送到远程,它都不会显示所有未推送的提交。
m
mopoke
git diff origin

假设您的分支设置为跟踪原点,那么这应该会向您显示差异。

git log origin

将为您提供提交的摘要。


git log origin 将显示已已被推送的提交,但不会显示尚未被推送< /b>,这更符合原始海报的要求。