Sometimes , Need to do complicated Git operation , And there's a lot of intermediate logic . use Shell Doing complex logic operation and process control is a disaster . therefore , use Python To realize it is a pleasant choice . At this time , It needs to be in Python In the operation Git The library of .
GitPython brief introduction
GitPython It's a relationship with Git Library interactive Python library , Including the underlying commands (Plumbing) With high-level orders (Porcelain). It can achieve the vast majority of Git Read and write operations , Avoid frequent contact with Shell Interactive malformed code . It is not a pure Python Realization , It is partly dependent on direct execution git command , The other part depends on GitDB.
GitDB Also a Python library . It's for .git/objects A database model is established , You can read and write directly . Due to the use of streaming (stream) Reading and writing , So it runs efficiently 、 Low memory usage .
GitPython install pip install GitPython
It depends on GitDB It will be installed automatically , But executable git Command requires additional installation .
Basic usage
init
import git
repo = git.Repo.init(path='.')
This creates a in the current directory Git library . Of course , The path can be customized .
because git.Repo Realized __enter__ And __exit__, So you can with A combination of .
with git.Repo.init(path='.') as repo:
# do sth with repo
however , Because only some cleaning operations are implemented , You can still read and write after closing , So it is not necessary to use this form . See Appendix for details .
clone
clone There are two kinds . First, from the current database clone To another location :
new_repo = repo.clone(path='../new')
Second, from a certain URL Where? clone To a local location :
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 The original version is not implemented git status, It gives some information .
>>> 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( Clean up all changes )
>>> repo.is_dirty()
True
>>> repo.index.checkout(force=True)
<generator object <genexpr> at 0x7f2bf35e6b40>
>>> repo.is_dirty()
False
branch
Get the current branch :
head = repo.head
The new branch :
new_head = repo.create_head('new_head', 'HEAD^')
Switch branches :
new_head.checkout()
head.checkout()
Delete the branch :
git.Head.delete(repo, new_head)
# or
git.Head.delete(repo, 'new_head')
merge
The following shows how to do this in a branch (other),merge The other branch (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
establish remote:
remote = repo.create_remote(name='gitlab', url='[email protected]:USER/REPO.git')
Remote interactive operation :
remote = repo.remote()
remote.fetch()
remote.pull()
remote.push()
Delete remote:
repo.delete_remote(remote)
# or
repo.delete_remote('gitlab')
Other
There are other Tag、Submodule And so on , Not very often , I won't introduce it here .
GitPython Its advantage is that internal information can be easily obtained when reading , The disadvantage is that it is not easy to write , attempt an ineffective solution . Of course , It also supports direct execution git operation .
git = repo.git
git.status()
git.checkout('HEAD', b="my_new_branch")
git.branch('another-new-one')
git.branch('-D', 'another-new-one')
this …… I feel like I am back to the old way , And still feel weird .
Other operating Git Methods
subprocess
That's what's called 『 " 』. In another process , perform Shell command , And pass stdio To parse the returned results .
import subprocess
subprocess.call(['git', 'status'])
dulwich
dulwich It's pure. Python Realized Git Interactive Library , I will study it later when I have time .
Official website :www.dulwich.io/
pygit2
pygit2 Is based on libgit2 The realization of a Python library . The bottom is C, And the top Python Just the interface , The operation efficiency should be the highest , However, Gu still gave up . The drawback is that , Pre installation in the environment is required libgit2. by comparison ,GitPython Just the environment presets Git, Much simpler .
Official website :www.pygit2.org/
The above is all the content shared this time , Want to know more python Welcome to official account :Python Programming learning circle , send out “J” Free access to , Daily dry goods sharing