Push(推送)是指将本地提交发送到远程 Git 仓库,使其可供团队其他成员使用。推送后,更改会出现在 GitHub、GitLab 或 Bitbucket 上。根据 GitHub Octoverse 2024 的数据,每天有超过 1000 万次提交被推送到该平台。 Git push 是在分布式团队中同步工作的关键操作。
要点
Git push 是一个命令,它将提交从本地仓库传输到远程仓库。与仅将更改保存在开发者本地机器上的 commit 不同,push 将这些更改发布给整个团队。 Push 是在创建 Pull Request 和部署之前的必要步骤。
Git 的架构假设每个开发者都在自己的本地仓库中工作。提交在本地创建并积累,直到开发者决定推送它们。这提供了自由:可以进行许多本地提交、实验和重写历史,而不会影响同事。
# 推送到 origin 远程,main 分支
git push origin main
# 将当前分支推送到远程并设置 upstream
git push -u origin feature/new-dashboard
# 推送所有匹配名称的分支
git push --all origin
# 带 lease 的强制推送(安全强制推送)
git push --force-with-lease
推送后,远程仓库会更新 refs(分支引用)以指向新的提交。其他开发者可以通过 git pull 或 git fetch 获取这些更改。正是这种提交交换构成了协作开发的基础。
git push 命令比较本地和远程分支,仅传输缺失的提交。Git 不会重新发送所有文件 — 它只传输差异(delta),这使得即使在大型仓库中推送也很快。 Git 协议 使用智能传输,最大限度地减少传输的数据量。
如果远程分支包含本地不存在的提交,推送将被拒绝。这是一种防止更改丢失的保护机制。在这种情况下,开发者应该先执行 git pull,合并更改,然后再推送。替代方案是 force push(强制推送),它会覆盖远程分支,但必须谨慎使用。
| 命令 | 操作 | 何时使用 |
|---|---|---|
| git push | 标准推送到跟踪分支 | 常规发送更改 |
| git push -u | 设置 upstream 推送 | 新分支的首次推送 |
| git push --force-with-lease | 安全强制推送 | 在自己的分支 rebase 之后 |
| git push --force | 强制推送 | 仅当确信没有冲突时 |
| git push --delete | 删除远程分支 | 合并分支后清理 |
理解远程仓库是正确推送的关键。通常使用 origin — 远程仓库的默认名称。git remote -v 命令显示远程仓库列表及其 URL。可以添加多个 remote(例如,origin 用于主仓库,upstream 用于 fork)。
基本规则:应该在每个逻辑上完成的工作阶段之后进行推送。如果开发者完成了任务或部分任务 — 是时候推送了。但是,不建议推送未完成的会破坏构建的工作。 未损坏的构建 是推送到任何分支的最低要求。
在团队开发中,接受以下节奏:早上 — git pull 获取同事的更改,白天 — 几次提交和一两次推送,晚上 — 所有已完成任务的最终推送。开发者推送得越频繁,合并分支时的冲突风险就越小,工作进度就越透明。
安全推送是一套防止数据丢失和团队冲突的规则。第一条也是最重要的一条规则:切勿直接推送到 main 或 master 分支,除非项目中配置了直接部署。在现代团队中,main 分支的保护是在 GitHub branch protection 级别配置的。
第二条规则:在推送之前,与远程分支同步。执行 git pull --rebase 以避免合并时的 merge commit。这简化了历史并使其线性化。如果推送被拒绝 — 不要使用裸 force push,而是首先检查远程分支中出现了哪些提交。
第三条规则:配置 pre-push 钩子,在发送前自动运行测试和 linter。如果测试失败 — 推送被阻止。此类钩子通过 Husky 或 Git hooks(.git/hooks 中的 pre-push 文件)配置。
第四条规则:不要推送大型二进制文件。Git 不适用于存储二进制工件 — 它们会使仓库膨胀并减慢操作速度。对于大型文件,使用 Git LFS(Large File Storage)。如果二进制文件已被推送并进入历史记录,则必须通过 git filter-branch 删除。
推送失败的最常见原因 — 远程分支包含本地不存在的提交。当其他开发者将其更改推送到同一分支时会发生这种情况。解决方案:执行 git pull,解决可能的冲突,然后重试推送。
# 推送被拒绝 — 先 fetch 和 rebase
git fetch origin
git rebase origin/main
# 解决冲突,然后:
git push --force-with-lease
# 或直接合并远程更改
git pull origin main
git push
第二个原因 — 没有写入分支的权限。如果 main 分支受 branch protection 规则保护,则禁止直接推送。解决方案:推送到 feature 分支并创建 Pull Request。保护设置通常通过 GitHub settings 或 GitLab protected branches 管理。
第三个原因 — 身份验证问题。过期的凭据、切换到 SSH 或更改 personal access token。解决方案:检查远程 URL(git remote -v)并更新凭据。自 2021 年起,GitHub 已取消 HTTPS 的密码认证 — 使用个人令牌或 SSH 密钥。
常见问题
Push 是指将本地提交从开发者仓库发送到远程服务器(GitHub、GitLab)。推送后,更改对团队可用,出现在 Pull Request 中,并且可以部署。 Push 是团队协作之前本地代码工作的最后阶段。
Commit 将更改本地保存在开发者的仓库中。Push 将这些本地提交发送到远程服务器。没有 push 也可以进行许多提交,但要让同事看到更改,需要 push。 Commit — 保存,push — 发布。
如果远程分支包含本地不存在的提交,推送将被拒绝。解决方案:执行 git pull(或 git fetch + git rebase),合并更改并重试推送。如果你在自己的 feature 分支上工作并且对更改有信心,请使用 git push --force-with-lease。
可以,但要小心。使用 git revert <commit-hash> — 它会创建一个撤销更改的提交。然后推送新的提交。如果需要从历史记录中删除提交,请使用 git reset + git push --force-with-lease,但仅限在你自己的 feature 分支中。 git revert 是共享分支的安全选择。
定期推送可防止本地机器故障时的数据丢失,减少合并时的冲突,并为团队提供工作进度的可见性。如果开发者一周不推送,他的更改可能与 main 分支严重偏离,导致合并时出现 复杂冲突。
总结
我们将开发一款交钥匙移动应用程序
IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。