“Git提交”和“Git推送”有什么区别?

在我正在学习的Git教程中,git commit用于存储您所做的更改。

那么git push是用来做什么的呢?

858404 次浏览

基本上,git commit记录对存储库的更改”而git push更新远程参考以及关联的对象”。因此,第一个用于与本地存储库连接,而后者用于与远程存储库交互。

这是一张来自奥利弗·斯蒂尔的漂亮图片,它解释了Git模型和命令:

Git数据传输命令

阅读更多关于推和拉git pushgit pull(我首先提到的文章)。

git push用于将您在本地存储库上完成的提交添加到远程存储库。与git pull一起,它允许人们协作。

提交:将更改添加到本地存储库

推送:将最后一次提交传输到远程服务器

由于Git是分布式版本管理系统,不同之处在于提交会将更改提交到本地存储库,而推送会将更改推送到远程存储库。

好吧,基本上Git提交将您的更改放入本地存储库,而git ush将您的更改发送到远程位置。

git commit将您的更改记录到当地存储库。

git push更新远程存储库与您的本地更改。

git commit是提交本地存储库中暂存的文件。git push是快进合并本地端的主分支和远程主分支。但合并并不总是成功。如果出现拒绝,您必须pull才能成功git push

提交:存储库的快照|变更集|版本|历史记录|'另存为'。Git存储库=承诺的系列(树)。

当地存储库:计算机上的存储库。

远程存储库:服务器上的存储库(github)。

git commit:将新的提交(最后提交+上演修改)附加到当地存储库。(提交存储在文件夹/.git中。)

git pushgit pull:将当地存储库与其关联的远程存储库同步。push-将当地的更改应用于远程pull-将远程的更改应用于当地

一个非常粗略的类比:如果我们将git commit与保存已编辑的文件进行比较,那么git push将把该文件复制到另一个位置。

请不要把这个类比从这个上下文中拿出来——提交和推送并不像保存编辑过的文件并复制它。也就是说,为了比较起见,它应该成立。

只是想补充以下几点:

在您提交之前,您无法推送,因为我们使用git push将本地分支上的提交推送到远程存储库。

git push命令接受两个参数:

远程名称,例如origin分支名称,例如master

例如:

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

Git提交只是正式保存我们的更改。对于每次提交,我们都会给提交消息,并且一旦我们完成了提交,我们可以将其推送到远程以查看我们的全局更改。

这意味着我们可以在推送到远程之前进行多次提交(我们可以看到发生的提交列表和消息)。Git使用40位代码的提交ID保存每个提交。

只有当我想在远程查看我的更改时,我才使用Git推送(之后我会检查我的代码是否在Jenkins中工作)。

如果您想象在GitHub上的存储库中维护一个日志文件,那么更容易理解Git命令addcommit的使用。

对我来说,一个典型项目的日志文件可能如下所示:

---------------- Day 1 --------------------Message: Completed Task AIndex of files changed: File1, File2
Message: Completed Task BIndex of files changed: File2, File3-------------------------------------------
---------------- Day 2 --------------------Message: Corrected typosIndex of files changed: File3, File1-------------------------------------------.........and so on

我通常以git pull请求开始我的一天,并以git push请求结束它。因此,一天记录中的所有内容都对应于它们之间发生的事情。每天,我都会完成一个或多个逻辑任务,需要更改一些文件。在该任务中编辑的文件列在索引中。

每个子任务(这里的任务A和任务B)都是单独的提交。git add命令将文件添加到“已更改文件索引”列表中。此过程也称为暂存,实际上记录更改的文件和执行的更改。git commit命令记录/完成更改和相应的索引列表以及可供以后参考的自定义消息。

请记住,您仍然只更改存储库的本地副本,而不是GitHub上的副本。之后,只有当您执行git push时,才会将所有这些记录的更改以及每次提交的索引文件记录在主存储库(在GitHub上)上。

例如,要获取该虚拟日志文件中的第二个条目,我将执行以下操作:

git pull
# Make changes to File3 and File4git add File3 File4
# Verify changes, run tests etc..git commit -m 'Corrected typos'git push

简而言之,git addgit commit允许您将主存储库的更改分解为系统的逻辑子更改。正如其他答案和评论所指出的,它们当然有更多的用途。然而,这是最常见的用法之一,也是Git作为多阶段修订控制系统背后的驱动原则,与SVN等其他流行的版本控制系统不同。

有三件事要注意:

  1. 工作目录-我们的代码文件所在的文件夹

  2. 本地存储库-这是我们的系统内部。当我们这样做时提交命令第一次,然后创建这个本地存储库在我们的工作目录所在的同一个地方。创建Checkit(. git)文件。之后,每当我们提交时,这将存储我们在工作目录的文件中进行的更改为本地存储库(. git)。

  3. 远程存储库-这位于我们的系统之外,就像在服务器上一样位于世界任何地方,如GitHub。当我们做一个推送命令,然后从我们的本地代码存储库被存储在这个远程存储库

当您提交更改时,您将更改保存为本地存储库中的单个逻辑集。您可以在不推送的情况下多次执行此操作。在它们被推送之前,它们不会离开您的本地存储库,这意味着远程存储库还不会有这些更改集,因此当其他人从远程存储库中提取时,您的提交不会被提取。

当您推送时,您在本地存储库中所做的所有提交都将转移到远程存储库,因此当共享此远程存储库的其他开发人员拉取时,他们将把您的更改转移到他们的本地存储库。检查Git命令和备忘单这里

Git如何工作的常识解释

我已经使用Git多年了,但奇怪的是,这里或网上都没有人似乎能够在简单的术语中解释Git的pushpullcommitpull requests是如何工作的。所以,下面是一个简单的解释。我希望它能更清楚地解释事情。它帮助了我!

Git如何工作的简单总结

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

通过这种方式,Git允许您远程与他人共享本地项目代码,同时保存这些代码更改的版本,以防出现问题,您必须重做一些糟糕的代码。这就是Git工作原理和使用周期的简单解释。

更多GIT细节

第一步是始终在本地计算机上编写代码,忽略Git,它不涉及以任何方式保存或测试代码。当您将本地代码保存在计算机上时,它不会像您想象的那样默认保存在Git中。您必须执行第二步称为“提交”。(尚未提交的保存代码称为“分阶段”代码,顺便说一句。)

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

在您完成所有代码保存并将代码提交到本地Git存储库后,push就完成了。推送命令将您的本地存储库更改(仅提交)发送到远程存储库,以便对其进行更新。当它这样做时,它会将100%的更改完全写入远程存储库使两者同步或代码在两者之间100%匹配。将此视为“远程Git保存”。它使用您计算机上本地的代码写入远程存储库上的代码。一开始这对我来说毫无意义。这不会抹去远程上其他开发人员的更改吗?如果远程与您的更改冲突,或者您在本地存储库中首先需要的远程中没有更改怎么办?起初我很困惑,因为没有人能在线解释这是否与“合并”、“提交”、“拉取请求”等相同。事实证明这只在一个条件下有效。否则它会阻止你的推送并失败!

“推送”只有在你是唯一更改远程仓库的人,并且两个代码库除了你在本地添加的提交之外相同的情况下才有效。否则,其他用户在该远程仓库上所做的任何更改都将取消你的推送。所以把push想象成与你本地代表上相同副本的“私人远程写入”。但我们知道许多开发人员会像你一样通过推送推送对远程副本的更改,对吧?所以推送会失败,每个人都会在他们的本地副本上与这种设计下的远程副本不同步。

正如我提到的,如果在您进行更改之前远程存储库处于与您的本地存储库完全相同的状态,则此推送是只有允许的(在远程存储库上未阻止)。换句话说,当您向上推送提交本地更改时,如果远程存储库未被任何其他开发人员修改,您只能将本地更改推送到远程项目并用push完全写入它。这是Git让人困惑的一个奇怪方面。如果您的本地代码副本由于已更改而与远程存储库不同步,则推送将失败,并且您将被迫执行pull或“rebase”,这是“首先使用远程副本更新本地存储库”的花哨词汇。如果您的推送被阻止,然后您执行pull,它将复制远程代码并将其代码更改“合并”到您的本地副本中。再次同步后,您仍然可以通过推送向上推送您的提交,因为它们在拉取或合并后应该仍然存在。

这在大多数情况下都能完美地工作,除非代码更改与提交冲突,或者你让其他开发人员也在同一代码区域进行的代码更改。在这种极少数情况下,你必须在本地解决冲突,然后才能继续执行其他任何操作,因为你可能不小心擦除了其他开发人员的更改。这就是pull requests(见下文)而不是推送的帮助所在,因为前者强制主要代码更改必须先由代码所有者或管理员手动在远程副本上解决,然后才能允许任何代码更改远程存储库。

有趣的是,“拉”与“推”的作用相同,但在这种情况下,将最新远程项目的副本拉到您的本地git系统,然后将这些更改“合并”到您自己的副本中,而不是像“推”那样写入它们。当然,这会再次同步您的远程和本地副本,减去您设置为再次使用“推”在远程回购上更新的新提交。

一旦您通过pull将本地副本同步到远程副本,您现在可以执行push并将commits或更改再次发送回远程副本,并安全地写入它,知道您已将更改与所有其他开发人员所做的更改合并。

push将您的本地副本的提交或更改写入远程副本后,远程将与您的本地副本完全匹配。因为它们都匹配,所以您在本地进行的任何额外提交或保存都可以再次远程推送而无需拉取-只要没有开发人员像您一样更改了远程。如果是这种情况,Git将始终在推送时提醒您。你不能搞砸它。你可以做“强制”推送.、“rebasing”和其他技巧,但这并不重要。但是一旦其他开发人员推送他们的更改,你又不同步了,在推送之前必须再次拉取。

这个推-拉-推是Git开发的真正节奏,没有人告诉你,并假设你理解。大多数人都没有。它只是不直观或不合乎逻辑。

当然,你可以“强制”推送并覆盖所有内容。但是这个系统会在你尝试之前提醒你。当一个开发人员更新他们拥有的远程存储库中的一个分支时,这种拉取和推送系统总是工作得更好。一旦新人在远程存储库中添加或更改任何内容,它就会失败。这就是导致推送和拉取警报和失败的原因,直到每个人再次与远程同步。完成后,开发人员有权推送更改,因为他们的代码再次与远程匹配。但当有很多分支和代码要更改或合并到远程存储库时,最好使用Gitpull request命令。

最后,重要的是要注意,在Git中开发的人几乎总是被鼓励在对软件进行更改之前首先创建一个新的本地和远程存储库分支。在这种情况下,pushpull是非常有意义的,因为代码更改几乎总是由一个从不与其他开发人员更改冲突的开发人员在软件的独立分支上完成。这就解释了为什么一个开发人员在他们自己的分支上工作是很常见的,在这种情况下,pushpull工作得很好,可以快速推/拉更改,永远不会导致代码冲突,并允许一个开发人员将他们最终的本地更改的副本存储在他推动的远程仓库分支上,以便稍后使用下面描述的pull request系统合并到主分支中。

奇怪的拉请求

git拼图的最后一部分。从远程存储库的角度来看,Apull request是一个将本地仓库代码拉入其中的“拉取”。但它是一个请求,最初不会物理拉取或更改任何代码,也不会推送或合并任何代码。它只是你从本地仓库发送到远程仓库的请求,以审查代码,如果他们批准,就将你的代码拉入他们的远程副本。

pull request中,您要求远程仓库管理员或所有者上传您的代码更改或提交,审查您的本地仓库提交更改,然后在他们批准后将您的代码更改合并到远程仓库中。当他们批准您审查的本地仓库提交或更改时,他们会提取您的本地仓库代码或分支并将其合并到远程仓库分支。

远程仓库有管理员或所有者,他们控制着远程仓库中准备用于生产的关键顶级代码分支。他们不喜欢在没有控制代码质量的情况下将代码更改合并到这些较大的分支中。当你做pull request时,你是在提醒管理员或远程仓库所有者,你作为本地开发人员有一些完成的代码分支,并希望他们手动将你的本地仓库代码拉到远程仓库代码中。这与从本地仓库到远程仓库的push相同,但在这种情况下,需要顶级远程仓库所有者从相反的方向完成。它还需要首先对远程存储库所有者的更改进行手动代码审查和批准。

注意:#0在两个远程仓库分支之间合并代码更常见,通常会影响必须合并到主远程分支的远程服务器或设备上的已完成代码分支,而不仅仅是本地提交更改。同样,不直观,但就是这样!

如果你有pushpull Git命令同步和合并代码,为什么你需要拉取请求?pull requests在很多人都在拉取和推送对完成的树枝的巨大更改并合并到主要远程仓库分支的情况下比推送工作得更好,并且在进入主要版本或代码库更新之前,许多代码可能会冲突或添加必须首先测试或审查代码的代码。在本地和远程存储库之间编写pullpush代码要比将复杂远程存储库更改的大量分支合并到远程存储库的主分支中容易得多。

所以记住…

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

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

所以我喜欢把pull requests想象成主推,把push想象成本地推送。我希望Git的人能让这些进程的名字更有逻辑,更容易理解。这一点也不直观!

事实证明,pull request也是一种添加代码安全层的方法,当将大量代码合并到关键的顶级远程时,首先需要管理员或团队成员的许可项目中分支的分支或合并。因此,它要求团队成员批准大批量的本地仓库代码更改,并在将它们拉入重要的远程仓库分支之前先提交。

这是为了保护重要分支的代码更新,而代码更新必须首先经过代码评审和审批。但是,这也允许更重要分支上的代码更改在测试、审批等之前暂停。这就是为什么开发者私有的小分支可以简单地拉推更改,但是这些分支中较大的合并通常会被拉推请求阻止。这种情况更典型的是使用推送完成的分支,然后这些分支被合并到Git树上更大的分支中。

弄清楚这一点需要花费数小时的研究,即使在我使用Git多年之后,因为没有在线留档解释这种差异。

所以……在处理您自己的代码更改或分配给您的项目部分时,请始终使用提交-拉取-推送例程。首先下拉存储库以确保您的本地存储库包含其他开发人员对其所做的所有最新更改。如果您愿意,在拉取之前和之后提交或保存您的所有本地更改……没关系。如果有冲突,请尝试在本地解决它们。然后,也只有那时,使用您的本地代码进行推送以编写远程副本。然后,您的本地和远程存储库在git world中100%同步!

最后,当您的本地和远程分支完成后,向您的git管理员发送拉取请求,让他们处理您完成的远程存储库分支的合并。