标签归档:Git

《Flask 入门教程》第 1 章:准备工作

在通过这本书学习 Flask 开发前,我假设你了解了 Python 和 HTML 的基础知识。你的 Python 版本可以是 2.7,也可以是 3.3 及以上版本。电脑的操作系统可以是 Windows,也可以是 macOS 或 Linux。

安装编辑器和浏览器

对于编辑器来说,每个人都有不同的偏好,你可以自由选择。可以选择功能丰富的IDE(集成开发环境),比如 PyCharm;也可以选择相对轻量的编辑器,比如 Atom 或 Sublime Text。浏览器建议使用 Firefox 或 Chrome

使用命令行

在本书中,你需要使用命令行窗口来执行许多操作。你可以使用 Windows 下的 cmd.exe,或是 macOS 和 Linux 下的终端(Terminal)。下面我们执行一个最简单的 whoami 命令(即 Who Am I?):

$ whoami
greyli

这个命令会打印出当前计算机用户的名称。其他常用的命令还有 cd 命令,用来切换目录(change directory);mkdir 命令,用来创建目录(makdirectory)。在不同的操作系统上,执行某个操作的命令可能会有所不同,在必要的地方,书里会进行提示。

我们先来为我们的程序创建一个文件夹:

$ mkdir watchlist
$ cd watchlist

除非特别说明,从现在开始,本书假设你的工作目录将是在项目的根目录,即 watchlist/ 目录。

为了确保你已经正确安装了 Python,可以执行下面的命令测试是否有报错:

$ python --version
Python 2.7.11

对于 Windows 用户,请使用 cmder(一个基于 ConEmu 实现的终端模拟器) 来代替系统自带的 cmd.exe,或是使用安装 Git for Windows 后(下一节)附带的 Git Bash。cmder 集成了 Git Bash,支持一些在 Linux 或 macOS 下才能使用的命令(程序),比如 ls、cat、nano、ssh 等,这些命令我们在后面会用到。

使用 Git

Git 是一个流行的版本控制工具,我们可以用它来记录程序源码和文件的变动情况,或是在编程时进行多人协作,你可以把它看做一个优雅的代码变动备份工具。

如果你还不熟悉 Git 也没关系,可以先按照书中的命令去做,有时间再去了解原理。现在要做的第一件事就是在你的电脑上安装 Git (可以执行 git --help 命令检查是否已经安装,没有提示“命令未找到(Command not found)”则表示已安装)。

安装后可以在命令行先使用使用下面的命令查看版本,没有报错则表示已正确安装:

$ git --version
git version 2.17.1

为了让 Git 知道你是谁,以便在提交代码到版本仓库的时候进行记录,使用下面的命令设置你的信息:

$ git config --global user.name "Grey Li"  # 替换成你的名字
$ git config --global user.email "withlihui@gmail.com"  # 替换成你的邮箱地址

现在为我们的项目文件夹创建一个 Git 仓库,这会在我们的项目根目录创建一个 .git 文件夹:

$ git init
Initialized empty Git repository in ~/watchlist/.git/

Git 默认会追踪项目文件夹(或者说代码仓库)里所有文件的变化,但是有些无关紧要的文件不需要记录变化,我们在项目根目录创建一个 .gitignore 文件,在文件中写入忽略文件的规则。因为文件内容比较简单,我们直接在命令使用 nano 来创建:

$ nano .gitignore

在 nano 编辑界面写入常见的可忽略文件规则

*.pyc
*~
__pycache__
.DS_Store

使用 Control + O 和 Enter 键保存,然后按下 Control + X 键退出。在后续章节,对于简单的文件,都会使用 nano 创建,这部分操作你也可以使用编辑器来完成。

将程序托管到 GitHub(可选)

这一步是可选的,将程序托管到 GitHub、GitLab 或是 BitBucket 等平台上,可以更方便的备份、协作和部署。这些托管平台作为 Git 服务器,你可以为本地仓库创建远程仓库。

首先要注册一个 GitHub 账户,点击访问注册页面,根据指示完成注册流程。登录备用。

设置 SSH 密钥

一般情况下,当推送本地改动到远程仓库时,需要输入用户名和密码。因为传输通常是通过 SSH 加密,所以可以通过设置 SSH 密钥来省去验证账号的步骤。

首先使用下面的命令检查是否已经创建了 SSH 密钥:

$ cat ~/.ssh/id_rsa.pub

如果显示“No such file or directory”,就使用下面的命令生成 SSH 密钥对,否则复制输出的值备用:

$ ssh-keygen

一路按下 Enter 采用默认值,最后会在用户根目录创建一个 .ssh 文件夹,其中包含两个文件,id_rsa 和 id_rsa.pub,前者是私钥,不能泄露出去,后者是公钥,用于认证身份,就是我们要保存到 GitHub 上的密钥值。再次使用前面提到的命令获得文件内容:

$ cat ~/.ssh/id_rsa.pub
ssh-rsa AAAAB3Nza...省略 N 个字符...3aph book@greyli

选中并复制输出的内容,访问 GitHub 的 SSH 设置页面(导航栏头像 – Settings – SSH and GPG keys),点击 New SSH key 按钮,将复制的内容粘贴到 Key 输入框里,再填一个标题,比如“My PC”,最后点击“Add SSH key”按钮保存。

创建远程仓库

访问新建仓库页面(导航栏“+” – New repository),在“Repository name”处填写仓库名称,这里填“watchlist”即可,接着选择仓库类型(公开或私有)等选项,最后点击“Create repository”按钮创建仓库。

因为我们已经提前创建了本地仓库,所以需要指定仓库的远程仓库地址(如果还没有创建,则可以直接将远程仓库克隆到本地):

$ git remote add origin git@github.com:greyli/watchlist.git  # 注意更换地址中的用户名

这会为本地仓库关联一个名为“origin”的远程仓库,注意将仓库地址中的“greyli”换成你的 GitHub 用户名

创建虚拟环境

虚拟环境是独立于 Python 全局环境的 Python 解释器环境,使用它的好处如下:

  • 保持全局环境的干净
  • 指定不同的依赖版本
  • 方便记录和管理依赖

我们将使用 Pipenv 来创建和管理虚拟环境、以及在虚拟环境中安装和卸载依赖包。它集成了 pip 和 virtualenv,可以替代这两个工具的惯常用法。另外,它还集成了 Pipfile,它是新的依赖记录标准,使用 Pipfile 文件记录项目依赖,使用 Pipfile.lock 文件记录固定版本的依赖列表。这两个文件替代了手动通过 requirements.txt 文件记录依赖的方式。我们首先使用 pip 安装 Pipenv,Windows 系统使用下面的命令:

$ pip install pipenv

Linux 和 macOS 使用下面的命令:

$ sudo -H pip install pipenv

使用 Pipenv 创建虚拟环境非常简单,使用 pipenv install 命令即可为当前项目创建一个虚拟环境:

$ pipenv install

这个命令执行的过程包含下面的行为:

  • 为当前目录创建一个 Python 解释器环境,按照 pip、setuptool、virtualenv 等工具库。
  • 如果当前目录有 Pipfile 文件或 requirements.txt 文件,那么从中读取依赖列表并安装。
  • 如果没有发现 Pipfile 文件,就自动创建。

创建虚拟环境后,我们可以使用 pipenv shell 命令来激活虚拟环境,如下所示:

$ pipenv shell

安装 Flask

无论是否已经激活虚拟环境,你都可以使用下面的命令来安装 Flask:

$ pipenv install flask

这会把 Flask 以及相关的一些依赖包安装到对应的虚拟环境,同时 Pipenv 会自动更新依赖文件中。

本章小结

当你进行到这里,就意味这我们已经做好学习和开发Flask程序的全部准备了。使用 git status 命令可以查看当前仓库的文件变动状态:

$ git status

下面让我们将文件改动提交进 Git 仓库,并推送到在 GitHub 上创建的远程仓库:

$ git add .
$ git commit -m "I'm ready!"
$ git push -u origin master # 如果你没有把仓库托管到 GitHub,则跳过这条命令,后面章节亦同

这里最后一行命令添加了 -u 参数,会将推送的目标仓库和分支设为默认值,后续的推送直接使用 git push 命令即可。在 GitHub 上,你可以通过 https://github.com/你的用户名/watchlist 查看你的仓库内容。

提示 你可以在 GitHub 上查看本书示例程序的对应 commit:1b6fe4a

进阶提示

为Git仓库里的.idea文件夹正名

在网络上,我曾多次看到人们对于Git仓库中的.idea文件夹的偏见。最近的一次是在某个博客中技术专家对于志愿者提交的项目的点评,其中在“项目规范”中有一条加分项为“没有 .idea 这种不该上传的文件夹”;另一次是在知乎评价某程序员的问题下某个回答的评论中,有人发现该程序员的GitHub仓库里有.idea目录,就居高临下的将其作为理由讽刺该程序员,潜台词即“项目里有.idea = 水平低下”。想当然的,我没看到的类似情况会更多,而这些观点又会影响很多不熟悉具体事实的人,我想我应该尽一份力来改变这个错误的观点继续蔓延。

提示 尽管本文的标题使用了Git,本文的内容同样适用于其他VCS(Version Control System,版本控制系统)。

什么是.idea文件夹

当你使用JetBrains出品的IDE(Integrated Development Enviroment,集成开发环境)时,比如PyCharm、WebStorm或IntelliJ IDEA等,它们会在创建项目后在项目根目录创建一个.idea文件夹,其中保存了项目特定的配置文件。

至于为什么命名为.idea,则是因为IntelliJ IDEA是JetBrains最早推出的IDE(JetBrains一开始叫IntelliJ),因此使用IDEA作为配置文件夹的名称。按照这个SO回答里最高票答案的猜测,或许IntelliJ IDEA这个名字的含义是这样组成的:

  • Intelli ===> Intelligent
  • J ===> Java
  • Idea ===>IDE that is Advanced or Idea just means idea( I have a good idea …like this ) …

是否应该把.idea提交进Git仓库

这个问题没有唯一的答案,在Stack Overflow有很多类似的讨论。总的来说,开发者可以自由选择是否把IDE相关的配置文件(即.idea目录下的文件)提交到Git仓库中:

  • 如果你想让其他使用相同IDE的用户可以更方便(规范)的对项目进行开发,那么就把它提交到Git仓库中。
  • 如果你觉得Git仓库不应该包含和项目本身无关的文件,那么也可以不将它提交到Git仓库中。

正确的提交方法

当然,将.idea目录整个提交到Git仓库的行为并不可取。因为.idea目录下的文件中有包含隐私的内容,比如你的文件操作变动、用户词典、系统环境变量、数据库密码等等,这些文件对项目其他潜在的参与者没有用处,而且会泄露你的隐私。

按照JetBrains官方的建议,在使用VCS时我们应该遵循下面的原则:

分享下面的文件:

  • 除了workspace.xml、usage.statistics.xml和tasks.xml以外.idea目录下的所有文件
  • 所有可以被在不同模块目录下定位到的.iml模块文件(适用于IntelliJ IDEA)

谨慎分享下面的文件

  • Android artifacts that produce a signed build,因为它们包含keystore密码(前半句不理解,暂时保留原文)
  • 在IntelliJ IDEA 13 和之前的版本中的dataSources.ids和datasources.xml文件,它们包含数据库密码

避免分享下面的文件:

  • 对于使用Gradle或Maven的项目,避免分享.iml和.idea/modules.xml文件,因为它们会在导入时生成
  • gradle.xml文件
  • 用户字典(dictionaries文件夹)
  • .idea/libraries目录下的XML文件,因为它们会从Gradle或Maven项目中生成

另外,对于旧的项目格式(.ipr/.iml/.iws files)来说:

  • 分享项目.ipr文件和所有的.iml模块文件,不要分享.iws文件,因为它存储用户特定设置。

对于Git,你可以参考GitHub提供的JetBrains适用的.gitignore模板

我的新书中包含多个Flask项目,这些项目中的.gitignore文件则是通过gitignore.io来生成的。你可以在gitignore.io主页的输入框中输入你使用的操作系统、编程语言和IDE,它会快速为你来生成一份适用这些语言和平台的.gitignore规则,比如这个是输入Python+PyCharm生成的模板。你可以在这个模板的基础上添加自定义规则。

总结

如果你不想在Git仓库中提交IDE相关的配置文件,那么你可以忽略.idea文件夹;相反,你也可以有选择的把.idea目录下的文件提交进Git仓库。也就是说,项目Git仓库中是否包含.idea文件夹与程序员的开发水平并没有直接关系。