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