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

GitBetter Shell.

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

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

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

Change current working directory to path.

def do_git(self, arg: str):
144    def do_git(self, arg: str):
145        """Directly execute `git {arg}`.
146
147        i.e. You can still do everything directly invoking git can do."""
148        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):
150    def do_new_repo(self, _: str):
151        """Create a new git repo in this directory."""
152        self.git.new_repo()

Create a new git repo in this directory.

def do_new_branch(self, name: str):
154    def do_new_branch(self, name: str):
155        """Create and switch to a new branch named after the supplied arg."""
156        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):
158    @with_parser(new_remote_parser)
159    def do_new_gh_remote(self, args: Namespace):
160        """Create a remote GitHub repository for this repo.
161
162        GitHub CLI must be installed and configured for this to work."""
163        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):
165    def do_initcommit(self, _: str):
166        """Stage and commit all files with message "Initial Commit"."""
167        self.git.initcommit()

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

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

Undo all uncommitted changes.

@with_parser(add_files_parser, [files_postparser])
def do_add(self, args: argshell.argshell.Namespace):
173    @with_parser(add_files_parser, [files_postparser])
174    def do_add(self, args: Namespace):
175        """Stage a list of files.
176        If no files are given, all files will be added."""
177        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):
179    def do_commit(self, args: str):
180        """Commit staged files with provided `args` string."""
181        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):
183    @with_parser(commit_files_parser, [files_postparser])
184    def do_commitf(self, args: Namespace):
185        """Stage and commit a list of files."""
186        self.git.commit_files(args.files, args.message)

Stage and commit a list of files.

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

Stage and commit all files with this message.

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

Switch to this branch.

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

Add remote origin url for repo and push repo.

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

Push this new branch to origin with -u flag.

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

Execute git push.

args can be any additional args that git push accepts.

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

Execute git pull.

args can be any additional args that git pull accepts.

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

Show local and remote branches.

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

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

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

Execute git status.

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

Merge supplied branch_name with the currently active branch.

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

Tag current commit with tag_id.

@with_parser(add_files_parser, [files_postparser])
def do_amend(self, args: argshell.argshell.Namespace):
242    @with_parser(add_files_parser, [files_postparser])
243    def do_amend(self, args: Namespace):
244        """Stage files and add to previous commit."""
245        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):
247    @with_parser(delete_branch_parser)
248    def do_delete_branch(self, args: Namespace):
249        """Delete branch."""
250        self.git.delete_branch(args.branch, not args.remote)

Delete branch.

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

Pull this branch from the origin.

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

Add the list of patterns to .gitignore.

def do_make_private(self, owner: str):
263    def do_make_private(self, owner: str):
264        """Make the GitHub remote for this repo private.
265
266        Expects an argument for the repo owner, i.e. the `OWNER` in `github.com/{OWNER}/{repo-name}`
267
268        This repo must exist and GitHub CLI must be installed and configured."""
269        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):
271    def do_make_public(self, owner: str):
272        """Make the GitHub remote for this repo public.
273
274        Expects an argument for the repo owner, i.e. the `OWNER` in `github.com/{OWNER}/{repo-name}`
275
276        This repo must exist and GitHub CLI must be installed and configured."""
277        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):
279    def do_delete_gh_repo(self, owner: str):
280        """Delete this repo from GitHub.
281
282        Expects an argument for the repo owner, i.e. the `OWNER` in `github.com/{OWNER}/{repo-name}`
283
284        GitHub CLI must be installed and configured.
285
286        May require you to reauthorize and rerun command."""
287        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():
290def main():
291    GitBetter().cmdloop()