共计 2751 个字符,预计需要花费 7 分钟才能阅读完成。
有时,须要做简单的 Git 操作,并且有很多两头逻辑。用 Shell 做简单的逻辑运算与流程管制就是一个劫难。所以,用 Python 来实现是一个欢快的抉择。这时,就须要在 Python 中操作 Git 的库。
GitPython 简介
GitPython 是一个与 Git 库交互的 Python 库,包含底层命令(Plumbing)与高层命令(Porcelain)。它能够实现绝大部分的 Git 读写操作,防止了频繁与 Shell 交互的畸形代码。它并非是一个纯正的 Python 实现,而是有一部分依赖于间接执行 git 命令,另一部分依赖于 GitDB。
GitDB 也是一个 Python 库。它为.git/objects 建设了一个数据库模型,能够实现间接的读写。因为采纳流式(stream)读写,所以运行高效、内存占用低。
GitPython 装置 pip install GitPython
其依赖 GitDB 会主动装置,不过可执行的 git 命令须要额定装置。
根本用法
init
import git
repo = git.Repo.init(path='.')
这样就在当前目录创立了一个 Git 库。当然,门路能够自定义。
因为 git.Repo 实现了__enter__与__exit__,所以能够与 with 联结应用。
with git.Repo.init(path='.') as repo:
# do sth with repo
不过,因为只是实现了一些清理操作,敞开后依然能够读写,所以应用这种模式的必要性不高。详见附录。
clone
clone 分两种。一是从以后库 clone 到另一个地位:
new_repo = repo.clone(path='../new')
二是从某个 URL 那里 clone 到本地某个地位:
new_repo = git.Repo.clone_from(url='git@github.com:USER/REPO.git', to_path='../new')
commit
with open('test.file', 'w') as fobj:
fobj.write('1st line\n')
repo.index.add(items=['test.file'])
repo.index.commit('write a line into test.file')
with open('test.file', 'aw') as fobj:
fobj.write('2nd line\n')
repo.index.add(items=['test.file'])
repo.index.commit('write another line into test.file')
status
GitPython 并未实现原版 git status,而是给出了局部的信息。
>>> repo.is_dirty()
False
>>> with open('test.file', 'aw') as fobj:
>>> fobj.write('dirty line\n')
>>> repo.is_dirty()
True
>>> repo.untracked_files
[]
>>> with open('untracked.file', 'w') as fobj:
>>> fobj.write('')
>>> repo.untracked_files
['untracked.file']
checkout(清理所有批改)
>>> repo.is_dirty()
True
>>> repo.index.checkout(force=True)
<generator object <genexpr> at 0x7f2bf35e6b40>
>>> repo.is_dirty()
False
branch
获取以后分支:
head = repo.head
新建分支:
new_head = repo.create_head('new_head', 'HEAD^')
切换分支:
new_head.checkout()
head.checkout()
删除分支:
git.Head.delete(repo, new_head)
# or
git.Head.delete(repo, 'new_head')
merge
以下演示如何在一个分支(other),merge 另一个分支(master)。
master = repo.heads.master
other = repo.create_head('other', 'HEAD^')
other.checkout()
repo.index.merge_tree(master)
repo.index.commit('Merge from master to other')
remote, fetch, pull, push
创立 remote:
remote = repo.create_remote(name='gitlab', url='git@gitlab.com:USER/REPO.git')
近程交互操作:
remote = repo.remote()
remote.fetch()
remote.pull()
remote.push()
删除 remote:
repo.delete_remote(remote)
# or
repo.delete_remote('gitlab')
其它
其它还有 Tag、Submodule 等相干操作,不是很罕用,这里就不介绍了。
GitPython 的长处是在做读操作时能够不便地获取外部信息,毛病是在做写操作时感觉很不棘手,隔靴搔痒。当然,它还反对间接执行 git 操作。
git = repo.git
git.status()
git.checkout('HEAD', b="my_new_branch")
git.branch('another-new-one')
git.branch('-D', 'another-new-one')
这……感觉又回到了老路,而且依然感觉怪怪的。
其它操作 Git 的办法
subprocess
这就是所谓『老路』。在另一个过程,执行 Shell 命令,并通过 stdio 来解析返回后果。
import subprocess
subprocess.call(['git', 'status'])
dulwich
dulwich 是一个纯 Python 实现的 Git 交互库,当前有空再钻研吧。
官方网站:https://www.dulwich.io/
pygit2
pygit2 是基于 libgit2 实现的一个 Python 库。底层是 C,而下层 Python 只是接口,运行效率应该是最高的,然而孤还是放弃了。其毛病是,须要环境中事后装置 libgit2。相比之下,GitPython 只须要环境预置 Git,简略多了。
官方网站:http://www.pygit2.org/
以上就是本次分享的所有内容,想要理解更多 python 常识欢送返回公众号:Python 编程学习圈,发送“J”即可收费获取,每日干货分享