了解git-commit命令的用途



我看过一些教程,以下是我对语句中显示的"提交"命令的理解:

  • 由于git使用了整个代码库的"快照"系统,git需要了解更改的历史记录,并向所有在每一时刻都做了什么的程序员展示。

  • "提交"就像记录项目内存中的更改。

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

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

  • 将更改上传到master分支就是在"推送"我所有的提交,对吧?

我对这些说法正确吗?

  • 由于git使用了整个代码库的"快照"系统,git需要了解更改的历史记录,并向所有做了什么的程序员显示在每一个时刻

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

  • "提交"就像记录项目内存中的更改

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

  • 上传我更改后的项目版本,即我的分支到主在线回购(master)是另一回事吗

推送时,远程服务器会将您的更改附加到远程分支,前提是您的历史记录遵循服务器历史记录。例如,如果有人在推送之前将任何更改附加到服务器历史记录中,则双方都显示了某个点的不同版本的历史记录。因此,您需要首先重写本地历史记录,使其符合服务器的历史记录。(通常使用git pull,根据您的选择,它将合并重新建立分支机构的基础)

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

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

  • 将更改上传到master分支是在"推送"我所有的提交,对吧

推送是将您的更改"上传"(如果您希望使用该词)到远程的主分支。正如我之前所说,只有在您的更改建立在远程主机上可用的最新历史记录的基础上时,远程才会接受。

请注意,所有这些对于任何分支都是正确的,您可以拥有任意多的分支,而不仅仅是master

git基本上使用以下三种东西来存储数据:

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

就是这样。从概念上讲,它没有其他东西。在实践中,有分支和标记,但这些只是指向提交的特殊"便签"。也有一些机制可以减少存储等,但除非你破解代码或深入研究,否则它们不会引起兴趣。

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

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

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

1)"由于git使用了整个代码库的"快照"系统,git需要了解更改的历史记录,并向所有在每个时刻都做了什么的程序员显示。">

是的,这就是版本控制系统所做的。它们允许你回到上一个时间点的代码状态,并恢复丢失或删除的工作。它们还可以让你看到谁在什么时候做了什么。转到一个版本化的文件,键入git annotate path/to/file,看看会发生什么。

2) "提交就像记录项目内存中的更改。">

首先(不要试图分析),对文件的更改不会存储在内存中,就像存储在RAM中一样,它们通过文件系统存储在硬盘驱动器的磁盘扇区上。将更改保存到有问题的文件后,您可以考虑将这些更改存储在git中。这包括两个步骤。首先进行更改,然后提交。暂存更改也称为将更改添加到暂存区域或将更改暂存到索引。可以将暂存区或索引视为"正在构建的提交",但还没有准备好。您可以使用git add将文件添加到暂存区域。您可以看到使用git status添加了哪些文件。您可以使用git diff --cached查看分阶段更改的详细信息。当您最终满意地将要提交的所有更改添加到暂存区域时,可以使用git commit提交您的暂存更改。因此,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) "将更改上传到主分支是在推送我所有的提交,对吧?">

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

相关内容

  • 没有找到相关文章

最新更新