如何使用 Python 操作 Git 程式碼?GitPython 入門介紹
有時,需要做複雜的 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='[email protected]: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='[email protected]: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互動庫,以後有空再研究吧。
pygit2
pygit2是基於libgit2實現的一個Python庫。底層是C,而上層Python只是介面,執行效率應該是最高的,然而孤還是放棄了。其缺點是,需要環境中預先安裝libgit2。相比之下,GitPython只需要環境預置Git,簡單多了。
以上就是本次分享的所有內容,想要了解更多 python 知識歡迎前往公眾號:Python 程式設計學習圈 ,傳送 “J” 即可免費獲取,每日干貨分享
- 介紹一款能取代 Scrapy 的爬蟲框架 - feapder
- 直觀講解一下 RPC 呼叫和 HTTP 呼叫的區別!
- MySQL 億級資料分頁的優化
- Python 多執行緒小技巧:比 time.sleep 更好用的暫停寫法!
- Python面試官:請說說併發場景鎖怎麼用?
- Python如何非同步傳送日誌到遠端伺服器?
- Python 中的數字到底是什麼?
- 如何建立一個完美的 Python 專案?
- 詳解 Python 的二元算術運算,為什麼說減法只是語法糖?
- Python 為什麼沒有 main 函式?為什麼我不推薦寫 main 函式?
- Bug分析,假刪除導致文章釋出成功卻打不開的問題
- Python 進階:queue 佇列原始碼分析
- Python例項篇:自動操作Excel檔案(既簡單又特別實用)
- 誰說程式設計師不懂浪漫,當代碼遇到文學..
- Python 為什麼沒有 void 關鍵字?
- 程式語言中分號“;”的簡明歷史
- Python 什麼情況下會生成 pyc 檔案?
- 函式和方法的裝飾器
- Python 任務自動化工具:nox 的配置與 API
- 你可能不知道的 Python 技巧