在使用 Git 之前,我们需要了解一些其他的知识:

什么是版本控制?

  • 版本控制,也称为源代码控制,是一种跟踪和管理软件代码变更的实践。版本控制系统是软件工具,可帮助软件团队管理源代码随时间推移而发生的变更。随着开发环境的加速,版本控制系统可以帮助软件团队更快、更智能地工作。

  • 版本控制软件在特殊类型的数据库中跟踪对代码的每一次修改。如果犯了错误,开发人员可以回退并比较代码的早期版本,以帮助修复错误,同时最大限度地减少对所有团队成员的干扰。

  • 版本控制可以跟踪每个贡献者的每一个单独变更,并帮助防止并行工作发生冲突。对软件某一部分所做的变更可能与同时工作的另一位开发人员所做的变更不兼容。应该在不妨碍团队其他成员工作的情况下有序地发现和解决这个问题。此外,在所有软件开发中,任何变更都可能自行引入新的错误,新软件在经过测试之前是不可信的。因此,测试和开发将一起进行,直到新版本准备就绪。

关于源代码管理

  • 源代码管理 (SCM) 用于跟踪对源代码存储库的修改。 SCM 跟踪代码库变更的运行历史记录,并帮助解决合并来自多个贡献者的更新时发生的冲突。 SCM 也是版本控制的代名词。

  • 随着软件项目代码行数和贡献者人数的增加,通信开销和管理复杂性的成本也在增加。 SCM 是缓解不断增长的开发成本带来的组织压力的关键工具。


那么, Git 是什么呢?

引言

到目前为止,当今世界上使用最广泛的现代版本控制系统是 Git 。 Git 是一个成熟的、积极维护的开源项目,最初由 Linux 操作系统内核的著名创建者 Linus Torvalds 于 2005 年开发。有海量软件项目依赖 Git 进行版本控制,包括商业项目和开源项目。使用过 Git 的开发人员在可用的软件开发人才库中占有很好的比例,它在各种操作系统和 IDE(集成开发环境)上都能很好地运行。

Git 采用分布式架构,是 DVCS(分布式版本控制系统)的示例。在 Git 中,每个开发人员的代码工作副本也是一个可以包含所有变更完整历史记录的存储库,而不是像曾经流行的 CVS 或 Subversion(也称为 SVN )等版本控制系统那样,只有一个地方存放软件的完整版本历史记录。

除了分布式外, Git 的设计还考虑了性能、安全性和灵活性。

为什么使用 Git ?

从集中式版本控制系统切换到 Git 会改变开发团队创建软件的方式。而且,如果您是一家依赖其软件来开发任务关键型应用的公司,那么改变您的开发工作流程会影响你的整个业务。

功能分支工作流

Git 的最大优势之一是其分支功能。与集中式版本控制系统不同, Git 分支便宜且易于合并。这简化了受许多 Git 用户欢迎的功能分支工作流程。

功能分支为代码库的每次变更提供了一个隔离的环境。当开发人员想要开始做某件事时(无论大小),他们都会创建一个新分支。这样可以确保主分支始终包含生产质量的代码。

使用功能分支不仅比直接编辑生产代码更可靠,而且还能为组织带来好处。它们允许您以与敏捷待办事项列表相同的精度呈现开发工作。

Workflow
Workflow

分布式开发

在 SVN 中,每个开发人员都会获得一个指向单个中央存储库的工作副本。但是, Git 是一个分布式版本控制系统。不是工作副本,而是每个开发人员都有自己的本地存储库,里面有完整的提交历史记录。

拥有完整的本地历史记录可以让 Git 变得更快,因为这意味着您不需要网络连接即可创建提交、检查文件的先前版本或在提交之间执行比对。

分布式开发还可以更轻松地扩展您的工程团队。如果有人破坏了 SVN 中的生产分支,则其他开发人员在修复之前无法添加变更。对于 Git 来说,这种障碍是不存在的。每个人都可以继续在自己的本地存储库中作业。

而且,与功能分支类似,分布式开发创造了更可靠的环境。即使开发者删除了自己的存储库,他们也可以简单地克隆别人的存储库然后重新开始。

拉取请求

拉取请求是一种要求其他开发人员将您的一个分支合并到他们存储库中的方式。这不仅使项目主管更容易跟踪变更,还可以让开发人员在将其与代码库其余部分集成之前围绕他们的工作展开讨论。

Pull Request
Pull Request

由于它们本质上是附加到功能分支的评论话题,因此拉取请求的用途非常广泛。当开发人员遇到棘手问题时,他们可以提出拉取请求,向团队其他成员寻求帮助。或者,初级开发人员可以通过将拉取请求视为正式的代码审查来确信他们不会破坏整个项目。

社区

在许多圈子里,Git 已成为新项目的预期版本控制系统。如果您的团队正在使用 Git,您很可能不必对新员工进行工作流程培训,因为他们已经熟悉了分布式开发。

此外,Git 在开源项目中非常受欢迎。这意味着可以轻松利用第三方库并鼓励其他人克隆您自己的开源代码。

更快的发布周期

功能分支、分布式开发、拉取请求和稳定社区的最终结果是更快的发布周期。这些功能促进了敏捷的工作流程,鼓励开发人员更频繁地共享较小的变更。反过来,与集中式版本控制系统常见的单一版本相比,变更可以更快地推送到部署管道中。

正如您所预料的那样, Git 在持续集成和持续交付环境中运行得很好。 Git 钩子允许您在存储库内发生某些事件时运行脚本,这使您可以自动部署到您想要的内容。您甚至可以从特定分支构建代码或将代码部署到不同的服务器。

例如,您可能需要配置 Git ,以便在有人将拉取请求合并到测试服务器时,将最新的提交从开发分支部署到测试服务器。将这种构建自动化与同行评审相结合,意味着在代码从开发到暂存再到生产的过程中,您可以极大地放心。

入门

从本章节开始,将一一介绍 Git 如何使用。

设置代码库

此部分将指导您初始化新的或现有项目的 Git 代码库。下面的工作流示例包括在本地创建的代码库和从远程代码库克隆的代码库。本指南假定读者基本熟悉命令行界面。本指南涵盖的要点包括:

  • 初始化新的 Git 代码库
  • 克隆现有 Git 代码库
  • 将文件的修订版提交到代码库
  • 配置用于远程协作的 Git 代码库
  • 常用 Git 版本控制命令

到本模块结束时,您应该能够创建 Git 代码库、使用常用的 Git 命令、提交修改的文件、查看项目的历史记录等。

什么是 Git 代码库?

Git 代码库是项目的虚拟存储区域。它可让您保存代码的各个版本,以便在需要时进行访问。

初始化新代码库

使用 git init 命令来创建新的代码库。 git init 是一个一次性命令,您可以在新代码库的初始设置期间使用它。执行此命令将在您当前工作目录中创建一个新的 .git 子目录。这也将同时创建一个新的主分支。

1
2
cd /path/to/your/new/code/folder
git init

您也可以在现有的项目文件夹创建新的 Git 代码库,首先要切换到该项目的根目录中,然后再执行 git init 命令:

1
2
cd /path/to/your/existing/code
git init

您也可以在初始化 Git 代码库时,直接指定项目的根目录名:

1
git init yourCodeRepositoryName

更多有关于 git init 命令,请点击这里

克隆现有代码库

如果已在中央代码库中创建了项目,或者想要在新的设备中进行本地项目开发,则 git clone 是获取本地开发克隆的常用方式。其与 git init 一样,克隆通常是一次性操作。开发人员将项目克隆到了本地后,所有版本控制操作都可通过本地的代码库进行。

1
git clone <repo url>

您向 git clone 提供一个代码库的 URL 即可在本地创建远程代码库的副本或克隆体。 Git 支持几种不同的网络协议和相应的 URL 格式。在此示例中,我们将使用 Git SSH 协议,例如从 GitHub 克隆代码库到本地:

1
git clone git@github.com:yourname/repositoryName.git

执行时,主分支上远程代码库文件的最新版本将被下拉并添加到本地的文件夹。该文件夹将包含远程代码库和新创建的主分支的完整历史记录。

更多有关于 git clone 命令,请点击这里

将变更保存到代码库

当您看到这里时,我相信您一定已经拥有了一个自己的代码库。此时,可以向其提交文件版本变更(即增加或删除文件,或者更改现有的文件)。例如:

  • 切换目录到代码库根目录 /path/to/project
  • 创建一个内容是 “test content for git tutorial" 的新文件 CommitTest.txt
  • 使用 git add 将 CommitTest.txt 添加到代码库的暂存区域。
  • 创建一个包含消息的新提交,该消息描述了在本次提交中完成了哪些操作
1
2
3
4
cd /path/to/project
echo "test content for git tutorial" >> CommitTest.txt
git add CommitTest.txt
git commit -m "added CommitTest.txt to the repo"

执行完后,您的代码库已经将 CommitTest.txt 添加到历史记录中,并跟踪该文件的未来更新。

在此示例中,引入了 git 的两个命令: git addgit commit 。更多有关命令的介绍请点击 addcommit

库间协作

Git 的“工作副本”理念与通过从 SVN 代码库检出源代码所获得的工作副本截然不同,了解这一点很重要。与 SVN 不同, Git 不区分工作副本和中央代码库 —— 他们都是完整的 Git 代码库。

这就使得 Git 的协作从根本上不同于 SVN 。 SVN 依赖于中央代码库和工作副本之间的关系,而 Git 的写作模式基于代码库与代码库之间的互动,即提交的操作是从一个代码库推送或拉取到另一个代码库。

当然,您可以向某些 Git 代码库赋予特殊意义。例如,只需要将一个 Git 代码库指定为 “中央代码库” ,就可以使用 Git 来复制集中式工作流,但这仅仅是通过约定而不是硬连接来实现的。

裸代码库与克隆的代码库

如果您在之前的 “初始化新代码库” 部分中使用了 git clone 来设置本地代码库,那么您的代码库已经配置为远程协作。 git clone 将自动配置代码库,并远程指向您所克隆的代码库的 Git URL 。这意味着,对文件进行变更并提交这些变更后,您可以使用 git push 将这些变更推送到远程代码库。

如果您使用 git init 来创建新的代码库,将没有远程代码库来接受推送的变更。在初始化新代码库时,常见的模式是在常用的 Git 托管服务创建一个代码库。该服务将提供一个 Git URL ,您可以在之后将其添加到本地 Git 代码库,并使用 git push 推送到托管的代码库。使用您选择的服务创建远程代码库后,需要使用映射更新您的本地代码库。

配置和设置

设置好远程代码库后,您需要将远程代码库 URL 添加到本地的 git config 设置里,并且要为您本地的分支设置一个上游分支。 git remote 命令提供此功能。

1
git remote add <remote_name> <remote_repo_url>

此命令会将 <remote_repo_url> 的远程存储库映射到本地代码库中 <remote_name> 下的 ref 。映射远程代码库后,您可以将本地分支推送到远程代码库。

1
git push -u <remote_name> <local_branch_name>

此命令会将 <local_branch_name> 下的本地代码库分支推送到 <remote_name> 上的远程代码库。

更多关于 git remote 命令,请点击这里

除了配置远程代码库 URL 之外,您还需要设置全局 Git 配置选项,如用户名或电子邮件。使用 git config 命令可在命令行中配置 Git 代码库的安装,从用户信息到首选项,再到代码库行为,此命令可以定义的所有内容皆可配置。以下列出的为常用的配置选项:

Git 的配置有三种级别: 代码库(本地)、用户(全局)或整个系统:

  • 本地: /.git/config - 代码库特定设置。这里存储着使用 --local 标记来配置的信息。
  • 全局: /.gitconfig - 用户特定设置。这里存储着使用 --global 标记来配置的信息。
  • 系统: $(prefix)/etc/gitconfig - 系统范围的设置。这里存储着使用 --system 标记来配置的信息。

定义用户的作者姓名。

1
git config --global user.name <name>

定义代码库的电子邮件

1
git config --local user.email <email>

更多关于 git config 命令,请点击这里

保存变更

在 Git 或其他版本控制系统中工作时, “保存” 的概念比在文字处理器或其他传统文件编辑应用中保存的流程更为细致。传统的软件表达方式 “保存” 与 Git 术语 “提交” 同义。 Git 中的提交相当于 “保存” 。应将传统保存视为一种用于覆盖现有文件或写入新文件的文件系统操作。或者, Git 提交是一种作用于文件和目录集合的操作。

在 Git 和 SVN 中保存变更也是不同的流程。 SVN 提交或 “签入” 是指远程推送到集中式服务器的操作。这意味着 SVN 提交需要访问互联网才能完全 “保存” 项目变更。 Git 提交可以在本地捕获和构建,然后根据需要使用 git push-u origin 命令推送到远程服务器。这两种方法之间的区别是架构设计之间的根本区别。 Git 是分布式应用模型,而 SVN 是集中式模型。分布式应用通常更强大,因为它们不像集中式服务器那样存在单点故障。

 git addgit statusgit commit 命令都组合使用,用于保存 Git 项目当前状态的快照。

Git 还有一个名为 “the stash” 的额外保存机制。 stash 是一个临时存储区,用于存放尚未准备提交的变更。 stash 在工作目录上运行,工作目录是三棵树中的第一个,有大量使用选项。

同时,还可将 Git 存储库配置为忽略特定的文件或目录。这将防止 Git 保存对任何忽略内容的变更。Git 有多种管理忽略列表的配置方法。

工作原理

 git addgit commit 命令构成了基本的 Git 工作流程。这是每个 Git 用户需要理解的两个命令,无论他们的团队采用何种协作模式。它们是将项目版本记录到存储库历史记录中的方法。

开发项目围绕基本的编辑/暂存/提交模式进行。首先,在工作目录中编辑文件。当您准备好保存项目当前状态的副本时,您可以使用 git add 暂存变更。对暂存的快照感到满意后,您可以使用 git commit 将其提交到项目历史记录中。 git reset 命令用于撤销提交或暂存的快照。

除了 git addgit commit 外,第三个命令 git push 对于完整的协作 Git 工作流程至关重要。 git push 用于将提交的变更发送到远程存储库进行协作。这使其他团队能够访问一组已保存的变更。更多关于 git push 命令,请点击这里

注意:

切记不可将 git add 命令与 svn add 混淆,后者会将文件添加到存储库中;而前者在更抽象的变更层面上起作用。这一位置每次修改文件时都需要调用 git add ,而 svn add 只需要为每个文件调用一次。这听起来可能多余,但是这种流程会让项目保持井然有序。

暂存区域

 git add 命令的主要功能是将工作目录中待处理的变更提升到 git staging 区域。暂存区域是 Git 比较独特的功能之一,对于习惯了 SVN 这样类似的系统,需要一定时间的适应(大家可把暂存区域视为工作目录和项目历史记录之间的缓冲区)。暂存区域被认为是 Git 的 “三棵树” 之一,另外两个即为工作目录和提交历史记录。

暂存并不会提交之前所有的变更,而是将相关变更提交到项目历史记录之前,将相关变更分组为高度集中的快照。这意味着您可以对不相关的文件进行各种编辑,然后返回并将它们拆分为逻辑提交,方法是将相关变更添加到暂存并逐段提交。与任何版本控制系统一样,创建原子提交很重要,这样可以轻松跟踪错误并还原变更,同时最大限度地减少对项目其余部分的影响。

常用选项

1
git add <file>

将所有变更暂存到 中,供下次提交。

1
git add <directory>

将所有变更暂存到 中,供下次提交。

1
git add -p

开始交互式暂存会话,允许您选择要添加到下一次提交中的文件部分。这将为您提供大量变更并提示您输入命令。使用 y 暂存区块, n 忽略区块, s 将其拆分为较小的区块, e 用于手动编辑区块,使用 q 退出。

检查代码库

 git status 命令显示工作目录和暂存区域的状态。可以用来查看哪些变更已暂存、哪些尚未暂存以及哪些文件未被 Git 追踪。但输出信息中并未包含有关已提交项目历史记录的任何信息(如果需要,则使用 git log 命令)。

相关的 git 命令

 git tag ,标记是指向 Git 历史记录中特定点的引用。 git tag 通常用于捕获用于标记版本发布的历史记录点(即 v1.0.1)。

 git blame ,用来追溯一个指定文件的历史提交记录。这用于探索特定代码的历史记录并回答有关将代码添加到存储库的内容、方式和原因的问题。

 git log , 用来显示已提交的快照,此命令可列出项目历史记录、对其进行筛选并所搜特定的变更。

撤销更改

重写历史记录

指令大全


此间车厢已使用  次 |   人乘坐过此趟开往世界尽头的列车