gitbetter.gitbetter

  1import os
  2
  3from argshell import ArgShell, Namespace, with_parser
  4from pathier import Pathier
  5
  6from gitbetter import Git, parsers
  7
  8
  9class GitArgShell(ArgShell):
 10    git_header = "Built in Git commands (type '{command} -h' or '{command} --help'):"
 11    convenience_header = "Convenience commands (type 'help {command}'):"
 12
 13    def do_help(self, arg):
 14        """List available commands with "help" or detailed help with "help cmd".
 15        If using 'help cmd' and the cmd is decorated with a parser, the parser help will also be printed."""
 16        if arg:
 17            # XXX check arg syntax
 18            try:
 19                func = getattr(self, "help_" + arg)
 20            except AttributeError:
 21                try:
 22                    func = getattr(self, "do_" + arg)
 23                    doc = func.__doc__
 24                    if doc:
 25                        self.stdout.write("%s\n" % str(doc))
 26                    # =========================Modification start=========================
 27                    # Check for decorator and call decorated function with "--help"
 28                    if hasattr(func, "__wrapped__"):
 29                        self.stdout.write(
 30                            f"Parser help for {func.__name__.replace('do_','')}:\n"
 31                        )
 32                        func("--help")
 33                    if doc or hasattr(func, "__wrapped__"):
 34                        return
 35                    # |=========================Modification stop=========================|
 36                except AttributeError:
 37                    pass
 38                self.stdout.write("%s\n" % str(self.nohelp % (arg,)))
 39                return
 40            func()
 41        else:
 42            names = self.get_names()
 43            cmds_doc = []
 44            cmds_undoc = []
 45            topics = set()
 46            for name in names:
 47                if name[:5] == "help_":
 48                    topics.add(name[5:])
 49            names.sort()
 50            # There can be duplicates if routines overridden
 51            prevname = ""
 52            for name in names:
 53                if name[:3] == "do_":
 54                    if name == prevname:
 55                        continue
 56                    prevname = name
 57                    cmd = name[3:]
 58                    if cmd in topics:
 59                        cmds_doc.append(cmd)
 60                        topics.remove(cmd)
 61                    elif getattr(self, name).__doc__:
 62                        cmds_doc.append(cmd)
 63                    else:
 64                        cmds_undoc.append(cmd)
 65            # |========================Modification Start========================|
 66            content = Pathier(__file__).read_text()
 67            convenience_index = content.rfind("=Convenience=")
 68            git_commands = []
 69            convenience_commands = []
 70            for cmd in cmds_doc:
 71                if content.find(f"do_{cmd}") < convenience_index:
 72                    git_commands.append(cmd)
 73                else:
 74                    convenience_commands.append(cmd)
 75            self.stdout.write("%s\n" % str(self.doc_leader))
 76            self.print_topics(self.git_header, git_commands, 15, 80)
 77            self.print_topics(self.convenience_header, convenience_commands, 15, 80)
 78            # |========================Modification Stop========================|
 79            self.print_topics(self.misc_header, sorted(topics), 15, 80)
 80            self.print_topics(self.undoc_header, cmds_undoc, 15, 80)
 81
 82
 83class GitBetter(GitArgShell):
 84    """GitBetter Shell."""
 85
 86    execute_in_terminal_if_unrecognized = True
 87    git = Git()
 88    intro = "Starting gitbetter...\nEnter 'help' or '?' for command help."
 89    prompt = f"gitbetter::{Pathier.cwd()}>"
 90
 91    @property
 92    def unrecognized_command_behavior_status(self):
 93        return f"Unrecognized command behavior: {('Execute in shell with os.system()' if self.execute_in_terminal_if_unrecognized else 'Print unknown syntax error')}"
 94
 95    def default(self, line: str):
 96        if self.execute_in_terminal_if_unrecognized:
 97            os.system(line)
 98        else:
 99            super().default(line)
100
101    def do_cd(self, path: str):
102        """Change current working directory to `path`."""
103        os.chdir(path)
104        self.prompt = f"gitbetter::{Pathier.cwd()}>"
105
106    def do_help(self, arg: str):
107        """List available commands with "help" or detailed help with "help cmd"."""
108        super().do_help(arg)
109        if not arg:
110            print(self.unrecognized_command_behavior_status)
111            if self.execute_in_terminal_if_unrecognized:
112                print(
113                    "^Essentially makes this shell function as a super-shell of whatever shell you launched gitbetter from.^"
114                )
115        print()
116
117    def do_toggle_unrecognized_command_behavior(self, arg: str):
118        """Toggle whether the shell will attempt to execute unrecognized commands as system commands in the terminal.
119        When on (the default), `GitBetter` will treat unrecognized commands as if you added the `sys` command in front of the input, i.e. `os.system(your_input)`.
120        When off, an `unknown syntax` message will be printed and no commands will be executed.
121        """
122        self.execute_in_terminal_if_unrecognized = (
123            not self.execute_in_terminal_if_unrecognized
124        )
125        print(self.unrecognized_command_behavior_status)
126
127    # Seat |================================================Core================================================|
128
129    def do_git(self, args: str):
130        """Directly execute `git {args}`.
131
132        i.e. You can still do everything directly invoking git can do."""
133        self.git.git(args)
134
135    # Seat
136
137    def do_add(self, args: str):
138        """>>> git add {args}"""
139        self.git.add(args)
140
141    def do_am(self, args: str):
142        """>>> git am {args}"""
143        self.git.am(args)
144
145    def do_annotate(self, args: str):
146        """>>> git annotate {args}"""
147        self.git.annotate(args)
148
149    def do_archive(self, args: str):
150        """>>> git archive {args}"""
151        self.git.archive(args)
152
153    def do_bisect(self, args: str):
154        """>>> git bisect {args}"""
155        self.git.bisect(args)
156
157    def do_blame(self, args: str):
158        """>>> git blame {args}"""
159        self.git.blame(args)
160
161    def do_branch(self, args: str):
162        """>>> git branch {args}"""
163        self.git.branch(args)
164
165    def do_bugreport(self, args: str):
166        """>>> git bugreport {args}"""
167        self.git.bugreport(args)
168
169    def do_bundle(self, args: str):
170        """>>> git bundle {args}"""
171        self.git.bundle(args)
172
173    def do_checkout(self, args: str):
174        """>>> git checkout {args}"""
175        self.git.checkout(args)
176
177    def do_cherry_pick(self, args: str):
178        """>>> git cherry_pick {args}"""
179        self.git.cherry_pick(args)
180
181    def do_citool(self, args: str):
182        """>>> git citool {args}"""
183        self.git.citool(args)
184
185    def do_clean(self, args: str):
186        """>>> git clean {args}"""
187        self.git.clean(args)
188
189    def do_clone(self, args: str):
190        """>>> git clone {args}"""
191        self.git.clone(args)
192
193    def do_commit(self, args: str):
194        """>>> git commit {args}"""
195        self.git.commit(args)
196
197    def do_config(self, args: str):
198        """>>> git config {args}"""
199        self.git.config(args)
200
201    def do_count_objects(self, args: str):
202        """>>> git count_objects {args}"""
203        self.git.count_objects(args)
204
205    def do_describe(self, args: str):
206        """>>> git describe {args}"""
207        self.git.describe(args)
208
209    def do_diagnose(self, args: str):
210        """>>> git diagnose {args}"""
211        self.git.diagnose(args)
212
213    def do_diff(self, args: str):
214        """>>> git diff {args}"""
215        self.git.diff(args)
216
217    def do_difftool(self, args: str):
218        """>>> git difftool {args}"""
219        self.git.difftool(args)
220
221    def do_fast_export(self, args: str):
222        """>>> git fast_export {args}"""
223        self.git.fast_export(args)
224
225    def do_fast_import(self, args: str):
226        """>>> git fast_import {args}"""
227        self.git.fast_import(args)
228
229    def do_fetch(self, args: str):
230        """>>> git fetch {args}"""
231        self.git.fetch(args)
232
233    def do_filter_branch(self, args: str):
234        """>>> git filter_branch {args}"""
235        self.git.filter_branch(args)
236
237    def do_format_patch(self, args: str):
238        """>>> git format_patch {args}"""
239        self.git.format_patch(args)
240
241    def do_fsck(self, args: str):
242        """>>> git fsck {args}"""
243        self.git.fsck(args)
244
245    def do_gc(self, args: str):
246        """>>> git gc {args}"""
247        self.git.gc(args)
248
249    def do_gitk(self, args: str):
250        """>>> git gitk {args}"""
251        self.git.gitk(args)
252
253    def do_gitweb(self, args: str):
254        """>>> git gitweb {args}"""
255        self.git.gitweb(args)
256
257    def do_grep(self, args: str):
258        """>>> git grep {args}"""
259        self.git.grep(args)
260
261    def do_gui(self, args: str):
262        """>>> git gui {args}"""
263        self.git.gui(args)
264
265    def do_init(self, args: str):
266        """>>> git init {args}"""
267        self.git.init(args)
268
269    def do_instaweb(self, args: str):
270        """>>> git instaweb {args}"""
271        self.git.instaweb(args)
272
273    def do_log(self, args: str):
274        """>>> git log {args}"""
275        self.git.log(args)
276
277    def do_maintenance(self, args: str):
278        """>>> git maintenance {args}"""
279        self.git.maintenance(args)
280
281    def do_merge(self, args: str):
282        """>>> git merge {args}"""
283        self.git.merge(args)
284
285    def do_merge_tree(self, args: str):
286        """>>> git merge_tree {args}"""
287        self.git.merge_tree(args)
288
289    def do_mergetool(self, args: str):
290        """>>> git mergetool {args}"""
291        self.git.mergetool(args)
292
293    def do_mv(self, args: str):
294        """>>> git mv {args}"""
295        self.git.mv(args)
296
297    def do_notes(self, args: str):
298        """>>> git notes {args}"""
299        self.git.notes(args)
300
301    def do_pack_refs(self, args: str):
302        """>>> git pack_refs {args}"""
303        self.git.pack_refs(args)
304
305    def do_prune(self, args: str):
306        """>>> git prune {args}"""
307        self.git.prune(args)
308
309    def do_pull(self, args: str):
310        """>>> git pull {args}"""
311        self.git.pull(args)
312
313    def do_push(self, args: str):
314        """>>> git push {args}"""
315        self.git.push(args)
316
317    def do_range_diff(self, args: str):
318        """>>> git range_diff {args}"""
319        self.git.range_diff(args)
320
321    def do_rebase(self, args: str):
322        """>>> git rebase {args}"""
323        self.git.rebase(args)
324
325    def do_reflog(self, args: str):
326        """>>> git reflog {args}"""
327        self.git.reflog(args)
328
329    def do_remote(self, args: str):
330        """>>> git remote {args}"""
331        self.git.remote(args)
332
333    def do_repack(self, args: str):
334        """>>> git repack {args}"""
335        self.git.repack(args)
336
337    def do_replace(self, args: str):
338        """>>> git replace {args}"""
339        self.git.replace(args)
340
341    def do_request_pull(self, args: str):
342        """>>> git request_pull {args}"""
343        self.git.request_pull(args)
344
345    def do_rerere(self, args: str):
346        """>>> git rerere {args}"""
347        self.git.rerere(args)
348
349    def do_reset(self, args: str):
350        """>>> git reset {args}"""
351        self.git.reset(args)
352
353    def do_restore(self, args: str):
354        """>>> git restore {args}"""
355        self.git.restore(args)
356
357    def do_revert(self, args: str):
358        """>>> git revert {args}"""
359        self.git.revert(args)
360
361    def do_rm(self, args: str):
362        """>>> git rm {args}"""
363        self.git.rm(args)
364
365    def do_scalar(self, args: str):
366        """>>> git scalar {args}"""
367        self.git.scalar(args)
368
369    def do_shortlog(self, args: str):
370        """>>> git shortlog {args}"""
371        self.git.shortlog(args)
372
373    def do_show(self, args: str):
374        """>>> git show {args}"""
375        self.git.show(args)
376
377    def do_show_branch(self, args: str):
378        """>>> git show_branch {args}"""
379        self.git.show_branch(args)
380
381    def do_sparse_checkout(self, args: str):
382        """>>> git sparse_checkout {args}"""
383        self.git.sparse_checkout(args)
384
385    def do_stash(self, args: str):
386        """>>> git stash {args}"""
387        self.git.stash(args)
388
389    def do_status(self, args: str):
390        """>>> git status {args}"""
391        self.git.status(args)
392
393    def do_submodule(self, args: str):
394        """>>> git submodule {args}"""
395        self.git.submodule(args)
396
397    def do_switch(self, args: str):
398        """>>> git switch {args}"""
399        self.git.switch(args)
400
401    def do_tag(self, args: str):
402        """>>> git tag {args}"""
403        self.git.tag(args)
404
405    def do_verify_commit(self, args: str):
406        """>>> git verify_commit {args}"""
407        self.git.verify_commit(args)
408
409    def do_verify_tag(self, args: str):
410        """>>> git verify_tag {args}"""
411        self.git.verify_tag(args)
412
413    def do_version(self, args: str):
414        """>>> git version {args}"""
415        self.git.version(args)
416
417    def do_whatchanged(self, args: str):
418        """>>> git whatchanged {args}"""
419        self.git.whatchanged(args)
420
421    def do_worktree(self, args: str):
422        """>>> git worktree {args}"""
423        self.git.worktree(args)
424
425    # Seat |==================================Convenience==================================|
426
427    def do_add_url(self, url: str):
428        """Add remote origin url for repo and push repo.
429        >>> git remote add origin {url}
430        >>> git push -u origin main"""
431        self.git.add_remote_url(url)
432        self.git.push("-u origin main")
433
434    @with_parser(parsers.add_files_parser)
435    def do_amend(self, args: Namespace):
436        """Stage files and add to previous commit."""
437        self.git.amend(args.files)
438
439    def do_branches(self, _: str):
440        """Show local and remote branches.
441        >>> git branch -vva"""
442        self.git.list_branches()
443
444    def do_commitall(self, message: str):
445        """Stage and commit all modified and untracked files with this message.
446        >>> git add .
447        >>> git commit -m \"{message}\" """
448        message = message.strip('"').replace('"', "'")
449        self.git.add_all()
450        self.git.commit(f'-m "{message}"')
451
452    @with_parser(parsers.delete_branch_parser)
453    def do_delete_branch(self, args: Namespace):
454        """Delete branch."""
455        self.git.delete_branch(args.branch, not args.remote)
456
457    def do_delete_gh_repo(self):
458        """Delete this repo from GitHub.
459
460        GitHub CLI must be installed and configured.
461
462        May require you to reauthorize and rerun command."""
463        self.git.delete_remote()
464
465    def do_ignore(self, patterns: str):
466        """Add the list of patterns/file names to `.gitignore` and commit with the message `chore: add to gitignore`."""
467        self.git.ignore(patterns.split())
468        self.git.commit_files([".gitignore"], "chore: add to gitignore")
469
470    @with_parser(parsers.add_files_parser)
471    def do_initcommit(self, args: Namespace):
472        """Stage and commit all files with message "Initial Commit"."""
473        self.git.initcommit(args.files)
474
475    def do_loggy(self, _: str):
476        """>>> git --oneline --name-only --abbrev-commit --graph"""
477        self.git.loggy()
478
479    def do_make_private(self):
480        """Make the GitHub remote for this repo private.
481
482        This repo must exist and GitHub CLI must be installed and configured."""
483        self.git.make_private()
484
485    def do_make_public(self):
486        """Make the GitHub remote for this repo public.
487
488        This repo must exist and GitHub CLI must be installed and configured."""
489        self.git.make_public()
490
491    def do_new_branch(self, name: str):
492        """Create and switch to a new branch with this `name`."""
493        self.git.create_new_branch(name)
494
495    @with_parser(parsers.new_remote_parser)
496    def do_new_gh_remote(self, args: Namespace):
497        """Create a remote GitHub repository for this repo.
498
499        GitHub CLI must be installed and configured for this to work."""
500        self.git.create_remote_from_cwd(args.public)
501
502    def do_new_repo(self, _: str):
503        """Create a new git repo in this directory."""
504        self.git.new_repo()
505
506    def do_push_new(self, _: str):
507        """Push current branch to origin with `-u` flag.
508        >>> git push -u origin {this_branch}"""
509        self.git.push_new_branch(self.git.current_branch)
510
511    def do_undo(self, _: str):
512        """Undo all uncommitted changes.
513        >>> git checkout ."""
514        self.git.undo()
515
516    @with_parser(parsers.add_files_parser)
517    def do_untrack(self, args: Namespace):
518        """Untrack files matching provided path/pattern list.
519
520        For each path/pattern, equivalent to:
521        >>> git rm --cached {path}"""
522        self.git.untrack(*args.files)
523
524
525def main():
526    GitBetter().cmdloop()
527
528
529if __name__ == "__main__":
530    main()
class GitArgShell(argshell.argshell.ArgShell):
10class GitArgShell(ArgShell):
11    git_header = "Built in Git commands (type '{command} -h' or '{command} --help'):"
12    convenience_header = "Convenience commands (type 'help {command}'):"
13
14    def do_help(self, arg):
15        """List available commands with "help" or detailed help with "help cmd".
16        If using 'help cmd' and the cmd is decorated with a parser, the parser help will also be printed."""
17        if arg:
18            # XXX check arg syntax
19            try:
20                func = getattr(self, "help_" + arg)
21            except AttributeError:
22                try:
23                    func = getattr(self, "do_" + arg)
24                    doc = func.__doc__
25                    if doc:
26                        self.stdout.write("%s\n" % str(doc))
27                    # =========================Modification start=========================
28                    # Check for decorator and call decorated function with "--help"
29                    if hasattr(func, "__wrapped__"):
30                        self.stdout.write(
31                            f"Parser help for {func.__name__.replace('do_','')}:\n"
32                        )
33                        func("--help")
34                    if doc or hasattr(func, "__wrapped__"):
35                        return
36                    # |=========================Modification stop=========================|
37                except AttributeError:
38                    pass
39                self.stdout.write("%s\n" % str(self.nohelp % (arg,)))
40                return
41            func()
42        else:
43            names = self.get_names()
44            cmds_doc = []
45            cmds_undoc = []
46            topics = set()
47            for name in names:
48                if name[:5] == "help_":
49                    topics.add(name[5:])
50            names.sort()
51            # There can be duplicates if routines overridden
52            prevname = ""
53            for name in names:
54                if name[:3] == "do_":
55                    if name == prevname:
56                        continue
57                    prevname = name
58                    cmd = name[3:]
59                    if cmd in topics:
60                        cmds_doc.append(cmd)
61                        topics.remove(cmd)
62                    elif getattr(self, name).__doc__:
63                        cmds_doc.append(cmd)
64                    else:
65                        cmds_undoc.append(cmd)
66            # |========================Modification Start========================|
67            content = Pathier(__file__).read_text()
68            convenience_index = content.rfind("=Convenience=")
69            git_commands = []
70            convenience_commands = []
71            for cmd in cmds_doc:
72                if content.find(f"do_{cmd}") < convenience_index:
73                    git_commands.append(cmd)
74                else:
75                    convenience_commands.append(cmd)
76            self.stdout.write("%s\n" % str(self.doc_leader))
77            self.print_topics(self.git_header, git_commands, 15, 80)
78            self.print_topics(self.convenience_header, convenience_commands, 15, 80)
79            # |========================Modification Stop========================|
80            self.print_topics(self.misc_header, sorted(topics), 15, 80)
81            self.print_topics(self.undoc_header, cmds_undoc, 15, 80)

Subclass this to create custom ArgShells.

def do_help(self, arg):
14    def do_help(self, arg):
15        """List available commands with "help" or detailed help with "help cmd".
16        If using 'help cmd' and the cmd is decorated with a parser, the parser help will also be printed."""
17        if arg:
18            # XXX check arg syntax
19            try:
20                func = getattr(self, "help_" + arg)
21            except AttributeError:
22                try:
23                    func = getattr(self, "do_" + arg)
24                    doc = func.__doc__
25                    if doc:
26                        self.stdout.write("%s\n" % str(doc))
27                    # =========================Modification start=========================
28                    # Check for decorator and call decorated function with "--help"
29                    if hasattr(func, "__wrapped__"):
30                        self.stdout.write(
31                            f"Parser help for {func.__name__.replace('do_','')}:\n"
32                        )
33                        func("--help")
34                    if doc or hasattr(func, "__wrapped__"):
35                        return
36                    # |=========================Modification stop=========================|
37                except AttributeError:
38                    pass
39                self.stdout.write("%s\n" % str(self.nohelp % (arg,)))
40                return
41            func()
42        else:
43            names = self.get_names()
44            cmds_doc = []
45            cmds_undoc = []
46            topics = set()
47            for name in names:
48                if name[:5] == "help_":
49                    topics.add(name[5:])
50            names.sort()
51            # There can be duplicates if routines overridden
52            prevname = ""
53            for name in names:
54                if name[:3] == "do_":
55                    if name == prevname:
56                        continue
57                    prevname = name
58                    cmd = name[3:]
59                    if cmd in topics:
60                        cmds_doc.append(cmd)
61                        topics.remove(cmd)
62                    elif getattr(self, name).__doc__:
63                        cmds_doc.append(cmd)
64                    else:
65                        cmds_undoc.append(cmd)
66            # |========================Modification Start========================|
67            content = Pathier(__file__).read_text()
68            convenience_index = content.rfind("=Convenience=")
69            git_commands = []
70            convenience_commands = []
71            for cmd in cmds_doc:
72                if content.find(f"do_{cmd}") < convenience_index:
73                    git_commands.append(cmd)
74                else:
75                    convenience_commands.append(cmd)
76            self.stdout.write("%s\n" % str(self.doc_leader))
77            self.print_topics(self.git_header, git_commands, 15, 80)
78            self.print_topics(self.convenience_header, convenience_commands, 15, 80)
79            # |========================Modification Stop========================|
80            self.print_topics(self.misc_header, sorted(topics), 15, 80)
81            self.print_topics(self.undoc_header, cmds_undoc, 15, 80)

List available commands with "help" or detailed help with "help cmd". If using 'help cmd' and the cmd is decorated with a parser, the parser help will also be printed.

Inherited Members
cmd.Cmd
Cmd
precmd
postcmd
preloop
postloop
parseline
onecmd
default
completedefault
completenames
complete
get_names
complete_help
print_topics
columnize
argshell.argshell.ArgShell
do_quit
do_sys
cmdloop
emptyline
class GitBetter(GitArgShell):
 84class GitBetter(GitArgShell):
 85    """GitBetter Shell."""
 86
 87    execute_in_terminal_if_unrecognized = True
 88    git = Git()
 89    intro = "Starting gitbetter...\nEnter 'help' or '?' for command help."
 90    prompt = f"gitbetter::{Pathier.cwd()}>"
 91
 92    @property
 93    def unrecognized_command_behavior_status(self):
 94        return f"Unrecognized command behavior: {('Execute in shell with os.system()' if self.execute_in_terminal_if_unrecognized else 'Print unknown syntax error')}"
 95
 96    def default(self, line: str):
 97        if self.execute_in_terminal_if_unrecognized:
 98            os.system(line)
 99        else:
100            super().default(line)
101
102    def do_cd(self, path: str):
103        """Change current working directory to `path`."""
104        os.chdir(path)
105        self.prompt = f"gitbetter::{Pathier.cwd()}>"
106
107    def do_help(self, arg: str):
108        """List available commands with "help" or detailed help with "help cmd"."""
109        super().do_help(arg)
110        if not arg:
111            print(self.unrecognized_command_behavior_status)
112            if self.execute_in_terminal_if_unrecognized:
113                print(
114                    "^Essentially makes this shell function as a super-shell of whatever shell you launched gitbetter from.^"
115                )
116        print()
117
118    def do_toggle_unrecognized_command_behavior(self, arg: str):
119        """Toggle whether the shell will attempt to execute unrecognized commands as system commands in the terminal.
120        When on (the default), `GitBetter` will treat unrecognized commands as if you added the `sys` command in front of the input, i.e. `os.system(your_input)`.
121        When off, an `unknown syntax` message will be printed and no commands will be executed.
122        """
123        self.execute_in_terminal_if_unrecognized = (
124            not self.execute_in_terminal_if_unrecognized
125        )
126        print(self.unrecognized_command_behavior_status)
127
128    # Seat |================================================Core================================================|
129
130    def do_git(self, args: str):
131        """Directly execute `git {args}`.
132
133        i.e. You can still do everything directly invoking git can do."""
134        self.git.git(args)
135
136    # Seat
137
138    def do_add(self, args: str):
139        """>>> git add {args}"""
140        self.git.add(args)
141
142    def do_am(self, args: str):
143        """>>> git am {args}"""
144        self.git.am(args)
145
146    def do_annotate(self, args: str):
147        """>>> git annotate {args}"""
148        self.git.annotate(args)
149
150    def do_archive(self, args: str):
151        """>>> git archive {args}"""
152        self.git.archive(args)
153
154    def do_bisect(self, args: str):
155        """>>> git bisect {args}"""
156        self.git.bisect(args)
157
158    def do_blame(self, args: str):
159        """>>> git blame {args}"""
160        self.git.blame(args)
161
162    def do_branch(self, args: str):
163        """>>> git branch {args}"""
164        self.git.branch(args)
165
166    def do_bugreport(self, args: str):
167        """>>> git bugreport {args}"""
168        self.git.bugreport(args)
169
170    def do_bundle(self, args: str):
171        """>>> git bundle {args}"""
172        self.git.bundle(args)
173
174    def do_checkout(self, args: str):
175        """>>> git checkout {args}"""
176        self.git.checkout(args)
177
178    def do_cherry_pick(self, args: str):
179        """>>> git cherry_pick {args}"""
180        self.git.cherry_pick(args)
181
182    def do_citool(self, args: str):
183        """>>> git citool {args}"""
184        self.git.citool(args)
185
186    def do_clean(self, args: str):
187        """>>> git clean {args}"""
188        self.git.clean(args)
189
190    def do_clone(self, args: str):
191        """>>> git clone {args}"""
192        self.git.clone(args)
193
194    def do_commit(self, args: str):
195        """>>> git commit {args}"""
196        self.git.commit(args)
197
198    def do_config(self, args: str):
199        """>>> git config {args}"""
200        self.git.config(args)
201
202    def do_count_objects(self, args: str):
203        """>>> git count_objects {args}"""
204        self.git.count_objects(args)
205
206    def do_describe(self, args: str):
207        """>>> git describe {args}"""
208        self.git.describe(args)
209
210    def do_diagnose(self, args: str):
211        """>>> git diagnose {args}"""
212        self.git.diagnose(args)
213
214    def do_diff(self, args: str):
215        """>>> git diff {args}"""
216        self.git.diff(args)
217
218    def do_difftool(self, args: str):
219        """>>> git difftool {args}"""
220        self.git.difftool(args)
221
222    def do_fast_export(self, args: str):
223        """>>> git fast_export {args}"""
224        self.git.fast_export(args)
225
226    def do_fast_import(self, args: str):
227        """>>> git fast_import {args}"""
228        self.git.fast_import(args)
229
230    def do_fetch(self, args: str):
231        """>>> git fetch {args}"""
232        self.git.fetch(args)
233
234    def do_filter_branch(self, args: str):
235        """>>> git filter_branch {args}"""
236        self.git.filter_branch(args)
237
238    def do_format_patch(self, args: str):
239        """>>> git format_patch {args}"""
240        self.git.format_patch(args)
241
242    def do_fsck(self, args: str):
243        """>>> git fsck {args}"""
244        self.git.fsck(args)
245
246    def do_gc(self, args: str):
247        """>>> git gc {args}"""
248        self.git.gc(args)
249
250    def do_gitk(self, args: str):
251        """>>> git gitk {args}"""
252        self.git.gitk(args)
253
254    def do_gitweb(self, args: str):
255        """>>> git gitweb {args}"""
256        self.git.gitweb(args)
257
258    def do_grep(self, args: str):
259        """>>> git grep {args}"""
260        self.git.grep(args)
261
262    def do_gui(self, args: str):
263        """>>> git gui {args}"""
264        self.git.gui(args)
265
266    def do_init(self, args: str):
267        """>>> git init {args}"""
268        self.git.init(args)
269
270    def do_instaweb(self, args: str):
271        """>>> git instaweb {args}"""
272        self.git.instaweb(args)
273
274    def do_log(self, args: str):
275        """>>> git log {args}"""
276        self.git.log(args)
277
278    def do_maintenance(self, args: str):
279        """>>> git maintenance {args}"""
280        self.git.maintenance(args)
281
282    def do_merge(self, args: str):
283        """>>> git merge {args}"""
284        self.git.merge(args)
285
286    def do_merge_tree(self, args: str):
287        """>>> git merge_tree {args}"""
288        self.git.merge_tree(args)
289
290    def do_mergetool(self, args: str):
291        """>>> git mergetool {args}"""
292        self.git.mergetool(args)
293
294    def do_mv(self, args: str):
295        """>>> git mv {args}"""
296        self.git.mv(args)
297
298    def do_notes(self, args: str):
299        """>>> git notes {args}"""
300        self.git.notes(args)
301
302    def do_pack_refs(self, args: str):
303        """>>> git pack_refs {args}"""
304        self.git.pack_refs(args)
305
306    def do_prune(self, args: str):
307        """>>> git prune {args}"""
308        self.git.prune(args)
309
310    def do_pull(self, args: str):
311        """>>> git pull {args}"""
312        self.git.pull(args)
313
314    def do_push(self, args: str):
315        """>>> git push {args}"""
316        self.git.push(args)
317
318    def do_range_diff(self, args: str):
319        """>>> git range_diff {args}"""
320        self.git.range_diff(args)
321
322    def do_rebase(self, args: str):
323        """>>> git rebase {args}"""
324        self.git.rebase(args)
325
326    def do_reflog(self, args: str):
327        """>>> git reflog {args}"""
328        self.git.reflog(args)
329
330    def do_remote(self, args: str):
331        """>>> git remote {args}"""
332        self.git.remote(args)
333
334    def do_repack(self, args: str):
335        """>>> git repack {args}"""
336        self.git.repack(args)
337
338    def do_replace(self, args: str):
339        """>>> git replace {args}"""
340        self.git.replace(args)
341
342    def do_request_pull(self, args: str):
343        """>>> git request_pull {args}"""
344        self.git.request_pull(args)
345
346    def do_rerere(self, args: str):
347        """>>> git rerere {args}"""
348        self.git.rerere(args)
349
350    def do_reset(self, args: str):
351        """>>> git reset {args}"""
352        self.git.reset(args)
353
354    def do_restore(self, args: str):
355        """>>> git restore {args}"""
356        self.git.restore(args)
357
358    def do_revert(self, args: str):
359        """>>> git revert {args}"""
360        self.git.revert(args)
361
362    def do_rm(self, args: str):
363        """>>> git rm {args}"""
364        self.git.rm(args)
365
366    def do_scalar(self, args: str):
367        """>>> git scalar {args}"""
368        self.git.scalar(args)
369
370    def do_shortlog(self, args: str):
371        """>>> git shortlog {args}"""
372        self.git.shortlog(args)
373
374    def do_show(self, args: str):
375        """>>> git show {args}"""
376        self.git.show(args)
377
378    def do_show_branch(self, args: str):
379        """>>> git show_branch {args}"""
380        self.git.show_branch(args)
381
382    def do_sparse_checkout(self, args: str):
383        """>>> git sparse_checkout {args}"""
384        self.git.sparse_checkout(args)
385
386    def do_stash(self, args: str):
387        """>>> git stash {args}"""
388        self.git.stash(args)
389
390    def do_status(self, args: str):
391        """>>> git status {args}"""
392        self.git.status(args)
393
394    def do_submodule(self, args: str):
395        """>>> git submodule {args}"""
396        self.git.submodule(args)
397
398    def do_switch(self, args: str):
399        """>>> git switch {args}"""
400        self.git.switch(args)
401
402    def do_tag(self, args: str):
403        """>>> git tag {args}"""
404        self.git.tag(args)
405
406    def do_verify_commit(self, args: str):
407        """>>> git verify_commit {args}"""
408        self.git.verify_commit(args)
409
410    def do_verify_tag(self, args: str):
411        """>>> git verify_tag {args}"""
412        self.git.verify_tag(args)
413
414    def do_version(self, args: str):
415        """>>> git version {args}"""
416        self.git.version(args)
417
418    def do_whatchanged(self, args: str):
419        """>>> git whatchanged {args}"""
420        self.git.whatchanged(args)
421
422    def do_worktree(self, args: str):
423        """>>> git worktree {args}"""
424        self.git.worktree(args)
425
426    # Seat |==================================Convenience==================================|
427
428    def do_add_url(self, url: str):
429        """Add remote origin url for repo and push repo.
430        >>> git remote add origin {url}
431        >>> git push -u origin main"""
432        self.git.add_remote_url(url)
433        self.git.push("-u origin main")
434
435    @with_parser(parsers.add_files_parser)
436    def do_amend(self, args: Namespace):
437        """Stage files and add to previous commit."""
438        self.git.amend(args.files)
439
440    def do_branches(self, _: str):
441        """Show local and remote branches.
442        >>> git branch -vva"""
443        self.git.list_branches()
444
445    def do_commitall(self, message: str):
446        """Stage and commit all modified and untracked files with this message.
447        >>> git add .
448        >>> git commit -m \"{message}\" """
449        message = message.strip('"').replace('"', "'")
450        self.git.add_all()
451        self.git.commit(f'-m "{message}"')
452
453    @with_parser(parsers.delete_branch_parser)
454    def do_delete_branch(self, args: Namespace):
455        """Delete branch."""
456        self.git.delete_branch(args.branch, not args.remote)
457
458    def do_delete_gh_repo(self):
459        """Delete this repo from GitHub.
460
461        GitHub CLI must be installed and configured.
462
463        May require you to reauthorize and rerun command."""
464        self.git.delete_remote()
465
466    def do_ignore(self, patterns: str):
467        """Add the list of patterns/file names to `.gitignore` and commit with the message `chore: add to gitignore`."""
468        self.git.ignore(patterns.split())
469        self.git.commit_files([".gitignore"], "chore: add to gitignore")
470
471    @with_parser(parsers.add_files_parser)
472    def do_initcommit(self, args: Namespace):
473        """Stage and commit all files with message "Initial Commit"."""
474        self.git.initcommit(args.files)
475
476    def do_loggy(self, _: str):
477        """>>> git --oneline --name-only --abbrev-commit --graph"""
478        self.git.loggy()
479
480    def do_make_private(self):
481        """Make the GitHub remote for this repo private.
482
483        This repo must exist and GitHub CLI must be installed and configured."""
484        self.git.make_private()
485
486    def do_make_public(self):
487        """Make the GitHub remote for this repo public.
488
489        This repo must exist and GitHub CLI must be installed and configured."""
490        self.git.make_public()
491
492    def do_new_branch(self, name: str):
493        """Create and switch to a new branch with this `name`."""
494        self.git.create_new_branch(name)
495
496    @with_parser(parsers.new_remote_parser)
497    def do_new_gh_remote(self, args: Namespace):
498        """Create a remote GitHub repository for this repo.
499
500        GitHub CLI must be installed and configured for this to work."""
501        self.git.create_remote_from_cwd(args.public)
502
503    def do_new_repo(self, _: str):
504        """Create a new git repo in this directory."""
505        self.git.new_repo()
506
507    def do_push_new(self, _: str):
508        """Push current branch to origin with `-u` flag.
509        >>> git push -u origin {this_branch}"""
510        self.git.push_new_branch(self.git.current_branch)
511
512    def do_undo(self, _: str):
513        """Undo all uncommitted changes.
514        >>> git checkout ."""
515        self.git.undo()
516
517    @with_parser(parsers.add_files_parser)
518    def do_untrack(self, args: Namespace):
519        """Untrack files matching provided path/pattern list.
520
521        For each path/pattern, equivalent to:
522        >>> git rm --cached {path}"""
523        self.git.untrack(*args.files)

GitBetter Shell.

def default(self, line: str):
 96    def default(self, line: str):
 97        if self.execute_in_terminal_if_unrecognized:
 98            os.system(line)
 99        else:
100            super().default(line)

Called on an input line when the command prefix is not recognized.

If this method is not overridden, it prints an error message and returns.

def do_cd(self, path: str):
102    def do_cd(self, path: str):
103        """Change current working directory to `path`."""
104        os.chdir(path)
105        self.prompt = f"gitbetter::{Pathier.cwd()}>"

Change current working directory to path.

def do_help(self, arg: str):
107    def do_help(self, arg: str):
108        """List available commands with "help" or detailed help with "help cmd"."""
109        super().do_help(arg)
110        if not arg:
111            print(self.unrecognized_command_behavior_status)
112            if self.execute_in_terminal_if_unrecognized:
113                print(
114                    "^Essentially makes this shell function as a super-shell of whatever shell you launched gitbetter from.^"
115                )
116        print()

List available commands with "help" or detailed help with "help cmd".

def do_toggle_unrecognized_command_behavior(self, arg: str):
118    def do_toggle_unrecognized_command_behavior(self, arg: str):
119        """Toggle whether the shell will attempt to execute unrecognized commands as system commands in the terminal.
120        When on (the default), `GitBetter` will treat unrecognized commands as if you added the `sys` command in front of the input, i.e. `os.system(your_input)`.
121        When off, an `unknown syntax` message will be printed and no commands will be executed.
122        """
123        self.execute_in_terminal_if_unrecognized = (
124            not self.execute_in_terminal_if_unrecognized
125        )
126        print(self.unrecognized_command_behavior_status)

Toggle whether the shell will attempt to execute unrecognized commands as system commands in the terminal. When on (the default), GitBetter will treat unrecognized commands as if you added the sys command in front of the input, i.e. os.system(your_input). When off, an unknown syntax message will be printed and no commands will be executed.

def do_git(self, args: str):
130    def do_git(self, args: str):
131        """Directly execute `git {args}`.
132
133        i.e. You can still do everything directly invoking git can do."""
134        self.git.git(args)

Directly execute git {args}.

i.e. You can still do everything directly invoking git can do.

def do_add(self, args: str):
138    def do_add(self, args: str):
139        """>>> git add {args}"""
140        self.git.add(args)
>>> git add {args}
def do_am(self, args: str):
142    def do_am(self, args: str):
143        """>>> git am {args}"""
144        self.git.am(args)
>>> git am {args}
def do_annotate(self, args: str):
146    def do_annotate(self, args: str):
147        """>>> git annotate {args}"""
148        self.git.annotate(args)
>>> git annotate {args}
def do_archive(self, args: str):
150    def do_archive(self, args: str):
151        """>>> git archive {args}"""
152        self.git.archive(args)
>>> git archive {args}
def do_bisect(self, args: str):
154    def do_bisect(self, args: str):
155        """>>> git bisect {args}"""
156        self.git.bisect(args)
>>> git bisect {args}
def do_blame(self, args: str):
158    def do_blame(self, args: str):
159        """>>> git blame {args}"""
160        self.git.blame(args)
>>> git blame {args}
def do_branch(self, args: str):
162    def do_branch(self, args: str):
163        """>>> git branch {args}"""
164        self.git.branch(args)
>>> git branch {args}
def do_bugreport(self, args: str):
166    def do_bugreport(self, args: str):
167        """>>> git bugreport {args}"""
168        self.git.bugreport(args)
>>> git bugreport {args}
def do_bundle(self, args: str):
170    def do_bundle(self, args: str):
171        """>>> git bundle {args}"""
172        self.git.bundle(args)
>>> git bundle {args}
def do_checkout(self, args: str):
174    def do_checkout(self, args: str):
175        """>>> git checkout {args}"""
176        self.git.checkout(args)
>>> git checkout {args}
def do_cherry_pick(self, args: str):
178    def do_cherry_pick(self, args: str):
179        """>>> git cherry_pick {args}"""
180        self.git.cherry_pick(args)
>>> git cherry_pick {args}
def do_citool(self, args: str):
182    def do_citool(self, args: str):
183        """>>> git citool {args}"""
184        self.git.citool(args)
>>> git citool {args}
def do_clean(self, args: str):
186    def do_clean(self, args: str):
187        """>>> git clean {args}"""
188        self.git.clean(args)
>>> git clean {args}
def do_clone(self, args: str):
190    def do_clone(self, args: str):
191        """>>> git clone {args}"""
192        self.git.clone(args)
>>> git clone {args}
def do_commit(self, args: str):
194    def do_commit(self, args: str):
195        """>>> git commit {args}"""
196        self.git.commit(args)
>>> git commit {args}
def do_config(self, args: str):
198    def do_config(self, args: str):
199        """>>> git config {args}"""
200        self.git.config(args)
>>> git config {args}
def do_count_objects(self, args: str):
202    def do_count_objects(self, args: str):
203        """>>> git count_objects {args}"""
204        self.git.count_objects(args)
>>> git count_objects {args}
def do_describe(self, args: str):
206    def do_describe(self, args: str):
207        """>>> git describe {args}"""
208        self.git.describe(args)
>>> git describe {args}
def do_diagnose(self, args: str):
210    def do_diagnose(self, args: str):
211        """>>> git diagnose {args}"""
212        self.git.diagnose(args)
>>> git diagnose {args}
def do_diff(self, args: str):
214    def do_diff(self, args: str):
215        """>>> git diff {args}"""
216        self.git.diff(args)
>>> git diff {args}
def do_difftool(self, args: str):
218    def do_difftool(self, args: str):
219        """>>> git difftool {args}"""
220        self.git.difftool(args)
>>> git difftool {args}
def do_fast_export(self, args: str):
222    def do_fast_export(self, args: str):
223        """>>> git fast_export {args}"""
224        self.git.fast_export(args)
>>> git fast_export {args}
def do_fast_import(self, args: str):
226    def do_fast_import(self, args: str):
227        """>>> git fast_import {args}"""
228        self.git.fast_import(args)
>>> git fast_import {args}
def do_fetch(self, args: str):
230    def do_fetch(self, args: str):
231        """>>> git fetch {args}"""
232        self.git.fetch(args)
>>> git fetch {args}
def do_filter_branch(self, args: str):
234    def do_filter_branch(self, args: str):
235        """>>> git filter_branch {args}"""
236        self.git.filter_branch(args)
>>> git filter_branch {args}
def do_format_patch(self, args: str):
238    def do_format_patch(self, args: str):
239        """>>> git format_patch {args}"""
240        self.git.format_patch(args)
>>> git format_patch {args}
def do_fsck(self, args: str):
242    def do_fsck(self, args: str):
243        """>>> git fsck {args}"""
244        self.git.fsck(args)
>>> git fsck {args}
def do_gc(self, args: str):
246    def do_gc(self, args: str):
247        """>>> git gc {args}"""
248        self.git.gc(args)
>>> git gc {args}
def do_gitk(self, args: str):
250    def do_gitk(self, args: str):
251        """>>> git gitk {args}"""
252        self.git.gitk(args)
>>> git gitk {args}
def do_gitweb(self, args: str):
254    def do_gitweb(self, args: str):
255        """>>> git gitweb {args}"""
256        self.git.gitweb(args)
>>> git gitweb {args}
def do_grep(self, args: str):
258    def do_grep(self, args: str):
259        """>>> git grep {args}"""
260        self.git.grep(args)
>>> git grep {args}
def do_gui(self, args: str):
262    def do_gui(self, args: str):
263        """>>> git gui {args}"""
264        self.git.gui(args)
>>> git gui {args}
def do_init(self, args: str):
266    def do_init(self, args: str):
267        """>>> git init {args}"""
268        self.git.init(args)
>>> git init {args}
def do_instaweb(self, args: str):
270    def do_instaweb(self, args: str):
271        """>>> git instaweb {args}"""
272        self.git.instaweb(args)
>>> git instaweb {args}
def do_log(self, args: str):
274    def do_log(self, args: str):
275        """>>> git log {args}"""
276        self.git.log(args)
>>> git log {args}
def do_maintenance(self, args: str):
278    def do_maintenance(self, args: str):
279        """>>> git maintenance {args}"""
280        self.git.maintenance(args)
>>> git maintenance {args}
def do_merge(self, args: str):
282    def do_merge(self, args: str):
283        """>>> git merge {args}"""
284        self.git.merge(args)
>>> git merge {args}
def do_merge_tree(self, args: str):
286    def do_merge_tree(self, args: str):
287        """>>> git merge_tree {args}"""
288        self.git.merge_tree(args)
>>> git merge_tree {args}
def do_mergetool(self, args: str):
290    def do_mergetool(self, args: str):
291        """>>> git mergetool {args}"""
292        self.git.mergetool(args)
>>> git mergetool {args}
def do_mv(self, args: str):
294    def do_mv(self, args: str):
295        """>>> git mv {args}"""
296        self.git.mv(args)
>>> git mv {args}
def do_notes(self, args: str):
298    def do_notes(self, args: str):
299        """>>> git notes {args}"""
300        self.git.notes(args)
>>> git notes {args}
def do_pack_refs(self, args: str):
302    def do_pack_refs(self, args: str):
303        """>>> git pack_refs {args}"""
304        self.git.pack_refs(args)
>>> git pack_refs {args}
def do_prune(self, args: str):
306    def do_prune(self, args: str):
307        """>>> git prune {args}"""
308        self.git.prune(args)
>>> git prune {args}
def do_pull(self, args: str):
310    def do_pull(self, args: str):
311        """>>> git pull {args}"""
312        self.git.pull(args)
>>> git pull {args}
def do_push(self, args: str):
314    def do_push(self, args: str):
315        """>>> git push {args}"""
316        self.git.push(args)
>>> git push {args}
def do_range_diff(self, args: str):
318    def do_range_diff(self, args: str):
319        """>>> git range_diff {args}"""
320        self.git.range_diff(args)
>>> git range_diff {args}
def do_rebase(self, args: str):
322    def do_rebase(self, args: str):
323        """>>> git rebase {args}"""
324        self.git.rebase(args)
>>> git rebase {args}
def do_reflog(self, args: str):
326    def do_reflog(self, args: str):
327        """>>> git reflog {args}"""
328        self.git.reflog(args)
>>> git reflog {args}
def do_remote(self, args: str):
330    def do_remote(self, args: str):
331        """>>> git remote {args}"""
332        self.git.remote(args)
>>> git remote {args}
def do_repack(self, args: str):
334    def do_repack(self, args: str):
335        """>>> git repack {args}"""
336        self.git.repack(args)
>>> git repack {args}
def do_replace(self, args: str):
338    def do_replace(self, args: str):
339        """>>> git replace {args}"""
340        self.git.replace(args)
>>> git replace {args}
def do_request_pull(self, args: str):
342    def do_request_pull(self, args: str):
343        """>>> git request_pull {args}"""
344        self.git.request_pull(args)
>>> git request_pull {args}
def do_rerere(self, args: str):
346    def do_rerere(self, args: str):
347        """>>> git rerere {args}"""
348        self.git.rerere(args)
>>> git rerere {args}
def do_reset(self, args: str):
350    def do_reset(self, args: str):
351        """>>> git reset {args}"""
352        self.git.reset(args)
>>> git reset {args}
def do_restore(self, args: str):
354    def do_restore(self, args: str):
355        """>>> git restore {args}"""
356        self.git.restore(args)
>>> git restore {args}
def do_revert(self, args: str):
358    def do_revert(self, args: str):
359        """>>> git revert {args}"""
360        self.git.revert(args)
>>> git revert {args}
def do_rm(self, args: str):
362    def do_rm(self, args: str):
363        """>>> git rm {args}"""
364        self.git.rm(args)
>>> git rm {args}
def do_scalar(self, args: str):
366    def do_scalar(self, args: str):
367        """>>> git scalar {args}"""
368        self.git.scalar(args)
>>> git scalar {args}
def do_shortlog(self, args: str):
370    def do_shortlog(self, args: str):
371        """>>> git shortlog {args}"""
372        self.git.shortlog(args)
>>> git shortlog {args}
def do_show(self, args: str):
374    def do_show(self, args: str):
375        """>>> git show {args}"""
376        self.git.show(args)
>>> git show {args}
def do_show_branch(self, args: str):
378    def do_show_branch(self, args: str):
379        """>>> git show_branch {args}"""
380        self.git.show_branch(args)
>>> git show_branch {args}
def do_sparse_checkout(self, args: str):
382    def do_sparse_checkout(self, args: str):
383        """>>> git sparse_checkout {args}"""
384        self.git.sparse_checkout(args)
>>> git sparse_checkout {args}
def do_stash(self, args: str):
386    def do_stash(self, args: str):
387        """>>> git stash {args}"""
388        self.git.stash(args)
>>> git stash {args}
def do_status(self, args: str):
390    def do_status(self, args: str):
391        """>>> git status {args}"""
392        self.git.status(args)
>>> git status {args}
def do_submodule(self, args: str):
394    def do_submodule(self, args: str):
395        """>>> git submodule {args}"""
396        self.git.submodule(args)
>>> git submodule {args}
def do_switch(self, args: str):
398    def do_switch(self, args: str):
399        """>>> git switch {args}"""
400        self.git.switch(args)
>>> git switch {args}
def do_tag(self, args: str):
402    def do_tag(self, args: str):
403        """>>> git tag {args}"""
404        self.git.tag(args)
>>> git tag {args}
def do_verify_commit(self, args: str):
406    def do_verify_commit(self, args: str):
407        """>>> git verify_commit {args}"""
408        self.git.verify_commit(args)
>>> git verify_commit {args}
def do_verify_tag(self, args: str):
410    def do_verify_tag(self, args: str):
411        """>>> git verify_tag {args}"""
412        self.git.verify_tag(args)
>>> git verify_tag {args}
def do_version(self, args: str):
414    def do_version(self, args: str):
415        """>>> git version {args}"""
416        self.git.version(args)
>>> git version {args}
def do_whatchanged(self, args: str):
418    def do_whatchanged(self, args: str):
419        """>>> git whatchanged {args}"""
420        self.git.whatchanged(args)
>>> git whatchanged {args}
def do_worktree(self, args: str):
422    def do_worktree(self, args: str):
423        """>>> git worktree {args}"""
424        self.git.worktree(args)
>>> git worktree {args}
def do_add_url(self, url: str):
428    def do_add_url(self, url: str):
429        """Add remote origin url for repo and push repo.
430        >>> git remote add origin {url}
431        >>> git push -u origin main"""
432        self.git.add_remote_url(url)
433        self.git.push("-u origin main")

Add remote origin url for repo and push repo.

>>> git remote add origin {url}
>>> git push -u origin main
@with_parser(parsers.add_files_parser)
def do_amend(self, args: argshell.argshell.Namespace):
435    @with_parser(parsers.add_files_parser)
436    def do_amend(self, args: Namespace):
437        """Stage files and add to previous commit."""
438        self.git.amend(args.files)

Stage files and add to previous commit.

def do_branches(self, _: str):
440    def do_branches(self, _: str):
441        """Show local and remote branches.
442        >>> git branch -vva"""
443        self.git.list_branches()

Show local and remote branches.

>>> git branch -vva
def do_commitall(self, message: str):
445    def do_commitall(self, message: str):
446        """Stage and commit all modified and untracked files with this message.
447        >>> git add .
448        >>> git commit -m \"{message}\" """
449        message = message.strip('"').replace('"', "'")
450        self.git.add_all()
451        self.git.commit(f'-m "{message}"')

Stage and commit all modified and untracked files with this message.

>>> git add .
>>> git commit -m "{message}"
@with_parser(parsers.delete_branch_parser)
def do_delete_branch(self, args: argshell.argshell.Namespace):
453    @with_parser(parsers.delete_branch_parser)
454    def do_delete_branch(self, args: Namespace):
455        """Delete branch."""
456        self.git.delete_branch(args.branch, not args.remote)

Delete branch.

def do_delete_gh_repo(self):
458    def do_delete_gh_repo(self):
459        """Delete this repo from GitHub.
460
461        GitHub CLI must be installed and configured.
462
463        May require you to reauthorize and rerun command."""
464        self.git.delete_remote()

Delete this repo from GitHub.

GitHub CLI must be installed and configured.

May require you to reauthorize and rerun command.

def do_ignore(self, patterns: str):
466    def do_ignore(self, patterns: str):
467        """Add the list of patterns/file names to `.gitignore` and commit with the message `chore: add to gitignore`."""
468        self.git.ignore(patterns.split())
469        self.git.commit_files([".gitignore"], "chore: add to gitignore")

Add the list of patterns/file names to .gitignore and commit with the message chore: add to gitignore.

@with_parser(parsers.add_files_parser)
def do_initcommit(self, args: argshell.argshell.Namespace):
471    @with_parser(parsers.add_files_parser)
472    def do_initcommit(self, args: Namespace):
473        """Stage and commit all files with message "Initial Commit"."""
474        self.git.initcommit(args.files)

Stage and commit all files with message "Initial Commit".

def do_loggy(self, _: str):
476    def do_loggy(self, _: str):
477        """>>> git --oneline --name-only --abbrev-commit --graph"""
478        self.git.loggy()
>>> git --oneline --name-only --abbrev-commit --graph
def do_make_private(self):
480    def do_make_private(self):
481        """Make the GitHub remote for this repo private.
482
483        This repo must exist and GitHub CLI must be installed and configured."""
484        self.git.make_private()

Make the GitHub remote for this repo private.

This repo must exist and GitHub CLI must be installed and configured.

def do_make_public(self):
486    def do_make_public(self):
487        """Make the GitHub remote for this repo public.
488
489        This repo must exist and GitHub CLI must be installed and configured."""
490        self.git.make_public()

Make the GitHub remote for this repo public.

This repo must exist and GitHub CLI must be installed and configured.

def do_new_branch(self, name: str):
492    def do_new_branch(self, name: str):
493        """Create and switch to a new branch with this `name`."""
494        self.git.create_new_branch(name)

Create and switch to a new branch with this name.

@with_parser(parsers.new_remote_parser)
def do_new_gh_remote(self, args: argshell.argshell.Namespace):
496    @with_parser(parsers.new_remote_parser)
497    def do_new_gh_remote(self, args: Namespace):
498        """Create a remote GitHub repository for this repo.
499
500        GitHub CLI must be installed and configured for this to work."""
501        self.git.create_remote_from_cwd(args.public)

Create a remote GitHub repository for this repo.

GitHub CLI must be installed and configured for this to work.

def do_new_repo(self, _: str):
503    def do_new_repo(self, _: str):
504        """Create a new git repo in this directory."""
505        self.git.new_repo()

Create a new git repo in this directory.

def do_push_new(self, _: str):
507    def do_push_new(self, _: str):
508        """Push current branch to origin with `-u` flag.
509        >>> git push -u origin {this_branch}"""
510        self.git.push_new_branch(self.git.current_branch)

Push current branch to origin with -u flag.

>>> git push -u origin {this_branch}
def do_undo(self, _: str):
512    def do_undo(self, _: str):
513        """Undo all uncommitted changes.
514        >>> git checkout ."""
515        self.git.undo()

Undo all uncommitted changes.

>>> git checkout .
@with_parser(parsers.add_files_parser)
def do_untrack(self, args: argshell.argshell.Namespace):
517    @with_parser(parsers.add_files_parser)
518    def do_untrack(self, args: Namespace):
519        """Untrack files matching provided path/pattern list.
520
521        For each path/pattern, equivalent to:
522        >>> git rm --cached {path}"""
523        self.git.untrack(*args.files)

Untrack files matching provided path/pattern list.

For each path/pattern, equivalent to:

>>> git rm --cached {path}
Inherited Members
cmd.Cmd
Cmd
precmd
postcmd
preloop
postloop
parseline
onecmd
completedefault
completenames
complete
get_names
complete_help
print_topics
columnize
argshell.argshell.ArgShell
do_quit
do_sys
cmdloop
emptyline
def main():
526def main():
527    GitBetter().cmdloop()