gitbetter.gitbetter

  1import os
  2
  3from argshell import ArgShell, ArgShellParser, Namespace, with_parser
  4from pathier import Pathier
  5
  6from gitbetter import Git
  7
  8
  9def new_remote_parser() -> ArgShellParser:
 10    parser = ArgShellParser()
 11    parser.add_argument(
 12        "--public",
 13        action="store_true",
 14        help=""" Set the new remote visibility as public. Defaults to private. """,
 15    )
 16    return parser
 17
 18
 19def commit_files_parser() -> ArgShellParser:
 20    parser = ArgShellParser()
 21    parser.add_argument(
 22        "files", type=str, nargs="*", help=""" List of files to stage and commit. """
 23    )
 24    parser.add_argument(
 25        "-m",
 26        "--message",
 27        type=str,
 28        required=True,
 29        help=""" The commit message to use. """,
 30    )
 31    parser.add_argument(
 32        "-r",
 33        "--recursive",
 34        action="store_true",
 35        help=""" If a file name is not found in the current working directory,
 36        search for it in subfolders. This avoids having to type paths to files in subfolders,
 37        but if you have multiple files in different subfolders with the same name that have changes they
 38        will all be staged and committed.""",
 39    )
 40    return parser
 41
 42
 43def amend_files_parser() -> ArgShellParser:
 44    parser = ArgShellParser()
 45    parser.add_argument(
 46        "-f",
 47        "--files",
 48        type=str,
 49        nargs="*",
 50        help=""" List of files to stage and commit. """,
 51    )
 52    parser.add_argument(
 53        "-r",
 54        "--recursive",
 55        action="store_true",
 56        help=""" If a file name is not found in the current working directory,
 57        search for it in subfolders. This avoids having to type paths to files in subfolders,
 58        but if you have multiple files in different subfolders with the same name that have changes they
 59        will all be staged and committed.""",
 60    )
 61    return parser
 62
 63
 64def delete_branch_parser() -> ArgShellParser:
 65    parser = ArgShellParser()
 66    parser.add_argument(
 67        "branch", type=str, help=""" The name of the branch to delete. """
 68    )
 69    parser.add_argument(
 70        "-r",
 71        "--remote",
 72        action="store_true",
 73        help=""" Delete the remote and remote-tracking branches along with the local branch.
 74        By default only the local branch is deleted.""",
 75    )
 76    return parser
 77
 78
 79def recurse_files(filenames: list[str]) -> list[str]:
 80    files = []
 81    for filename in filenames:
 82        if not Pathier(filename).exists():
 83            results = list(Pathier.cwd().rglob(f"{filename}"))
 84            if not results:
 85                print(f"WARNING: Could not find any files with name {filename}")
 86            else:
 87                files.extend([str(result) for result in results])
 88        else:
 89            files.append(filename)
 90    return files
 91
 92
 93def files_postparser(args: Namespace) -> Namespace:
 94    if args.recursive:
 95        args.files = recurse_files(args.files)
 96    return args
 97
 98
 99class GitBetter(ArgShell):
100    """GitBetter Shell."""
101
102    intro = "Starting gitbetter...\nEnter 'help' or '?' for command help."
103    prompt = f"gitbetter::{Pathier.cwd()}>"
104    execute_in_terminal_if_unrecognized = True
105    git = Git()
106
107    def default(self, line: str):
108        if self.execute_in_terminal_if_unrecognized:
109            os.system(line)
110        else:
111            super().default(line)
112
113    def do_help(self, arg: str):
114        """List available commands with "help" or detailed help with "help cmd"."""
115        super().do_help(arg)
116        if not arg:
117            print(self.unrecognized_command_behavior_status)
118            if self.execute_in_terminal_if_unrecognized:
119                print(
120                    "^Essentially makes this shell function as a super-shell of whatever shell you launched gitbetter from.^"
121                )
122        print()
123
124    @property
125    def unrecognized_command_behavior_status(self):
126        return f"Unrecognized command behavior: {'Execute in shell with os.system()' if self.execute_in_terminal_if_unrecognized else 'Print unknown syntax error'}"
127
128    def do_toggle_unrecognized_command_behavior(self, arg: str):
129        """Toggle whether the shell will attempt to execute unrecognized commands as system commands in the terminal.
130        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)`.
131        When off, an `unknown syntax` message will be printed and no commands will be executed."""
132        self.execute_in_terminal_if_unrecognized = (
133            not self.execute_in_terminal_if_unrecognized
134        )
135        print(self.unrecognized_command_behavior_status)
136
137    def do_cd(self, path: str):
138        """Change current working directory to `path`."""
139        os.chdir(path)
140        self.prompt = f"gitbetter::{Pathier.cwd()}>"
141
142    def do_git(self, arg: str):
143        """Directly execute `git {arg}`.
144
145        i.e. You can still do everything directly invoking git can do."""
146        self.git.execute(arg)
147
148    def do_new_repo(self, _: str):
149        """Create a new git repo in this directory."""
150        self.git.new_repo()
151
152    def do_new_branch(self, name: str):
153        """Create and switch to a new branch named after the supplied arg."""
154        self.git.create_new_branch(name)
155
156    @with_parser(new_remote_parser)
157    def do_new_gh_remote(self, args: Namespace):
158        """Create a remote GitHub repository for this repo.
159
160        GitHub CLI must be installed and configured for this to work."""
161        self.git.create_remote_from_cwd(args.public)
162
163    def do_initcommit(self, _: str):
164        """Stage and commit all files with message "Initial Commit"."""
165        self.git.initcommit()
166
167    def do_undo(self, _: str):
168        """Undo all uncommitted changes."""
169        self.git.undo()
170
171    @with_parser(amend_files_parser, [files_postparser])
172    def do_add(self, args: Namespace):
173        """Stage a list of files.
174        If no files are given, all files will be added."""
175        self.git.add(None if not args.files else args.files)
176
177    def do_commit(self, args: str):
178        """Commit staged files with provided `args` string."""
179        self.git.commit(args)
180
181    @with_parser(commit_files_parser, [files_postparser])
182    def do_commitf(self, args: Namespace):
183        """Stage and commit a list of files."""
184        self.git.commit_files(args.files, args.message)
185
186    def do_commitall(self, message: str):
187        """Stage and commit all files with this message."""
188        if not message.startswith('"'):
189            message = '"' + message
190        if not message.endswith('"'):
191            message += '"'
192        self.git.add()
193        self.git.commit(f"-m {message}")
194
195    def do_switch(self, branch_name: str):
196        """Switch to this branch."""
197        self.git.switch_branch(branch_name)
198
199    def do_add_url(self, url: str):
200        """Add remote origin url for repo and push repo."""
201        self.git.add_remote_url(url)
202        self.git.push("-u origin main")
203
204    def do_push_new(self, branch_name: str):
205        """Push this new branch to origin with -u flag."""
206        self.git.push_new_branch(branch_name)
207
208    def do_push(self, args: str):
209        """Execute `git push`.
210
211        `args` can be any additional args that `git push` accepts."""
212        self.git.push(args)
213
214    def do_pull(self, args: str):
215        """Execute `git pull`.
216
217        `args` can be any additional args that `git pull` accepts."""
218        self.git.pull(args)
219
220    def do_branches(self, _: str):
221        """Show local and remote branches."""
222        self.git.list_branches()
223
224    def do_loggy(self, _: str):
225        """Execute `git --oneline --name-only --abbrev-commit --graph`."""
226        self.git.loggy()
227
228    def do_status(self, _: str):
229        """Execute `git status`."""
230        self.git.status()
231
232    def do_merge(self, branch_name: str):
233        """Merge supplied `branch_name` with the currently active branch."""
234        self.git.merge(branch_name)
235
236    def do_tag(self, tag_id: str):
237        """Tag current commit with `tag_id`."""
238        self.git.tag(tag_id)
239
240    @with_parser(amend_files_parser, [files_postparser])
241    def do_amend(self, args: Namespace):
242        """Stage files and add to previous commit."""
243        self.git.amend(args.files)
244
245    @with_parser(delete_branch_parser)
246    def do_delete_branch(self, args: Namespace):
247        """Delete branch."""
248        self.git.delete_branch(args.branch, not args.remote)
249
250    def do_pull_branch(self, branch: str):
251        """Pull this branch from the origin."""
252        self.git.pull_branch(branch)
253
254    def do_ignore(self, patterns: str):
255        """Add the list of patterns to `.gitignore`."""
256        patterns = "\n".join(patterns.split())
257        path = Pathier(".gitignore")
258        path.append("\n")
259        path.append(patterns, False)
260
261    def do_make_private(self, owner: str):
262        """Make the GitHub remote for this repo private.
263
264        Expects an argument for the repo owner, i.e. the `OWNER` in `github.com/{OWNER}/{repo-name}`
265
266        This repo must exist and GitHub CLI must be installed and configured."""
267        self.git.make_private(owner, Pathier.cwd().stem)
268
269    def do_make_public(self, owner: str):
270        """Make the GitHub remote for this repo public.
271
272        Expects an argument for the repo owner, i.e. the `OWNER` in `github.com/{OWNER}/{repo-name}`
273
274        This repo must exist and GitHub CLI must be installed and configured."""
275        self.git.make_public(owner, Pathier.cwd().stem)
276
277    def do_delete_gh_repo(self, owner: str):
278        """Delete this repo from GitHub.
279
280        Expects an argument for the repo owner, i.e. the `OWNER` in `github.com/{OWNER}/{repo-name}`
281
282        GitHub CLI must be installed and configured.
283
284        May require you to reauthorize and rerun command."""
285        self.git.delete_remote(owner, Pathier.cwd().stem)
286
287
288def main():
289    GitBetter().cmdloop()
290
291
292if __name__ == "__main__":
293    main()
def new_remote_parser() -> argshell.argshell.ArgShellParser:
10def new_remote_parser() -> ArgShellParser:
11    parser = ArgShellParser()
12    parser.add_argument(
13        "--public",
14        action="store_true",
15        help=""" Set the new remote visibility as public. Defaults to private. """,
16    )
17    return parser
def commit_files_parser() -> argshell.argshell.ArgShellParser:
20def commit_files_parser() -> ArgShellParser:
21    parser = ArgShellParser()
22    parser.add_argument(
23        "files", type=str, nargs="*", help=""" List of files to stage and commit. """
24    )
25    parser.add_argument(
26        "-m",
27        "--message",
28        type=str,
29        required=True,
30        help=""" The commit message to use. """,
31    )
32    parser.add_argument(
33        "-r",
34        "--recursive",
35        action="store_true",
36        help=""" If a file name is not found in the current working directory,
37        search for it in subfolders. This avoids having to type paths to files in subfolders,
38        but if you have multiple files in different subfolders with the same name that have changes they
39        will all be staged and committed.""",
40    )
41    return parser
def amend_files_parser() -> argshell.argshell.ArgShellParser:
44def amend_files_parser() -> ArgShellParser:
45    parser = ArgShellParser()
46    parser.add_argument(
47        "-f",
48        "--files",
49        type=str,
50        nargs="*",
51        help=""" List of files to stage and commit. """,
52    )
53    parser.add_argument(
54        "-r",
55        "--recursive",
56        action="store_true",
57        help=""" If a file name is not found in the current working directory,
58        search for it in subfolders. This avoids having to type paths to files in subfolders,
59        but if you have multiple files in different subfolders with the same name that have changes they
60        will all be staged and committed.""",
61    )
62    return parser
def delete_branch_parser() -> argshell.argshell.ArgShellParser:
65def delete_branch_parser() -> ArgShellParser:
66    parser = ArgShellParser()
67    parser.add_argument(
68        "branch", type=str, help=""" The name of the branch to delete. """
69    )
70    parser.add_argument(
71        "-r",
72        "--remote",
73        action="store_true",
74        help=""" Delete the remote and remote-tracking branches along with the local branch.
75        By default only the local branch is deleted.""",
76    )
77    return parser
def recurse_files(filenames: list[str]) -> list[str]:
80def recurse_files(filenames: list[str]) -> list[str]:
81    files = []
82    for filename in filenames:
83        if not Pathier(filename).exists():
84            results = list(Pathier.cwd().rglob(f"{filename}"))
85            if not results:
86                print(f"WARNING: Could not find any files with name {filename}")
87            else:
88                files.extend([str(result) for result in results])
89        else:
90            files.append(filename)
91    return files
def files_postparser(args: argshell.argshell.Namespace) -> argshell.argshell.Namespace:
94def files_postparser(args: Namespace) -> Namespace:
95    if args.recursive:
96        args.files = recurse_files(args.files)
97    return args
class GitBetter(argshell.argshell.ArgShell):
100class GitBetter(ArgShell):
101    """GitBetter Shell."""
102
103    intro = "Starting gitbetter...\nEnter 'help' or '?' for command help."
104    prompt = f"gitbetter::{Pathier.cwd()}>"
105    execute_in_terminal_if_unrecognized = True
106    git = Git()
107
108    def default(self, line: str):
109        if self.execute_in_terminal_if_unrecognized:
110            os.system(line)
111        else:
112            super().default(line)
113
114    def do_help(self, arg: str):
115        """List available commands with "help" or detailed help with "help cmd"."""
116        super().do_help(arg)
117        if not arg:
118            print(self.unrecognized_command_behavior_status)
119            if self.execute_in_terminal_if_unrecognized:
120                print(
121                    "^Essentially makes this shell function as a super-shell of whatever shell you launched gitbetter from.^"
122                )
123        print()
124
125    @property
126    def unrecognized_command_behavior_status(self):
127        return f"Unrecognized command behavior: {'Execute in shell with os.system()' if self.execute_in_terminal_if_unrecognized else 'Print unknown syntax error'}"
128
129    def do_toggle_unrecognized_command_behavior(self, arg: str):
130        """Toggle whether the shell will attempt to execute unrecognized commands as system commands in the terminal.
131        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)`.
132        When off, an `unknown syntax` message will be printed and no commands will be executed."""
133        self.execute_in_terminal_if_unrecognized = (
134            not self.execute_in_terminal_if_unrecognized
135        )
136        print(self.unrecognized_command_behavior_status)
137
138    def do_cd(self, path: str):
139        """Change current working directory to `path`."""
140        os.chdir(path)
141        self.prompt = f"gitbetter::{Pathier.cwd()}>"
142
143    def do_git(self, arg: str):
144        """Directly execute `git {arg}`.
145
146        i.e. You can still do everything directly invoking git can do."""
147        self.git.execute(arg)
148
149    def do_new_repo(self, _: str):
150        """Create a new git repo in this directory."""
151        self.git.new_repo()
152
153    def do_new_branch(self, name: str):
154        """Create and switch to a new branch named after the supplied arg."""
155        self.git.create_new_branch(name)
156
157    @with_parser(new_remote_parser)
158    def do_new_gh_remote(self, args: Namespace):
159        """Create a remote GitHub repository for this repo.
160
161        GitHub CLI must be installed and configured for this to work."""
162        self.git.create_remote_from_cwd(args.public)
163
164    def do_initcommit(self, _: str):
165        """Stage and commit all files with message "Initial Commit"."""
166        self.git.initcommit()
167
168    def do_undo(self, _: str):
169        """Undo all uncommitted changes."""
170        self.git.undo()
171
172    @with_parser(amend_files_parser, [files_postparser])
173    def do_add(self, args: Namespace):
174        """Stage a list of files.
175        If no files are given, all files will be added."""
176        self.git.add(None if not args.files else args.files)
177
178    def do_commit(self, args: str):
179        """Commit staged files with provided `args` string."""
180        self.git.commit(args)
181
182    @with_parser(commit_files_parser, [files_postparser])
183    def do_commitf(self, args: Namespace):
184        """Stage and commit a list of files."""
185        self.git.commit_files(args.files, args.message)
186
187    def do_commitall(self, message: str):
188        """Stage and commit all files with this message."""
189        if not message.startswith('"'):
190            message = '"' + message
191        if not message.endswith('"'):
192            message += '"'
193        self.git.add()
194        self.git.commit(f"-m {message}")
195
196    def do_switch(self, branch_name: str):
197        """Switch to this branch."""
198        self.git.switch_branch(branch_name)
199
200    def do_add_url(self, url: str):
201        """Add remote origin url for repo and push repo."""
202        self.git.add_remote_url(url)
203        self.git.push("-u origin main")
204
205    def do_push_new(self, branch_name: str):
206        """Push this new branch to origin with -u flag."""
207        self.git.push_new_branch(branch_name)
208
209    def do_push(self, args: str):
210        """Execute `git push`.
211
212        `args` can be any additional args that `git push` accepts."""
213        self.git.push(args)
214
215    def do_pull(self, args: str):
216        """Execute `git pull`.
217
218        `args` can be any additional args that `git pull` accepts."""
219        self.git.pull(args)
220
221    def do_branches(self, _: str):
222        """Show local and remote branches."""
223        self.git.list_branches()
224
225    def do_loggy(self, _: str):
226        """Execute `git --oneline --name-only --abbrev-commit --graph`."""
227        self.git.loggy()
228
229    def do_status(self, _: str):
230        """Execute `git status`."""
231        self.git.status()
232
233    def do_merge(self, branch_name: str):
234        """Merge supplied `branch_name` with the currently active branch."""
235        self.git.merge(branch_name)
236
237    def do_tag(self, tag_id: str):
238        """Tag current commit with `tag_id`."""
239        self.git.tag(tag_id)
240
241    @with_parser(amend_files_parser, [files_postparser])
242    def do_amend(self, args: Namespace):
243        """Stage files and add to previous commit."""
244        self.git.amend(args.files)
245
246    @with_parser(delete_branch_parser)
247    def do_delete_branch(self, args: Namespace):
248        """Delete branch."""
249        self.git.delete_branch(args.branch, not args.remote)
250
251    def do_pull_branch(self, branch: str):
252        """Pull this branch from the origin."""
253        self.git.pull_branch(branch)
254
255    def do_ignore(self, patterns: str):
256        """Add the list of patterns to `.gitignore`."""
257        patterns = "\n".join(patterns.split())
258        path = Pathier(".gitignore")
259        path.append("\n")
260        path.append(patterns, False)
261
262    def do_make_private(self, owner: str):
263        """Make the GitHub remote for this repo private.
264
265        Expects an argument for the repo owner, i.e. the `OWNER` in `github.com/{OWNER}/{repo-name}`
266
267        This repo must exist and GitHub CLI must be installed and configured."""
268        self.git.make_private(owner, Pathier.cwd().stem)
269
270    def do_make_public(self, owner: str):
271        """Make the GitHub remote for this repo public.
272
273        Expects an argument for the repo owner, i.e. the `OWNER` in `github.com/{OWNER}/{repo-name}`
274
275        This repo must exist and GitHub CLI must be installed and configured."""
276        self.git.make_public(owner, Pathier.cwd().stem)
277
278    def do_delete_gh_repo(self, owner: str):
279        """Delete this repo from GitHub.
280
281        Expects an argument for the repo owner, i.e. the `OWNER` in `github.com/{OWNER}/{repo-name}`
282
283        GitHub CLI must be installed and configured.
284
285        May require you to reauthorize and rerun command."""
286        self.git.delete_remote(owner, Pathier.cwd().stem)

GitBetter Shell.

def default(self, line: str):
108    def default(self, line: str):
109        if self.execute_in_terminal_if_unrecognized:
110            os.system(line)
111        else:
112            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_help(self, arg: str):
114    def do_help(self, arg: str):
115        """List available commands with "help" or detailed help with "help cmd"."""
116        super().do_help(arg)
117        if not arg:
118            print(self.unrecognized_command_behavior_status)
119            if self.execute_in_terminal_if_unrecognized:
120                print(
121                    "^Essentially makes this shell function as a super-shell of whatever shell you launched gitbetter from.^"
122                )
123        print()

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

def do_toggle_unrecognized_command_behavior(self, arg: str):
129    def do_toggle_unrecognized_command_behavior(self, arg: str):
130        """Toggle whether the shell will attempt to execute unrecognized commands as system commands in the terminal.
131        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)`.
132        When off, an `unknown syntax` message will be printed and no commands will be executed."""
133        self.execute_in_terminal_if_unrecognized = (
134            not self.execute_in_terminal_if_unrecognized
135        )
136        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_cd(self, path: str):
138    def do_cd(self, path: str):
139        """Change current working directory to `path`."""
140        os.chdir(path)
141        self.prompt = f"gitbetter::{Pathier.cwd()}>"

Change current working directory to path.

def do_git(self, arg: str):
143    def do_git(self, arg: str):
144        """Directly execute `git {arg}`.
145
146        i.e. You can still do everything directly invoking git can do."""
147        self.git.execute(arg)

Directly execute git {arg}.

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

def do_new_repo(self, _: str):
149    def do_new_repo(self, _: str):
150        """Create a new git repo in this directory."""
151        self.git.new_repo()

Create a new git repo in this directory.

def do_new_branch(self, name: str):
153    def do_new_branch(self, name: str):
154        """Create and switch to a new branch named after the supplied arg."""
155        self.git.create_new_branch(name)

Create and switch to a new branch named after the supplied arg.

@with_parser(new_remote_parser)
def do_new_gh_remote(self, args: argshell.argshell.Namespace):
157    @with_parser(new_remote_parser)
158    def do_new_gh_remote(self, args: Namespace):
159        """Create a remote GitHub repository for this repo.
160
161        GitHub CLI must be installed and configured for this to work."""
162        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_initcommit(self, _: str):
164    def do_initcommit(self, _: str):
165        """Stage and commit all files with message "Initial Commit"."""
166        self.git.initcommit()

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

def do_undo(self, _: str):
168    def do_undo(self, _: str):
169        """Undo all uncommitted changes."""
170        self.git.undo()

Undo all uncommitted changes.

@with_parser(amend_files_parser, [files_postparser])
def do_add(self, args: argshell.argshell.Namespace):
172    @with_parser(amend_files_parser, [files_postparser])
173    def do_add(self, args: Namespace):
174        """Stage a list of files.
175        If no files are given, all files will be added."""
176        self.git.add(None if not args.files else args.files)

Stage a list of files. If no files are given, all files will be added.

def do_commit(self, args: str):
178    def do_commit(self, args: str):
179        """Commit staged files with provided `args` string."""
180        self.git.commit(args)

Commit staged files with provided args string.

@with_parser(commit_files_parser, [files_postparser])
def do_commitf(self, args: argshell.argshell.Namespace):
182    @with_parser(commit_files_parser, [files_postparser])
183    def do_commitf(self, args: Namespace):
184        """Stage and commit a list of files."""
185        self.git.commit_files(args.files, args.message)

Stage and commit a list of files.

def do_commitall(self, message: str):
187    def do_commitall(self, message: str):
188        """Stage and commit all files with this message."""
189        if not message.startswith('"'):
190            message = '"' + message
191        if not message.endswith('"'):
192            message += '"'
193        self.git.add()
194        self.git.commit(f"-m {message}")

Stage and commit all files with this message.

def do_switch(self, branch_name: str):
196    def do_switch(self, branch_name: str):
197        """Switch to this branch."""
198        self.git.switch_branch(branch_name)

Switch to this branch.

def do_add_url(self, url: str):
200    def do_add_url(self, url: str):
201        """Add remote origin url for repo and push repo."""
202        self.git.add_remote_url(url)
203        self.git.push("-u origin main")

Add remote origin url for repo and push repo.

def do_push_new(self, branch_name: str):
205    def do_push_new(self, branch_name: str):
206        """Push this new branch to origin with -u flag."""
207        self.git.push_new_branch(branch_name)

Push this new branch to origin with -u flag.

def do_push(self, args: str):
209    def do_push(self, args: str):
210        """Execute `git push`.
211
212        `args` can be any additional args that `git push` accepts."""
213        self.git.push(args)

Execute git push.

args can be any additional args that git push accepts.

def do_pull(self, args: str):
215    def do_pull(self, args: str):
216        """Execute `git pull`.
217
218        `args` can be any additional args that `git pull` accepts."""
219        self.git.pull(args)

Execute git pull.

args can be any additional args that git pull accepts.

def do_branches(self, _: str):
221    def do_branches(self, _: str):
222        """Show local and remote branches."""
223        self.git.list_branches()

Show local and remote branches.

def do_loggy(self, _: str):
225    def do_loggy(self, _: str):
226        """Execute `git --oneline --name-only --abbrev-commit --graph`."""
227        self.git.loggy()

Execute git --oneline --name-only --abbrev-commit --graph.

def do_status(self, _: str):
229    def do_status(self, _: str):
230        """Execute `git status`."""
231        self.git.status()

Execute git status.

def do_merge(self, branch_name: str):
233    def do_merge(self, branch_name: str):
234        """Merge supplied `branch_name` with the currently active branch."""
235        self.git.merge(branch_name)

Merge supplied branch_name with the currently active branch.

def do_tag(self, tag_id: str):
237    def do_tag(self, tag_id: str):
238        """Tag current commit with `tag_id`."""
239        self.git.tag(tag_id)

Tag current commit with tag_id.

@with_parser(amend_files_parser, [files_postparser])
def do_amend(self, args: argshell.argshell.Namespace):
241    @with_parser(amend_files_parser, [files_postparser])
242    def do_amend(self, args: Namespace):
243        """Stage files and add to previous commit."""
244        self.git.amend(args.files)

Stage files and add to previous commit.

@with_parser(delete_branch_parser)
def do_delete_branch(self, args: argshell.argshell.Namespace):
246    @with_parser(delete_branch_parser)
247    def do_delete_branch(self, args: Namespace):
248        """Delete branch."""
249        self.git.delete_branch(args.branch, not args.remote)

Delete branch.

def do_pull_branch(self, branch: str):
251    def do_pull_branch(self, branch: str):
252        """Pull this branch from the origin."""
253        self.git.pull_branch(branch)

Pull this branch from the origin.

def do_ignore(self, patterns: str):
255    def do_ignore(self, patterns: str):
256        """Add the list of patterns to `.gitignore`."""
257        patterns = "\n".join(patterns.split())
258        path = Pathier(".gitignore")
259        path.append("\n")
260        path.append(patterns, False)

Add the list of patterns to .gitignore.

def do_make_private(self, owner: str):
262    def do_make_private(self, owner: str):
263        """Make the GitHub remote for this repo private.
264
265        Expects an argument for the repo owner, i.e. the `OWNER` in `github.com/{OWNER}/{repo-name}`
266
267        This repo must exist and GitHub CLI must be installed and configured."""
268        self.git.make_private(owner, Pathier.cwd().stem)

Make the GitHub remote for this repo private.

Expects an argument for the repo owner, i.e. the OWNER in github.com/{OWNER}/{repo-name}

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

def do_make_public(self, owner: str):
270    def do_make_public(self, owner: str):
271        """Make the GitHub remote for this repo public.
272
273        Expects an argument for the repo owner, i.e. the `OWNER` in `github.com/{OWNER}/{repo-name}`
274
275        This repo must exist and GitHub CLI must be installed and configured."""
276        self.git.make_public(owner, Pathier.cwd().stem)

Make the GitHub remote for this repo public.

Expects an argument for the repo owner, i.e. the OWNER in github.com/{OWNER}/{repo-name}

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

def do_delete_gh_repo(self, owner: str):
278    def do_delete_gh_repo(self, owner: str):
279        """Delete this repo from GitHub.
280
281        Expects an argument for the repo owner, i.e. the `OWNER` in `github.com/{OWNER}/{repo-name}`
282
283        GitHub CLI must be installed and configured.
284
285        May require you to reauthorize and rerun command."""
286        self.git.delete_remote(owner, Pathier.cwd().stem)

Delete this repo from GitHub.

Expects an argument for the repo owner, i.e. the OWNER in github.com/{OWNER}/{repo-name}

GitHub CLI must be installed and configured.

May require you to reauthorize and rerun command.

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():
289def main():
290    GitBetter().cmdloop()