Git的正确使用姿势与最佳实践 | 豆包MarsCode AI刷题

102 阅读13分钟

一、Git是什么

1. Git历史

Git 是最流行的分布式版本控制系统(Distributed Version Control System,简称 DVCS)。它由 Linus Torvalds 创建,当时非常需要一个快速、高效和大规模分布式的源代码管理系统,用于管理 Linux 源代码。

2.版本控制系统

版本控制是指对软件开发过程中各种程序代码、配置文件及说明文档等文件变更的管理,是软件配置管理的核心思想之一。版本控制技术是团队协作开发的桥梁,助力于多人协作同步进行大型项目开发。软件版本控制系统的核心任务就是查阅项目历史操作记录、实现协同开发。

常见版本控制主要有两种:集中式版本控制分布式版本控制

(1)集中式版本控制系统

集中式版本控制系统,版本库是集中存放在中央服务器的。工作时,每个人都要先从中央服务器获取最新的版本。完成之后,再把自己添加/修改的内容提交到中央服务器。所有文件和历史数据都存储在中央服务器上。SVN 是最流行的集中式版本控制系统之一。

集中式版本控制系统的缺点就是必须联网才能使用,如果使用局域网还好,速度会比较快。而如果是使用互联网,网速慢的话,就可能需要等待很长时间。除此之外,如果中央服务器出现故障,那么版本控制将不可用。如果中心数据库损坏,若数据未备份,数据就会丢失。

image.png

(2)分布式版本控制系统

分布式版本控制系统,每台终端都可以保存版本库,版本库可以不同,可以对每个版本库进行修改,修改完成后可以集中进行更新。虽然它没有中心服务器,但可以有一个备份服务器,它的功能有点类似于 SVN 的中央服务器,但它的作用仅是方便交换修改,而不像 SVN 那样还要负责源代码的管理。Git 是最流行的分布式版本控制系统之一。

和集中式版本控制系统相比,分布式版本控制系统的安全性要高很多,因为每个人电脑里都有完整的版本库,某一个人的电脑损坏不会影响到协作的其他人。

image.png

(3)SVN vs Git

Git 相较于 SVN:

  • 提交速度更快: 因为在 SVN 中需要更频繁地提交到中央存储库,所以网络流量会减慢每个人的速度。而使用 Git,主要在本地存储库上工作,只需每隔一段时间才提交到中央存储库。
  • 没有单点故障: 使用 SVN,如果中央存储库出现故障,则在修复存储库之前,其他开发人员无法提交他们的代码。使用 Git,每个开发人员都有自己的存储库,因此中央存储库是否损坏并不重要。开发人员可以继续在本地提交代码,直到中央存储库被修复,然后就可以推送他们的更改;
  • 可以离线使用: 与 SVN 不同,Git 可以离线工作,即使网络失去连接,也可以继续工作而不会丢失功能。

image.png

3. Git 安装

在Git官网下载、安装即可:git-scm.com/download 安装完成之后,可以使用git --version命令来查看Git是否安装成功。 如果安装成功,终端会打印安装的 Git 的版本:

image.png

4. Git 初始化

要给项目初始化一个Git仓库,可以在终端中打开项目目录,执行git init命令即可。 在使用 Git 进行代码管理时,不希望一些文件出现在跟踪列表中,比如node_modules文件。这种情况下,可以在项目的根目录中创建一个名为.gitignore的文件,在该文件中列出要忽略的文件和文件夹,来看一个示例:

image.png

5. Git 结构和状态

从Git的角度来看,可以在三个区域进行文件更改:工作区,暂存区和存储库。

  • 工作区: 本地看到的工作目录;
  • 暂存区: 一般存放在 .git 目录下的 index 文件(.git/index)中,所以暂存区有时也叫作索引(index)。暂存区是一个临时保存修改文件的地方;
  • 版本库: 工作区有一个隐藏目录 .git,这个不算工作区,而是 Git 的版本库,版本库中存储了很多配置信息、日志信息和文件版本信息等。

image.png Git 工作目录下的文件存在两种状态:

  • untracked:未跟踪,未被纳入版本控制,即该文件没有被Git版本管理;
  • tracked:已跟踪,被纳入版本控制,即该文件已被Git版本管理。

其中已跟踪状态可以细分为以下三种状态:

  • Unmodified:未修改状态
  • Modified:已修改状态
  • Staged:已暂存状态

二、Git入门

1. 全局配置

当安装Git后首先要做的就是配置所有本地存储库中使用的用户信息。每次Git提交都会使用该用户信息。

config 命令适用于不同的级别:

  • 本地级别: 所有配置都仅限于项目目录。默认情况下, 如果未通过任何配置, 则git config将在本地级别写入;
  • 全局级别: 此配置特定于操作系统上的用户,配置值位于用户的主目录中;
  • 系统级别: 这些配置放在系统的根路径下,它跟踪操作系统上的所有用户和所有存储库。

下面的配置均为写入系统级别:

(1)设置用户名

可以使用以下命令设置使用 Git 时的用户名:

image.png

(2)设置邮箱

可以使用以下命令设置使用 Git 时的邮箱:

image.png

(3)查看所有配置

通过上面的命令设置的信息会保存在本地的.gitconfig文件中。可以使用以下命令查看所有配置信息

image.png

(4)设置别名

git config 命令为我们提供了一种创建别名的方法,这种别名通常用于缩短现有的命令或者创建自定义命令。来看一个例子:

image.png 这里为commit -m创建一个别名 cm,这样在提交暂存区文件时,只需要输入以下命令即可:

image.png

2. 分支操作

分支是源代码控制的核心概念,它允许将工作分离到不同的分支中,这样就可以自由地处理源代码,而不会影响其他任何人的工作或主分支中的代码。下面来看一些常见的分支操作。

(1)查看分支

可以使用以下命令来查看当然所在的分支以及该项目所有的分支情况:

image.png 该命令可以列出项目所有的本地分支,显示绿色的分支就是当前分支:

image.png 可以使用以下命令来列出所有的远程分支:

image.png

image.png 可以使用以下命令来查看所有的本地分支和远程分支:

image.png

(2)创建分支

我们在计算机上只能访问本地分支,在将分支推送到远程仓库之前,需要先创建一个本地分支。

可以使用以下命令来创建分支

image.png 加上-b就可以在创建新的分支之后,直接切换到新创建的分支上:

image.png 如果想将新建的本地分支推送到远程仓库,以在远程仓库添加这个分支。可以执行以下命令:

image.png

(3)删除分支

可以使用以下命令来删除本地分支

image.png 需要注意,在删除分支之前,要先切换到其他分支,否则就会报错。 有时 Git 会拒绝删除本地分支,因为要删的分支可能有未提交的代码。这是为了保护代码以避免意外丢失数据。可以使用以下命令来强制删除本地分支

image.png 当然,我们也可以删除远程仓库分支,执行以下命令即可:

image.png

(4)合并分支

可以使用以下命令将其他分支的代码合并到当前分支:

image.png 如果想将A分支合并到B分支,就要先切换到B分支,然后执行命令:git merge A

(5)重命名分支

可以使用以下命令来将分支重命名:

image.png 如果newname名字分支已经存在,则需要使用-M来强制重命名:

image.png

3. 基础操作

Git 数据工作流程如下:

image.png

(1)暂存文件

可以使用以下命令来暂存已修改的文件,命令最后需要指定要暂存的文件名称:

image.png 如果想要将所有未跟踪和修改的文件添加到暂存区,可以执行以下命令:

image.png

(2)提交暂存

可以使用以下命令将暂存区的文件修改提交到本地仓库

image.png 其中-m参数表示message日志信息,参数后面要加一个日志信息,用双引号括起来。 如果上次提交暂存的messge写错了怎么办呢?可以使用使用以下命令来更新提交,而不需要撤销并重新提交:

image.png 如果有一个新的文件修改,也想提交到上一个commit中,可以使用以下命令来保持相同的提交信息:

image.png

(3)存储更改

假如我们正在开发迭代功能,但是还没开发完。这时有一个紧急的bug需要修复上线。可能就需要切换到一个hotfix分支去修复bug。这时对于开发了一部分的功能创建提交是没有逻辑意义的。可以使用以下任一命令来存储修改的内容:

image.png 该命令回保存所有未提交的更改并恢复到上次提交时存储库的状态。

当想再次继续开发此功能时,就可以使用以下命令检查所有存储:

image.png 这时终端中就会显示带有时间戳的所有已经暂存的列表。可以使用以下任一命令来取回所有的更改:

image.png apply 和 pop 之间的区别在于,pop 应用了 stash 中的更改并将其也从 stash 中删除,但 apply 即使在应用后仍将更改保留在 stash 中。

可以使用以下任一命令应用存储列表中的第 N 个存储:

image.png 整个过程的输出如下:

image.png

(4)合并指定提交

在不同分支之间进行代码合并时,通常会有两种情况:一种情况是需要另一个分支的所有代码变动,那么就可以直接合并(git merge),另一种情况是只需要部分代码的变动(某几次提交),这时就可以使用以下命令来合并指定的提交:

image.png 建议添加 -x 标志,因为它会生成标准化的提交消息,通知用户它是从哪里pick出来的:

image.png 那么这个commit hash是从哪里来的呢?可以在需要被合并的分支上执行以下命令:

image.png 这时终端就会显示出所有的提交信息:

image.png 这里黄色文字中commit后面的部分就是commit hash,复制即可。

(5)检查提交

Git允许我们在本地检查特定的提交。输入以下命令就可以查看有关当前提交的详细信息:

image.png 输出的结构如下,可以看到,它显示出了上次提交的commit id、作者信息(邮箱和姓名)、提交日期、commit message、代码diff等:

image.png 还可以使用HEAD~n语法或提交哈希来检查过去的提交。使用以下命令就可以获取往前数的第三次提交的详细信息:

image.png 除此之外,还可以添加一个--oneline标志,以简化输出信息

image.png

(6)查看贡献者

可以使用git shortlog命令来返回每个贡献者的commit次数以及每次commit的commit message

image.png 其可以添加两个参数:

  • s:省略每次 commit 的注释,仅仅返回一个简单的统计。
  • n:按照 commit 数量从多到少的顺利对用户进行排序。

加上这两个参数之后就可以看到每个用户中的提交次数以及排名情况:

image.png 除此之外,还可以添加一个--no-merges标志,以忽略合并提交的次数:

image.png

4. 远程操作

(1)查看远程仓库

可以使用以下命令来查看远程仓库:

image.png 该命令会列出指定的每一个远程服务器的简写。如果已经克隆了远程仓库,那么至少应该能看到 origin ,这是 Git 克隆的仓库服务器的默认名字。 可以执行以下命令来获取远程仓库的地址:

image.png 其中fetch是获取,push是推送:

image.png 可以使用以下命令来查看更加详细的信息:

image.png

(2)添加远程仓库

可以使用以下命令来将本地项目链接到远程仓库

image.png 其中:

  • remote_name:仓库名称(默认是origin)
  • remote_url:远程仓库地址

该命令允许 Git 跟踪远程存储库并将本地存储库连接到远程仓库。

(3)移除远程仓库

可以使用命令来移除远程仓库:

image.png 需要注意,该命令只是从本地移除远程仓库的记录(也就是解除本地仓库和远程仓库的关系),并不会真正影响到远程仓库。

(4)从远程仓库抓取与拉取

可以使用以下命令来从远程仓库获取最新版本到本地仓库,不会自动merge(合并数据):

image.png 由于该命令不会自定合并数据,所以该命令执行完后需要手动执行 git merge 远程分支到所在的分支。

可以使用以下命令来将远程指定分支拉取到本地指定分支上

image.png 使用以下命令来将远程指定分支拉取到本地当前分支上

image.png 使用以下命令将与本地当前分支同名的远程分支拉取到本地当前分支上:

image.png 注意:如果当前本地仓库不是从远程仓库克隆,而是本地创建的仓库,并且仓库中存在文件,此时再从远程仓库拉取文件的时候会报错(fatal: refusing to merge unrelated histories ),解决此问题可以在git pull命令后加入参数--allow-unrelated-histories,即:

image.png

(5)推送到远程仓库

可以使用以下命令将本地指定分支推送到远程指定分支上

image.png 可以使用以下命令将本地指定分支推送到与本地当前分支同名的远程分支上:

image.png 使用以下命令将本地当前分支推送到与本地当前分支同名的远程分支上

image.png 可以使用以下命令来将本地分支与远程同名分支相关联:

image.png 由于远程库是空的,第一次推送master分支时,加上了-u参数,Git不但会把本地的master分支内容推送的远程新的master分支,还会把本地的master分支和远程的master分支关联起来,在以后的推送或者拉取时就可以简化命令为git push。