课程 32 · 恢复
Push后恢复错误
修复其他人可能已经存在的错误:更喜欢新的提交,并且当您必须重写您拥有的分支时,强制将租约固定到您查看的确切远程提示上。
- 级别: 高级
- 阅读 3 分钟
- 4 分钟的视频
- 已更新
- 在这节课之前: 推送提交并发布分支, 恢复共享历史记录中的更改, 使用 reflog 查找丢失的提交
进度已保存在此浏览器中。
播放时会加载来自 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
: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)打开调色板。
- 构建演练,如下一节所示:将错误的提交推送到
shared,并将lease分支与 Leo 在服务器上的较新提交一起推送。 - Additive repair. 在
shared上,右键单击错误提交并选择 Revert Commit,然后单击 Push。这是正常的推送;不要选择强制推送(带租赁)...。 - Stale lease. 在
private/lease上,在本地重写草稿,使分支不再包含推送的提交,并尝试使用工具栏 Push 推送它。 GitTree 首先询问推送到哪里,因为private/lease用另一个名称跟踪origin/lease:选择 Push to origin/lease。然后,标题为“远程拒绝私有/租用”的对话框提供 Fetch Only、Rebase and Push、Merge and Push 和 Force Push…。 - 首先选择 Fetch Only 并阅读图表:远程分支现在具有 Leo 的提交,而您的重写不包含该提交。那是队友的工作。
- 打开Force Push…。对话框“强制将私有/租赁推送到原始/租赁?”表示您的分支缺少的提交将从远程中删除,仅当远程仍处于显示的提交时推送才会继续,并且替换的提示保留在
refs/ogt/trash下。取消;狮子座的工作不是你可以取代的。 - 改为协调:Rebase and Push 将您的草稿放在 Leo 的草稿之上,或者先询问他。如果运行了真正的强制推送,则通知会显示“强制推送。替换的遥控器尖端保持在...”,并且 Undo 将强制推送视为对遥控器的更改,您再次按下即可更改回来。
在航站楼
恢复后,在 shared:
git revert --no-edit "$BAD_SHA"
git push origin HEAD:shared
git merge-base --is-ancestor "$BAD_SHA" HEAD; echo $?答案是 0:该错误将留在历史中,并且没有人被迫修复克隆。
在 private/lease 上,Leo 的提交已在服务器上,使用您审阅的提交测试固定租约:
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'
1Git 拒绝(“陈旧信息”),服务器仍然命名 Leo 的提交,状态为空。当您的远程跟踪引用旧时,裸露的 git push --force-with-lease origin HEAD:lease 也会被拒绝,但在 git fetch origin lease 之后,相同的命令替换了 Leo 的提交,因为提取移动了与之比较的引用。命名您审查的提交,或与变基协调。
结果
Where you end: 错误的提交仍在 shared 的历史记录中,并且其之上的恢复已正常推送。在 lease 上,固定推送被拒绝,服务器仍然保留 Leo 的提交,并且您的本地重写完好无损。没有用力推动。
常见错误
- 当恢复可以时,重写其他人已经拉出的分支。
- 获取然后用裸租约强制推送,现在信任您刚刚下载的内容。
- 将租约视为替换队友承诺的许可。
- 假设撤消可以逆转服务器上的强制推送。
如果出现问题
如果强制推送替换了错误的提示,则替换的提交将保留在 refs/ogt/trash 下(对于本机推送,则保留在您的引用日志和队友的克隆中)。告诉队友,将尖端恢复为树枝,并在同意的情况下再次推送。拒绝的推动没有改变任何事情。
检查你的理解情况
回答每个问题,然后阅读原因。标记为“必填”的问题将有助于完成本课程。
0 个(共 6 个)正确
正确回答所需的问题以完成课程。
在此浏览器中检查。
练习
报告对 shared 的祖先检查、固定推送的退出代码和消息、针对 lease 显示的提交 ls-remote,以及在提取之前和之后裸租约是否会被拒绝。
您自己的确认:该网站无法看到您的计算机。
要完成本课程,请正确回答所需的问题并确认实践练习。
回顾
- 对于其他人可能拥有的任何东西,更喜欢新的提交。
- 将租约固定到您审查的提交。
- 租约保护的是你,而不是你队友的意图。
有关的
术语表介绍
租赁 — قفа;陈旧信息 — 重要信息;更换尖端 — ????????
视频文字记录
视频的旁白,逐条提示。
显示成绩单
- 你推错了。现在怎么办?
- 如果其他人可能有提交,请修复它 通过添加提交。
- 租约上写着:只有在以下情况下才更换遥控器: 这仍然是我所期望的。
- 但一次获取就移动了一个赤裸裸的租约 期望。
- 本地服务器上的两个分支:共享, 和租赁。
- 在共享时,恢复错误的提交。
- 正常推。没有力量。
- 这个错误留在了历史中,没有人 必须修复克隆。
- 在租赁时,重写的分支被拒绝。
- 仅获取并查看。 Leo的承诺是 那里。
- 仅当遥控器位于 这次提交,并保留旧的提示。
- 狮子座的工作不是你可以取代的。变基 就可以了,或者问他。
- 在终端中,祖先检查 共享为零。
- 命名您审查的提交。吉特说 陈旧的信息。
- 服务器仍然命名 Leo 的提交。
- 获取后的裸租约将有 取代了它。
- 撤消不会反转对某个对象的强制推动 服务器。
- 实践:报告退出代码,服务器 提交和状态。
- 接下来,同时处理两个分支 工作树。