阅读
- 第 1 部分:什么是 Git?
- 第 2 部分:Git 入门
- 第 3 部分:创建你的第一个 Git 仓库
- 第 4 部分:如何在 Git 中恢复旧版本文件
- 第 5 部分:3 个 Git 图形化工具
- 第 6 部分:如何构建你自己的 Git 服务器
- 第 7 部分:如何使用 Git 管理二进制大对象
现在是时候学习如何创建你自己的 Git 仓库,以及如何添加文件和进行提交。
在本系列的前几篇文章中,你学习了如何作为最终用户与 Git 交互;你就像一个漫无目的的流浪者,偶然发现了某个开源项目的网站,克隆了一个仓库,然后继续你的生活。你了解到与 Git 交互并不像你想象的那么令人困惑,也许你已经被说服,是时候开始为自己的工作利用 Git 了。
虽然 Git 绝对是大型软件项目的首选工具,但它并不仅仅适用于大型软件项目。它可以管理你的购物清单(如果它们对你来说很重要,而且它们可能很重要!)、你的配置文件、日记或日记、正在进行中的小说,甚至源代码!
而且这样做是值得的;毕竟,当你有一个刚刚被你搞得面目全非的备份副本时,你什么时候会感到生气呢?
除非你使用 Git,否则 Git 无法为你工作,而且现在就是最好的时机。或者,翻译成 Git 的话,“没有像 origin HEAD
这样的 push
”。稍后你会明白的,我保证。
录音类比
我们倾向于用快照来谈论计算机成像,因为我们大多数人都能认同拥有一个装满特定时刻照片的相册的想法。然而,将 Git 更多地视为模拟录音可能更有用。
传统的录音棚磁带录音机,如果你不熟悉,它有几个组件:它包含向前或向后转动的卷轴,用于保存声波的磁带,以及用于录制或检测磁带上的声波并将其呈现给听众的播放头。
除了向前播放磁带外,你还可以倒带回到磁带上的前一个点,或者快进跳到后面的点。
想象一下 1970 年代的乐队在磁带上录音。你可以想象一遍又一遍地练习一首歌,直到所有部分都完美,然后录制一个音轨。首先,你录制鼓,然后是贝斯,然后是吉他,然后是人声。每次录制时,录音棚工程师都会倒带并将磁带置于循环模式,以便在你演奏时播放上一部分;也就是说,如果你演奏贝斯,你可以在背景中听到鼓的声音,然后吉他手听到鼓和贝斯(以及牛铃)等等。在每个循环中,你都在该部分上演奏,然后在接下来的循环中,工程师按下录音按钮并将表演录制到磁带上。
如果你决定对正在处理的内容进行重新混音,你还可以完全复制和更换一卷磁带。
既然我已经希望描绘了一幅生动的 Roger Dean 品质的 70 年代录音棚生活景象,让我们将其转化为 Git。
创建 Git 仓库
第一步是出去为我们的虚拟磁带录音机购买一些磁带。在 Git 术语中,这就是仓库;它是所有工作将要存在的媒介或领域。
任何目录都可以成为 Git 仓库,但首先让我们从一个新的仓库开始。这需要三个命令
- 创建目录(如果你愿意,可以在你的 GUI 文件管理器中执行此操作)。
- 在终端中访问该目录。
- 将其初始化为由 Git 管理的目录。
具体来说,运行这些命令
$ mkdir ~/jupiter # make directory
$ cd ~/jupiter # change into the new directory
$ git init . # initialise your new Git repo
在这个例子中,文件夹 jupiter 现在是一个空的但有效的 Git 仓库。
这就是全部。你可以克隆仓库,你可以向后和向前浏览历史记录(一旦它有历史记录),创建备用时间线,以及 Git 通常可以做的所有其他事情。
在 Git 仓库内工作与在任何目录中工作相同;创建文件,将文件复制到目录中,将文件保存到其中。你可以像往常一样做所有事情;在你介入之前,Git 不会介入。
在本地 Git 仓库中,文件可以有三种状态之一
- 未跟踪:你在仓库中创建的文件,但尚未添加到 Git。
- 已跟踪:已添加到 Git 的文件。
- 已暂存:已跟踪的文件,该文件已被更改并添加到 Git 的提交队列。
你添加到 Git 仓库的任何文件都以未跟踪文件开始其生命周期。该文件存在于你的计算机上,但你尚未告诉 Git 关于它的信息。在我们的磁带录音机类比中,磁带录音机甚至还没有打开;乐队只是在录音棚里随意演奏,还远未准备好录音。
这是完全可以接受的,Git 会在你发生这种情况时通知你
$ echo "hello world" > foo
$ git status
On branch master
Untracked files:
(use "git add <file>..." to include in what will be committed)
foo
nothing added but untracked files present (use "git add" to track)
正如你所见,Git 还告诉你如何开始跟踪文件。
没有 Git 的 Git
在 GitHub 或 GitLab 中创建仓库需要更多的点击和指向操作。这并不困难;你单击新建仓库按钮并按照提示操作即可。
包含一个 README 文件是一个好习惯,这样路过的人就可以对你的仓库是做什么的有所了解,并且克隆一个非空仓库会更令人满意。
克隆仓库与往常没有什么不同,但是获得写回 GitHub 上仓库的权限稍微复杂一些,因为为了向 GitHub 验证身份,你必须拥有 SSH 密钥。如果你在 Linux 上,请使用此命令创建一个
$ ssh-keygen
然后复制你的新密钥,它是纯文本。你可以在纯文本编辑器中打开它,或使用 cat
命令
$ cat ~/.ssh/id_rsa.pub
现在将你的密钥粘贴到 GitHub 的 SSH 配置,或你的 GitLab 配置。
只要你通过 SSH 克隆你的 GitHub 项目,你就可以写回你的仓库。
或者,你可以使用 GitHub 的文件上传器界面来添加文件,甚至无需在你的系统上安装 Git。
https://open-source.net.cn/sites/default/files/2_githubupload.jpg" title="GitHub 文件上传器。" typeof="foaf:Image" width="520" height="148">
跟踪文件
正如 git status
的输出告诉你的那样,如果你希望 Git 开始跟踪文件,则必须 git add
它。git add
操作将文件放置在特殊的暂存区中,文件在此处等待被提交,或永久保存在快照中。git add
的目的是区分你希望包含在快照中的文件,以及你希望 Git 至少暂时忽略的新文件或临时文件。
在我们的磁带录音机类比中,此操作打开磁带录音机并使其准备好录音。你可以想象磁带录音机已按下录音和暂停按钮,或处于播放循环中,等待录制下一个音轨。
一旦你添加文件,Git 将其识别为已跟踪文件
$ git add foo
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: foo
将文件添加到 Git 的跟踪系统不是进行录音。它只是将文件放在舞台上,为录音做准备。在你添加文件后,你仍然可以更改文件;它正在被跟踪并保持暂存状态,因此你可以继续改进或更改它(然后再次添加它以获取这些更改),然后再将其提交到“磁带”。但请注意:你尚未录音,因此如果你破坏了文件中完美的内容,则暂时无法返回,因为你从未将那个完美时刻录制到磁带上。
如果你决定该文件实际上尚未准备好记录在 Git 历史记录中,那么你可以取消暂存某些内容,就像 Git 消息描述的那样
$ git reset HEAD foo
这实际上解除了磁带录音机准备录音的状态,你又回到了在录音棚里随意演奏的状态。
重要的提交
在某个时候,你将要提交某些内容;在我们的磁带录音机类比中,这意味着最终按下录音并录制一个音轨到磁带上。
在一个项目的不同生命周期阶段,你按下录音按钮的频率会有所不同。例如,如果你正在攻克一个新的 Python 工具包,并最终设法使一个窗口出现,那么你肯定会想要提交,以便在你尝试新的显示选项时不可避免地破坏它之后,你可以有所依赖。但是,如果你正在处理 Inkscape 中一些新图形的草稿,你可能会等到你有一些想要进一步开发的东西后再提交。但最终,提交的频率取决于你;Git 不会“花费”那么多,而且现在的硬盘都很大,所以在我看来,越多越好。
提交记录仓库中所有已暂存的文件。Git 仅记录已跟踪的文件,也就是说,你在过去的某个时间点执行过 git add
操作的任何文件,并且自上次提交以来已被修改。如果不存在之前的提交,则所有已跟踪的文件都包含在提交中,因为它们从不存在变为存在,这从 Git 的角度来看是一个相当大的修改。
要进行提交,请运行此命令
$ git commit -m 'My great project, first commit.'
这会将所有提交的文件永久保存(或者,如果你说 Gallifreyan 语,它们将成为“时间中的固定点”)。你不仅可以看到提交事件,还可以看到 Git 日志中指向该提交的引用指针
$ git log --oneline
55df4c2 My great project, first commit.
要获得更详细的报告,只需使用不带 --oneline
选项的 git log
。
此示例中提交的引用编号为 55df4c2
。它被称为提交哈希值,它表示你刚刚录制的所有新素材,叠加在之前的录音之上。如果你需要“倒带”回到历史记录中的那个点,你可以使用该哈希值作为引用。
你可以将提交哈希值视为音频磁带上的 SMPTE 时间码,或者如果我们稍微弯曲一下类比,可以将其视为黑胶唱片上歌曲之间的大间隔之一,或 CD 上的音轨编号。
当你进一步更改文件并将其添加到暂存区,并最终提交它们时,你会积累新的提交哈希值,每个哈希值都充当指向你的作品不同版本的指针。
这就是他们称 Git 为版本控制系统的原因,查理·布朗。
在下一篇文章中,我们将探讨你需要了解的关于 Git HEAD 的所有内容,并且我们将漫不经心地揭示时间旅行的秘密。没什么大不了的,但你会想阅读它(或者也许你已经读过了?)。
4 条评论