<kbd id="5sdj3"></kbd>
<th id="5sdj3"></th>

  • <dd id="5sdj3"><form id="5sdj3"></form></dd>
    <td id="5sdj3"><form id="5sdj3"><big id="5sdj3"></big></form></td><del id="5sdj3"></del>

  • <dd id="5sdj3"></dd>
    <dfn id="5sdj3"></dfn>
  • <th id="5sdj3"></th>
    <tfoot id="5sdj3"><menuitem id="5sdj3"></menuitem></tfoot>

  • <td id="5sdj3"><form id="5sdj3"><menu id="5sdj3"></menu></form></td>
  • <kbd id="5sdj3"><form id="5sdj3"></form></kbd>

    如何使用 Python 操作 Git 代碼?

    共 2971字,需瀏覽 6分鐘

     ·

    2020-02-17 23:25

    8d3eced9b943be8e54d960621d2ae866.webp


    cfd3f50566be98458b3b53881be94b97.webp作者:匿蟒

    鏈接:https://note.qidong.name/2018/01/gitpython

    有時(shí),需要做復(fù)雜的 Git 操作,并且有很多中間邏輯。用 Shell 做復(fù)雜的邏輯運(yùn)算與流程控制就是一個(gè)災(zāi)難。所以,用 Python 來(lái)實(shí)現(xiàn)是一個(gè)愉快的選擇。這時(shí),就需要在 Python 中操作 Git 的庫(kù)。

    0. GitPython 簡(jiǎn)介

    GitPython是一個(gè)與Git庫(kù)交互的Python庫(kù),包括底層命令(Plumbing)與高層命令(Porcelain)。它可以實(shí)現(xiàn)絕大部分的Git讀寫操作,避免了頻繁與Shell交互的畸形代碼。它并非是一個(gè)純粹的Python實(shí)現(xiàn),而是有一部分依賴于直接執(zhí)行git命令,另一部分依賴于GitDB。

    GitDB也是一個(gè)Python庫(kù)。它為.git/objects建立了一個(gè)數(shù)據(jù)庫(kù)模型,可以實(shí)現(xiàn)直接的讀寫。由于采用流式(stream)讀寫,所以運(yùn)行高效、內(nèi)存占用低。

    1. GitPython安裝

    pip?install?GitPython

    其依賴GitDB會(huì)自動(dòng)安裝,不過(guò)可執(zhí)行的git命令需要額外安裝。

    2. 基本用法

    init

    import?git
    repo?=?git.Repo.init(path='.')

    這樣就在當(dāng)前目錄創(chuàng)建了一個(gè)Git庫(kù)。當(dāng)然,路徑可以自定義。

    由于git.Repo實(shí)現(xiàn)了__enter____exit__,所以可以與with聯(lián)合使用。

    with?git.Repo.init(path='.')?as?repo:
    ????#?do?sth?with?repo

    不過(guò),由于只是實(shí)現(xiàn)了一些清理操作,關(guān)閉后仍然可以讀寫,所以使用這種形式的必要性不高。詳見(jiàn)附錄。

    clone

    clone分兩種。一是從當(dāng)前庫(kù)clone到另一個(gè)位置:

    new_repo?=?repo.clone(path='../new')

    二是從某個(gè)URL那里clone到本地某個(gè)位置:

    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并未實(shí)現(xiàn)原版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)
    ?at?0x7f2bf35e6b40>
    >>>?repo.is_dirty()
    False

    branch

    獲取當(dāng)前分支:

    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

    以下演示如何在一個(gè)分支(other),merge另一個(gè)分支(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

    創(chuàng)建remote:

    remote?=?repo.create_remote(name='gitlab',?url='[email protected]:USER/REPO.git')

    遠(yuǎn)程交互操作:

    remote?=?repo.remote()
    remote.fetch()
    remote.pull()
    remote.push()

    刪除remote:

    repo.delete_remote(remote)
    #?or
    repo.delete_remote('gitlab')

    其它

    其它還有Tag、Submodule等相關(guān)操作,不是很常用,這里就不介紹了。

    GitPython的優(yōu)點(diǎn)是在做讀操作時(shí)可以方便地獲取內(nèi)部信息,缺點(diǎn)是在做寫操作時(shí)感覺(jué)很不順手,隔靴搔癢。當(dāng)然,它還支持直接執(zhí)行git操作。

    git?=?repo.git
    git.status()
    git.checkout('HEAD',?b="my_new_branch")
    git.branch('another-new-one')
    git.branch('-D',?'another-new-one')

    這……感覺(jué)又回到了老路,而且仍然感覺(jué)怪怪的。

    3. 其它操作Git的方法

    subprocess

    這就是所謂『老路』。在另一個(gè)進(jìn)程,執(zhí)行Shell命令,并通過(guò)stdio來(lái)解析返回結(jié)果。

    import?subprocess
    subprocess.call(['git',?'status'])

    dulwich

    dulwich是一個(gè)純Python實(shí)現(xiàn)的Git交互庫(kù),以后有空再研究吧。

    官方網(wǎng)站:https://www.dulwich.io/

    pygit2

    pygit2是基于libgit2實(shí)現(xiàn)的一個(gè)Python庫(kù)。底層是C,而上層Python只是接口,運(yùn)行效率應(yīng)該是最高的,然而孤還是放棄了。其缺點(diǎn)是,需要環(huán)境中預(yù)先安裝libgit2。相比之下,GitPython只需要環(huán)境預(yù)置Git,簡(jiǎn)單多了。

    官方網(wǎng)站:http://www.pygit2.org/

    4. 參考閱讀

    • 《GitPython Documentation》

    • 《Welcome to GitDB’s documentation!》

    • 《Git - 底層命令 (Plumbing) 和高層命令 (Porcelain)》

    • 《GitPython | Hom》


    瀏覽 74
    點(diǎn)贊
    評(píng)論
    收藏
    分享

    手機(jī)掃一掃分享

    分享
    舉報(bào)
    評(píng)論
    圖片
    表情
    推薦
    點(diǎn)贊
    評(píng)論
    收藏
    分享

    手機(jī)掃一掃分享

    分享
    舉報(bào)

    <kbd id="5sdj3"></kbd>
    <th id="5sdj3"></th>

  • <dd id="5sdj3"><form id="5sdj3"></form></dd>
    <td id="5sdj3"><form id="5sdj3"><big id="5sdj3"></big></form></td><del id="5sdj3"></del>

  • <dd id="5sdj3"></dd>
    <dfn id="5sdj3"></dfn>
  • <th id="5sdj3"></th>
    <tfoot id="5sdj3"><menuitem id="5sdj3"></menuitem></tfoot>

  • <td id="5sdj3"><form id="5sdj3"><menu id="5sdj3"></menu></form></td>
  • <kbd id="5sdj3"><form id="5sdj3"></form></kbd>
    国精品无码一区二区三区在线 | 午夜成人无码免费视频 | 国产一级片电影免费专区 | 伊人婷婷色 | 8050午夜网站 |