1.Git
的速成班¶
如果你以前没有在命令行上做过很多工作,那么开始使用命令行的Git
可能会有一些挑战。由于本书中你将通过命令行与Git
进行交互,本章将带你快速了解如何进行交互。
有一个常见的工作流程,是你与Git
交往的基础。
- 创建一个现有版本库的分叉。
- 复制一个远程版本库到你自己的电脑。
- 在版本库中创建一个独立的工作区,你可以在那里进行修改而不影响其他人。
- 标记这些修改,保存到版本库的本地副本。
- 在你的版本库本地副本中保存这些修改。
- 将这些更改与远程版本库同步。
- 可以选择通知版本库所有者你的修改已经准备好被审查。
本章将带领你完成上述所有操作,帮助你熟悉通过命令行操作Git
的基本知识。
虽然本章不会详细解释一切,但它会让你对Git
仓库和基本的Git
工作流程有足够的熟悉,从而更好地理解接下来的章节。
什么是远程版本库?¶
远程仓库是一个项目的所有文件的集合,托管在你的本地机器之外的地方。它们可以托管在你的网络内部,但更多时候,你会使用托管在GitHub
和GitLab
等云服务上的远程仓库。
拥有一个集中的远程仓库可以使项目的分享和贡献变得容易。你不需要把文件发给感兴趣的人,而只需把他们指向托管的远程仓库,让他们尽快启动和运行。
第一步是创建你自己的在线副本,或者说是远程资源库的fork
。这给了你一个在线工作的地方,让你可以按照本章的指示去做,而不影响其他数以百万计的人阅读本书,自己跟着做。
fork
远程版本库¶
在浏览器中导航到以下URL
:
- https://github.com/raywenderlich/programmer-jokes
你会看到一个像下面这样的屏幕:
这是你在本书中要使用的项目的GitHub
主页面。关于GitHub
的所有细节,你会在后面讲到。
确保你已经用自己的GitHub
用户名登录,然后点击页面右上角的Fork
按钮:
Note
如果你在GitHub
上属于一个以上的组织,你可能会看到一个类似于下面的对话框,询问你在哪里分叉programmer-jokes
仓库:
在这种情况下,GitHub
并不是真的问你在哪里分叉到物理上;而是问你想用哪个账户创建分叉。选择你自己的用户名。
当GitHub
在你的账户下创建仓库分叉时,你会看到一个进度屏幕。当GitHub
完成创建分叉后,你会看到另一个屏幕,看起来很像原来的页面,只是现在你在不同的地方工作。
而这正是你想要的。这是原程序员笑话库的完全复制,只是这个副本住在你自己的账户下。这意味着你可以对这个仓库做任何事情,甚至删除它,而不影响住在 raywenderlich
组织下的原始仓库。
要开始工作,你需要复制,或者说clone
,这个远程版本库到你的本地工作站。要做到这一点,你需要这个版本库的远程URL
。这很容易得到--只需点击页面上的Code
按钮,然后点击对话框中https://github.com/username...
网址旁边的小剪贴板图标:
现在你的剪贴板上有这个仓库的远程URL
。
你已经完成了这个网页,现在你可以开始在命令行上使用Git
了。
打开终端、PowerShell
或相应的控制台提示符,准备跟着做吧。
克隆仓库¶
在命令提示符下,输入以下命令,不要按Enter
键:
git clone
之后,按空格键插入一个空格字符。然后用Command-V
或Control-V
将剪贴板中的内容粘贴到命令行中,这取决于你操作系统中的Paste
命令。
你的命令提示符中应该有类似于以下的内容:
git clone https://github.com/<your-username>/programmer-jokes.git
现在,我们把它分解一下:
git
是命令行Git
工具的名称。你在命令行上与Git
的每一次互动都会以git
开头,后面是你想执行的Git
命令。clone
是你想执行的命令的名字。clone
告诉Git
复制一个特定的命名仓库到你的本地机器上。https://github.com/<your-username>/programmer-jokes
是你想克隆的仓库的完整URL
。进一步分解,https://github.com
是托管版本库的云服务,<your-username>
是这个版本库分叉的所有者,programmer-jokes
是你想克隆的版本库的名字。
按Enter
或Return
来执行该命令。Git
会在命令行上给你一点输出,告诉你它做了什么:
Cloning into 'programmer-jokes'...
remote: Enumerating objects: 7, done.
remote: Total 7 (delta 0), reused 0 (delta 0), pack-reused 7
Receiving objects: 100% (7/7), done.
该输出的细节并不重要,但要看一下第一行:
Cloning into 'programmer-jokes'...
Git
告诉你,它正在把远程仓库克隆到它创建的一个新目录中:programmer-jokes
。
用下面的命令从命令行导航到该目录:
cd programmer-jokes
接下来,执行下面的命令,以获得该目录中长格式的文件列表--只是因为它更容易阅读:
ls -l
你会看到类似以下的输出:
-rw-r--r-- 1 chrisbelanger staff 1070 29 May 11:25 LICENSE
-rw-r--r-- 1 chrisbelanger staff 370 29 May 11:25 README.md
这个版本库有两个文件:LICENSE
,它有一些关于版本库内容的无聊的法律信息;README.MD
,它是一个简单的文本文件,包含一些值得吐槽的编程笑话。
现在你已经把版本库克隆到你的本地机器上了,下一步是创建一个独立的工作空间,或者叫branch
,在那里你可以改变README.MD
的内容,而不用担心会把版本库的原始内容搞乱。
创建一个分支¶
从概念上讲,分支是版本库原始内容的副本。你可以在一个分支中工作而不影响版本库的原始内容,直到你准备好将所有工作重新合并在一起。
如果你曾经在开始编辑一个重要的文件之前复制了一份,分支的概念是完全一样的。
在命令行中,执行下面的命令来创建一个新的分支:
git branch my-joke
把它分解开来:
git
,同样是命令行工具的名称。branch
是你希望Git
执行的命令的名称。my-joke
是你想要创建的分支的名字。给分支起的名字并不重要,但一般要给它一个描述性的名字,就像你在桌面上创建新文件夹一样。
你可以通过执行下面的命令看到Git
已经创建了一个新的分支:
git branch
这看起来与上面的命令相似,但在这种情况下,你没有提供一个分支名称。Git
的理解是:"哦,你不想创建一个分支,你只是想看看我知道的所有分支。"
Git
的回应是以下输出:
* main
my-joke
main
是版本库的原始副本,而my-joke
是你刚刚创建的分支。星号*
表示你目前在哪个分支工作。现在,你还在main
上,但这不是你想要的 - 你想切换到my-joke
,这样就不会影响main
。
要切换到my-joke
分支,请执行以下步骤:
git checkout my-joke
啊,一个新的命令:checkout
。你可能期待一个像switch-branch
这样的命令,但Git
认为切换分支是为了“checking out”
。这类似于你在图书馆借出一本书的方式。这本书的副本现在只属于你,直到你把它还给图书馆。
Git
对checkout
命令的回应如下:
Switched to branch 'my-joke'
如果你像我一样是个偏执狂,你可以用下面的命令来确认:
git branch
Git
用以下的回答来消除你的恐惧:
main
* my-joke
星号告诉你,你现在正安全地在my-joke
分支内工作,你的修改不会影响版本库的主副本。
现在,是时候给README.md
添加一个令人惊叹的笑话了。
制作和暂存更改¶
README.md
是一个简单的文本文件。在你选择的文本编辑器中打开它,你会看到它有以下内容:
# programmer-jokes
In order to understand recursion you must first understand recursion.
There are 10 kinds of people in this world: Those who understand binary, and those who don't.
An SEO expert walked into a bar, pub, liquor store, brewery, alcohol, beer, whiskey, vodka...
Why did the two functions stop calling each other? Because they had constant arguments.
他们是搞笑的,对吧!?那么,你绝对可以通过在这个列表中添加你自己的笑话来改进它们。
为了防止你没有一个方便的程序员笑话库,请在文本文件中添加以下一行:
Why couldn’t the confirmed bachelor use Git? Because he was afraid to commit!
保存你的改动并退出文本编辑器。
Git
很聪明,但它也知道不要假设太多。仅仅因为你修改了一个文件,Git
不会认为你想把它放到仓库里。相反,它将等待你将这些修改标记到仓库中。
执行下面的命令来标记你对文件所做的修改,记住这个案例很重要:
git add README.md
add
命令告诉Git
把你对README.md
所做的修改添加到要添加到仓库的列表中,也就是stage
。在这个例子中,你只对一个文件做了一个改动,但实际上,你通常会对很多文件做很多改动。
现在Git
知道你要做这个改动,你需要commit
它到你的本地仓库。
提交更改¶
Git
在这里支持你。它知道有时你可能会添加一个改动,但后来又有了新的想法,或者你可能有其他的改动想同时提交。这就是为什么Git
将暂存文件的行为与提交这些修改的行为分开。
提交是说:"是的,我已经准备好了这些改动,我想把这些改动正式记录在我的本地仓库副本中。"
Git
不仅能正式记录这些修改,还能让你提供一个commit message
,向其他人--甚至是未来的自己--提供一些关于这些修改内容的背景。
现在用下面的命令提交你的改动:
git commit -m "Adding my new joke"
这告诉Git
正式记录你当前的改动--尽管在这种情况下,你只有一个改动,也就是你添加的那个笑话。
Git
的回应是类似于以下的输出:
[my-joke f8f8854] Adding my new joke
1 file changed, 1 insertion(+)
这可能看起来很混乱,但里面有很多信息:
my-joke
是你要提交的分支。f8f8854
是你提交的唯一标识符,也被称为你的修改的commit hash
。你可以用这个标识符在以后的工作中唯一地引用这个特定的提交。注意,如果你在阅读过程中跟随并输入命令,你的哈希值会有所不同。Adding my new joke
是你上面添加的提交信息。1 file changed, 1 insertion(+)
提供了一些关于这次提交中被修改的内容:一个文件,增加了一行。
你已经在本地版本库中正式记录了这些修改,但现在你需要把它们同步,或者说pushed
到远程版本库中。
推送你的改动¶
Git
的大部分操作都是从本地工作站的角度进行的。所以你要做的就是把你的本地提交推送到远程服务器上。
执行下面的命令,将本地修改发送到分叉的远程仓库:
git push --set-upstream origin my-joke
这确实有点愚昧。在这一点上不要太在意;你将在未来的章节中讲述这意味着什么。基本上,这些部分的意思是这样的:
push
告诉Git
把你的本地修改放到服务器上。-set-upstream
告诉Git
在你的本地仓库和远程仓库之间为这个分支形成一个跟踪链接。origin
是一个引用远程仓库的约定。my-joke
是你想推送的分支。
Git
会以一堆输出作为回应:
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 8 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 389 bytes | 389.00 KiB/s, done.
Total 3 (delta 1), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (1/1), completed with 1 local object.
remote:
remote: Create a pull request for 'my-joke' on GitHub by visiting:
remote: https://github.com/<your-username>/programmer-jokes/pull/new/my-joke
remote:
To https://github.com/<your-username>/programmer-jokes.git
* [new branch] my-joke -> my-joke
Branch 'my-joke' set up to track remote branch 'my-joke' from 'origin'.
Note
命令行可能会提示你输入GitHub
的用户名和密码。如果是这样,请输入用户名和密码,然后点击Enter
或Return
。
Git
已经成功推送了你的修改到远程仓库,但还有一件事要做。向其他使用这个仓库的人发出信号,告诉他们你有东西想集成到远程仓库,或者说pull
。你可以通过一个叫做pull request
的机制来实现。
创建一个拉动请求¶
回到你的浏览器,如果你还没有打开,请打开你分叉仓库的GitHub
主页面 https://github.com/<your-username>/programmer-jokes
。
如果你仔细观察,你会发现页面有一些变化,以反映你的修改成功地进入了远程仓库的事实:
你可以看到GitHub
正在告诉你这个repo
现在有两个分支。点击“3 branches”
的链接,你会看到以下页面,显示你的新分支,以及一个“New pull request”
按钮:
点击这个按钮,你会被带到另一个页面,在那里你可以输入一些关于你的修改的细节。在大文本框中输入Adds a real knee-slapper
,以提供关于此拉动请求中包含的更改的一些额外细节,然后点击Create pull request
按钮:
GitHub
会带你到另一个页面,在那里你可以看到你的拉动请求现在是活动的,还有与你的拉动请求有关的各种信息:
这就是你需要通过这个简短的Git
速成课程来了解的情况。如果你没有完全理解沿途发生的一切,不要担心!本章只是让你熟悉基本的fork → clone → branch → add → commit → push → pull request
机制。本章只是为了让你熟悉Git
的基本fork → clone → branch → add → commit → push → pull request
机制。
本书的其余部分将详细介绍这些步骤,以及更多更晦涩难懂的Git
命令。你还会参观一下Git
的内部结构,这可能会帮助你更好地理解为什么Git
会这样做。
在下一章中,你将开始更深入地了解clone
命令。到时见!