fastgit 0.1.2__tar.gz → 0.1.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {fastgit-0.1.2/fastgit.egg-info → fastgit-0.1.4}/PKG-INFO +13 -7
- fastgit-0.1.4/README.md +90 -0
- fastgit-0.1.4/fastgit/__init__.py +9 -0
- {fastgit-0.1.2 → fastgit-0.1.4}/fastgit/_modidx.py +4 -0
- {fastgit-0.1.2 → fastgit-0.1.4}/fastgit/core.py +70 -27
- {fastgit-0.1.2 → fastgit-0.1.4/fastgit.egg-info}/PKG-INFO +13 -7
- {fastgit-0.1.2 → fastgit-0.1.4}/fastgit.egg-info/SOURCES.txt +0 -1
- fastgit-0.1.2/MANIFEST.in +0 -5
- fastgit-0.1.2/README.md +0 -84
- fastgit-0.1.2/fastgit/__init__.py +0 -9
- {fastgit-0.1.2 → fastgit-0.1.4}/LICENSE +0 -0
- {fastgit-0.1.2 → fastgit-0.1.4}/fastgit.egg-info/dependency_links.txt +0 -0
- {fastgit-0.1.2 → fastgit-0.1.4}/fastgit.egg-info/entry_points.txt +0 -0
- {fastgit-0.1.2 → fastgit-0.1.4}/fastgit.egg-info/requires.txt +0 -0
- {fastgit-0.1.2 → fastgit-0.1.4}/fastgit.egg-info/top_level.txt +0 -0
- {fastgit-0.1.2 → fastgit-0.1.4}/pyproject.toml +0 -0
- {fastgit-0.1.2 → fastgit-0.1.4}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fastgit
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.4
|
|
4
4
|
Summary: Use git from python, fast
|
|
5
5
|
Author-email: Jeremy Howard <github@jhoward.fastmail.fm>
|
|
6
6
|
License: Apache-2.0
|
|
@@ -23,9 +23,9 @@ Dynamic: license-file
|
|
|
23
23
|
|
|
24
24
|
<!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->
|
|
25
25
|
|
|
26
|
-
`fastgit` is a
|
|
26
|
+
`fastgit` is a Python wrapper for the `git` command line, for use in scripts and interactive sessions. You call git subcommands as Python methods and pass options as keyword arguments.
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
Commands run through the installed `git` executable and return its text output. There is no separate object model for repositories and commits. Both synchronous and asynchronous clients are available.
|
|
29
29
|
|
|
30
30
|
## Usage
|
|
31
31
|
|
|
@@ -39,7 +39,7 @@ $ pip install fastgit
|
|
|
39
39
|
|
|
40
40
|
### How to use
|
|
41
41
|
|
|
42
|
-
Create a [`Git`](https://AnswerDotAI.github.io/fastgit/core.html#git) for
|
|
42
|
+
Create a [`Git`](https://AnswerDotAI.github.io/fastgit/core.html#git) object for the directory you want to work in. Every command runs in that directory. The default local runner expands `~` and resolves relative paths. A custom `runner` receives the supplied directory unchanged. Results have leading and trailing whitespace stripped:
|
|
43
43
|
|
|
44
44
|
``` python
|
|
45
45
|
import shutil, tempfile
|
|
@@ -61,7 +61,11 @@ g.commit(m='add .gitignore')
|
|
|
61
61
|
|
|
62
62
|
'[main (root-commit) 5113ce1] add .gitignore\n 1 file changed, 1 insertion(+)\n create mode 100644 .gitignore'
|
|
63
63
|
|
|
64
|
-
Keyword arguments become
|
|
64
|
+
Keyword arguments become command-line options:
|
|
65
|
+
|
|
66
|
+
- Single-letter names produce short options, such as `n=1` for `-n 1`.
|
|
67
|
+
- Longer names produce long options, with underscores replaced by dashes.
|
|
68
|
+
- A value of `True` passes the flag without a value.
|
|
65
69
|
|
|
66
70
|
``` python
|
|
67
71
|
g.log(n=1, oneline=True)
|
|
@@ -85,7 +89,9 @@ g.current_branch, g.commits
|
|
|
85
89
|
|
|
86
90
|
('main', ['5113ce1 add .gitignore'])
|
|
87
91
|
|
|
88
|
-
A failed command prints git’s message and returns `None
|
|
92
|
+
Command output is returned in a `str` subclass with the exit code in `.returncode`. A failed command prints git’s message and returns `None`. Pass `raise_exc=True` to raise an exception instead. You can set this per call or when creating the client.
|
|
93
|
+
|
|
94
|
+
Some git commands use exit code 1 for a negative result. For example, `grep` returns 1 when nothing matches. fastgit returns the output for these results without treating them as failures:
|
|
89
95
|
|
|
90
96
|
``` python
|
|
91
97
|
res = g.grep('missing')
|
|
@@ -94,7 +100,7 @@ res.returncode
|
|
|
94
100
|
|
|
95
101
|
1
|
|
96
102
|
|
|
97
|
-
Pass `sync=False` for an async client
|
|
103
|
+
Pass `sync=False` for an async client. Its commands and properties return awaitables. Waiting for git does not block the event loop:
|
|
98
104
|
|
|
99
105
|
``` python
|
|
100
106
|
ag = Git(td, sync=False)
|
fastgit-0.1.4/README.md
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# fastgit
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
<!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->
|
|
5
|
+
|
|
6
|
+
`fastgit` is a Python wrapper for the `git` command line, for use in scripts and interactive sessions. You call git subcommands as Python methods and pass options as keyword arguments.
|
|
7
|
+
|
|
8
|
+
Commands run through the installed `git` executable and return its text output. There is no separate object model for repositories and commits. Both synchronous and asynchronous clients are available.
|
|
9
|
+
|
|
10
|
+
## Usage
|
|
11
|
+
|
|
12
|
+
### Installation
|
|
13
|
+
|
|
14
|
+
Install latest from [pypi](https://pypi.org/project/fastgit/)
|
|
15
|
+
|
|
16
|
+
``` sh
|
|
17
|
+
$ pip install fastgit
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
### How to use
|
|
21
|
+
|
|
22
|
+
Create a [`Git`](https://AnswerDotAI.github.io/fastgit/core.html#git) object for the directory you want to work in. Every command runs in that directory. The default local runner expands `~` and resolves relative paths. A custom `runner` receives the supplied directory unchanged. Results have leading and trailing whitespace stripped:
|
|
23
|
+
|
|
24
|
+
``` python
|
|
25
|
+
import shutil, tempfile
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
``` python
|
|
29
|
+
td = tempfile.mkdtemp()
|
|
30
|
+
g = Git(td)
|
|
31
|
+
g.init(b='main')
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
'Initialized empty Git repository in /private/var/folders/51/b2_szf2945n072c0vj2cyty40000gn/T/tmp8zyj76q7/.git/'
|
|
35
|
+
|
|
36
|
+
``` python
|
|
37
|
+
(g.d/'.gitignore').mk_write('*.bak')
|
|
38
|
+
g.add('.gitignore')
|
|
39
|
+
g.commit(m='add .gitignore')
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
'[main (root-commit) 5113ce1] add .gitignore\n 1 file changed, 1 insertion(+)\n create mode 100644 .gitignore'
|
|
43
|
+
|
|
44
|
+
Keyword arguments become command-line options:
|
|
45
|
+
|
|
46
|
+
- Single-letter names produce short options, such as `n=1` for `-n 1`.
|
|
47
|
+
- Longer names produce long options, with underscores replaced by dashes.
|
|
48
|
+
- A value of `True` passes the flag without a value.
|
|
49
|
+
|
|
50
|
+
``` python
|
|
51
|
+
g.log(n=1, oneline=True)
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
'5113ce1 add .gitignore'
|
|
55
|
+
|
|
56
|
+
You can also pass path arguments after `--` using the `__` parameter:
|
|
57
|
+
|
|
58
|
+
``` python
|
|
59
|
+
g.log('--oneline', __=['.gitignore'])
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
'5113ce1 add .gitignore'
|
|
63
|
+
|
|
64
|
+
Frequent queries are properties:
|
|
65
|
+
|
|
66
|
+
``` python
|
|
67
|
+
g.current_branch, g.commits
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
('main', ['5113ce1 add .gitignore'])
|
|
71
|
+
|
|
72
|
+
Command output is returned in a `str` subclass with the exit code in `.returncode`. A failed command prints git’s message and returns `None`. Pass `raise_exc=True` to raise an exception instead. You can set this per call or when creating the client.
|
|
73
|
+
|
|
74
|
+
Some git commands use exit code 1 for a negative result. For example, `grep` returns 1 when nothing matches. fastgit returns the output for these results without treating them as failures:
|
|
75
|
+
|
|
76
|
+
``` python
|
|
77
|
+
res = g.grep('missing')
|
|
78
|
+
res.returncode
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
1
|
|
82
|
+
|
|
83
|
+
Pass `sync=False` for an async client. Its commands and properties return awaitables. Waiting for git does not block the event loop:
|
|
84
|
+
|
|
85
|
+
``` python
|
|
86
|
+
ag = Git(td, sync=False)
|
|
87
|
+
await ag.last_commit
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
'add .gitignore'
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"""Use git from python, fast
|
|
2
|
+
|
|
3
|
+
`fastgit` is a Python wrapper for the `git` command line, for use in scripts and interactive sessions. You call git subcommands as Python methods and pass options as keyword arguments.
|
|
4
|
+
|
|
5
|
+
Commands run through the installed `git` executable and return its text output. There is no separate object model for repositories and commits. Both synchronous and asynchronous clients are available."""
|
|
6
|
+
|
|
7
|
+
__version__ = "0.1.4"
|
|
8
|
+
|
|
9
|
+
from .core import *
|
|
@@ -20,8 +20,12 @@ d = { 'settings': { 'branch': 'main',
|
|
|
20
20
|
'fastgit.core.Git.top': ('core.html#git.top', 'fastgit/core.py'),
|
|
21
21
|
'fastgit.core.GitRes': ('core.html#gitres', 'fastgit/core.py'),
|
|
22
22
|
'fastgit.core.GitRes.__new__': ('core.html#gitres.__new__', 'fastgit/core.py'),
|
|
23
|
+
'fastgit.core._arunlocal': ('core.html#_arunlocal', 'fastgit/core.py'),
|
|
24
|
+
'fastgit.core._depr_uname': ('core.html#_depr_uname', 'fastgit/core.py'),
|
|
23
25
|
'fastgit.core._gitcmd': ('core.html#_gitcmd', 'fastgit/core.py'),
|
|
24
26
|
'fastgit.core._gitres': ('core.html#_gitres', 'fastgit/core.py'),
|
|
27
|
+
'fastgit.core._longopts': ('core.html#_longopts', 'fastgit/core.py'),
|
|
28
|
+
'fastgit.core._runlocal': ('core.html#_runlocal', 'fastgit/core.py'),
|
|
25
29
|
'fastgit.core.acallgit': ('core.html#acallgit', 'fastgit/core.py'),
|
|
26
30
|
'fastgit.core.callgit': ('core.html#callgit', 'fastgit/core.py'),
|
|
27
31
|
'fastgit.core.get_top': ('core.html#get_top', 'fastgit/core.py')}}}
|
|
@@ -12,6 +12,7 @@ from fastcore.utils import *
|
|
|
12
12
|
from fastcore.aio import then
|
|
13
13
|
import subprocess,asyncio
|
|
14
14
|
from subprocess import CalledProcessError
|
|
15
|
+
from functools import cache
|
|
15
16
|
|
|
16
17
|
# %% ../nbs/00_core.ipynb #880c6a46
|
|
17
18
|
_ok1 = {'merge-tree','merge-base','grep','check-ignore','diff','diff-index','diff-files','diff-tree','show-ref','config','rev-parse'}
|
|
@@ -24,53 +25,83 @@ class GitRes(str):
|
|
|
24
25
|
return self
|
|
25
26
|
|
|
26
27
|
# %% ../nbs/00_core.ipynb #e4c0a290
|
|
27
|
-
def _gitcmd(path, *args,
|
|
28
|
-
assert not (uname and pre), "Pass `uname` or `pre`, not both"
|
|
29
|
-
if uname:
|
|
30
|
-
warn("`uname` is deprecated; pass e.g `pre=['/usr/bin/sudo','-u',uname]` instead", DeprecationWarning, stacklevel=3)
|
|
31
|
-
pre = ['/usr/bin/sudo', '-u', uname]
|
|
28
|
+
def _gitcmd(path, *args, pre=None):
|
|
32
29
|
cmd = ['git', '-C', str(Path(path).expanduser().resolve())] + list(args)
|
|
33
30
|
return [*pre, *cmd] if pre else cmd
|
|
34
31
|
|
|
35
|
-
def
|
|
32
|
+
def _depr_uname(uname, pre):
|
|
33
|
+
assert not (uname and pre), "Pass `uname` or `pre`, not both"
|
|
34
|
+
if not uname: return pre
|
|
35
|
+
warn("`uname` is deprecated; pass e.g `pre=['/usr/bin/sudo','-u',uname]` instead", DeprecationWarning, stacklevel=4)
|
|
36
|
+
return ['/usr/bin/sudo', '-u', uname]
|
|
37
|
+
|
|
38
|
+
def _gitres(args, out, err, returncode, ok_exit):
|
|
36
39
|
if ok_exit is None: ok_exit = 1 if args and args[0] in _ok1 else 0
|
|
37
|
-
if returncode not in (0, *listify(ok_exit)): raise CalledProcessError(returncode,
|
|
40
|
+
if returncode not in (0, *listify(ok_exit)): raise CalledProcessError(returncode, ['git', *args], out, err)
|
|
38
41
|
return GitRes((out + err).strip(), returncode)
|
|
39
42
|
|
|
40
|
-
def
|
|
41
|
-
"
|
|
42
|
-
|
|
43
|
-
r
|
|
44
|
-
|
|
43
|
+
def _runlocal(path, args, pre=None):
|
|
44
|
+
"Default runner: compose the local argv and run it in a subprocess"
|
|
45
|
+
r = subprocess.run(_gitcmd(path, *args, pre=pre), capture_output=True, text=True)
|
|
46
|
+
return r.stdout, r.stderr, r.returncode
|
|
47
|
+
|
|
48
|
+
def callgit(
|
|
49
|
+
path, # Directory to run git in
|
|
50
|
+
*args, # git subcommand and arguments
|
|
51
|
+
uname=None, # Deprecated; use `pre`
|
|
52
|
+
pre=None, # argv prefix, e.g. a sudo wrapper
|
|
53
|
+
ok_exit=None, # Extra accepted exit codes (default: 1 for `_ok1` commands)
|
|
54
|
+
runner=None, # Replaces the local subprocess: `(path, args, pre) -> (stdout, stderr, returncode)`
|
|
55
|
+
):
|
|
56
|
+
"Run git in `path`, returning stripped stdout+stderr as a `GitRes`"
|
|
57
|
+
out,err,rc = (runner or _runlocal)(path, list(args), pre=_depr_uname(uname, pre))
|
|
58
|
+
return _gitres(args, out, err, rc, ok_exit)
|
|
45
59
|
|
|
46
60
|
# %% ../nbs/00_core.ipynb #4c0df6c6
|
|
47
|
-
def get_top(folder):
|
|
48
|
-
try: return callgit(folder, 'rev-parse', '--show-toplevel')
|
|
61
|
+
def get_top(folder, runner=None):
|
|
62
|
+
try: return callgit(folder, 'rev-parse', '--show-toplevel', runner=runner)
|
|
49
63
|
except CalledProcessError: return None
|
|
50
64
|
|
|
65
|
+
# %% ../nbs/00_core.ipynb #2c57b813
|
|
66
|
+
@cache
|
|
67
|
+
def _longopts(cmd):
|
|
68
|
+
"Long options `git <cmd>` lists for completion; empty if unavailable"
|
|
69
|
+
try: r = subprocess.run(['git', cmd, '--git-completion-helper'], capture_output=True, text=True)
|
|
70
|
+
except OSError: return set()
|
|
71
|
+
return {o.rstrip('=') for o in r.stdout.split()} if r.returncode==0 else set()
|
|
72
|
+
|
|
51
73
|
# %% ../nbs/00_core.ipynb #97f78839
|
|
52
74
|
class Git:
|
|
53
75
|
"Run git commands in dir `d`; `sync=False` makes every command return an awaitable"
|
|
54
|
-
def __init__(self, d, pre=None, raise_exc=False, sync=True): self.d,self.pre,self.raise_exc,self._sync = Path(d)
|
|
55
|
-
|
|
56
|
-
def __call__(self,
|
|
76
|
+
def __init__(self, d, pre=None, raise_exc=False, sync=True, runner=None): self.d,self.pre,self.raise_exc,self._sync,self.runner = Path(d),pre,raise_exc,sync,runner
|
|
77
|
+
|
|
78
|
+
def __call__(self,
|
|
79
|
+
cmd, # git subcommand to run
|
|
80
|
+
*args, # Positional arguments for the subcommand
|
|
81
|
+
mute_errors=False, # Suppress the printed ERROR line on failure?
|
|
82
|
+
raise_exc=None, # Raise `CalledProcessError` on failure? (default: `self.raise_exc`)
|
|
83
|
+
ok_exit=None, # Extra accepted exit codes (default: 1 for commands like `diff` where it isn't an error)
|
|
84
|
+
**kwargs # Become flags: short keys as `-k v`, long as `--key=v` (`_` to `-`; `True` bare, `False` dropped); `__` passes paths after `--`
|
|
85
|
+
):
|
|
86
|
+
"Run `git cmd` in `self.d`, returning a `GitRes` (or an awaitable of one when `sync=False`)"
|
|
57
87
|
paths = [str(p) for p in listify(kwargs.pop('__', None) or [])]
|
|
58
88
|
args = listify(args)
|
|
59
89
|
kwargs = {k:v for k,v in kwargs.items() if v is not False}
|
|
60
|
-
|
|
61
|
-
args +=
|
|
62
|
-
args += [f'
|
|
63
|
-
args += [f'--{k.replace("_","-")}' for k,v in kwargs.items() if
|
|
90
|
+
def _short(k): return len(k)==1 or (len(k)<=3 and k.isalnum() and (o:=_longopts(cmd)) and f'--{k}' not in o)
|
|
91
|
+
args += concat((f'-{k}',str(v)) for k,v in kwargs.items() if _short(k) and v is not True)
|
|
92
|
+
args += [f'-{k}' for k,v in kwargs.items() if _short(k) and v is True]
|
|
93
|
+
args += [f'--{k.replace("_","-")}={v}' for k,v in kwargs.items() if not _short(k) and v is not True]
|
|
94
|
+
args += [f'--{k.replace("_","-")}' for k,v in kwargs.items() if not _short(k) and v is True]
|
|
64
95
|
if paths: args += ['--'] + paths
|
|
65
96
|
f = self._run if self._sync else self._arun
|
|
66
97
|
return f(cmd, args, mute_errors, ifnone(raise_exc, self.raise_exc), ok_exit)
|
|
67
98
|
|
|
68
99
|
def _run(self, cmd, args, mute_errors, raise_exc, ok_exit):
|
|
69
|
-
try: return callgit(self.d, cmd, *args, pre=self.pre, ok_exit=ok_exit)
|
|
100
|
+
try: return callgit(self.d, cmd, *args, pre=self.pre, ok_exit=ok_exit, runner=self.runner)
|
|
70
101
|
except CalledProcessError as e: self._err(e, cmd, args, mute_errors, raise_exc)
|
|
71
102
|
|
|
72
103
|
async def _arun(self, cmd, args, mute_errors, raise_exc, ok_exit):
|
|
73
|
-
try: return await acallgit(self.d, cmd, *args, pre=self.pre, ok_exit=ok_exit)
|
|
104
|
+
try: return await acallgit(self.d, cmd, *args, pre=self.pre, ok_exit=ok_exit, runner=self.runner)
|
|
74
105
|
except CalledProcessError as e: self._err(e, cmd, args, mute_errors, raise_exc)
|
|
75
106
|
|
|
76
107
|
def _err(self, e, cmd, args, mute_errors, raise_exc):
|
|
@@ -101,9 +132,21 @@ def commits(self:Git): return then(self.log('--oneline', mute_errors=True, raise
|
|
|
101
132
|
def current_branch(self:Git): return self.branch('--show-current')
|
|
102
133
|
|
|
103
134
|
# %% ../nbs/00_core.ipynb #b69ecf1c
|
|
104
|
-
async def
|
|
105
|
-
"Async `
|
|
106
|
-
cmd = _gitcmd(path, *args,
|
|
135
|
+
async def _arunlocal(path, args, pre=None):
|
|
136
|
+
"Async `_runlocal`"
|
|
137
|
+
cmd = _gitcmd(path, *args, pre=pre)
|
|
107
138
|
p = await asyncio.create_subprocess_exec(*cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
108
139
|
out,err = await p.communicate()
|
|
109
|
-
return
|
|
140
|
+
return out.decode(), err.decode(), p.returncode
|
|
141
|
+
|
|
142
|
+
async def acallgit(
|
|
143
|
+
path, # Directory to run git in
|
|
144
|
+
*args, # git subcommand and arguments
|
|
145
|
+
uname=None, # Deprecated; use `pre`
|
|
146
|
+
pre=None, # argv prefix, e.g. a sudo wrapper
|
|
147
|
+
ok_exit=None, # Extra accepted exit codes (default: 1 for `_ok1` commands)
|
|
148
|
+
runner=None, # Async runner replacing the local subprocess: `async (path, args, pre) -> (stdout, stderr, returncode)`
|
|
149
|
+
):
|
|
150
|
+
"Async `callgit`: identical contract, run in an `asyncio` subprocess"
|
|
151
|
+
out,err,rc = await (runner or _arunlocal)(path, list(args), pre=_depr_uname(uname, pre))
|
|
152
|
+
return _gitres(args, out, err, rc, ok_exit)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fastgit
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.4
|
|
4
4
|
Summary: Use git from python, fast
|
|
5
5
|
Author-email: Jeremy Howard <github@jhoward.fastmail.fm>
|
|
6
6
|
License: Apache-2.0
|
|
@@ -23,9 +23,9 @@ Dynamic: license-file
|
|
|
23
23
|
|
|
24
24
|
<!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->
|
|
25
25
|
|
|
26
|
-
`fastgit` is a
|
|
26
|
+
`fastgit` is a Python wrapper for the `git` command line, for use in scripts and interactive sessions. You call git subcommands as Python methods and pass options as keyword arguments.
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
Commands run through the installed `git` executable and return its text output. There is no separate object model for repositories and commits. Both synchronous and asynchronous clients are available.
|
|
29
29
|
|
|
30
30
|
## Usage
|
|
31
31
|
|
|
@@ -39,7 +39,7 @@ $ pip install fastgit
|
|
|
39
39
|
|
|
40
40
|
### How to use
|
|
41
41
|
|
|
42
|
-
Create a [`Git`](https://AnswerDotAI.github.io/fastgit/core.html#git) for
|
|
42
|
+
Create a [`Git`](https://AnswerDotAI.github.io/fastgit/core.html#git) object for the directory you want to work in. Every command runs in that directory. The default local runner expands `~` and resolves relative paths. A custom `runner` receives the supplied directory unchanged. Results have leading and trailing whitespace stripped:
|
|
43
43
|
|
|
44
44
|
``` python
|
|
45
45
|
import shutil, tempfile
|
|
@@ -61,7 +61,11 @@ g.commit(m='add .gitignore')
|
|
|
61
61
|
|
|
62
62
|
'[main (root-commit) 5113ce1] add .gitignore\n 1 file changed, 1 insertion(+)\n create mode 100644 .gitignore'
|
|
63
63
|
|
|
64
|
-
Keyword arguments become
|
|
64
|
+
Keyword arguments become command-line options:
|
|
65
|
+
|
|
66
|
+
- Single-letter names produce short options, such as `n=1` for `-n 1`.
|
|
67
|
+
- Longer names produce long options, with underscores replaced by dashes.
|
|
68
|
+
- A value of `True` passes the flag without a value.
|
|
65
69
|
|
|
66
70
|
``` python
|
|
67
71
|
g.log(n=1, oneline=True)
|
|
@@ -85,7 +89,9 @@ g.current_branch, g.commits
|
|
|
85
89
|
|
|
86
90
|
('main', ['5113ce1 add .gitignore'])
|
|
87
91
|
|
|
88
|
-
A failed command prints git’s message and returns `None
|
|
92
|
+
Command output is returned in a `str` subclass with the exit code in `.returncode`. A failed command prints git’s message and returns `None`. Pass `raise_exc=True` to raise an exception instead. You can set this per call or when creating the client.
|
|
93
|
+
|
|
94
|
+
Some git commands use exit code 1 for a negative result. For example, `grep` returns 1 when nothing matches. fastgit returns the output for these results without treating them as failures:
|
|
89
95
|
|
|
90
96
|
``` python
|
|
91
97
|
res = g.grep('missing')
|
|
@@ -94,7 +100,7 @@ res.returncode
|
|
|
94
100
|
|
|
95
101
|
1
|
|
96
102
|
|
|
97
|
-
Pass `sync=False` for an async client
|
|
103
|
+
Pass `sync=False` for an async client. Its commands and properties return awaitables. Waiting for git does not block the event loop:
|
|
98
104
|
|
|
99
105
|
``` python
|
|
100
106
|
ag = Git(td, sync=False)
|
fastgit-0.1.2/MANIFEST.in
DELETED
fastgit-0.1.2/README.md
DELETED
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
# fastgit
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
<!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->
|
|
5
|
-
|
|
6
|
-
`fastgit` is a thin Python wrapper for the `git` CLI: one [`Git`](https://AnswerDotAI.github.io/fastgit/core.html#git) object whose attribute calls run git commands, so if you know git, you already know fastgit. There is no reimplementation of git internals and no object model to learn – commands return git’s own output as (subclassed) `str`s.
|
|
7
|
-
|
|
8
|
-
It is designed for interactive use and automation alike: errors print tersely by default (like git itself) or raise on request, exit codes that mean “no” rather than “failed” are returned normally, and passing `sync=False` gives an async client for servers and concurrent code.
|
|
9
|
-
|
|
10
|
-
## Usage
|
|
11
|
-
|
|
12
|
-
### Installation
|
|
13
|
-
|
|
14
|
-
Install latest from [pypi](https://pypi.org/project/fastgit/)
|
|
15
|
-
|
|
16
|
-
``` sh
|
|
17
|
-
$ pip install fastgit
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
### How to use
|
|
21
|
-
|
|
22
|
-
Create a [`Git`](https://AnswerDotAI.github.io/fastgit/core.html#git) for any directory; every command runs with that directory as its working tree. Method names map to git subcommands, and results come back as stripped strings:
|
|
23
|
-
|
|
24
|
-
``` python
|
|
25
|
-
import shutil, tempfile
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
``` python
|
|
29
|
-
td = tempfile.mkdtemp()
|
|
30
|
-
g = Git(td)
|
|
31
|
-
g.init(b='main')
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
'Initialized empty Git repository in /private/var/folders/51/b2_szf2945n072c0vj2cyty40000gn/T/tmp8zyj76q7/.git/'
|
|
35
|
-
|
|
36
|
-
``` python
|
|
37
|
-
(g.d/'.gitignore').mk_write('*.bak')
|
|
38
|
-
g.add('.gitignore')
|
|
39
|
-
g.commit(m='add .gitignore')
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
'[main (root-commit) 5113ce1] add .gitignore\n 1 file changed, 1 insertion(+)\n create mode 100644 .gitignore'
|
|
43
|
-
|
|
44
|
-
Keyword arguments become options: single-letter names are short options (`n=1` → `-n 1`), longer names long options with underscores turned into dashes, and `True` passes the bare flag:
|
|
45
|
-
|
|
46
|
-
``` python
|
|
47
|
-
g.log(n=1, oneline=True)
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
'5113ce1 add .gitignore'
|
|
51
|
-
|
|
52
|
-
You can also pass path arguments after `--` using the `__` parameter:
|
|
53
|
-
|
|
54
|
-
``` python
|
|
55
|
-
g.log('--oneline', __=['.gitignore'])
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
'5113ce1 add .gitignore'
|
|
59
|
-
|
|
60
|
-
Frequent queries are properties:
|
|
61
|
-
|
|
62
|
-
``` python
|
|
63
|
-
g.current_branch, g.commits
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
('main', ['5113ce1 add .gitignore'])
|
|
67
|
-
|
|
68
|
-
A failed command prints git’s message and returns `None`; pass `raise_exc=True` (per call or at init) to raise instead. Where git uses exit 1 to mean “no” rather than “error” – like `grep` finding nothing – the output is returned as usual, with the code on `.returncode`:
|
|
69
|
-
|
|
70
|
-
``` python
|
|
71
|
-
res = g.grep('missing')
|
|
72
|
-
res.returncode
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
1
|
|
76
|
-
|
|
77
|
-
Pass `sync=False` for an async client: the same commands and properties, each returning an awaitable, so a server never blocks its event loop on git:
|
|
78
|
-
|
|
79
|
-
``` python
|
|
80
|
-
ag = Git(td, sync=False)
|
|
81
|
-
await ag.last_commit
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
'add .gitignore'
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
"""Use git from python, fast
|
|
2
|
-
|
|
3
|
-
`fastgit` is a thin Python wrapper for the `git` CLI: one `Git` object whose attribute calls run git commands, so if you know git, you already know fastgit. There is no reimplementation of git internals and no object model to learn -- commands return git's own output as (subclassed) `str`s.
|
|
4
|
-
|
|
5
|
-
It is designed for interactive use and automation alike: errors print tersely by default (like git itself) or raise on request, exit codes that mean "no" rather than "failed" are returned normally, and passing `sync=False` gives an async client for servers and concurrent code."""
|
|
6
|
-
|
|
7
|
-
__version__ = "0.1.2"
|
|
8
|
-
|
|
9
|
-
from .core import *
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|