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
106    def default(self, line: str):
107        if self.execute_in_terminal_if_unrecognized:
108            os.system(line)
109        else:
110            super().default(line)
111
112    def do_help(self, arg: str):
113        """List available commands with "help" or detailed help with "help cmd"."""
114        super().do_help(arg)
115        if not arg:
116            print(self.unrecognized_command_behavior_status)
117            if self.execute_in_terminal_if_unrecognized:
118                print(
119                    "^Essentially makes this shell function as a super-shell of whatever shell you launched gitbetter from.^"
120                )
121        print()
122
123    @property
124    def unrecognized_command_behavior_status(self):
125        return f"Unrecognized command behavior: {'Execute in shell with os.system()' if self.execute_in_terminal_if_unrecognized else 'Print unknown syntax error'}"
126
127    def do_toggle_unrecognized_command_behavior(self, arg: str):
128        """Toggle whether the shell will attempt to execute unrecognized commands as system commands in the terminal.
129        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)`.
130        When off, an `unknown syntax` message will be printed and no commands will be executed."""
131        self.execute_in_terminal_if_unrecognized = (
132            not self.execute_in_terminal_if_unrecognized
133        )
134        print(self.unrecognized_command_behavior_status)
135
136    def do_cd(self, path: str):
137        """Change current working directory to `path`."""
138        os.chdir(path)
139        self.prompt = f"gitbetter::{Pathier.cwd()}>"
140
141    def do_git(self, arg: str):
142        """Directly execute `git {arg}`.
143
144        i.e. You can still do everything directly invoking git can do."""
145        git.execute(arg)
146
147    def do_new_repo(self, _: str):
148        """Create a new git repo in this directory."""
149        git.new_repo()
150
151    def do_new_branch(self, name: str):
152        """Create and switch to a new branch named after the supplied arg."""
153        git.create_new_branch(name)
154
155    @with_parser(new_remote_parser)
156    def do_new_gh_remote(self, args: Namespace):
157        """Create a remote GitHub repository for this repo.
158
159        GitHub CLI must be installed and configured for this to work."""
160        git.create_remote_from_cwd(args.public)
161
162    def do_initcommit(self, _: str):
163        """Stage and commit all files with message "Initial Commit"."""
164        git.initcommit()
165
166    def do_undo(self, _: str):
167        """Undo all uncommitted changes."""
168        git.undo()
169
170    @with_parser(amend_files_parser, [files_postparser])
171    def do_add(self, args: Namespace):
172        """Stage a list of files.
173        If no files are given, all files will be added."""
174        git.add(None if not args.files else args.files)
175
176    def do_commit(self, message: str):
177        """Commit staged files with this message."""
178        if not message.startswith('"'):
179            message = '"' + message
180        if not message.endswith('"'):
181            message += '"'
182        git.commit(f"-m {message}")
183
184    @with_parser(commit_files_parser, [files_postparser])
185    def do_commitf(self, args: Namespace):
186        """Stage and commit a list of files."""
187        git.commit_files(args.files, args.message)
188
189    def do_commitall(self, message: str):
190        """Stage and commit all files with this message."""
191        if not message.startswith('"'):
192            message = '"' + message
193        if not message.endswith('"'):
194            message += '"'
195        git.add()
196        git.commit(f"-m {message}")
197
198    def do_switch(self, branch_name: str):
199        """Switch to this branch."""
200        git.switch_branch(branch_name)
201
202    def do_add_url(self, url: str):
203        """Add remote origin url for repo and push repo."""
204        git.add_remote_url(url)
205        git.push("-u origin main")
206
207    def do_push_new(self, branch_name: str):
208        """Push this new branch to origin with -u flag."""
209        git.push_new_branch(branch_name)
210
211    def do_push(self, args: str):
212        """Execute `git push`.
213
214        `args` can be any additional args that `git push` accepts."""
215        git.push(args)
216
217    def do_pull(self, args: str):
218        """Execute `git pull`.
219
220        `args` can be any additional args that `git pull` accepts."""
221        git.pull(args)
222
223    def do_branches(self, _: str):
224        """Show local and remote branches."""
225        git.list_branches()
226
227    def do_loggy(self, _: str):
228        """Execute `git --oneline --name-only --abbrev-commit --graph`."""
229        git.loggy()
230
231    def do_status(self, _: str):
232        """Execute `git status`."""
233        git.status()
234
235    def do_merge(self, branch_name: str):
236        """Merge supplied `branch_name` with the currently active branch."""
237        git.merge(branch_name)
238
239    def do_tag(self, tag_id: str):
240        """Tag current commit with `tag_id`."""
241        git.tag(tag_id)
242
243    @with_parser(amend_files_parser, [files_postparser])
244    def do_amend(self, args: Namespace):
245        """Stage files and add to previous commit."""
246        git.amend(args.files)
247
248    @with_parser(delete_branch_parser)
249    def do_delete_branch(self, args: Namespace):
250        """Delete branch."""
251        git.delete_branch(args.branch, not args.remote)
252
253    def do_pull_branch(self, branch: str):
254        """Pull this branch from the origin."""
255        git.pull_branch(branch)
256
257    def do_ignore(self, patterns: str):
258        """Add the list of patterns to `.gitignore`."""
259        patterns = "\n".join(patterns.split())
260        path = Pathier(".gitignore")
261        path.append("\n")
262        path.append(patterns, False)
263
264    def do_make_private(self, owner: str):
265        """Make the GitHub remote for this repo private.
266
267        Expects an argument for the repo owner, i.e. the `OWNER` in `github.com/{OWNER}/{repo-name}`
268
269        This repo must exist and GitHub CLI must be installed and configured."""
270        git.make_private(owner, Pathier.cwd().stem)
271
272    def do_make_public(self, owner: str):
273        """Make the GitHub remote for this repo public.
274
275        Expects an argument for the repo owner, i.e. the `OWNER` in `github.com/{OWNER}/{repo-name}`
276
277        This repo must exist and GitHub CLI must be installed and configured."""
278        git.make_public(owner, Pathier.cwd().stem)
279
280    def do_delete_gh_repo(self, owner: str):
281        """Delete this repo from GitHub.
282
283        Expects an argument for the repo owner, i.e. the `OWNER` in `github.com/{OWNER}/{repo-name}`
284
285        GitHub CLI must be installed and configured.
286
287        May require you to reauthorize and rerun command."""
288        git.delete_remote(owner, Pathier.cwd().stem)
289
290
291def main():
292    GitBetter().cmdloop()
293
294
295if __name__ == "__main__":
296    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
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        git.execute(arg)
147
148    def do_new_repo(self, _: str):
149        """Create a new git repo in this directory."""
150        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        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        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        git.initcommit()
166
167    def do_undo(self, _: str):
168        """Undo all uncommitted changes."""
169        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        git.add(None if not args.files else args.files)
176
177    def do_commit(self, message: str):
178        """Commit staged files with this message."""
179        if not message.startswith('"'):
180            message = '"' + message
181        if not message.endswith('"'):
182            message += '"'
183        git.commit(f"-m {message}")
184
185    @with_parser(commit_files_parser, [files_postparser])
186    def do_commitf(self, args: Namespace):
187        """Stage and commit a list of files."""
188        git.commit_files(args.files, args.message)
189
190    def do_commitall(self, message: str):
191        """Stage and commit all files with this message."""
192        if not message.startswith('"'):
193            message = '"' + message
194        if not message.endswith('"'):
195            message += '"'
196        git.add()
197        git.commit(f"-m {message}")
198
199    def do_switch(self, branch_name: str):
200        """Switch to this branch."""
201        git.switch_branch(branch_name)
202
203    def do_add_url(self, url: str):
204        """Add remote origin url for repo and push repo."""
205        git.add_remote_url(url)
206        git.push("-u origin main")
207
208    def do_push_new(self, branch_name: str):
209        """Push this new branch to origin with -u flag."""
210        git.push_new_branch(branch_name)
211
212    def do_push(self, args: str):
213        """Execute `git push`.
214
215        `args` can be any additional args that `git push` accepts."""
216        git.push(args)
217
218    def do_pull(self, args: str):
219        """Execute `git pull`.
220
221        `args` can be any additional args that `git pull` accepts."""
222        git.pull(args)
223
224    def do_branches(self, _: str):
225        """Show local and remote branches."""
226        git.list_branches()
227
228    def do_loggy(self, _: str):
229        """Execute `git --oneline --name-only --abbrev-commit --graph`."""
230        git.loggy()
231
232    def do_status(self, _: str):
233        """Execute `git status`."""
234        git.status()
235
236    def do_merge(self, branch_name: str):
237        """Merge supplied `branch_name` with the currently active branch."""
238        git.merge(branch_name)
239
240    def do_tag(self, tag_id: str):
241        """Tag current commit with `tag_id`."""
242        git.tag(tag_id)
243
244    @with_parser(amend_files_parser, [files_postparser])
245    def do_amend(self, args: Namespace):
246        """Stage files and add to previous commit."""
247        git.amend(args.files)
248
249    @with_parser(delete_branch_parser)
250    def do_delete_branch(self, args: Namespace):
251        """Delete branch."""
252        git.delete_branch(args.branch, not args.remote)
253
254    def do_pull_branch(self, branch: str):
255        """Pull this branch from the origin."""
256        git.pull_branch(branch)
257
258    def do_ignore(self, patterns: str):
259        """Add the list of patterns to `.gitignore`."""
260        patterns = "\n".join(patterns.split())
261        path = Pathier(".gitignore")
262        path.append("\n")
263        path.append(patterns, False)
264
265    def do_make_private(self, owner: str):
266        """Make the GitHub remote for this repo private.
267
268        Expects an argument for the repo owner, i.e. the `OWNER` in `github.com/{OWNER}/{repo-name}`
269
270        This repo must exist and GitHub CLI must be installed and configured."""
271        git.make_private(owner, Pathier.cwd().stem)
272
273    def do_make_public(self, owner: str):
274        """Make the GitHub remote for this repo public.
275
276        Expects an argument for the repo owner, i.e. the `OWNER` in `github.com/{OWNER}/{repo-name}`
277
278        This repo must exist and GitHub CLI must be installed and configured."""
279        git.make_public(owner, Pathier.cwd().stem)
280
281    def do_delete_gh_repo(self, owner: str):
282        """Delete this repo from GitHub.
283
284        Expects an argument for the repo owner, i.e. the `OWNER` in `github.com/{OWNER}/{repo-name}`
285
286        GitHub CLI must be installed and configured.
287
288        May require you to reauthorize and rerun command."""
289        git.delete_remote(owner, Pathier.cwd().stem)

GitBetter Shell.

def default(self, line: str):
107    def default(self, line: str):
108        if self.execute_in_terminal_if_unrecognized:
109            os.system(line)
110        else:
111            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):
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()

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

def do_toggle_unrecognized_command_behavior(self, arg: str):
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)

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):
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()}>"

Change current working directory to path.

def do_git(self, arg: str):
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        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):
148    def do_new_repo(self, _: str):
149        """Create a new git repo in this directory."""
150        git.new_repo()

Create a new git repo in this directory.

def do_new_branch(self, name: str):
152    def do_new_branch(self, name: str):
153        """Create and switch to a new branch named after the supplied arg."""
154        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):
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        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):
163    def do_initcommit(self, _: str):
164        """Stage and commit all files with message "Initial Commit"."""
165        git.initcommit()

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

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

Undo all uncommitted changes.

@with_parser(amend_files_parser, [files_postparser])
def do_add(self, args: argshell.argshell.Namespace):
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        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, message: str):
177    def do_commit(self, message: str):
178        """Commit staged files with this message."""
179        if not message.startswith('"'):
180            message = '"' + message
181        if not message.endswith('"'):
182            message += '"'
183        git.commit(f"-m {message}")

Commit staged files with this message.

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

Stage and commit a list of files.

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

Stage and commit all files with this message.

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

Switch to this branch.

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

Add remote origin url for repo and push repo.

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

Push this new branch to origin with -u flag.

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

Execute git push.

args can be any additional args that git push accepts.

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

Execute git pull.

args can be any additional args that git pull accepts.

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

Show local and remote branches.

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

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

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

Execute git status.

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

Merge supplied branch_name with the currently active branch.

def do_tag(self, tag_id: str):
240    def do_tag(self, tag_id: str):
241        """Tag current commit with `tag_id`."""
242        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):
244    @with_parser(amend_files_parser, [files_postparser])
245    def do_amend(self, args: Namespace):
246        """Stage files and add to previous commit."""
247        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):
249    @with_parser(delete_branch_parser)
250    def do_delete_branch(self, args: Namespace):
251        """Delete branch."""
252        git.delete_branch(args.branch, not args.remote)

Delete branch.

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

Pull this branch from the origin.

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

Add the list of patterns to .gitignore.

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