<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          每天提交Git太煩?直接用Python就好了

          共 3889字,需瀏覽 8分鐘

           ·

          2020-09-02 23:54


          作者:匿蟒

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

          對于協(xié)作開發(fā)的項(xiàng)目,每天開發(fā)前后更新和提交 Git 倉庫是基本操作。但作為總是想偷懶的程序員,一定會想這種重復(fù)操作有沒有可能自動化?如果在控制臺用 Shell 做復(fù)雜的邏輯運(yùn)算與流程控制是一個災(zāi)難。所以,用 Python 來實(shí)現(xiàn)是一個愉快的選擇。這時(shí),就需要在 Python 中操作 Git 的庫。

          0. GitPython 簡介

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

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

          1. GitPython安裝

          pip?install?GitPython

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

          2. 基本用法

          init

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

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

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

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

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

          clone

          clone分兩種。一是從當(dāng)前庫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并未實(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

          以下演示如何在一個分支(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

          創(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í)感覺很不順手,隔靴搔癢。當(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')

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

          3. 其它操作Git的方法

          subprocess

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

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

          dulwich

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

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

          pygit2

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

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

          4. 參考閱讀

          • 《GitPython Documentation》

            http://gitpython.readthedocs.io/en/stable/

          • 《Welcome to GitDB’s documentation!》

            http://gitdb.readthedocs.io/en/latest/

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

            https://git-scm.com/book/zh/v1/Git-%E5%86%85%E9%83%A8%E5%8E%9F%E7%90%86-%E5%BA%95%E5%B1%82%E5%91%BD%E4%BB%A4-Plumbing-%E5%92%8C%E9%AB%98%E5%B1%82%E5%91%BD%E4%BB%A4-Porcelain

          • 《GitPython | Hom》

            http://gohom.win/2016/01/24/gitpython/

          5.?附錄

          git.Repo中對context相關(guān)接口的實(shí)現(xiàn)如下:

              def __enter__(self):
          return self

          def __exit__(self, exc_type, exc_value, traceback):
          self.close()

          def __del__(self):
          try:
          self.close()
          except:
          pass

          def close(self):
          if self.git:
          self.git.clear_cache()
          gc.collect()
          gitdb.util.mman.collect()
          gc.collect()

          可見只是一些清理操作,關(guān)閉的必要性不高。即使關(guān)閉,也仍然可以對這個git.Repo的instance進(jìn)行讀寫操作。


          _往期文章推薦_

          極簡Github上手教程




          瀏覽 55
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

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

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  欧洲操逼视频 | 国产毛片精品一区二区色欲黄A片 | 婷婷丁香色五月 | 大香焦久久| 中文无码视屏 |