推荐收藏 | 【Git实战专题】「必坑宝典」带你深入剖析Git操作指令下的奥秘原理和运作机制

前提介绍

Git是一个分布式版本控制系统,它可以跟踪文件的修改、记录历史版本,并支持多人协作开发。 上面是Git中最常用的命令,用于在工作目录、暂存目录(也称为索引)和仓库、远程仓库之间复制文件。

常用的Git命令

命令 描述
git init 在当前目录初始化一个新的Git仓库。
git clone <repository> 克隆一个远程仓库到本地。
git add <file> 将文件添加到暂存区。
git commit -m "<message>" 提交暂存区的文件到本地仓库,并添加提交信息。
git status 查看当前仓库的状态,包括修改的文件和暂存区的文件。
git log 查看提交历史记录。
git branch 查看当前仓库的分支列表。
git checkout <branch> 切换到指定的分支。
git merge <branch> 将指定分支的修改合并到当前分支。
git push 将本地仓库的修改推送到远程仓库。
git pull 从远程仓库拉取最新的修改到本地仓库。
git reset -- files 用来撤销最后一次git add files,你也可以用git reset撤销所有暂存区域文件。
git checkout -- files 把文件从暂存区域复制到工作目录,用来丢弃本地修改。

跳步级别操作

直接跳过缓存区-提交代码

直接从仓库中取出文件或者直接提交代码,而无需经过暂存区域。这种方式可以简化Git的工作流程。以下是相关的命令。

git commit -a

git commit -a 命令实际上是先执行 git add 来跟踪并准备所有的更改(在当前工作目录中),然后执行提交(commit)。这会添加所有的修改到暂存区,并创建一个新的提交。 直接提交代码: git commit -a -m "<message>":使用-a选项可以跳过暂存区域,直接将所有已修改的文件提交到仓库。这样可以快速提交代码。

如果你在工作目录中有一些未追踪的更改,git commit -a 会自动将它们添加到暂存区,然后进行提交。如果你只想提交已经追踪的更改,那么使用 git commit 命令会更好,因为它不会自动添加未追踪的更改到暂存区。

直接跳过缓存区 - 回滚代码

git checkout -- files 这个命令的作用是将文件从暂存区复制到工作目录,覆盖掉工作目录中的修改,从而达到丢弃本地修改的目的。

在Git 中,当你对文件进行修改后,这些修改默认是存放在工作目录下的。当你使用 git add 命令将文件添加到暂存区后,这些修改实际上已经被记录为"准备提交的更改"。 如果你想丢弃这些本地修改,你可以使用 git checkout -- files 命令。这里,files 是你想要恢复的文件的路径。执行这个命令后,这些文件会被恢复到你最后一次提交的状态,即丢弃了所有的本地修改。

git checkout HEAD -- files

git checkout HEAD -- files命令用于回滚到最后一次提交时的文件状态。它会将指定的文件恢复到最后一次提交时的状态,即复制最后一次提交的文件内容并覆盖当前工作目录中的对应文件。

  • git checkout:Git命令,用于切换分支、恢复文件或检出文件。
  • HEAD:指向当前分支最新提交的指针。
  • --:用于分隔命令和文件路径。
  • files:要回滚的文件路径。

通过执行git checkout HEAD -- files命令,Git会将指定的文件恢复到最后一次提交时的状态,即复制最后一次提交的文件内容并覆盖当前工作目录中的对应文件。这样可以撤销对文件的修改,回到最后一次提交的状态。

git的graphFlow流程

在下面的图片中,我们可以看到一些颜色标识和字符表示的提交信息。这些信息有助于理解提交历史和分支结构。

  • 每一个提交节点都是5位字符进行表示,用于唯一标识每个提交。每个提交都有一个唯一的ID,用于跟踪和引用。
  • 父节点是指向前一个提交的指针。通过父节点,我们可以追溯到提交的历史。
  • 历史分支用橘色点显示,并指向特定的提交。分支是指向某个提交的指针,它可以帮助我们在提交历史中标记和访问特定的位置。
  • 当前分支是有绿色点限时,附在其上的HEAD标识。HEAD是一个特殊的指针,它指向当前所在的分支。通过HEAD,我们可以知道当前所在的分支是哪个。

通过这些信息,我们可以更好地理解提交历史和分支结构。

git checkout <commit> -- <file>:从指定的提交中取出文件,并将其覆盖当前工作目录中的对应文件。这样可以恢复或查看历史版本的文件。

命令详解

Diff

有许多种方法可以查看两次提交之间的变动。

  1. 使用git diff <commit1> <commit2>命令来比较两次提交之间的差异。这将显示出两次提交之间文件内容的变化。
  2. 使用git diff <branch1> <branch2>命令来比较两个分支之间的差异。这将显示出两个分支之间文件内容的变化。
  3. 使用git log --oneline <commit1>..<commit2>命令来查看两次提交之间的提交历史。这将显示出这两次提交之间的所有提交记录。

Commit

Git会使用暂存区域的文件创建一个新的提交,并将当前节点设为父节点。然后,Git会将当前分支指向新的提交节点。在下图中,当前分支是feature4.0。在运行命令之前,HEAD指针指向e43b1。提交后,HEAD指针指向新的分支feature5.0(a43b1),并将e43b1作为父节点。 通过这个过程,我们可以将新的更改保存为一个新的提交,并将分支指向该提交,使得分支的最新状态反映了这次提交。

前置分支提交

即使当前分支是某次提交的祖父节点,Git仍然会执行相应的操作。在下图中,我们可以看到在feature4.0分支上进行了一次提交,生成了一个新的提交节点,标记为a43b2。就形成了一个旁路FlowGraph。 当分支之间存在这样的关系时,合并或者衍合操作是必要的。合并操作将两个分支的修改合并到一起,创建一个新的提交节点,以包含两个分支的修改。衍合操作则是将一个分支的修改应用到另一个分支上,创建一系列新的提交节点,以模拟另一个分支的修改历史。 通过合并或者衍合操作,我们可以将两个分支的修改整合在一起,保持分支之间的同步和一致性。

提交覆盖机制amend

如果想更改一次提交,使用 git commit --amend。git会使用与当前提交相同的父节点进行一次新提交,旧的提交会被取消。

Checkout

git checkout命令用于从历史提交(或者暂存区域)中拷贝文件到工作目录,同时也可以用于切换分支。

当给定某个文件名时(或者使用-p选项,或者同时给定文件名和-p选项),git checkout会从指定的提交中拷贝文件到暂存区域和工作目录。

例如,git checkout HEAD~ 文件名会将提交节点HEAD~(即当前提交节点的父节点)中的文件复制到工作目录,并将其添加到暂存区域中。

如果命令中没有指定提交节点,则会从暂存区域中拷贝内容。这个操作不会改变当前分支。

当不指定文件名,而是给出一个(本地)分支时,git checkout命令会将HEAD标识移动到该分支,实现分支的切换。同时,暂存区域和工作目录中的内容会与HEAD对应的提交节点保持一致。

  • 当执行git checkout <branch>命令时,如果不指定文件名,而是给出一个(本地)分支名,Git会将HEAD标识移动到该分支,实现分支的切换。这意味着我们现在处于指定的分支上,可以在该分支上进行操作。
  • 同时,暂存区域和工作目录中的内容会与HEAD对应的提交节点保持一致。这意味着新的提交节点中的所有文件都会被复制到暂存区域和工作目录中,以反映该提交的内容。
  • 与此同时,只存在于旧的提交节点中的文件会被删除,以保持与新的提交节点一致。而不属于上述两者的文件会被忽略,不受影响。

checkout总结

git checkout命令可以用于从历史提交中获取文件的副本,并将其放入工作目录和暂存区域。这对于恢复特定版本的文件或者查看历史文件的内容非常有用。同时,git checkout也可以用于切换分支,但在这种情况下,需要使用不同的参数和选项。

Reset

git reset命令可以将当前分支指向另一个提交位置。如果不指定选项,那么当前分支将指向指定的提交。这样可以改变当前分支的位置,以便回退或者前进到不同的提交。

git reset命令选择性地修改工作目录和暂存区

  • --hard选项,工作目录和暂存区都会被更新,与指定的提交保持一致。这将丢弃工作目录和暂存区中的所有未提交的修改,慎用此选项。

  • --soft选项,工作目录和暂存区都不会被修改。当前分支仍然指向指定的提交,但工作目录和暂存区中的内容保持不变。这可以用于撤销最近的提交,而不影响工作目录和暂存区的内容。

如果没有给出提交点的版本号,那么默认用HEAD。这样,分支指向不变,但是索引会回滚到最后一次提交,如果用--hard选项,工作目录也同样。

Merge

git merge命令用于将不同的分支合并在一起。在执行合并之前,必须确保索引(暂存区)与当前提交保持一致。根据不同的情况,git merge命令会有不同的行为:

  1. 如果另一个分支是当前提交的祖父节点,那么合并命令将不做任何操作。这是因为当前提交已经包含了另一个分支的所有更改,所以不需要进行合并。

  2. 另一种情况是,如果当前提交是另一个分支的祖父节点,就会导致快速合并(fast-forward merge)。在这种情况下,合并操作只是简单地将分支指针向前移动,并生成一个新的提交。这是因为当前分支已经包含了要合并的分支的所有更改,所以不需要进行实际的合并操作。

Cherry Pick

git cherry-pick命令可以理解为在当前分支上"复制"一个提交节点,并在当前分支上创建一个完全相同的新提交。 具体来说,git cherry-pick命令的作用是选择一个或多个提交节点,并将这些提交节点的更改应用到当前分支上,创建一个新的提交。这个新的提交与原始提交节点的内容完全一样,但是在当前分支上进行了新的提交。

通过使用git cherry-pick命令,可以选择性地将其他分支或者提交中的更改应用到当前分支上,而不需要合并整个分支。这对于从其他分支中选择性地获取特定的更改非常有用。

注意,git cherry-pick命令会在当前分支上创建新的提交,而不会影响原始提交节点的状态。这意味着原始提交节点仍然存在于其原始分支上,并且在当前分支上只是创建了一个新的提交。

复制代码
相关推荐
搬码后生仔1 小时前
asp.net core webapi项目中 在生产环境中 进不去swagger
chrome·后端·asp.net
凡人的AI工具箱1 小时前
每天40分玩转Django:Django国际化
数据库·人工智能·后端·python·django·sqlite
Lx3522 小时前
Pandas数据重命名:列名与索引为标题
后端·python·pandas
小池先生2 小时前
springboot启动不了 因一个spring-boot-starter-web底下的tomcat-embed-core依赖丢失
java·spring boot·后端
百罹鸟2 小时前
【vue高频面试题—场景篇】:实现一个实时更新的倒计时组件,如何确保倒计时在页面切换时能够正常暂停和恢复?
vue.js·后端·面试
小蜗牛慢慢爬行3 小时前
如何在 Spring Boot 微服务中设置和管理多个数据库
java·数据库·spring boot·后端·微服务·架构·hibernate
大猫和小黄4 小时前
Windows、CentOS环境下搭建自己的版本管理资料库:GitBlit
linux·服务器·windows·git
孤水寒月4 小时前
Git忽略文件.gitignore
git·elasticsearch
wm10434 小时前
java web springboot
java·spring boot·后端
龙少95436 小时前
【深入理解@EnableCaching】
java·后端·spring