跳转至

10.创建一个存储库

在你的Git之旅中,你已经走了很长一段路,从第一次提交,到了解Git背后的工作,再到管理一些相当复杂的合并场景。但在你所有关于仓库的工作中,你还没有了解到一个仓库的确切来源。当然,你已经克隆了一个版本库,你已经分叉了一个版本库,并且使用了远程,但你如何从头开始创建一个版本库和一个远程?

本章告诉你如何在你的本地机器上创建一个全新的版本库,以及如何创建一个远程来承载你的全新版本库,让大家看到。

开始吧

很多人会盲目地告诉你,创建仓库的最简单方法是"去GitHub,点击New Repository,然后在本地克隆"。但是,在大多数情况下,在你考虑把它变成一个成熟的仓库之前,你已经在磁盘上建立了一个小项目。所以这一章将让你进入项目开发的正轨,指导你把一个简单的项目目录变成一个成熟的版本库。

但是,首先,你需要一个项目! 检查本章的starter文件夹;在里面,你会发现一个小型的启动项目,它是本书销售页面的起始网页。

starter文件夹中复制整个git-apprentice-web目录到你的主GitApprentice文件夹。

现在,打开你的终端程序,导航到git-apprentice-web目录。如果你到目前为止一直在跟随本书,你可能还在GitApprentice/ideas文件夹中,所以执行以下命令进入git-apprentice-web子目录:

cd ../git-apprentice-web/

在那里,执行下面的命令,告诉Git把这个目录设置成一个新的仓库:

git init

Git告诉你,它已经建立了一个空的仓库:

Initialized empty Git repository in /Users/chrisbelanger/GitApprentice/git-apprentice-web/.git/

为什么Git会告诉你这是一个空仓库,而这个目录里有文件?回想一下你是如何将文件加入到仓库中的。你必须使用git add命令来告诉Git要在仓库中加入什么;Git不会认为它应该捡起任何躺着的旧文件。这里也是如此;Git已经创建了一个空的仓库,就等着你去添加一些文件。

2020年末开始,GitHub现在使用main作为所有新仓库的默认分支名。但如果你在本地工作站安装了普通的Git,你很可能配置了master作为默认的分支名。

要检查这一点,只需执行下面的命令,看看git init将什么作为你的第一个分支名:

git branch

在我的案例中,Git的回应如下:

* master

要解决这个问题,请执行以下命令:

git branch -M main

虽然Git没有给你输出,但这个命令把你的分支的本地名称从master改为main。同样,对Git来说,多疑是要付出代价的,所以再次执行git branch来确认你的分支已经被重命名为main

现在,在你添加任何文件之前,你要在你的仓库中添加两样东西,这对任何旨在在线共享的仓库来说都是很好的卫生条件:一个LICENSE文件和一个README文件。

创建一个LICENSE文件

在你盲目地创建一个许可证文件之前,值得了解一下为什么你需要一个许可证文件。

在你的版本库里有一个许可证文件,可以清楚地表明其他人可以或不可以使用你的代码。在这个现代的数字时代,有些人认为复制/偷窃/借用/重复使用任何东西都是公平的,但大多数人都想尊重你的许可条款,尽管你可能是在网上免费提供代码。

许可证概述了其他人如何对你的项目做出贡献以及他们的权利是什么。有趣的是,当你不在你的作品中加入一个许可证时。如果你创建了一个项目并把它挂在GitHub上,但没有许可证,你就说明没有人有许可证在任何情况下使用你的代码--他们可以看一下,但仅此而已。

如果"只看不摸"是你真正想要的,这一切都很好,但如果你邀请别人与你合作,那么没有许可证就意味着一旦别人接触了代码,就不清楚谁拥有版权了。在你的代码中包含一个许可证文件,就可以清楚地知道这个代码的所有权在哪里。

诚然,在你的项目中包含一个许可证并不能保护你不被那些只想拿走你的工作并在未经你允许的情况下使用它的代码窃贼伤害。但它所做的*是向任何想以公平方式合作或以任何其他方式使用你的作品的人说明使用和重用你的项目的条款。这是一种活到老、学到老的事情。

现在,说到这里,你应该选择什么样的许可证?这并不总是一个容易回答的问题。大多数情况下,你的项目中只有代码,但如果它们包含图像呢?如果它们包含硬件设计呢?3D打印文件?你的开源书籍手稿?你设计并想开源的字体?如果你的项目是这些或更多的混合体呢?

有一个很好的网站可以帮助你浏览项目的来龙去脉,并帮助你为你的新项目选择一个许可证。导航到https://choosealicense.com/,你会看到很多选项。

img

你可以在你的闲暇时间探索这个网站,但是,在这种情况下,我很乐意让其他人在我建立网页的过程中以任何方式学习和重用我的工作。因此,选择MIT License链接,你会被带到MIT许可证的主许可证页面,这是最常见和最宽松的许可证之一。

img

点击Copy license text to clipboard按钮,将MIT许可证的文本复制到你的剪贴板。

现在,回到你的终端程序,在根目录下创建一个名为LICENSE的新文件(是的,大写字母,不需要扩展名),并将剪贴板上的内容填入其中。完成后保存你的工作。

这就解决了许可证文件的问题。现在,是时候把你的注意力转向README文件了。

创建一个README文件

README文件比许可证文件要直接得多。在README中,你可以把任何你想让人们知道的关于你和你的项目的细节,以及任何能帮助他们开始使用你的项目的东西放在里面。

通常的惯例是用Markdown来制作README文件,主要是为了在GitHubGitLab或其他云主机上的仓库首页以易于阅读的格式呈现。

在项目的根目录下创建一个新文件,命名为README.md,并在其中填入以下信息(可根据需要修改):

# git-apprentice-web

This is the main website for the Git Apprentice book, from raywenderlich.com.

contact: @crispytwit

保存你的修改并退出编辑器。

你已经有了当前的项目、LICENSE文件和README文件--看起来你已经准备好向仓库提交你的文件了。

要想知道第一次提交的内容是什么,执行 git status 来看看Git对工作区的看法:

~GitApprentice/git-apprentice-web $ git status
On branch main

No commits yet

Untracked files:
  (use "git add <file>..." to include in what will be committed)

    LICENSE
    README.md
    css/
    images/
    index.html

nothing added to commit but untracked files present (use "git add" to track)

这看起来和你所期望的一样。项目的基本文件在那里,还有新的LICENSEREADME.md文件。

到此为止,你应该可以将这些文件提交到你的新版本库了。在按照下面的说明进行操作之前,请先试着自己分阶段提交完整的文件集。记住:如果你把事情搞砸了,你可以简单地使用git reset来恢复你的修改。

用下面的命令将文件分阶段提交:

git add .

这将添加当前目录和子目录下的所有内容。

现在,提交你的修改到版本库,提供一个合理的提交信息:

git commit -m "Initial commit of the web site, README and LICENSE"

由于这是你第一次提交到仓库,Git会显示一些不同的输出:

[main (root-commit) 443f9b3] Initial commit of the web site, README and LICENSE
 5 files changed, 111 insertions(+)
 create mode 100644 LICENSE
 create mode 100644 README.md
 create mode 100644 css/style.css
 create mode 100644 images/SFR_b+w_-_penguin.jpg
 create mode 100644 index.html

仓库的第一个提交有点特别,因为它没有任何父类。还记得之前你学到的Git的每个提交都至少有一个父类吗?那么,这是一个特殊的情况,Git为仓库创建了一个根提交,以后的提交都将以这个根提交为基础。

就这样了! 你已经为你的仓库做了第一个提交。但你还没有完成 - 你想把这个仓库推送到远程,让全世界都来和。在本章的后半部分,你将会这样做。

创建模式

这个create mode是你以前在git commit的输出中见过的,并且可能想知道。在这一点上,它只具有学术意义;在你与仓库互动的这个阶段,它真的不会对你有什么影响。

但为了彻底了解情况,这里有create mode这个数字的含义。

  • create mode后面的数字是一个八进制(base 8),表示你要创建的文件类型,以及该文件的读/写/执行权限。
  • 这个二进制数字的第一部分是一个4位的值,表示你要创建的种文件。在这个例子中,你正在创建一个普通文件,Git用二进制的1000来标示。还有其他类型的文件,包括symlinksgitlinks,在你的Git生涯中你还没有用到它们。
  • 该二进制数字的下一部分是三个未使用的位。000.
  • 二进制数的最后一部分由9位组成,代表这个文件的UNIX式权限。前三位是所有者的读/写/执行权限位,后三位是组的读/写/执行位,最后三位是全局读/写/执行位。
  • 因此,由于你拥有该文件,Git将前三个位设置为110(读、写,但没有执行,因为这不是一个可执行的二进制或脚本文件)。
  • 为了允许你的小组中的任何人读取但不写这个文件,Git100(读,不写,不执行)。
  • 要允许世界上的任何人读取但不写这个文件,Git会分配给他们 100(读,不写,不执行)。
  • 当所有的二进制文件被串联在一起时,你就有了1000000110100100=1000000110100100的完整二进制字符串。
  • 1000000110100100转换为八进制(base 8),你就有了100644作为指示该文件的类型和权限的紧凑方式。

看到了吗?我*告诉过你,这只是学术上的兴趣。

创建和同步一个远程

目前,你在你的本地系统上有你自己的版本库。但这有点像你在房间里练了一辈子吉他,却从来没有在派对上弹奏过,这样你就可以用"Wonderwall"的表演来惊艳你的客人。你需要把这个项目放到别人可以看到的地方,并有可能进行合作。

去GitHub为你的项目创建一个新的远程仓库,并登录到你的账户。

点击屏幕右上角的+号,并选择New repository

img

img

这里有几个细节需要注意:

  • 给你的版本库起个好名字;在这个例子中,我将使用与我的项目目录名称相同的名字,git-apprentice-web,尽管这不是严格意义上的必要。
  • 将版本库设置为Public,这样任何人都可以看到它。
  • 最后,不要勾选Initialize this repository with:部分的所有内容,因为你将从本地工作站导入版本库,它已经存在,并且已经有LICENSEREADME
  • 点击Create repository按钮,Git将很快把你带到Quick setup页面。

img

这给了你几个指示,如何把一些内容放到你的版本库中。在你的例子中,你已经有一个现有的仓库,所以你可以使用…or push an existing repository from the command line下的说明。因为你对命令行Git的精通,对吗?

确保在本页顶部仓库的URL旁边选择了 HTTPS 选项。把提供的URL复制到你的剪贴板上。

回到你的终端程序,执行下面的命令,为你的本地仓库添加一个新的远程,在必要时替换你自己仓库的复制的URL

git remote add origin https://github.com/<your-repo-name>/git-apprentice-web.git

Git没有给你这个命令的输出,但你可以用下面的命令来验证你是否已经添加了一个远程:

git remote -v

你应该看到输出中显示了你的遥控器:

origin  https://github.com/<your-username>/git-apprentice-web.git (fetch)
origin  https://github.com/<your-username>/git-apprentice-web.git (push)

好了 - 所以你的本地版本库已经准备好推送到远程。现在,执行快速设置页面的最后一条命令:

git push -u origin main

这将推送你的修改,正如你所期望的那样,并有一些相应的输出。-u开关是--push-upstream的简写,它确保你本地仓库的每个分支都能追踪到远程仓库的相应分支。否则,Git不会自动"知道"跟踪你的本地分支和远程分支。

origin选项只是你想推送的远程仓库的名称;记住,origin只是Git在用git init设置仓库时使用的常规默认远程名称,而不是一个标准。

main是你想推送到远程的本地分支的名字。

你可以通过查看git push命令输出的最后几行来验证Git是否已经推送并开始跟踪你的本地分支与远程分支:

 * [new branch]      main -> main
Branch 'main' set up to track remote branch 'main' from 'origin'.

回到你的GitHub仓库主页,刷新页面,看看你的新仓库:

img

在这一点上,你的版本库已经准备好让你或其他任何人查看、克隆和贡献。

关键点

  • 使用 git init 来建立一个Git仓库。
  • 在你的仓库里有一个LICENSE文件和一个README.md文件是公认的做法。
  • 使用git addgit commit来创建新仓库的第一个提交。
  • 创建模式只是Git告诉你它在添加到仓库的文件上设置了哪些文件权限。
  • 你可以在GitHub上创建一个空的远程来托管你的仓库,你也可以选择不让GitHub在默认情况下为你的远程填充LICENSEREADME.md
  • 使用git remote add origin <remote-url>来添加一个远程到你的本地仓库。
  • 使用git remote -v来查看与本地仓库相关的远程。
  • 如果你的Git安装使用master作为新仓库的默认分支,而你想推送到新创建的GitHub仓库,并将main作为默认分支,你需要执行git branch -M main,将本地的master分支改名为main,以匹配你的远程。
  • 使用git push --set-upstream origin maingit push -u origin main将仓库中的本地提交推送到远程,并开始跟踪本地分支与远程分支。

接下来该怎么走?

你对Git的介绍已经绕了一圈了!你从克隆别人的仓库开始,对其进行了大量修改。你从克隆别人的仓库开始,对其进行了大量的修改,学会了如何分阶段提交修改,如何查看日志,如何分支,如何拉动和推送修改,现在你又回到了起点,只不过你*是你自己仓库的创建者。这感觉很好,不是吗?

如果你是个好奇心强的人,你可能对Git还有很多问题没有解答,特别是它是如何工作的,什么是合并冲突,如何处理部分完整的工作文件,以及如何做一些你在网上听说过的事情,比如压制提交,重写历史,以及使用重放作为合并的替代。

Git系列的下一本书叫《高级 Git》(https://www.raywenderlich.com/books/advanced-git)。这本书让你进一步了解Git,向你展示更多关于Git内部的信息,并引导你了解一些场景,这些场景把很多开发者吓得不敢用Git的高级方式来使用。但你很快就会发现,Git的优雅和相对简单让你可以做一些惊人的事情,可以大大改善你和你的分布式开发团队的生活。