A Python interface to the Git command line.
Project description
Git-Adapter: A Python interface to the Git command line.
[[TOC]]
Overview
Git-Adapter provides Python bindings to the Git command line (and also to other command-line applications). It is useful when you know exactly what Git commands you would call from the shell prompt or in a shell script.
Calling a git
command returns a str
generator representing the lines
of output.
Note that in git
commands and command-line flags, hyphens are replaced
by underscores.
Also, Python reserved keywords have to be escaped with a trailing
underscore.
E.g.
git.cherry_pick(commit)
for line in git.grep("keyword", ignore_case=True, break_=True):
print(line)
corresponds to
git cherry-pick $commit
git grep --ignore-case --break keyword
in the shell.
Example
git = Git.clone_repo("git@git.host:test-repo")
log_lines = git.log(first_parent=True, max_count=20, author="me")
# do something with the log_lines generator …
for file_ in git.ls_files():
print("Git file: " + file_)
with open("greeting.txt", "w") as fh:
fh.write("Hello world\n")
git.commit("greeting.txt", m="Greet the world.", author="me")
origin = git.remote().first_line()
branch = git.current_branch()
git.push(origin, branch)
The Git
class
The Git class has a few specific commands, like git.hard_reset()
or
git.current_branch()
; any other method call 'git.<CMD>(…)
' is converted
to a system call 'git CMD …
', e.g.
from git_adapter.git import Git
git = Git(".")
git.log() ↦ git log
git.ls_files() ↦ git ls-files
git.commit(m="T'was brillig.", author="me")
↦ git commit -m "T'was brillig." --author=me
git.log(first_parent=True, max_count=20, author="me")
↦ git log --first-parent --max-count=20 --author=me
git.worktree.add(PATH, BRANCH)
↦ git worktree add PATH BRANCH
Calling a git command returns a generator of str
representing the lines of
output from the command:
files = list(git.ls_files())
To retrieve just the first line of output, the generator has an extra
method first_line()
:
head = git.rev_parse("HEAD").first_line()
Note that in the command name and in the kwargs
, underscores are mapped to
hyphens, so there currently is no way to call
git strange_command --strange_option
, because git_adapter would try to
call git strange-command --strange-option
instead.
The Command
class
The Command
class can be used pretty much like Git
for other shell
commands:
Command(["ls"])("-l") ↦ run 'ls -l'
ip = Command(["ip"])
ip.address.show() ↦ ip address show
ip.address.show("dev", "lo") ↦ ip address show dev lo
ip.address.show.dev("lo") ↦ ditto
ip.address.show.dev.lo() ↦ ditto
Command(["git"]).log() ↦ run 'git log'
Again, the result is a generator of str
representing the lines ouf
output from the command.
Logging
When using Git-Adapter from long-running scripts, the user may want to
get output from commands without long delays, but also all output being
logged to a file.
This can be achieved with the FileLogger
class in Git-Adapter:
from git_adapter.git import Git, FileLogger, run_cmd
# Run a long-running shell command, refreshing output each time a line is
# printed:
run_cmd(
["sh", "-c", "for i in $(seq 5); do echo $i; sleep 1; done"],
verbose=True
)
# The same, but also log to a file:
run_cmd(
["sh", "-c", "for i in $(seq 5); do echo $i; sleep 1; done"],
logger=FileLogger(log_dir=".", log_file="cmd.log")
)
# Run a long-running git command, refreshing output each time a line is
# printed:
git = Git(".", verbose=True)
import time, sys
for ref in git.ls_remote():
time.sleep(0.01)
print(".", end="")
sys.stdout.flush()
print()
# The same, but also log to a file:
git = Git(".", FileLogger(log_dir=".", log_file="git.log"))
import time, sys
for ref in git.ls_remote():
time.sleep(0.01)
print(".", end="")
sys.stdout.flush()
print()
If you cannot open the log file when you create the Git
object (e.g.
because you want to log to the directory that git clone
will create), you
can use the set_logger()
method later:
sandbox = "./sandbox"
git = Git.clone_repo(repository_url, sandbox=sandbox)
git.set_logger(FileLogger(sandbox, "git.log"))
Alternatives
There are a number of ways to run git
commands directly from Python:
- Using
subprocess
:
import subprocess
subprocess.check_call(["git", "rev-parse", "HEAD"])
subprocess.check_call(["git", "ls-files"])
-
Using GitPython:
from git import Repo git = Repo(".").git git.rev_parse('HEAD') git.ls_files()
-
Using sh (as recommended in this post):
import sh git = sh.git print(git("rev-parse", "HEAD")) print(git("ls-files"))
Git-Adapter differs from these solutions in
- Output handling
- Logging
Requirements
Git-Adapter currently requires Python 3.6.9 or later.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Hashes for git_adapter-0.2.4-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 3dea6647c797777e097385b5817cf36e0897f4191e35e4afb6a24cf12cf2a28c |
|
MD5 | 5ea377df694dc9620f93ecdfe0c4e288 |
|
BLAKE2b-256 | 997ae1d1e10c5079ac34df7feb55dfb67084e96d0e461eb3a705d321274c74ba |