"git commit" 和 "git push" 有什么不同?

1004
在我正在学习的 Git 教程中,git commit 用于存储您所做的更改。
那么 git push 用于什么呢?

94
你也可以查看这份“Git备忘单”,它帮助我很好地理解概念: http://ndpsoftware.com/git-cheatsheet.html - adriendenat
2
这是另一张速查表:https://www.atlassian.com/git/tutorials/atlassian-git-cheatsheet - Kellen Stuart
11
已有答案提供,无需回答。只是一个观察。在我看来,“commit”应该被称为“保存”,而“push”应该被称为“提交”。这是经典的命名场景问题。 - dublinx
@dublinx - 我会把“push”命令称为“上传”,因为你将文件上传到远程仓库,而且大家都知道“上传”这个词 :) - Gabriel
@dublinx - 我会把“push”命令称为“上传”,因为你把文件上传到远程仓库,而且大家都知道“上传”这个词 :) - undefined
15个回答

1786

基本上,git commit记录仓库中的更改”,而git push更新远程引用及其关联对象”。因此,第一个命令用于操作本地仓库,而后者用于与远程仓库交互。

以下是来自Oliver Steele的精美图片,它解释了Git模型和相应的命令:

Git data transport commands

阅读更多关于git pushgit pull的信息,请参考我首先提到的文章:推送和拉取


26
好的,我会尽力进行翻译。以下是需要翻译的内容:这里是原始来源:http://osteele.com/archives/2008/05/my-git-workflow,还有另一张git工作流程图。 - tanascius
10
GitHub只是托管公共“云端”代码库以便git push工作的一个解决方案。实际上,git push的目标可以是任何 Git 存储库。它可以位于本地硬盘驱动器中的另一个目录(例如git remote add clone ~/proj/clone.git; git push clone mastergit push ~/proj/clone.git master),也可以是您自己托管的 Git 存储库。 - Santa
3
那么...你需要先推送还是先提交? - Kokodoko
5
@Piet,它始于你的工作区,那里你修改文件。然后将它们添加到索引中,提交到本地仓库,最后推送到远程仓库。 - tanascius
2
@Celik 当你没有远程仓库时,推送是无用的。因此分离是有意义的。但是也可能有多个远程仓库 - 因此您需要多次推送。 - tanascius
显示剩余25条评论

266

commit(提交):将更改添加到本地仓库

push(推送):将最近的提交(commit)传输到远程服务器


4
非常精炼的答案!这里的很多答案都过于冗长。 - Dave F

76

简而言之,Git commit 将您的更改放入本地存储库,而 git push 将您的更改发送到远程位置。


12
这是我使用GIT的第二天。看了上面的回答,我仍然没有明确的了解,但你的回答很准确。谢谢。 - Bopha
2
git push 会上传实际更新的文件还是一些特殊的“差异”文件? - multigoodverse

30

git push用于将您在本地仓库中完成的提交添加到远程仓库中。与git pull一起使用,它使人们可以进行协作。


29

提交(Commit):对一个代码库进行的快照、变更集、版本记录、历史记录或“另存为”。Git 代码库是一系列提交(Commits)的组合。

本地(Local)代码库:存储在您计算机上的代码库。

远程(Remote)代码库:存储在服务器 (GitHub) 上的代码库。

git commit: 将新的提交(最后一次提交 + 暂存修改)添加到本地代码库中。(提交存储在文件夹 /.git 中。)

git pushgit pull:将本地代码库与其关联的远程代码库同步。 push - 应用来自本地代码库的更改到远程代码库中,pull - 应用来自远程代码库的更改到本地代码库中。


“Snapshot | Changeset | Version | History-record”是什么意思?例如,它是指特定的应用程序或网站吗? - Peter Mortensen
@PeterMortensen 不是的。这些只是不同的可能的一般描述符。 - xged

27

由于Git是一种分布式版本控制系统,因此其区别在于commit会将更改提交到本地存储库,而push会将更改推送到远程存储库。


13

git commit 命令将您的更改记录到本地代码库。

git push 命令将您的本地更改上传到远程代码库。


23
你的回答基本上与这个答案完全相同,没有增加任何新内容。 - user456814

11

需要注意三件事:

  1. 工作目录 — 存放我们的代码文件的文件夹。

  2. 本地仓库 — 在我们的系统内。当我们第一次执行 commit 命令时, 会在与我们的 工作目录 相同的位置创建此 本地仓库。 检查 (.git) 文件是否创建。 之后每当我们提交变更,都会将这些变更存储到工作目录中的文件, 以便将其保存到本地仓库 (.git)。

  3. 远程仓库 — 位于我们的系统外,如 GitHub 等服务器,可以位于世界上的任何地方。 当我们执行 push 命令时,来自本地仓库的代码将被存储在此远程仓库中。


“Checkit (.git) file get created”是什么意思(看起来不可理解)?请通过编辑(更改)您的答案来回答,不要在这里留言(不要添加“编辑:”,“更新:”或类似内容 - 答案应该像今天写的一样)。 - Peter Mortensen
好的,OP已经离开了:"上次出现已经超过3年了"。 - Peter Mortensen

7

我想补充以下几点:

在我们使用 git push 命令将本地分支上的提交推送到远程存储库之前,你不能进行推送。

git push 命令需要两个参数:

一个是远程名称,例如,origin

另一个是分支名称,例如,master

例如:

git push  <REMOTENAME> <BRANCHNAME> 
git push  origin       master

7

Git工作原理通俗易懂的解释

我使用Git已经多年了,但是奇怪的是,无论在这里还是在线上,似乎没有人能够简单地解释Git的pushpullcommitpull requests是如何工作的。因此,下面是一个简单的解释,希望能更清楚地解释事情。这对我很有帮助!

Git工作原理的简单总结

在Git中,你总是先在本地计算机上创建代码,然后将代码保存到本地计算机上的Git的“本地存储库”(repo)中。当你完成时,你可以将你的修改上传到Git的共享“远程存储库”,以便他人可以访问你的代码更改。你还可以从“远程存储库”下载更改到你的“本地存储库”,以便你的代码与其他开发者的更改保持最新。然后你再次开始这个过程。

通过这种方式,Git允许你与他人远程共享本地项目代码,并在出现问题需要重做错误代码时保存这些代码更改的版本。这就是Git工作的简单解释和它的使用周期。

更多Git细节

第一步总是在本地计算机上编写代码,忽略Git,Git不会以任何方式参与保存或测试代码。 当你在电脑上保存本地代码时,默认情况下不会将代码保存到Git中,你需要进行第二步,称为“提交(commit)”。(尚未提交的已保存代码称为“staged”代码,顺便说一句)。

commit在“Git世界”中保存本地代码更改的操作,这让人们感到困惑。但是当我看到“commit”这个词时,我认为它是一个“Git Save”。这是额外的一步,因为你已经保存了一次代码更改,现在必须将其作为提交再次保存到Git系统中,否则它们将不成为你的本地Git存储库系统的一部分。“提交”可能是一些人认为Git设计不好的原因之一。它只是不直观。

在将代码保存并在本地Git仓库提交代码后,你需要执行push操作。该操作会将你的本地仓库变更(仅限于提交)上传到远程仓库以便更新。此时,它会完全覆盖远程仓库中的所有内容,使得两者处于同步状态,也就是说两者之间的代码完全相同。可以将其视为“远程Git保存”。它会将本地计算机上的代码覆盖远程仓库上的代码。一开始我对此感到困惑。难道这不会删除其他开发人员在远程上所做的更改吗?如果远程与你的更改存在冲突,或者在本地仓库中需要首先拥有远程没有的更改怎么办?一开始我很困惑,因为没有人能够在线解释它是否与“合并”,“提交”,“拉取请求”等相同。事实证明,只有在一个条件下,该命令才能正常工作。否则,会阻止你的推送并失败!
只有当你是唯一修改远程仓库的人,并且两个代码库除了你本地添加的提交之外完全相同时,“push”才能正常工作。否则,远程其他用户所做的任何更改都会取消你的推送。因此,将push视为与本地库相同副本的“私有远程写入”操作。不过我们知道,很多开发人员会提交更改到远程副本,就像你一样使用push,对吗?因此,在这种设计下,推送将失败,并且每个人的本地库与远程库始终不同步。
正如我所提到的,只有在你做出更改之前远程仓库处于与你的本地仓库完全相同的状态时,“push”才能正常工作(远程仓库不会阻止) 。换句话说,只有当你在推送本地变更之前远程仓库未被任何其他开发人员更改时,才能将本地更改推送到远程项目并完全覆盖它。这是Git中令人困惑的一个奇怪方面。如果你的本地代码与远程仓库不同步,因为远程仓库已经被更改,推送将失败,你将被迫执行pull或“rebase”(更新本地仓库以匹配远程仓库)。如果你的推送被阻止并且随后执行pull,它将复制远程代码并将其代码更改合并到你的本地副本中。一旦同步,你仍然可以使用push将提交推送上去,因为在执行拉取或合并后,它们应该仍然存在。
这在大多数情况下都能正常工作,除非代码更改与其他开发人员在相同的代码区域进行的提交或代码更改产生冲突。在这种罕见的情况下,你必须在继续进行任何操作之前先在本地解决冲突,因为你可能会意外地覆盖其他开发人员的更改。 这就是pull request(请参见下文)比push更有用的原因,因为前者强制要求代码所有者或管理员首先手动解决远程复制品上的重大代码更改
有趣的是,“pull”与“push”执行相同的操作,但在这种情况下,它会将远程项目的最新副本拉到您的本地GIT系统中,然后将这些更改“合并”到您自己的副本中,而不像“push”那样覆盖它们。当然,这会再次将您的远程和本地副本同步,但减去了您要使用“push”更新到远程存储库的新提交。

一旦通过“pull”将本地副本同步到远程副本,您现在可以执行“push”,将您的提交或更改发送回远程副本,并安全地覆盖它们,因为您已经将您的更改与其他开发人员所做的更改合并在一起。

在“push”使用本地副本的提交或更改覆盖远程副本之后,远程副本与本地副本完全匹配。由于它们都匹配,只要没有其他开发人员像您一样更改了远程内容,你就可以再次将本地的任何额外提交或保存推送到远程,而无需进行拉取操作,Git在推送时始终会向您发出警告,如果有这种情况发生的话。您无法弄糟它。您可以执行“强制”推送、“变基”和其他技巧,但那不重要。但是,只要其他开发人员推送了他们的更改,您就会再次失去同步并且必须先进行一次拉取操作然后才能再次推送。

这种提交-拉取-推送的流程是Git开发中真正的节奏,没有人告诉您这一点,并假定您已经理解了它。大多数人都不知道它。它只是不直观或逻辑。

当然,你可以“强制”推送并覆盖所有东西。但在你尝试之前,该系统会向你发出警报。当一个新人添加或更改远程内容时,使用这种拉取和推送的系统就会失败。这就是导致推送和拉取警告以及故障的原因,直到每个人再次与远程同步为止。完成后,开发人员便有权将更改推送到远程,因为他们的代码再次与远程匹配。但是,在有很多更改或分支和代码合并要去远程存储库时,最好使用Git的“pull request”命令。

最后,值得注意的是,使用Git进行开发的人几乎总是被鼓励在对软件进行更改之前先创建一个新的本地和远程存储库分支。在这种情况下,“push”和“pull”就有了完美的意义,因为几乎总是由单个开发人员在软件的隔离分支上进行代码更改,从不与其他开发人员的更改冲突。这就解释了为什么一个开发人员通常会在自己的分支上工作,在这种情况下,“push”和“pull”可以完美地工作,可以快速推送/拉取更改,永远不会引起代码冲突,并允许一个开发人员将其最终本地更改副本存储在远程存储库分支中,稍后使用下面描述的“pull request”系统合并到主分支中。

奇怪的Pull请求

Git谜题的最后一部分。从远程存储库的角度来看,pull request是一个“pull”,将本地仓库代码拉取到它里面。但它是一个“请求”,最初并不会实际拉取或更改任何内容,也不会推送或合并任何代码。它只是您从本地仓库发送给远程仓库的请求,要求审查代码,如果他们批准,则将您的代码拉取到他们的远程副本中。
在pull request中,您正在请求远程存储库管理员或所有者上传您的代码更改或提交,审核您的本地仓库提交更改,然后在他们的批准下将您的代码更改合并到远程存储库中。当他们批准您审核过的本地仓库提交或更改时,他们会拉取您的本地仓库代码或分支,并将其合并到远程仓库分支中。
远程存储库有管理员或所有者,他们控制远程存储库中准备用于生产的关键顶层代码分支。他们不喜欢将代码更改合并到这些较大的分支中,而没有对代码质量进行一定的控制。当您进行pull request时,您正在提醒管理员或远程存储库所有者,作为本地开发人员,您拥有某个完成的代码分支,并希望他们手动将您的本地仓库代码拉取到远程仓库代码中。这与从本地到远程存储库的推送相同,但在这种情况下需要由顶级远程存储库所有者完成相反方向的操作。还需要远程存储库所有者对更改进行手动代码审核和批准。
注意:pull request更常见于两个远程存储库分支之间合并代码,通常影响远程服务器或设备上的已完成代码分支,必须将其合并到主要远程分支中,而不仅仅是本地提交更改。再次说明一下,这并不直观!
如果您使用推送和拉取Git命令同步和合并代码,为什么需要pull request?在需要许多人将大量更改推送到具有合并到主要远程存储库分支的已完成分支的情况下,以及需要测试或审核代码后才能进行重大发布或代码基础更新的情况下,pull requests比推送更有效。 Push和在仅有一个或两个开发人员正在处理和共享的孤立小分支方面的效果更好。在本地和远程存储库之间拉取和推送代码比将复杂的远程存储库更改的大量分支合并到远程存储库的主分支中要容易得多。
因此,请记住...

使用“push”更新您在本地和远程都控制的小分支。

使用“pull request”让远程存储库人员将您的较小的分支合并到远程服务器上的较大分支中。

我喜欢把pull requests看作是一个主推送(Master Push),而将push视为本地推送(Local Push)。我希望Git的开发者们能够为这些过程取一个更合乎逻辑、更易于理解的名称。现在这样的命名方式完全不直观!
实际上,pull request也是一种添加代码安全层的方式,它在将大量代码堆栈合并到关键顶级远程分支或项目分支时首先要求管理员或团队成员的许可。因此,它会要求团队成员先批准本地Repo代码的大量更改和提交,然后再将它们拉入重要的远程Repo分支。
这有助于通过代码审查和批准来保护对关键分支的代码更新。但是,它还可以让被许多团队更新的远程Repo在测试、批准等之前暂停更改更重要的分支和合并。这就是为什么对于只涉及开发人员私有小分支的代码更改,通常只需要使用拉取(pull)和推送(push),而对于那些较大的合并分支,则通常会阻止推送而使用Pull Request。这更符合使用推送完成的完成分支通常会被合并到Git树的更大分支中。
弄清楚这一点需要数小时的研究,即使我使用Git已经多年了,在线上也没有文档解释这种区别。
因此...当你在处理自己的代码更改或分配给你的项目部分时,一定要使用提交-拉取-推送的程序。首先将Repo下拉以确保本地Repo具有其他开发人员所做的所有最新更改。如果您愿意,可以在拉取之前和之后提交或保存所有本地更改...这没有关系。如果有冲突,请尝试在本地解决。然后,只有在这之后,才进行推送以覆盖远程副本中的本地代码。你的本地和远程仓库在Git世界中完全同步!
最后,当您的本地和远程分支都完成时,请向Git管理员发送一个Pull Request,并由他们处理您已完成的远程Repo分支的合并。

太棒了,写得很好。谢谢! - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接