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.commit_files_parser)
453    def do_commitf(self, args: Namespace):
454        """Stage and commit a list of files."""
455        self.git.commit_files(args.files, args.message)
456
457    @with_parser(parsers.delete_branch_parser)
458    def do_delete_branch(self, args: Namespace):
459        """Delete branch."""
460        self.git.delete_branch(args.branch, not args.remote)
461
462    def do_delete_gh_repo(self):
463        """Delete this repo from GitHub.
464
465        GitHub CLI must be installed and configured.
466
467        May require you to reauthorize and rerun command."""
468        self.git.delete_remote()
469
470    def do_ignore(self, patterns: str):
471        """Add the list of patterns/file names to `.gitignore`."""
472        self.git.ignore(patterns.split())
473
474    @with_parser(parsers.add_files_parser)
475    def do_initcommit(self, args: Namespace):
476        """Stage and commit all files with message "Initial Commit"."""
477        self.git.initcommit(args.files)
478
479    def do_loggy(self, _: str):
480        """>>> git --oneline --name-only --abbrev-commit --graph"""
481        self.git.loggy()
482
483    def do_make_private(self):
484        """Make the GitHub remote for this repo private.
485
486        This repo must exist and GitHub CLI must be installed and configured."""
487        self.git.make_private()
488
489    def do_make_public(self):
490        """Make the GitHub remote for this repo public.
491
492        This repo must exist and GitHub CLI must be installed and configured."""
493        self.git.make_public()
494
495    def do_new_branch(self, name: str):
496        """Create and switch to a new branch with this `name`."""
497        self.git.create_new_branch(name)
498
499    @with_parser(parsers.new_remote_parser)
500    def do_new_gh_remote(self, args: Namespace):
501        """Create a remote GitHub repository for this repo.
502
503        GitHub CLI must be installed and configured for this to work."""
504        self.git.create_remote_from_cwd(args.public)
505
506    def do_new_repo(self, _: str):
507        """Create a new git repo in this directory."""
508        self.git.new_repo()
509
510    def do_push_new(self, _: str):
511        """Push current branch to origin with `-u` flag.
512        >>> git push -u origin {this_branch}"""
513        self.git.push_new_branch(self.git.current_branch)
514
515    def do_undo(self, _: str):
516        """Undo all uncommitted changes.
517        >>> git checkout ."""
518        self.git.undo()
519
520
521def main():
522    GitBetter().cmdloop()
523
524
525if __name__ == "__main__":
526    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.commit_files_parser)
454    def do_commitf(self, args: Namespace):
455        """Stage and commit a list of files."""
456        self.git.commit_files(args.files, args.message)
457
458    @with_parser(parsers.delete_branch_parser)
459    def do_delete_branch(self, args: Namespace):
460        """Delete branch."""
461        self.git.delete_branch(args.branch, not args.remote)
462
463    def do_delete_gh_repo(self):
464        """Delete this repo from GitHub.
465
466        GitHub CLI must be installed and configured.
467
468        May require you to reauthorize and rerun command."""
469        self.git.delete_remote()
470
471    def do_ignore(self, patterns: str):
472        """Add the list of patterns/file names to `.gitignore`."""
473        self.git.ignore(patterns.split())
474
475    @with_parser(parsers.add_files_parser)
476    def do_initcommit(self, args: Namespace):
477        """Stage and commit all files with message "Initial Commit"."""
478        self.git.initcommit(args.files)
479
480    def do_loggy(self, _: str):
481        """>>> git --oneline --name-only --abbrev-commit --graph"""
482        self.git.loggy()
483
484    def do_make_private(self):
485        """Make the GitHub remote for this repo private.
486
487        This repo must exist and GitHub CLI must be installed and configured."""
488        self.git.make_private()
489
490    def do_make_public(self):
491        """Make the GitHub remote for this repo public.
492
493        This repo must exist and GitHub CLI must be installed and configured."""
494        self.git.make_public()
495
496    def do_new_branch(self, name: str):
497        """Create and switch to a new branch with this `name`."""
498        self.git.create_new_branch(name)
499
500    @with_parser(parsers.new_remote_parser)
501    def do_new_gh_remote(self, args: Namespace):
502        """Create a remote GitHub repository for this repo.
503
504        GitHub CLI must be installed and configured for this to work."""
505        self.git.create_remote_from_cwd(args.public)
506
507    def do_new_repo(self, _: str):
508        """Create a new git repo in this directory."""
509        self.git.new_repo()
510
511    def do_push_new(self, _: str):
512        """Push current branch to origin with `-u` flag.
513        >>> git push -u origin {this_branch}"""
514        self.git.push_new_branch(self.git.current_branch)
515
516    def do_undo(self, _: str):
517        """Undo all uncommitted changes.
518        >>> git checkout ."""
519        self.git.undo()

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.commit_files_parser)
def do_commitf(self, args: argshell.argshell.Namespace):
453    @with_parser(parsers.commit_files_parser)
454    def do_commitf(self, args: Namespace):
455        """Stage and commit a list of files."""
456        self.git.commit_files(args.files, args.message)

Stage and commit a list of files.

@with_parser(parsers.delete_branch_parser)
def do_delete_branch(self, args: argshell.argshell.Namespace):
458    @with_parser(parsers.delete_branch_parser)
459    def do_delete_branch(self, args: Namespace):
460        """Delete branch."""
461        self.git.delete_branch(args.branch, not args.remote)

Delete branch.

def do_delete_gh_repo(self):
463    def do_delete_gh_repo(self):
464        """Delete this repo from GitHub.
465
466        GitHub CLI must be installed and configured.
467
468        May require you to reauthorize and rerun command."""
469        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):
471    def do_ignore(self, patterns: str):
472        """Add the list of patterns/file names to `.gitignore`."""
473        self.git.ignore(patterns.split())

Add the list of patterns/file names to .gitignore.

@with_parser(parsers.add_files_parser)
def do_initcommit(self, args: argshell.argshell.Namespace):
475    @with_parser(parsers.add_files_parser)
476    def do_initcommit(self, args: Namespace):
477        """Stage and commit all files with message "Initial Commit"."""
478        self.git.initcommit(args.files)

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

def do_loggy(self, _: str):
480    def do_loggy(self, _: str):
481        """>>> git --oneline --name-only --abbrev-commit --graph"""
482        self.git.loggy()
>>> git --oneline --name-only --abbrev-commit --graph
def do_make_private(self):
484    def do_make_private(self):
485        """Make the GitHub remote for this repo private.
486
487        This repo must exist and GitHub CLI must be installed and configured."""
488        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):
490    def do_make_public(self):
491        """Make the GitHub remote for this repo public.
492
493        This repo must exist and GitHub CLI must be installed and configured."""
494        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):
496    def do_new_branch(self, name: str):
497        """Create and switch to a new branch with this `name`."""
498        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):
500    @with_parser(parsers.new_remote_parser)
501    def do_new_gh_remote(self, args: Namespace):
502        """Create a remote GitHub repository for this repo.
503
504        GitHub CLI must be installed and configured for this to work."""
505        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):
507    def do_new_repo(self, _: str):
508        """Create a new git repo in this directory."""
509        self.git.new_repo()

Create a new git repo in this directory.

def do_push_new(self, _: str):
511    def do_push_new(self, _: str):
512        """Push current branch to origin with `-u` flag.
513        >>> git push -u origin {this_branch}"""
514        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):
516    def do_undo(self, _: str):
517        """Undo all uncommitted changes.
518        >>> git checkout ."""
519        self.git.undo()

Undo all uncommitted changes.

>>> git checkout .
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():
522def main():
523    GitBetter().cmdloop()