跳至内容
GitTree

课程 32 · 恢复

Push后恢复错误

修复其他人可能已经存在的错误:更喜欢新的提交,并且当您必须重写您拥有的分支时,强制将租约固定到您查看的确切远程提示上。

进度已保存在此浏览器中。

播放时会加载来自 YouTube 的视频(隐私增强模式)。

英文旁白 · English and Arabic 字幕

打开视频页面在 YouTube 上观看

你将学到什么

  • 在附加修复和针对推送错误的重写之间进行选择。
  • 解释租约检查的内容以及预期承诺为何重要。
  • 预测陈旧租约被拒绝并保留队友的工作。
  • 了解 GitTree 在强制推送之前保留什么。

开始之前

本地排练服务器上的两种情况。在 shared 上,错误的提交已被推送,其他人可能拥有它。在 lease 上,您推送了草稿,然后在本地重写了它,但 Leo 同时将更新的提交推送到了同一分支。

一切都是本地的并且采用免费套餐(GitTree 要求您登录):没有托管帐户、没有提供商、没有互联网。每个身份都是虚构的(example.com)。切勿在实际项目中运行本课程。

在 GitTree 中或使用本机 Git 命令进行更改,而不是在同一副本中进行更改。读取结果总是安全的。菜单标签来自 GitTree 2.0 自己的字符串,本机命令使用 Git 2.43 在一次性副本中运行。 GitTree 步骤未在 macOS、Windows 或 Linux 上运行。

概念和状态效应

如果队友可能有错误的提交,请使用新的提交(恢复,第 28 课)修复它并正常推送:历史记录会保留错误,并且没有人的克隆会失效。仅当您拥有已发布的分支时才重写它。

lease 使强制推送成为有条件的:只有当远程分支仍然指向您期望的位置时,Git 才会替换它。 --force-with-lease=<ref>:<commit> 命名预期的提交。裸露的 --force-with-lease 使用您的远程跟踪引用,而 git fetch 会移动该引用,因此获取然后推送可能会覆盖您刚刚下载的内容。 GitTree 固定上次提取的提交,将其显示在对话框中,并将替换的提示保留在 refs/ogt/trash 下。

租约并不能决定您是否可以覆盖队友的工作。它只能保护您免于覆盖您未见过的内容。

准备准确的项目状态

从第 18 课结果的单独普通副本开始,使用新的本地裸存储库作为其唯一的远程存储库。 RECOVERY_BAD 是错误的样式表; LEASE_A、LEASE_B 和 LEASE_REWRITE 是注释的三个版本。

完整的文件输入

完全按照所示方式保存下面的每个文件:UTF-8、LF 行结尾和最后一个换行符,没有 Markdown 栅栏线。未列出的文件保留其内容不被 M.

styles.css — RECOVERY_BAD

文件摘录 · css
:root {
  color-scheme: light;
  --page: #f7f8fa;
  --surface: #ffffff;
  --text: #f7f8fa;
  --link: #154ab5;
  --line: #bac4d0;
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  background: var(--page);
  color: var(--text);
  font: 1rem/1.6 system-ui, sans-serif;
}

a {
  color: var(--link);
}

.site-header,
main,
footer {
  width: min(68rem, 100% - 2rem);
  margin-inline: auto;
}

.site-header {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 1rem;
  padding-block: 1rem;
}

.hero {
  max-width: 48rem;
  padding-block: 3rem;
}

h1 {
  font-size: clamp(2rem, 5vw, 3.5rem);
  line-height: 1.2;
}

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(16rem, 100%), 1fr));
  gap: 1rem;
}

.feature-card {
  padding: 1rem;
  border: 1px solid var(--line);
  border-radius: 0.75rem;
  background: var(--surface);
}

section {
  margin-block-end: 2rem;
}

button,
input {
  font: inherit;
}

button,
input {
  padding: 0.5rem 0.75rem;
}

:focus-visible {
  outline: 3px solid var(--link);
  outline-offset: 3px;
}

form {
  display: grid;
  max-width: 28rem;
  gap: 0.5rem;
}

文档/lease-note.md — LEASE_A

输出
# Private release rehearsal

The reviewed draft is still private.

文档/lease-note.md — LEASE_B

输出
# Private release rehearsal

Leo added a review that must not be overwritten.

docs/lease-note.md — LEASE_REWRITE

输出
# Private release rehearsal

This alternative draft has not seen Leo's review.

在GitTree

使用 Command+Shift+P(在 Ubuntu 上为 Ctrl+Shift+P)打开调色板。

  1. 构建演练,如下一节所示:将错误的提交推送到 shared,并将 lease 分支与 Leo 在服务器上的较新提交一起推送。
  2. Additive repair. 在 shared 上,右键单击错误提交并选择 Revert Commit,然后单击 Push。这是正常的推送;不要选择强制推送(带租赁)...。
  3. Stale lease. 在 private/lease 上,在本地重写草稿,使分支不再包含推送的提交,并尝试使用工具栏 Push 推送它。 GitTree 首先询问推送到哪里,因为 private/lease 用另一个名称跟踪 origin/lease:选择 Push to origin/lease。然后,标题为“远程拒绝私有/租用”的对话框提供 Fetch Only、Rebase and Push、Merge and Push 和 Force Push…。
  4. 首先选择 Fetch Only 并阅读图表:远程分支现在具有 Leo 的提交,而您的重写不包含该提交。那是队友的工作。
  5. 打开Force Push…。对话框“强制将私有/租赁推送到原始/租赁?”表示您的分支缺少的提交将从远程中删除,仅当远程仍处于显示的提交时推送才会继续,并且替换的提示保留在 refs/ogt/trash 下。取消;狮子座的工作不是你可以取代的。
  6. 改为协调:Rebase and Push 将您的草稿放在 Leo 的草稿之上,或者先询问他。如果运行了真正的强制推送,则通知会显示“强制推送。替换的遥控器尖端保持在...”,并且 Undo 将强制推送视为对遥控器的更改,您再次按下即可更改回来。

在航站楼

恢复后,在 shared:

Command · bash
git revert --no-edit "$BAD_SHA"
git push origin HEAD:shared
git merge-base --is-ancestor "$BAD_SHA" HEAD; echo $?

答案是 0:该错误将留在历史中,并且没有人被迫修复克隆。

在 private/lease 上,Leo 的提交已在服务器上,使用您审阅的提交测试固定租约:

Command · bash
git push --force-with-lease=refs/heads/lease:"$EXPECTED_SHA" origin HEAD:lease; echo $?
git ls-remote origin refs/heads/lease
git status --short
输出
 ! [rejected]        HEAD -> lease (stale info)
error: failed to push some refs to '../origin.git'
1

Git 拒绝(“陈旧信息”),服务器仍然命名 Leo 的提交,状态为空。当您的远程跟踪引用旧时,裸露的 git push --force-with-lease origin HEAD:lease 也会被拒绝,但在 git fetch origin lease 之后,相同的命令替换了 Leo 的提交,因为提取移动了与之比较的引用。命名您审查的提交,或与变基协调。

结果

Where you end: 错误的提交仍在 shared 的历史记录中,并且其之上的恢复已正常推送。在 lease 上,固定推送被拒绝,服务器仍然保留 Leo 的提交,并且您的本地重写完好无损。没有用力推动。

常见错误

  • 当恢复可以时,重写其他人已经拉出的分支。
  • 获取然后用裸租约强制推送,现在信任您刚刚下载的内容。
  • 将租约视为替换队友承诺的许可。
  • 假设撤消可以逆转服务器上的强制推送。

如果出现问题

如果强制推送替换了错误的提示,则替换的提交将保留在 refs/ogt/trash 下(对于本机推送,则保留在您的引用日志和队友的克隆中)。告诉队友,将尖端恢复为树枝,并在同意的情况下再次推送。拒绝的推动没有改变任何事情。

检查你的理解情况

回答每个问题,然后阅读原因。标记为“必填”的问题将有助于完成本课程。

  1. 第 1 题,共 6 题

    共享分支上已经存在错误的提交。什么是最安全的维修?

    选择一个答案。

  2. 第 2 题,共 6 题

    关于 --force-with-lease,以下哪一项是正确的? (多选)

    选择每个适用的答案。

  3. 第 3 题,共 6 题
    必填

    您将租约固定到您审查的提交上进行推送,但 Leo 在那之后进行了推送。会发生什么?

    选择一个答案。

  4. 第 4 题,共 6 题

    更改输入:运行 git fetch origin lease,然后运行空的 git push --force-with-lease origin HEAD:lease。会发生什么?

    选择一个答案。

  5. 第 5 题,共 6 题
    必填

    一位同事表示,“强制租赁使强制推送对每个人来说都是安全的”。正确的回答是什么?

    选择一个答案。

  6. 第 6 题,共 6 题
    必填

    固定推送后,哪些读回显示没有丢失任何内容? (多选)

    选择每个适用的答案。

0 个(共 6 个)正确

正确回答所需的问题以完成课程。

在此浏览器中检查。

练习

报告对 shared 的祖先检查、固定推送的退出代码和消息、针对 lease 显示的提交 ls-remote,以及在提取之前和之后裸租约是否会被拒绝。

您自己的确认:该网站无法看到您的计算机。

要完成本课程,请正确回答所需的问题并确认实践练习。

回顾

  • 对于其他人可能拥有的任何东西,更喜欢新的提交。
  • 将租约固定到您审查的提交。
  • 租约保护的是你,而不是你队友的意图。

术语表介绍

租赁 — قفа;陈旧信息 — 重要信息;更换尖端 — ????????

视频文字记录

视频的旁白,逐条提示。

显示成绩单
  1. 你推错了。现在怎么办?
  2. 如果其他人可能有提交,请修复它 通过添加提交。
  3. 租约上写着:只有在以下情况下才更换遥控器: 这仍然是我所期望的。
  4. 但一次获取就移动了一个赤裸裸的租约 期望。
  5. 本地服务器上的两个分支:共享, 和租赁。
  6. 在共享时,恢复错误的提交。
  7. 正常推。没有力量。
  8. 这个错误留在了历史中,没有人 必须修复克隆。
  9. 在租赁时,重写的分支被拒绝。
  10. 仅获取并查看。 Leo的承诺是 那里。
  11. 仅当遥控器位于 这次提交,并保留旧的提示。
  12. 狮子座的工作不是你可以取代的。变基 就可以了,或者问他。
  13. 在终端中,祖先检查 共享为零。
  14. 命名您审查的提交。吉特说 陈旧的信息。
  15. 服务器仍然命名 Leo 的提交。
  16. 获取后的裸租约将有 取代了它。
  17. 撤消不会反转对某个对象的强制推动 服务器。
  18. 实践:报告退出代码,服务器 提交和状态。
  19. 接下来,同时处理两个分支 工作树。