CodeGym /Java 博客 /随机的 /Git 入门:新手综合指南
John Squirrels
第 41 级
San Francisco

Git 入门:新手综合指南

已在 随机的 群组中发布

而不是介绍

你好!今天我们要聊的是版本控制系统,也就是Git。Git 入门:新手综合指南 - 1如果您不知道/不了解 Git,那么您与编程毫无关系。但美妙之处在于,您不必为了持续使用而将所有 Git 命令和功能都记在脑子里。您需要了解一组命令,以帮助您了解正在发生的一切。

Git 基础知识

Git 是我们代码的分布式版本控制系统。我们为什么需要它?分布式团队需要某种系统来管理他们的工作。需要跟踪随时间发生的变化。也就是说,我们需要能够逐步查看哪些文件已更改以及如何更改。当您调查在单个任务的上下文中发生了什么变化时,这一点尤其重要,从而可以恢复更改。

安装 Git

让我们在您的计算机上安装 Java。

在 Windows 上安装

像往常一样,您需要下载并运行一个 exe 文件。这里的一切都很简单:点击第一个谷歌链接,执行安装,就是这样。为此,我们将使用 Windows 提供的 bash 控制台。在 Windows 上,您需要运行 Git Bash。下面是它在“开始”菜单中的样子:Git 入门:新手综合指南 - 2现在这是一个您可以使用的命令提示符。为避免每次都必须转到项目所在的文件夹才能在那里打开 Git,您可以在项目文件夹中使用鼠标右键打开命令提示符,并输入我们需要的路径:Git 入门:新手综合指南 - 3

在 Linux 上安装

通常 Git 是 Linux 发行版的一部分并且已经安装,因为它是最初为 Linux 内核开发而编写的工具。但有些情况下它不是。要检查,您需要打开一个终端并输入:git --version。如果你得到一个可理解的答案,那么就不需要安装任何东西。打开终端并在 Ubuntu 上安装 Git。我在 Ubuntu 上工作,所以我可以告诉你为它写什么:sudo apt-get install git。

在 macOS 上安装

在这里,您也首先需要检查 Git 是否已经存在。如果您没有它,那么最简单的获取方式就是在此处下载最新版本。如果安装了Xcode,那么Git肯定会自动安装。

Git 设置

Git 为提交工作的用户设置了用户设置。这是有道理的,也是必要的,因为 Git 在创建提交时将此信息用于 Author 字段。通过运行以下命令为所有项目设置用户名和密码:

git config --global user.name "Ivan Ivanov"
git config --global user.email ivan.ivanov@gmail.com
如果需要更改特定项目的作者,可以删除“--global”。这将为我们提供以下内容:

git config user.name "Ivan Ivanov"
git config user.email ivan.ivanov@gmail.com

一点理论...

为了深入探讨这个话题,我们应该向您介绍一些新的词语和动作……
  • git 仓库
  • 犯罪
  • 分支
  • 合并
  • 冲突
  • 如何忽略一些文件(.gitignore)
等等。

Git 中的状态

Git有几个雕像需要理解和记住:
  • 未追踪
  • 修改的
  • 上演
  • 坚定的

你应该怎么理解这个?

这些是适用于包含我们代码的文件的状态:
  1. 创建但尚未添加到存储库的文件具有“未跟踪”状态。
  2. 当我们对已经添加到 Git 存储库的文件进行更改时,它们的状态为“已修改”。
  3. 在我们更改的文件中,我们选择我们需要的那些,这些类被更改为“暂存”状态。
  4. 提交是从处于暂存状态的准备文件创建的,并进入 Git 存储库。之后,没有文件处于“暂存”状态。但可能仍然存在状态为“已修改”的文件。
这是它的样子:Git 入门:新手综合指南 - 4

什么是提交?

提交是版本控制的主要事件。它包含自提交开始以来所做的所有更改。提交像单链表一样链接在一起。更具体地说:有一个第一次提交。当创建第二个提交时,它知道第一个之后会发生什么。并且以这种方式,可以跟踪信息。提交也有自己的信息,即所谓的元数据:
  • 提交的唯一标识符,可用于查找它
  • 提交作者的名字,创建者
  • 创建提交的日期
  • 描述提交期间所做的事情的注释
这是它的样子:Git 入门:新手综合指南 - 5

什么是分支?

分支是指向某个提交的指针。因为提交知道哪个提交在它之前,所以当一个分支指向一个提交时,所有那些先前的提交也适用于它。因此,我们可以说您可以拥有任意数量的分支指向同一个提交。工作发生在分支中,因此当创建新提交时,分支会将其指针移至最近的提交。

开始使用 Git

您可以单独使用本地存储库,也可以使用远程存储库。要练习所需的命令,您可以将自己限制在本地存储库中。它只将所有项目的信息存储在本地的 .git 文件夹中。如果我们谈论的是远程存储库,那么所有信息都存储在远程服务器的某个位置:只有项目的副本存储在本地。可以将对本地副本所做的更改推送 (git push) 到远程存储库。在这里和下面的讨论中,我们讨论的是在控制台中使用 Git。当然,您可以使用某种基于 GUI 的解决方案(例如 IntelliJ IDEA),但首先您应该弄清楚正在执行的命令及其含义。

在本地存储库中使用 Git

接下来,我建议您按照阅读本文时执行的所有步骤进行操作。这将提高您对材料的理解和掌握。嗯,祝你胃口好!:) 要创建本地存储库,您需要编写:

git init
Git 入门:新手综合指南 - 6这将在控制台的当前目录中创建一个 .git 文件夹。.git 文件夹存储有关 Git 存储库的所有信息。不要删除它 ;) 接下来,将文件添加到项目中,并将它们指定为“未跟踪”状态。要检查您的工作的当前状态,请这样写:

git status
Git 入门:新手综合指南 - 7我们在 master 分支,我们会一直呆在这里,直到我们切换到另一个分支。这显示哪些文件已更改但尚未添加到“暂存”状态。要将它们添加到“暂存”状态,您需要编写“git add”。我们在这里有几个选项,例如:
  • git add -A — 将所有文件添加到“暂存”状态
  • 混帐添加。— 添加此文件夹和所有子文件夹中的所有文件。本质上,这与上一个相同
  • git add <file name> — 添加特定文件。在这里您可以使用正则表达式根据某种模式添加文件。例如,git add *.java:这意味着您只想添加扩展名为 java 的文件。
前两个选项显然很简单。随着最新的添加,事情变得更加有趣,所以让我们写:

git add *.txt
要检查状态,我们使用我们已知的命令:

git status
Git 入门:新手综合指南 - 8在这里您可以看到正则表达式已正常工作:test_resource.txt 现在处于“暂存”状态。最后,使用本地存储库的最后阶段(使用远程存储库时还有一个阶段;))——创建一个新的提交:

git commit -m "all txt files were added to the project"
Git 入门:新手综合指南 - 9接下来是一个很棒的命令,用于查看分支上的提交历史记录。让我们利用它:

git log
Git 入门:新手综合指南 - 10在这里您可以看到我们已经创建了第一个提交,它包括我们在命令行上提供的文本。理解这段文字应该尽可能准确地解释这次提交期间做了什么是非常重要的。这将在未来多次帮助我们。尚未入睡的好奇读者可能想知道 GitTest.java 文件发生了什么。让我们现在就知道。为此,我们使用:

git status
Git 入门:新手综合指南 - 11如您所见,它仍处于“未跟踪”状态,正在等待。但是,如果我们根本不想将它添加到项目中怎么办?有时会发生这种情况。为了让事情变得更有趣,让我们现在尝试更改我们的 test_resource.txt 文件。让我们在那里添加一些文本并检查状态:

git status
Git 入门:新手综合指南 - 12在这里您可以清楚地看到“未跟踪”和“已修改”状态之间的区别。GitTest.java 是“未跟踪的”,而 test_resource.txt 是“已修改的”。现在我们有处于修改状态的文件,我们可以检查对它们所做的更改。这可以使用以下命令完成:

git diff
Git 入门:新手综合指南 - 13也就是说,您可以在这里清楚地看到我添加到我们的文本文件中的内容:hello world!让我们将更改添加到文本文件并创建一个提交:

git add test_resource.txt
git commit -m "added hello word! to test_resource.txt"
要查看所有提交,请编写:

git log
Git 入门:新手综合指南 - 14如您所见,我们现在有两个提交。我们将以相同的方式添加 GitTest.java。这里没有评论,只有命令:

git add GitTest.java
git commit -m "added GitTest.java"
git status
Git 入门:新手综合指南 - 15

使用 .gitignore

显然,我们只想在存储库中单独保留源代码,而不是其他任何东西。那还能有什么呢?至少,由开发环境生成的编译类和/或文件。要告诉 Git 忽略它们,我们需要创建一个特殊文件。这样做:在项目的根目录中创建一个名为 .gitignore 的文件。此文件中的每一行代表一个要忽略的模式。在此示例中,.gitignore 文件将如下所示:

```
*.class
target/
*.iml
.idea/
```
让我们来看看:
  • 第一行是忽略所有扩展名为.class的文件
  • 第二行是忽略“目标”文件夹及其包含的所有内容
  • 第三行是忽略所有扩展名为.iml的文件
  • 第四行忽略.idea文件夹
让我们尝试使用一个例子。为了看看它是如何工作的,让我们将编译后的 GitTest.class 添加到项目中并检查项目状态:

git status
Git 入门:新手综合指南 - 16显然,我们不想以某种方式不小心将已编译的类添加到项目中(使用 git add -A)。为此,创建一个 .gitignore 文件并添加前面描述的所有内容:Git 入门:新手综合指南 - 17现在让我们使用提交将 .gitignore 文件添加到项目中:

git add .gitignore
git commit -m "added .gitignore file"
现在是关键时刻:我们有一个“未跟踪”的已编译类 GitTest.class,我们不想将其添加到 Git 存储库中。现在我们应该看到 .gitignore 文件的效果:

git status
Git 入门:新手综合指南 - 18完美的!.gitignore +1 :)

使用分支机构等

自然地,只在一个分支工作对于孤独的开发人员来说是不方便的,而当团队中有多个人时,这是不可能的。这就是为什么我们有分支机构。正如我之前所说,分支只是指向提交的可移动指针。在这一部分中,我们将探索在不同的分支中工作:如何将一个分支的更改合并到另一个分支,可能会出现什么冲突,等等。要查看存储库中所有分支的列表并了解您所在的分支,您需要编写:

git branch -a
Git 入门:新手综合指南 - 19你可以看到我们只有一个 master 分支。它前面的星号表示我们在其中。顺便说一句,你也可以使用“git status”命令来找出我们在哪个分支。然后有几个创建分支的选项(可能还有更多——这些是我使用的):
  • 根据我们所在的分支创建一个新分支(99% 的情况)
  • 根据特定提交创建分支(1% 的案例)

让我们根据特定的提交创建一个分支

我们将依赖提交的唯一标识符。为了找到它,我们写:

git log
Git 入门:新手综合指南 - 20我用注释“added hello world...”突出显示了提交,它的唯一标识符是 6c44e53d06228f888f2f454d3cb8c1c976dd73f8。我想创建一个从此提交开始的“开发”分支。为此,我写道:

git checkout -b development 6c44e53d06228f888f2f454d3cb8c1c976dd73f8
创建一个分支时,只有来自 master 分支的前两个提交。为了验证这一点,我们首先确保切换到不同的分支并查看那里的提交数量:

git status
git log
Git 入门:新手综合指南 - 21正如预期的那样,我们有两个提交。顺便说一句,这里有一个有趣的点:这个分支中还没有 .gitignore 文件,所以我们的编译文件 (GitTest.class) 现在以“未跟踪”状态突出显示。现在我们可以通过编写以下代码再次查看我们的分支:

git branch -a
Git 入门:新手综合指南 - 22可以看到有两个分支:“master”和“development”。我们目前正在开发中。

让我们在当前的基础上创建一个分支

创建分支的第二种方法是从另一个分支创建它。我想在 master 分支的基础上创建一个分支。首先,我需要切换到它,下一步是创建一个新的。让我们来看看:
  • git checkout master——切换到master分支
  • git status — 验证我们实际上在 master 分支中
Git 入门:新手综合指南 - 23这里可以看到我们切换到了master分支,.gitignore文件生效了,编译后的类不再高亮为“untracked”。现在我们在master分支的基础上新建一个分支:

git checkout -b feature/update-txt-files
Git 入门:新手综合指南 - 24如果您不确定这个分支是否与“master”相同,您可以通过执行“git log”并查看所有提交来轻松检查。应该有四个。

解决冲突

在我们探讨什么是冲突之前,我们需要讨论将一个分支合并到另一个分支。这张图片描绘了将一个分支合并到另一个分支的过程:Git 入门:新手综合指南 - 25在这里,我们有一个主分支。在某些时候,从主分支创建一个辅助分支,然后对其进行修改。工作完成后,我们需要将一个分支合并到另一个分支中。我不会描述各种功能:在本文中,我只想传达一个大概的理解。如果您需要详细信息,可以自己查找。在我们的示例中,我们创建了 feature/update-txt-files 分支。正如分支名称所示,我们正在更新文本。Git 入门:新手综合指南 - 26现在我们需要为这项工作创建一个新的提交:

git add *.txt 
git commit -m "updated txt files"
git log
Git 入门:新手综合指南 - 27现在,如果我们想将 feature/update-txt-files 分支合并到 master 中,我们需要到 master 中编写“git merge feature/update-txt-files”:

git checkout master
git merge feature/update-txt-files
git log
Git 入门:新手综合指南 - 28因此,master 分支现在还包含添加到 feature/update-txt-files 的提交。添加了此功能,因此您可以删除功能分支。为此,我们写:

git branch -D feature/update-txt-files
到目前为止一切都很清楚,是吗?让情况复杂化:现在假设您需要再次更改 txt 文件。但是现在这个文件也将在 master 分支中被更改。换句话说,它会平行变化。当我们想将我们的新代码合并到 master 分支时,Git 将无法弄清楚该怎么做。我们走吧!我们将基于 master 创建一个新分支,对 text_resource.txt 进行更改,并为此工作创建一个提交:

git checkout -b feature/add-header
... we make changes to the file
Git 入门:新手综合指南 - 29

git add *.txt
git commit -m "added header to txt"
Git 入门:新手综合指南 - 30转到 master 分支并在与 feature 分支相同的行上更新此文本文件:

git checkout master
… we updated test_resource.txt
Git 入门:新手综合指南 - 31

git add test_resource.txt
git commit -m "added master header to txt"
现在最有趣的一点是:我们需要将更改从 feature/add-header 分支合并到 master。我们在master分支,所以只需要写:

git merge feature/add-header
但是结果会在 test_resource.txt 文件中发生冲突:Git 入门:新手综合指南 - 32这里我们可以看到 Git 无法自行决定如何合并这段代码。它告诉我们需要先解决冲突,然后才执行提交。好的。我们在文本编辑器中打开有冲突的文件,看看:Git 入门:新手综合指南 - 33要了解 Git 在这里做了什么,我们需要记住我们做了哪些更改以及在哪里,然后进行比较:
  1. 主分支中这一行的更改位于“<<<<<<< HEAD”和“=======”之间。
  2. feature/add-header 分支中的更改位于“=======”和“>>>>>>> feature/add-header”之间。
这就是 Git 告诉我们它无法弄清楚如何在文件中的这个位置执行合并的方式。它把这个部分从不同的分支分成两部分,并邀请我们自己解决合并冲突。很公平。我大胆地决定删除所有内容,只留下“header”一词:Git 入门:新手综合指南 - 34让我们看看更改的状态。描述会略有不同。我们没有“修改”状态,而是“未合并”。那么我们可以提到第五种身份吗?我不认为这是必要的。让我们来看看:

git status
Git 入门:新手综合指南 - 35我们可以说服自己,这是一个特殊的、不寻常的案例。让我们继续:

git add *.txt
Git 入门:新手综合指南 - 36您可能会注意到描述建议只写“git commit”。让我们尝试这样写:

git commit
Git 入门:新手综合指南 - 37就这样,我们做到了——我们在控制台中解决了冲突。当然,这在集成开发环境中可以做得更容易一些。例如,在 IntelliJ IDEA 中,一切都设置得非常好,您可以在其中执行所有必要的操作。但是 IDE 在“幕后”做了很多事情,我们常常不了解那里到底发生了什么。当没有理解时,问题就会出现。

使用远程存储库

最后一步是找出使用远程存储库所需的更多命令。正如我所说,远程存储库是存储存储库的地方,您可以从中克隆它。有哪些远程存储库?例子:
  • GitHub是最大的存储库和协作开发存储平台。我已经在之前的文章中描述过了。在GitHub
    上关注我。我经常在我为工作而学习的那些领域炫耀我在那里的工作。

  • GitLab是一个基于 Web 的开源DevOps生命周期工具。它是一个基于Git的系统,用于管理代码存储库,具有自己的 wiki、错误跟踪系统、CI/CD 管道和其他功能。 在微软收购 GitHub 的消息传出后,一些开发者在 GitLab 中复制了他们的项目。

  • BitBucket 是一个基于 Mercurial 和 Git 版本控制系统的项目托管和协作开发的 Web 服务。有一段时间,它比 GitHub 有一个很大的优势,因为它提供免费的私有存储库。去年,GitHub 也免费向大家推出了这个能力。

  • 等等…

使用远程存储库时,首先要做的是将项目克隆到本地存储库。为此,我导出了我们在本地制作的项目,现在每个人都可以通过编写自己克隆它:

git clone https://github.com/romankh3/git-demo
现在有项目的完整本地副本。为了确保项目的本地副本是最新的,您需要通过编写来拉取项目:

git pull
Git 入门:新手综合指南 - 38在我们的例子中,远程存储库中目前没有任何变化,所以响应是:已经是最新的。但是如果我对远程存储库进行任何更改,本地存储库会在我们拉取它们后更新。最后,最后一个命令是将数据推送到远程存储库。当我们在本地做了一些事情,想要发送到远程仓库时,首先要在本地创建一个新的commit。为了证明这一点,让我们在文本文件中添加一些其他内容:Git 入门:新手综合指南 - 39现在对我们来说很常见的东西——我们为这项工作创建一个提交:

git add test_resource.txt
git commit -m "prepared txt for pushing"
将其推送到远程存储库的命令是:

git push
Git 入门:新手综合指南 - 40嗯,这就是我想说的。感谢您的关注。在GitHub上关注我,我在这里发布了与我的个人学习和工作相关的各种很酷的示例项目。

有用的链接

评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION