了解git commit命令的目的

时间:2016-03-18 11:19:24

标签: git git-commit

我看了几篇教程,这是我对语句中显示的“commit”命令的理解:

  • 由于git使用整个代码库的“快照”系统,因此git需要知道更改的历史记录,并向所有在每个时刻都做了什么的编码员显示。

  • “提交”就像记录项目内存中的更改一样。

  • 上传我改变的项目版本,即我的主要在线回购(主)的分支是另一回事?

  • 当我将本地更改上传到项目的主要版本时,我的提交(记录在.git文件中)会为其他人所知。

  • 将更改上传到master分支是“推送”我的所有提交,对吗?

我对这些陈述是否正确?

3 个答案:

答案 0 :(得分:2)

  
      
  • 因为git使用"快照系统"在整个代码库中,git需要知道更改的历史,并向所有执行过操作的编码器显示   在每个时刻。
  •   

这是一种合理的方式来表达它。

  
      
  • "提交"就像记录项目记忆中的变化一样。
  •   

是的,提交是在分支顶部添加您的更改记录(与之前的提交相比)。

  
      
  • 上传我改变的项目版本,即我的主要在线回购(主)的分支是另一回事?
  •   

当您推送时,远程服务器会将您的更改附加到远程分支,前提是您的历史记录遵循服务器历史记录。例如,如果任何人在您推送之前已对服务器历史记录添加任何更改,则您将从某个点显示历史记录的不同版本。因此,您首先需要重写本地历史记录,以使其符合服务器的历史记录。 (通常使用git pull,根据您的选择合并 rebase 您的分支机构)

  
      
  • 当我将本地更改上传到项目的主要版本时,我的提交(记录在.git文件中)会为其他人所知。
  •   

是的,当您推送时,让其他人知道您如何修改历史记录。

  
      
  • 将更改上传到主分支是"推送"我所有的提交,对吗?
  •   

推送是"上传" (如果您希望使用该词)您对远程主分支的更改。正如我之前所说,如果您的更改是基于远程主机上的最新历史记录,则遥控器将只接受。

请注意,对于任何分支都是如此,您可以拥有任意数量的分支,而不仅仅是 master

答案 1 :(得分:1)

1)"因为git使用"快照系统"在整个代码库中,git需要知道变化的历史,并向所有在每个时刻都做了什么的编码员展示。"

是的,这就是版本控制系统的功能。它们允许您在之前的某个时间点返回到代码的状态,并恢复丢失或删除的工作。它们还允许您查看谁做了什么以及何时做了什么。转到其中一个版本化文件,然后输入git annotate path/to/file,看看会发生什么。

2)"提交就像记录项目记忆中的变化一样。"

首先(不试图肛门),对文件的更改不会存储在内存中,因为在RAM中,它们通过文件系统存储在硬盘驱动器的磁盘扇区中。将更改保存到相关文件后,您可以考虑将这些更改存储在git中。这涉及两个步骤。首先进行更改,然后提交它们。暂存更改也称为添加对暂存区域的更改或暂存对索引的更改。将暂存区域或索引视为正在构建的"提交#34;但尚未准备就绪。您可以使用git add将文件添加到暂存区域。您可以使用git status查看已添加的文件。您可以使用git diff --cached查看暂存更改的详细信息。如果您最终确信已将要提交的所有更改添加到暂存区域,则可以使用git commit提交暂存的更改。因此,commit命令完成"正在构建的提交"。在内部,在git数据库中创建一个新的提交对象,并更新当前分支的分支指针以指向此提交。这两阶段提交机制为您提供了一条防范,可以防止意外提交您不想提交的更改。在提交之前,您必须考虑添加到临时区域的所有内容。尝试使用git add -p对您上演的内容以及您不喜欢的内容进行非常精细的控制。

3)"上传我改变的项目版本,即我的主要在线回购(主)的分支是另一回事?"

是的,这是另一回事。 Git更像是点对点架构,而不是客户端 - 服务器架构。这允许您在不与他人共享的情况下进行本地提交。它允许您随时随地接收其他人的工作,并允许您在真正准备好时与他们分享您的工作。在git中可以同时跟踪多个上游存储库。那说git有类似于客户端 - 服务器架构的东西,但不一样。有两种git存储库。开发人员使用的裸存储库,用于彼此共享代码(类似于客户端 - 服务器体系结构中的服务器)和非裸存储库,开发人员在其工作站本地工作(类似于客户端 - 服务器中的客户端)建筑)。要将代码更改从您(非裸)存储库中的分支移动到您首次克隆的在线(裸)存储库上的分支,请使用git push。裸存储库仅包含.git目录的内容,其中包含提交数据库,但不包含版本化文件本身,因此名称为"裸"。它不必以.git本身命名。惯例是将其命名为my_project.git,并通过网络提供。另一方面,非裸存储库就像您提交的存储库一样。有一个隐藏的.git目录,其中包含与git以及您正在处理的文件有关的所有内容。您无法将更改推送到非裸存储库中,并且您可以通过执行此操作来严重搞乱其他人的工作。

4)当我将本地更改上传到项目的主要版本时,我的提交(记录在.git文件中)会为其他人所知。

这意味着它们现在存储在公共裸存储库中。其他人只有在选择使用git fetch选择获取这些更改时才会知道这些更改。获取这些更改后,他们可以使用git merge将这些更改合并到相应的本地分支中,或者使用git rebase在更改之后重新定位其本地更改。要一步完成此过程,他们可以使用git pull。拉策略(合并或重新绑定)由配置选项pull.rebase确定,由git config pull.rebase true命令配置。我强烈建议重新合并,因为这会鼓励线性历史,因为合并提交有两个祖先提交,而重新提交的提交只有一个。

5)"将更改上传到master分支正在推送我的所有提交,对吗?"

几乎是正确的。 git push命令也可以接受参数,但如果没有这些参数,它将进行合理的默认推理。 Git将使用一些名为refspecs和上游分支配置来进行这些推断。当您推送时,您正在将提交从非裸存储库上的分支移动到裸存储库上的分支。如果git无法正确地进行这些推断(即,您想要将哪个存储库移动到哪个更改位置,以及要移动它们的哪个本地分支),则必须将这些参数显式提供给git push命令。

答案 2 :(得分:1)

git基本上使用这三件事来存储你的数据:

  • blob只是一个二进制blob(你的源代码,图像,等等)。 blob不包含有关内容类型或名称的信息,只是一个字节的大小。
  • A tree指向一个或多个blob,想想“目录”。它包含它指向的blob的文件名等。
  • commit(数据对象,而不是git命令)是一个单独的实体,它指向一棵树(该时间点所有文件的状态)和零个或多个其他提交(父级) (s),可能在存储库中的第一次提交时丢失,并且在合并的情况下可能是多次。)

就是这样。从概念上讲,没有别的东西可以做到。在实践中,有分支和标签,但这些只是指向提交的特殊“粘滞便笺”。还有一些机制可以减少存储等等,但除非您破解代码或深入了解,否则它们不会引起人们的兴趣。

在这种情况下回答你的问题很容易:

  • 当您在工作目录中签出提交时,您将从一个特定的commit获取文件。比方说,便签(分支)master指向提交afd876123,您将存储库克隆到一个新的工作目录,然后您获得tree中表示的文件{ {1}}指向。
  • git当然会跟踪并创建一个特殊的便签commit afd876123,它存储您在HEAD和提交master上的信息。它还会创建一个afd876123,您可以将其视为匿名index
  • 您可以编辑工作目录中的某些文件。
  • 当您运行tree时,git会根据您的更改更新git add。虽然在内部它的工作方式不同,但您可以将其视为使用您的更改更新index
  • 没有tree "index"与此commit相关联,因此它不是永久性的;它不会影响推拉,拉动等等。
  • 当您运行tree时,它会创建一个新的git commit对象,该对象指向当前索引所代表的commit,以及之前的提交tree和其他信息(如时间戳,日志消息......)。然后将此afd876123对象添加到数据存储中,从而最终确定。

关于推/拉的其余假设基本上是正确的。