GitPython 是一个 Python 代码库,用于以编程方式读取和写入 Gitsource 控制存储库。
让我们通过快速安装和读取本地克隆的 Git 存储库来学习如何使用 GitPython。
我们的工具
本教程适用于 Python 2.7 或 3,但强烈建议所有新应用程序使用 Python 3,尤其是 3.6+。我使用 Python 3.6.3 来写这篇文章。除了 Python,在整个教程中我们还将使用以下应用程序依赖项:
- Git,一个源(版本)控制实现,版本2.15.1
- GitPython版本2.1.7
- pip和virtualenv,与Python 3一起打包,用于安装和将 GitPython 库与任何其他 Python 项目隔离
如果您需要特定的说明来设置基本的 Python 开发环境,请查看此在 Ubuntu 16.04 LTS 上设置 Python 3 和 Flask 的指南。
这篇博文中的所有代码都可以在 GitHub 上的 blog-code-examples 存储库的 first-steps-gitpython 目录下获得 MIT 许可下的开源代码。在您自己的应用程序中随意使用和滥用源代码。
安装 GitPython
首先为您的项目创建一个新的虚拟环境。我的 virtualenvis 名为 testgit
但您可以根据您正在创建的项目命名您的名称。
python3 -m venv gitpy
激活新创建的 virtualenv。
source gitpy/bin/activate
virtualenv 的名称将在激活后添加到命令提示符中。
现在 virutalenv 已激活,我们可以使用 pip
命令安装 GitPython。
pip install gitpython==2.1.7
运行 pip
命令,安装完所有内容后,您应该会看到类似于以下“已成功安装”消息的输出。
(gitpy) $ pip install gitpython==2.1.7 Collecting gitpython==2.1.7 Downloading GitPython-2.1.7-py2.py3-none-any.whl (446kB) 100% |ââââââââââââââââââââââââââââââââ| 450kB 651kB/s Collecting gitdb2>=2.0.0 (from gitpython==2.1.7) Downloading gitdb2-2.0.3-py2.py3-none-any.whl (63kB) 100% |ââââââââââââââââââââââââââââââââ| 71kB 947kB/s Collecting smmap2>=2.0.0 (from gitdb2>=2.0.0->gitpython==2.1.7) Downloading smmap2-2.0.3-py2.py3-none-any.whl Installing collected packages: smmap2, gitdb2, gitpython Successfully installed gitdb2-2.0.3 gitpython-2.1.7 smmap2-2.0.3
接下来,我们可以在安装了 GitPython 的 Python 应用程序中开始以编程方式与 Git 存储库进行交互。
克隆存储库
GitPython 可以使用远程存储库,但在本教程中为了简单起见,我们将在本地系统上使用克隆的存储库。
将要使用的存储库克隆到本地系统。如果您没有特定的想法,请使用托管在 GitHub 上的开源 Full Stack Python Git 存储库。
git clone [email protected]:mattmakai/fullstackpython.com fsp
记下您克隆存储库的位置,因为我们需要该路径来告诉 GitPython 要处理的存储库。使用 cd
切换到新 Git 存储库的目录,然后运行 pwd
(当前工作目录)命令以获取完整路径。
cd fsp pwd
您将看到一些类似/Users/matt/devel/py/fsp
的输出。此路径是您到 Git 存储库基础的绝对路径。
使用export
命令为Git仓库的绝对路径设置环境变量。
export GIT_REPO_PATH='/Users/matt/devel/py/fsp' # make sure this your own path
我们的 Git 存储库和路径环境变量都已设置好,让我们编写使用 GitPython 的 Python 代码。
读取存储库并提交数据
创建一个名为 read_repo.py
的新 Python 文件并打开它,以便我们可以开始编写一个简单的脚本。
从几个导入和一个常量开始:
import os from git import Repo COMMITS_TO_PRINT = 5
os
模块可以方便地读取环境变量,例如我们之前设置的GIT_REPO_PATH
变量。当我们创建 from git import Repo
对象时,Repo
使我们的应用程序可以访问 GitPython 库。COMMITS_TO_PRINT
是一个限制数量的常量输出的行数基于我们希望我们的脚本在其上打印信息的提交数量。Full Stack Python 有超过 2,250 个提交,所以如果我们打印每个提交,将会有大量输出。
接下来在我们的 read_repo.py
文件中创建一个函数来打印个人提交信息:
def print_commit(commit): print('----') print(str(commit.hexsha)) print("\"{}\" by {} ({})".format(commit.summary, commit.author.name, commit.author.email)) print(str(commit.authored_datetime)) print(str("count: {} and size: {}".format(commit.count(), commit.size)))
print_commit
函数接受一个 GitPython 提交对象并打印提交的 40 个字符的 SHA-1 散列,后跟:
- 提交摘要
- 作者姓名
- 作者电子邮件
- 提交日期和时间
- 计数和更新大小
在print_commit
函数下面,创建另一个名为print_repository
的函数来打印Repo
对象的详细信息:
def print_repository(repo): print('Repo description: {}'.format(repo.description)) print('Repo active branch is {}'.format(repo.active_branch)) for remote in repo.remotes: print('Remote named "{}" with URL "{}"'.format(remote, remote.url)) print('Last commit for repo is {}.'.format(str(repo.head.commit.hexsha)))
print_repository
与 print_commit
类似,但打印存储库描述、活动分支、为此存储库配置的所有远程 Git URL 和最新提交。
最后,当我们使用 python
命令从终端调用脚本时,我们需要一个“main”函数。完善我们的
if __name__ == "__main__": repo_path = os.getenv('GIT_REPO_PATH') # Repo object used to programmatically interact with Git repositories repo = Repo(repo_path) # check that the repository loaded correctly if not repo.bare: print('Repo at {} successfully loaded.'.format(repo_path)) print_repository(repo) # create list of commits then print some of them to stdout commits = list(repo.iter_commits('master'))[:COMMITS_TO_PRINT] for commit in commits: print_commit(commit) pass else: print('Could not load repository at {} :('.format(repo_path))
main 函数处理抓取 GIT_REPO_PATH
环境变量,并在可能的情况下根据路径创建 Repo 对象。
如果仓库不为空,表示找不到仓库,则调用print_repository
和print_commit
函数显示仓库数据。
如果您想一次复制并粘贴上面找到的所有代码,请查看 GitHub 上的read_repo.py
文件。
是时候测试我们的 GitPython 使用脚本了。使用以下命令调用 read_repo.py
文件。
(gitpy) $ python read_repo.py
如果激活了 virtualenv 并且正确设置了 GIT_REPO_PATH
环境变量,我们应该会看到类似于以下的输出。
Repo at ~/devel/py/fsp/ successfully loaded. Repo description: Unnamed repository; edit this file 'description' to name the repository. Repo active branch is master Remote named "origin" with URL "[email protected]:mattmakai/fullstackpython.com" Last commit for repo is 1fa2de70aeb2ea64315f69991ccada51afac1ced. ---- 1fa2de70aeb2ea64315f69991ccada51afac1ced "update latest blog post with code" by Matt Makai ([email protected]) 2017-11-30 17:15:14-05:00 count: 2256 and size: 254 ---- 1b026e4268d3ee1bd55f1979e9c397ca99bb5864 "new blog post, just needs completed code section" by Matt Makai ([email protected]) 2017-11-30 09:00:06-05:00 count: 2255 and size: 269 ---- 2136d845de6f332505c3df38efcfd4c7d84a45e2 "change previous email newsletters list style" by Matt Makai ([email protected]) 2017-11-20 11:44:13-05:00 count: 2254 and size: 265 ---- 9df077a50027d9314edba7e4cbff6bb05c433257 "ensure picture sizes are reasonable" by Matt Makai ([email protected]) 2017-11-14 13:29:39-05:00 count: 2253 and size: 256 ---- 3f6458c80b15f58a6e6c85a46d06ade72242c572 "add databases logos to relational databases pagem" by Matt Makai ([email protected]) 2017-11-14 13:28:02-05:00 count: 2252 and size: 270
您看到的具体提交会根据我推送到 GitHub 存储库的最后 5 次提交而有所不同,但是如果您看到类似于上面的输出的内容,这是一个好兆头,一切都按预期进行。
下一步是什么?
我们刚刚克隆了一个 Git 存储库,并使用 GitPython 库读取了大量关于该存储库及其所有提交的数据。
GitPython 不仅可以读取数据,还可以创建和写入 Git 存储库!查看官方 GitPython 教程中的修改参考文档页面,或者在以后有机会编写更高级的 GitPython 演练时返回此处查看。
有问题吗?在 Twitter@fullstackpython 或@mattmakai 上通过 Full Stack Python 存储库上的 GitHub 问题单让我知道。
看到这篇博文有什么问题了吗?在 GitHub 上创建此页面的源代码并提交拉取请求。