不只是版本控制:使用Git搭建你的工作流
全文字数:5241
阅读时长:15分钟
开始
在2021 Stack Overflow 最受欢迎的工具调查排名中,有超过90%的开发者选择git,它如今已成为开发人员的基本技能和工作时首选的版本控制系统。本文将介绍git的基本概念和常用操作,教你使用git快速完成自己的工作流。
本文只介绍基本操作和概念,若想对git有更详细的了解,请到git官网(https://git-scm.com)获取更多细节。推荐到官网阅读并下载 Pro Git 中文版阅读(https://book.git-scm.com/book/zh/v2)。有时网络不太好,你可以在公众号消息界面发送 ProGit 即可获得文章编写时的最新pdf文件。
git(/ɡɪt/)是一个分布式版本控制软件软件,最初由Linus Torvalds创作,于2005年以GPL许可协议发布。最初目的是为了更好地管理Linux内核开发而设计。
历史(Wikipedia)
自2002年开始,Linus Torvalds决定使用BitKeeper作为Linux内核主要的版本控制系统用以维护代码。因为BitKeeper为专有软件,这个决定在社群中长期遭受质疑。在Linux社群中,特别是理查德·斯托曼与自由软件基金会的成员,主张应该使用开放源代码的软件来作为Linux内核的版本控制系统。Linus曾考虑过采用现成软件作为版本控制系统(例如Monotone),但这些软件都存在一些问题,特别是性能不佳。现成的方案,如CVS的架构,受到Linus的批评。
2005年,Andrew Tridgell写了一个简单程序,可以连接BitKeeper的仓库,BitKeeper著作权拥有者拉里·麦沃伊认为Andrew对BitKeeper内部使用的协议进行逆向工程,决定收回无偿使用BitKeeper的许可。Linux内核开发团队与BitMover公司进行磋商,但无法解决他们之间的歧见。Linus决定自行开发版本控制系统替代BitKeeper,以十天的时间编写出git第一个版本。
安装配置
- Linux
在Linux上可以方便地通过自己系统的软件包管理器安装 git,如:
|
|
- Windows
Windows下的安装一般选择直接到官网下载适合自己系统的版本(https://book.git-scm.com/download/win)。
若有winget(Windows下的包管理器),也可以使用:
|
|
- macOS
一般使用HomeBrew或MacPorts:
|
|
一些概念
版本控制
我们使用git,主要是将它作为一个版本控制工具,那么什么是版本控制?
在手机上安装完软件后,我们经常需要对它们进行升级,或者说版本更新。旧版和新版软件最明显的区别是什么?就是它们的版本号不同。而一般来说,每个版本对应的软件包,它们在界面、功能、体验等方面总有一些差别,除非开发者故意拿一套不变的代码糊弄。同样的,在实际开发过程中,总是要对程序做修改,导致文件前后发生变化。我们把这些软件包,源代码,或者说文件的不同“内容”,叫做不同的版本,可以写个版本号来表示。而版本控制,就是用来记录一个或多个文件内容(版本)变化的系统。
开发程序的过程中,我们用版本控制工具来管理程序的源代码文件。但几乎所有版本控制工具都可以拿来管理 所有文件 的版本。我们可以用它来管理 .kt, .cpp, .rs, .docx, .xlsx, .txt, .png 甚至 .mp4文件。
我们为什么需要版本控制呢?假设你是一位装修设计师,正在设计一个房间,本来房间的基本架构都做好了,某天你突然想改装一下卫生间,之后又想改装一下飘窗,后面发现这样会弄坏承重墙和楼下邻居的天花板,由于你改得一团糟,很难再改回去了。这时如果你使用了版本控制,你可以很轻松地恢复到原来的样子,通常这样比备份多个文件更方便。
分布式版本控制系统
分布式是相对于集中式而言的,它们是描述多人协作的版本控制方式的。假设要开发一个大型软件,这个软件要求连接互联网,可以与人对话,会根据用户手机壳颜色更换主题(/手动滑稽),显然一个人不太可能精通所有方面,所以需要很多人同时开发,写好自己的代码然后合并在一个软件里面。
集中式指的是,这个软件的代码存放在一个中心服务器上,即它的仓库是在一个地方统一管理的,每个程序员在开发时都要连接这个服务器,取出最新的文件然后开发再上传。你可以看到这个软件每个人开发的最新情况是什么样的,也可以在别人把服务器卡死不能工作的时候回家休息一段时间。
分布式,则指的是这个软件的完整代码,分布在每一个开发人员手上,即每个人都需要有这个软件的完整仓库。分布式一般会设置一个仓库作为中心仓库,存放目前开发的主线(应该是用来作为代码交换的中心),在每次工作结束之后,每个人只需要提交自己的改动即可,同时再同步一下别人的改动。你可以按照自己的想法完全修改这个仓库,可以在公司停电的情况下在自家工作,也可以在克隆仓库时花一个多小时(一般只在第一次,且大多数都在几分钟)。
存储文件快照
不同于CVS等版本控制工具,git对待数据的方式是直接记录文件的快照(某个版本的文件本身),而不是记录文件的变化(这是基于差异的版本控制系统 delta-based)。
具体来说,基于差异的控制方式是,只记录每次的改动:假设你有一个香蕉,某天你在香蕉上贴了标签,这作为一个版本,之后你又在香蕉上打蜡,再作为一个版本。那么你现有的三个版本是这样记录的,一个香蕉, 香蕉上贴了标签, 香蕉上打了蜡。
而git则是记录每次的文件本身:还是这根香蕉,使用git记录的话,这三个版本则是这样的,一个香蕉,一个贴了标签的香蕉,一个贴了标签并打了蜡的香蕉。
git的一些特点
-
几乎都在本地执行。git中绝大多数操作只需要访问本地资源,一般不需要互联网或其他计算机的信息,这让它在工作时具有令人极其舒服的快速。
-
文件完整性校验。git中所有的数据在存储前都会计算SHA-1值,然后通过哈希值来引用,而不是文件名。这样,你就无法在git不知情的情况下修改文件及内容。同样,git也会发现你在传输过程中发生的信息丢失或文件损坏。
-
一般只添加数据。我们执行的git操作几乎只向数据库中添加数据,而很难从数据库中删除数据,它几乎不会执行任何可能导致文件不能回复的操作,这让它更加安全。
Git Bash
在Linux/macOS上,运行git只需要在终端执行 git [commands命令] [arguments参数]
之类的命令即可。在Windows下,会提供 git bash 工具,使用 git bash 可以保持命令的一致性。本文的所有git命令均可以在不同平台运行。
全局配置
版本控制系统需要知道每次都是谁对文件做了修改,因此你需要为git配置你的一些信息,每台计算机(严格说是某个计算机的某个系统中的某个用户)只需要全局配置一次,今后的版本控制都将默认使用全局配置,你也可以在特定仓库中使用不同的配置。
进行全局配置的工具为 git config
,git将配置存储在一些文件中:
-
Linux/macOS:
-
系统配置文件: /etc/gitconfig
使用
git config --system
进行读写。 -
全局配置文件: ~/.gitconfig 或 ~/.config/git/config
使用
git config --global
进行读写。-
仓库配置文件:仓库/.git/config
使用
git config --local
进行读写,前提是你已经在此仓库中。
-
-
Windows(使用命令同上)
- 系统配置文件:C:\ProgramFiles\Git\etc\gitconfig (在你的Git安装目录下寻找)
- 全局配置文件:C:\Users\用户名.gitconfig
- 仓库配置文件:仓库\.git\gitconfig
大多数情况下,我们只需要关注全局配置文件,在极少数的情况下会配置仓库配置文件。以下为配置的命令:
|
|
只需要输入两行命令就可以完成配置,之后就可以使用git来工作了。
工作区
在git中,文件存在三种状态:
- 已修改 modified
- 已暂存 staged
- 已提交 committed
与之对应,git项目就会有三个阶段:
- 工作区 working directory
- 暂存区 staging area (Index)
- git仓库 .git repository
需要知道的是,你的仓库就是在 项目 .git 文件夹下的一些内容,当你克隆仓库时,你不需要复制克隆别的文件,克隆的只是 .git文件夹。
工作区就是你本来的项目文件,它在.git文件夹外。严格来说,在你使用git管理你的项目文件后,之前的项目文件就应该看做是从.git仓库的某个特定版本的数据库中提取出来的文件,放在磁盘上以供修改使用。
暂存区是一个文件,按git的术语也可以叫做索引(Index),它一般放在.git文件夹下,保存了下次将要提交的文件列表信息。比如,你对工作区中的a文件做了修改,那么在你保存后,暂存区中就会记录a文件已经修改,准备下次提交,你可以手动选择是否提交。
git仓库是你提交的内容,你的本地仓库,它在.git文件夹下,存放项目元数据和对象数据库。
使用Git
这里将从头开始创建一个git仓库,并在实际操作中学习如何使用git工作。
创建仓库
在本地创建仓库有两种方式:
- 将一个本地目录转换为git仓库:
|
|
- 从其他计算机或服务器克隆一个git仓库:
|
|
在创建一个git仓库后,对应目录下会出现一个 .git 目录,这里面含有你初始化git仓库所有必要的文件,它是git仓库的骨干。
检查文件状态
你工作目录下的文件只有两种状态:已跟踪 和 未跟踪,它们的区别是是否纳入版本控制。对于已跟踪的文件,git知道要记录它们的版本变化。通过以下命令查看当前文件是否跟踪:
|
|
跟踪、暂存文件
在创建仓库之后,我们需要将项目文件添加到版本控制。
|
|
需要注意的是,只有对文件进行跟踪,才可以使用git进行版本控制。每次修改完成后,应该再次使用add将文件添加到暂存区。
忽略掉某些文件
通常来说,为了方便我们会直接运行 git add 命令来将项目所有文件纳入跟踪并添加到暂存区。但有时候,会有一些本地配置文件或生成的中间文件(如gcc编译的目标文件),我们并不需要将其纳入版本控制,但一个一个进行add又有些麻烦。
这种情况下,我们可以在项目根目录(事实上可以在项目内的任何一个目录创建,以起到分别对目录管理)创建一个 .gitignore 文件,在里面列出要忽略的文件格式。
.gitignore文件的格式规范可查看官方文档,这里是一些常用的示例:
|
|
查看修改
可以使用 git statue 命令查看文件的修改状态,有时在向仓库提交前我们要查看一些详细的信息,比如某一行修改的具体内容,这时候就可以使用 git diff:
|
|
提交到本地仓库
当把所有修改完成的文件提交到暂存区后,就可以提交到本地仓库了。在此之前,请务必确认所有已修改或新建的文件都有 add 过,可以使用git status查看,否则提交的时候变化不会被包含在里面。使用如下命令进行提交:
|
|
要注意,提交到仓库的是暂存区的文件快照,如果工作区的修改未提交到暂存区,将会造成遗漏。
移动、移除文件
有时,我们需要git停止对某一文件的跟踪,或者删除某些错误提交到版本库中的文件,或是移动某些文件的位置,这时就需要用到:
|
|
查看提交历史
当我们想查看项目或文件的提交历史时:
|
|
撤销操作
在某个阶段,比如正常运行的程序在修改后无法运行,这时我们可能需要撤销对相应文件的修改。撤销操作有可能会导致之前的工作丢失,在执行撤销前一定要注意。
|
|
远程仓库
为了能在git管理的项目上写作,我们通常会使用远程仓库,比如 Git Hub ,下面介绍如何连接远程仓库。
|
|