git log --oneline 命令不显示最近的提交

git log --oneline command not displaying recent commit

我前几天 运行 在工作中遇到的有趣问题。所以我是一名正在学习的新数据工程师。我将两个文件 git 提交到我的远程 b运行ch 并进行了 PR,等待合并审查。

但是,我的经理告诉我取消其中一个文件,因为几乎没有任何更改。我的新手大声拒绝,并从此 window 删除了文件。 (为了举例,news/reddit.py 是示例文件

现在,这显然是一个新的提交。我想使用 git revert <commithash> --no-edit 恢复这些更改。我遇到的问题是,当我在终端中 运行 git log --oneline 时,删除文件时创建的提交没有哈希值。

现在,当我从这里的 github 获取哈希时:

和运行git revert 738bd6a --no-edit

我收到此错误:fatal: bad revision '738bd6a'

还运行使用完整的哈希执行恢复命令我收到了这个:fatal: bad object 738bd6a3bccab7d96e9e7f93871285eea72943cf

我知道我可以关闭 PR 并重新提交文件,但想看看是否有人知道为什么哈希不起作用以及为什么我找不到哈希 运行ning git log --oneline

谢谢!

我认为这里的答案是您混淆了 GitHub 和 Git。 GitHub 是一个托管 Git 存储库并允许您使用托管存储库执行各种操作的站点,包括许多 base 不提供的附加服务Git。 Git 本身是软件:

  • 进行版本控制(在某种程度上)
  • 通过提供 commit 存储文件的对象的分布式+复制数据库。

因此,您在自己的计算机(例如笔记本电脑)上安装 Git,并在那里创建和操作一个或多个 Git 存储库。这些存储库包含提交,您所做的大部分事情最终都会导致添加新的提交。

您在笔记本电脑上添加到您的 存储库的新提交在您笔记本电脑的存储库中。要将这些新提交提交给其他一些 Git——一些其他存储库管理软件,通常在其他机器上——你将 发送 提交 给他们git push。如果另一个 Git 驻留在 GitHub 的一台计算机上,那很好:现在他们有了你的新提交(加上任何旧的:当一个 Git 与另一个交谈时,他们通常会发送 所有他们可能的提交,尽管这里的细节很复杂)。

当您在笔记本电脑上使用 git clone 时,您正在让 Git(笔记本电脑上的软件)创建一个新的空存储库,然后保存一个 URL一些其他 Git,例如 GitHub 上的一个。然后,您将 Git 连接到他们的 Git 并 复制 他们所有的提交到您的存储库中。该复制步骤发生在 git fetch 中,它与 git push 相反,或者接近于 Git 的一个。你会认为 git pull 会相反,但事实并非如此。

所以,出了什么问题?嗯,你在你的笔记本电脑上做了一些提交,将它们发送到 GitHub,并使用 GitHub clicky web 界面使 GitHub 调用 pull request,这是一个GitHub的概念。 (Base Git 没有 Pull Requests。)到目前为止,我们都很好。但是随后您使用 GitHub 可点击 Web 界面将新提交 添加到 GitHub 上的存储库。该提交就在那里,在 Git Hub 上的那个 Git 存储库中,但它在您的笔记本电脑上

所以,然后你走到你的笔记本电脑 Git 并告诉它恢复提交,给它提交的哈希 ID 只存在于 [= 的存储库中228=]集线器。你的Git说:什么?你到底在说什么?我没有 738bd6a. 那是因为......它没有那个提交。

要让您的Git拥有该提交,您必须将您的Git(您的软件在您的笔记本电脑存储库中运行)连接到他们的Git(他们的软件 运行ning 在您的 GitHub 存储库中),使用 git fetchgit pullgit fetch 步骤是最关键的一步:您的 Git 将调用他们的 Git,他们将列出他们的 b运行ch 名称和哈希 ID,以及您的 Git 会看到 738bd6a3bccab7d96e9e7f93871285eea72943cf 并自言自语: 哦,嘿,我没有那个提交!我最好主动提出来! 你的 Git 会要求他们的 Git 寄过来,他们会的,现在 你'会有 738bd6a3bccab7d96e9e7f93871285eea72943cf.

虽然 git fetch 单独 得到 这个提交,但这还不够。您笔记本电脑上的存储库有提交,您的 Git 和他们的 Git 将相互共享。他们的存储库有提交,您的 Git 和他们的 Git 将相互共享。但是你和他们的存储库都有 b运行ch 名称,并且这些名称 没有共享: 不完全是。

相反,当您的 Git 与他们交谈并从他们那里获得提交时,您的 Git 会看到他们的 b运行ch 名称,但 会更改这些名称。您的 Git 不是 mainmaster,而是在前面添加您的 远程名称 origin,再加上一个斜线,这样名称现在是 origin/mainorigin/master。这不是 b运行ch 名称,而是 远程跟踪名称 。您的 Git 将新提交填充到您自己的存储库中,并根据需要创建或更新任何远程跟踪名称,以便能够找到这些提交。1

但是:您在 您的 b运行ch 名称上进行工作。所以一旦你从别人那里得到了一些新的提交,你可能想要更新你自己的 b运行ches。为此,您通常需要 运行 git mergegit rebase 或其他一些额外的 Git 命令。确切地使用哪个命令、何时使用以及为什么使用,这涉及到很多问题,并且包括您特定工作场所的文化细节,因此很难说您应该首先使用哪个命令。不过,对于这个 特殊的 案例,合并可能是正确的答案。

Git 的 git pull 命令 运行s git fetch 给你,然后——假设获取步骤有效2—运行s 第二个 Git 命令,通常是 git mergegit rebase.3 所以如果你知道获取步骤将工作和做一些特别的事情,你可以使用 git pull 作为快捷方式,而不是 运行 两个单独的命令。我建议新手无论如何都使用这两个单独的命令,因为它在多个方面都有帮助:

  • git fetch(总是安全的,几乎总是有效的)和第二个命令(有时不安全,经常无效)之间的区分很清楚。
  • 它允许您查看 git fetch 在 之前 获取了什么 第二个命令 运行。
  • 当第二个命令失败时,您知道您使用的是哪个命令运行,因此,在获得帮助时接下来的步骤是什么(merge 与 rebase 不同)。

事实上 Git 分布式的,因此每个 Git 克隆都可以拥有整个存储库的完整副本(直到它是克隆的或最后一次使用 fetch 重新更新的),这对许多 Git 新手来说很棘手。加上各种其他 Git 命令的复杂性,Git 成为许多程序员的天坑。我鼓励您:

  • 运行git log --all --graphgit log --all --graph --oneline;另见 Pretty Git branch graphs
  • 然后,运行 git fetch 并重复 git log --graph

查看传入的提交如何更新 origin/<somebranch>。请注意新提交如何 add on 到 b运行ches 的末尾(正如您的远程跟踪名称所记住的那样),“向前移动 b运行ch” ,事实上。您的 Git 现在反映了您使用 GitHub 的 Git 所做的事情。您现在可以更新您自己的 b运行ch,在这种情况下,它只会将您的 b运行ch name 向前移动,使用 git mergegit merge --ff-only。然后您可以还原提交,将另一个提交添加到您自己的(本地)b运行ch 的末尾。 运行git log --graph再次一路观察这些更新

最后,您可以 git push 将新提交提交到 GitHub 的 Git。这会将提交添加到链中,并向您展示另一个特性:当您使用 git fetch 时,您 get 提交 from 它们,然后您的 Git 更新您的 远程跟踪名称 。在您的存储库中,每个 b运行ch 名称都有一个远程跟踪名称,因此这是一件安全的事情。但是:当你 运行 git push 时,你向他们发送了一个新的提交,然后要求 他们 更新其中一个 他们的 b运行ch 名称。他们在这里没有等效的远程跟踪名称。你只需让他们更新他们的 b运行ch 名称。

因为我们(和Git)喜欢find commits using b运行ch names,这最终会引起你会遇到的问题(最终) 运行 进入,其中他们的 Git 说“我不会接受这个名称更新请求,因为它是一个 非快进 ”。参见,例如,Git push rejected "non-fast-forward"。有时你想强迫他们无论如何都接受这个更新:是的,扔掉一些提交,这些是他们新的和改进的替代品。有时你不需要。


1您可能想知道为什么我们需要名称来查找提交。从技术上讲,我们不这样做:您可以一直使用 738bd6a3bccab7d96e9e7f93871285eea72943cf。但是明天你会记得738bd6a3bccab7d96e9e7f93871285eea72943cf吗?如果它有一个简单易记的别名作为别名,例如 foobranchorigin/foobranch,现在 你可以记住。

此外,b运行ch names 会在您添加新提交时自动更新。当您 运行 git fetch 时,远程跟踪名称会自动更新,这会添加您从他们 那里获得的任何新提交,这有点相同,只是不同。 b运行ch 名称和 remote-tracking 名称之间的巨大区别,除了您的 Git 从 their b运行ch 名称创建和更新您的远程跟踪名称,是 git switch origin/<em>b运行ch</em> 拒绝 运行 和 git checkout origin/<em>b运行ch</em> 将您置于“独立 HEAD”模式,这不是进行正常日常工作的好方法。

简而言之:b运行ch names = where you do your stuff远程跟踪 名字 = 你的 Git 对他们 Git 的兄弟 运行 的记忆。使用 git fetch 更新您的远程跟踪名称。