skilleter-thingy 0.1.24__py3-none-any.whl → 0.1.26__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of skilleter-thingy might be problematic. Click here for more details.

@@ -6,6 +6,7 @@ import os
6
6
  import sys
7
7
  import fnmatch
8
8
  import configparser
9
+ import subprocess
9
10
 
10
11
  from dataclasses import dataclass, field
11
12
 
@@ -13,7 +14,8 @@ import thingy.git2 as git
13
14
  import thingy.colour as colour
14
15
 
15
16
  ################################################################################
16
-
17
+ # TODO List:
18
+ #
17
19
  # DONE: ***MUST use relative paths in config file, or we can't store in git and clone and use somewhere else!***
18
20
  # DONE: / Output name of each working tree as it is processed as command sits there seeming to do nothing otherwise.
19
21
  # DONE: Better error-handling - e.g. continue/abort option after failure in one working tree
@@ -25,11 +27,17 @@ import thingy.colour as colour
25
27
  # DONE: When specifying list of working trees, if name doesn't contain '/' prefix it with '*'?
26
28
  # DONE: command to categorise working trees then command line filter to only act on working trees in category (in addition to other filtering options) - +tag <TAG> command tags all selected working trees and updates the configuration, +untag <TAG> command to remove tags in the same way
27
29
  # DONE: init function
30
+ # DONE Consistent colours in output
31
+ #
28
32
  # NOPE: Clone to have option to update - as discussed, should be part of init
29
33
  # NOPE: Dry-run option - just pass the option to the Git command
30
34
  # NOPE: Is it going to be a problem if the same repo is checked out twice or more in the same workspace - user problem
31
- # NOPE: Pull/fetch - only output after running command and only if something updated
35
+ # NOPE: Pull/fetch - only output after running command and only if something updated - nope, git commands should run as-is without interference
32
36
  # NOPE: Switch to tomlkit
37
+ # NOPE: Use PathLib - Don't really see the need
38
+ # NOPE: When we have something with multiple matches display a menu for user to select the one that they one - make it a library routine so can be used, for instance, for branch selection - Use fzf
39
+ # NOPE: Use pygit2 directly - don't see the need
40
+ #
33
41
  # TODO: 2 .init option '--update' to update the configuration file with new working trees and remove ones that are no longer there
34
42
  # TODO: 2. +run command to do things other than git commands
35
43
  # TODO: 2. If run in a subdirectory, only process working trees in that tree (or have an option to do so, or an option _not_ to do so; --all)
@@ -39,13 +47,12 @@ import thingy.colour as colour
39
47
  # TODO: 3. Command that takes partial working tree name and either returns full path or pops up window to autocomplete until single match found
40
48
  # TODO: 3. Verbose option
41
49
  # TODO: 3. When filtering by tag or by repo name, if name starts with '!' only match if tag isn't present or repo name doesn't match (and don't allow '!' at start of tag otherwise)
50
+ # TODO: 3. (alternative to above) A '--not' option that inverts all the matching criteria, so '--not --branched --modified' selects all unmodified repos which aren't branched
51
+ # TODO: 3. (alternative to both above) Additional options; --!modified --!branched --!tag which act as the inverse of each option, so --!branched selects all unbranched repos.
52
+ # TODO: 3. (another alternative) - Use 'not-' instead of '!', so have --not-branched, --not-modified, --not-tag (single-letter options -B, -M, -T).
42
53
  # TODO: 4. Option to +dir to return all matches so that caller can select one they want
43
54
  # TODO: 4. Shell autocomplete for +dir
44
55
  # TODO: 5. -j option to run in parallel - yes, but it will only work with non-interactive Git commands
45
- # TODO: 5. Consistent colours in output
46
- # TODO: 6. Use PathLib
47
- # TODO: 6. When we have something with multiple matches display a menu for user to select the one that they one - make it a library routine so can be used, for instance, for branch selection
48
- # TODO: 7. Use pygit2 directly
49
56
  ################################################################################
50
57
 
51
58
  DEFAULT_CONFIG_FILE = 'multigit.toml'
@@ -59,8 +66,8 @@ DEFAULT_BRANCH = 'DEFAULT'
59
66
  # Command line help - we aren't using argparse since it isn't flexible enough to handle arbtirary git
60
67
  # commands are parameters so we have to manually create the help and parse the command line
61
68
 
62
- HELP_INFO = """usage: multigit [-h] [--verbose] [--quiet] [--config CONFIG] [--repos REPOS] [--modified] [--branched] [--sub] [--tag TAGS]
63
- {+clone, +init, +config, +dir, GIT_COMMAND} ...
69
+ HELP_INFO = """usage: multigit [--help|-h] [--verbose|-v] [--quiet|-q] [--config|-c CONFIG] [--repos|-r REPOS] [--modified|-m] [--branched|-b] [--sub|-s] [--tag|-t TAGS] [--continue|-o] [--path|-C PATH]
70
+ {+clone, +init, +config, +dir, +list, +run, GIT_COMMAND} ...
64
71
 
65
72
  Run git commands in multiple Git repos. DISCLAIMER: This is beta-quality software, with missing features and liable to fail with a stack trace, but shouldn't eat your data
66
73
 
@@ -76,16 +83,19 @@ options:
76
83
  --branched, -b Select repos that do not have the default branch checked out
77
84
  --tag TAG, -t TAG Select repos that have the specified tag (can be issued multiple times on the command line)
78
85
  --sub, -s Select only the repos in the current directory and subdirectories
79
- --continue, -C Continue if a git command returns an error (by default, executation terminates when a command fails)
86
+ --continue, -o Continue if a git command returns an error (by default, executation terminates when a command fails)
87
+ --path, -C PATH Run as if the command was started in PATH instead of the current working directory
80
88
 
81
89
  Sub-commands:
82
- {+clone, +init,+dir,+config, GIT_COMMAND}
90
+ {+clone, +init, +dir, +config, +list, +run, GIT_COMMAND}
83
91
  +clone REPO {BRANCH} Clone a repo containing a multigit configuration file, then clone all the child repos and check out the default branch in each
84
92
  +init Build or update the configuration file using the current branch in each repo as the default branch
85
93
  +config Return the name and location of the configuration file
86
94
  +dir Return the location of a working tree, given the repo name, or if no parameter specified, the root directory of the multigit tree
95
+ +list Return a list of the top level directories of each of the Git repos
87
96
  +tag TAG Apply a configuration tag to repos filtered by the command line options (list configuration tags if no parameter specified)
88
97
  +untag TAG Remove a configuration tag to repos filtered by the command line options
98
+ +run COMMAND Run the specified command in repos filtered by the command line options
89
99
  GIT_COMMAND Any git command, including options and parameters - this is then run in all specified working trees
90
100
 
91
101
  """
@@ -310,10 +320,10 @@ def mg_clone(args, config, console):
310
320
  # Sanity checks
311
321
 
312
322
  if not args.parameters:
313
- colour.error('The "clone" subcommand takes 1 or 2 parameters - the repo to clone and, optionally, the branch to check out', prefix=True)
323
+ colour.error('The "[BOLD:clone]" subcommand takes 1 or 2 parameters - the repo to clone and, optionally, the branch to check out', prefix=True)
314
324
 
315
325
  if args.branched or args.modified:
316
- colour.error('The "modified" and "branched" options cannot be used with the "clone" subcommand', prefix=True)
326
+ colour.error('The "[BOLD:modified]" and "[BOLD:branched]" options cannot be used with the "[BOLD:clone]" subcommand', prefix=True)
317
327
 
318
328
  # Destination directory is the last portion of the repo URL with the extension removed
319
329
 
@@ -345,7 +355,7 @@ def mg_clone(args, config, console):
345
355
  args.configuration_file = args.default_configuration_file
346
356
 
347
357
  if not os.path.isfile(args.configuration_file):
348
- colour.error(f'Cannot find the configuration file: [BOLD:{args.default_configuration_file}]', prefix=True)
358
+ colour.error(f'Cannot find the configuration file: [BLUE:{args.default_configuration_file}]', prefix=True)
349
359
 
350
360
  config.read(args.configuration_file)
351
361
 
@@ -360,7 +370,7 @@ def mg_clone(args, config, console):
360
370
  os.makedirs(directory, exist_ok=True)
361
371
 
362
372
  if not args.quiet:
363
- colour.write(f'Cloning [BOLD:{repo["origin"]}] into [BLUE:{directory}]')
373
+ colour.write(f'Cloning [BLUE:{repo["origin"]}] into [BLUE:{directory}]')
364
374
 
365
375
  git.clone(repo['origin'], path=repo.name)
366
376
 
@@ -379,7 +389,7 @@ def mg_init(args, config, console):
379
389
  # Sanity checks
380
390
 
381
391
  if args.modified or args.branched or args.tag or args.subdirectories:
382
- colour.error('The "--tag", "--modified" "--sub", and "--branched" options cannot be used with the "init" subcommand', prefix=True)
392
+ colour.error('The "[BOLD:--tag]", "[BOLD:--modified]" "[BOLD:--sub]", and "[BOLD:--branched]" options cannot be used with the "[BOLD:init]" subcommand', prefix=True)
383
393
 
384
394
  # Search for .git directories and add any that aren't already in the configuration
385
395
 
@@ -413,7 +423,8 @@ def mg_init(args, config, console):
413
423
  else:
414
424
  config[repo]['repo name'] = os.path.basename(repo)
415
425
 
416
- colour.write(f'Added [BOLD:{repo}] with default branch [BLUE:{default_branch}]')
426
+ if not args.quiet:
427
+ colour.write(f'Added [BLUE:{repo}] with default branch [BLUE:{default_branch}]')
417
428
 
418
429
  if not args.quiet:
419
430
  colour.write(cleareol=True)
@@ -428,7 +439,7 @@ def mg_init(args, config, console):
428
439
 
429
440
  for entry in removals:
430
441
  del config[entry]
431
- colour.write(f'Removed [BOLD:{repo}] as it no longer exists')
442
+ colour.write(f'Removed [BLUE:{repo}] as it no longer exists')
432
443
 
433
444
  # The configuration file needs to be updated
434
445
 
@@ -447,12 +458,12 @@ def mg_dir(args, config, console):
447
458
  verbose(args, f'dir: Parameters: {", ".join(args.parameters)}')
448
459
 
449
460
  if len(args.parameters) > 1:
450
- colour.error('The +dir command takes no more than one parameter - the name of the working tree to search for', prefix=True)
461
+ colour.error('The "[BOLD:+dir]" command takes no more than one parameter - the name of the working tree to search for', prefix=True)
451
462
 
452
463
  # TODO: mg_dir _should_ use these options
453
464
 
454
465
  if args.modified or args.branched or args.tag or args.subdirectories:
455
- colour.error('The "--tag", "--modified" "--sub", and "--branched" options cannot be used with the "dir" subcommand', prefix=True)
466
+ colour.error('The "[BOLD:--tag]", "[BOLD:--modified]" "[BOLD:--sub]", and "[BOLD:--branched]" options cannot be used with the "[BOLD:+dir]" subcommand', prefix=True)
456
467
 
457
468
  # If a parameter is specified, look for matches, otherwise just return the location of the
458
469
  # configuration file
@@ -501,7 +512,7 @@ def mg_tag(args, config, console):
501
512
  _ = console
502
513
 
503
514
  if len(args.parameters) > 1:
504
- colour.error('The +tag command takes no more than one parameter', prefix=True)
515
+ colour.error('The "[BOLD:+tag]" command takes no more than one parameter', prefix=True)
505
516
 
506
517
  for repo in select_git_repos(args, config):
507
518
  try:
@@ -515,7 +526,7 @@ def mg_tag(args, config, console):
515
526
  repo['tags'] = ','.join(tags)
516
527
  args.config_modified = True
517
528
  elif tags:
518
- colour.write(f'[BOLD:{repo["repo name"]}] - {", ".join(tags)}')
529
+ colour.write(f'[BLUE:{repo["repo name"]}] - {", ".join(tags)}')
519
530
 
520
531
  ################################################################################
521
532
 
@@ -525,7 +536,7 @@ def mg_untag(args, config, console):
525
536
  _ = console
526
537
 
527
538
  if len(args.parameters) > 1:
528
- colour.error('The +tag command takes no more than one parameter', prefix=True)
539
+ colour.error('The "[BOLD:+tag]" command takes no more than one parameter', prefix=True)
529
540
 
530
541
  for repo in select_git_repos(args, config):
531
542
  try:
@@ -547,18 +558,59 @@ def mg_config(args, config, console):
547
558
  _ = console
548
559
 
549
560
  if len(args.parameters):
550
- colour.error('The +config command does not take parameters', prefix=True)
561
+ colour.error('The "[BOLD:+config]" command does not take parameters', prefix=True)
551
562
 
552
563
  colour.write(os.path.relpath(args.configuration_file))
553
564
 
554
565
  ################################################################################
555
566
 
556
- def run_git_command(args, config, console):
567
+ def mg_list(args, config, console):
568
+ """List the top-level directories of the Git repos in the configuration"""
569
+
570
+ _ = console
571
+
572
+ for repo in select_git_repos(args, config):
573
+ print(repo.name)
574
+
575
+ ################################################################################
576
+
577
+ def mg_run(args, config, console):
557
578
  """Run a command in each of the working trees, optionally continuing if
558
579
  there's an error"""
559
580
 
560
581
  _ = console
561
582
 
583
+ if not args.parameters:
584
+ colour.error('[BOLD:+run] command - missing parameter(s)')
585
+
586
+ # Run the command in each of the working trees
587
+
588
+ for repo in select_git_repos(args, config):
589
+ if not args.quiet:
590
+ colour.write(f'\n[BLUE:{os.path.relpath(repo.name)}]\n')
591
+
592
+ repo_path = absolute_repo_path(args, repo.name)
593
+
594
+ try:
595
+ status = subprocess.run(args.parameters, cwd=repo_path)
596
+ except FileNotFoundError:
597
+ err_msg = f'"[BLUE:{args.parameters[0]}]" - Command not found'
598
+ if args.error_continue:
599
+ colour.write(f'[RED:WARNING]: {err_msg}')
600
+ else:
601
+ colour.error(f'[RED:ERROR]: {err_msg}')
602
+ else:
603
+ if status.returncode and not args.error_continue:
604
+ sys.exit(status)
605
+
606
+ ################################################################################
607
+
608
+ def run_git_command(args, config, console):
609
+ """Run a Git command in each of the working trees, optionally continuing if
610
+ there's an error"""
611
+
612
+ _ = console
613
+
562
614
  for repo in select_git_repos(args, config):
563
615
  repo_command = [args.command]
564
616
 
@@ -567,9 +619,10 @@ def run_git_command(args, config, console):
567
619
  for cmd in args.parameters:
568
620
  repo_command.append(branch_name(cmd, repo['default branch']))
569
621
 
570
- colour.write(f'\n[BOLD:{os.path.relpath(repo.name)}]\n')
622
+ if not args.quiet:
623
+ colour.write(f'\n[BLUE:{os.path.relpath(repo.name)}]\n')
571
624
 
572
- # Run the command in the workng tree
625
+ # Run the command in the working tree
573
626
 
574
627
  repo_path = absolute_repo_path(args, repo.name)
575
628
 
@@ -590,67 +643,91 @@ def parse_command_line():
590
643
 
591
644
  arg_list = sys.argv[1:]
592
645
 
646
+ # Iterate through each lump of options (e.g. '-xyz' is a lump of 3 options and
647
+ # '--config' is a lump containing a single option, as is just '-x')
648
+
593
649
  while arg_list and arg_list[0].startswith('-'):
594
650
  # Split a parameter into a list, so --x becomes [x] but -xyz becomes [x, y, z]
651
+ # Note that this means that an option with a parameter must always have a space
652
+ # between the option and the parameter (e.g. '-C path' not '-Cpath'
653
+ # Also note that we don't support '--option=VALUE' - it must be '--option VALUE'
595
654
 
596
655
  arg_entry = arg_list.pop(0)
597
656
  if arg_entry.startswith('--'):
598
- params = [arg_entry[2:]]
657
+ option_list = [arg_entry[2:]]
599
658
  else:
600
- params = list(arg_entry[1:])
659
+ option_list = list(arg_entry[1:])
660
+
661
+ # Process each option in the current option lump.
662
+ # For short options that take a parameter (e.g. '-C PATH') we check that the option list
663
+ # is empty as '-Cx PATH' expands to '-C', '-x PATH', not '-C PATH', '-x'
601
664
 
602
- while params:
603
- param = params.pop(0)
665
+ while option_list:
666
+ option = option_list.pop(0)
604
667
 
605
- if param in ('verbose', 'v'):
668
+ if option in ('verbose', 'v'):
606
669
  args.verbose = True
607
670
 
608
- elif param in ('quiet', 'q'):
671
+ elif option in ('quiet', 'q'):
609
672
  args.quiet = True
610
673
 
611
- elif param in ('config', 'c'):
612
- if params:
613
- colour.error('--config - missing configuration file parameter', prefix=True)
614
- else:
615
- try:
616
- args.default_configuration_file = arg_list.pop(0)
617
- except IndexError:
618
- colour.error('--config - missing configuration file parameter', prefix=True)
619
-
620
- elif param in ('repos', 'r'):
621
- if params:
622
- colour.error('--repos - missing repo parameter', prefix=True)
674
+ elif option in ('config', 'c'):
675
+ if option_list:
676
+ colour.error('The "[BLUE:--config]" option takes a configuration file parameter', prefix=True)
677
+
678
+ try:
679
+ args.default_configuration_file = arg_list.pop(0)
680
+ except IndexError:
681
+ colour.error('"The [BLUE:--config]" option takes a configuration file parameter', prefix=True)
682
+
683
+ elif option in ('repos', 'r'):
684
+ if option_list:
685
+ colour.error('The "[BLUE:--repos]" option takes a repo parameter', prefix=True)
686
+
623
687
  try:
624
688
  args.repos.append(arg_list.pop(0))
625
689
  except IndexError:
626
- colour.error('--repos - missing repo parameter', prefix=True)
690
+ colour.error('The "[BLUE:--repos]" option takes a repo parameter', prefix=True)
691
+
692
+ elif option in ('tag', 't'):
693
+ if option_list:
694
+ colour.error('The "[BLUE:--tag]" option takes a tag parameter', prefix=True)
627
695
 
628
- elif param in ('tag', 't'):
629
- if params:
630
- colour.error('--tag - missing tag parameter', prefix=True)
631
696
  try:
632
697
  args.tag.append(arg_list.pop(0))
633
698
  except IndexError:
634
- colour.error('--tag - missing tag parameter', prefix=True)
699
+ colour.error('The "[BLUE:--tag]" option takes a tag parameter', prefix=True)
635
700
 
636
- elif param in ('modified', 'm'):
701
+ elif option in ('modified', 'm'):
637
702
  args.modified = True
638
703
 
639
- elif param in ('branched', 'b'):
704
+ elif option in ('branched', 'b'):
640
705
  args.branched = True
641
706
 
642
- elif param in ('sub', 's'):
707
+ elif option in ('sub', 's'):
643
708
  args.subdirectories = True
644
709
 
645
- elif param in ('continue', 'C'):
710
+ elif option in ('continue', 'o'):
646
711
  args.error_continue = True
647
712
 
648
- elif param in ('help', 'h'):
713
+ elif option in ('path', 'C'):
714
+ if option_list:
715
+ colour.error('The "[BOLD:--path]" option takes a path parameter')
716
+
717
+ try:
718
+ workingdir = arg_list.pop(0)
719
+ os.chdir(workingdir)
720
+ except IndexError:
721
+ colour.error('The "[BOLD:-C]" option takes a path parameter', prefix=True)
722
+ except FileNotFoundError:
723
+ colour.error(f'"[BOLD:--path]" - path "[BLUE:{workingdir}]" not found', prefix=True)
724
+
725
+ elif option in ('help', 'h'):
649
726
  colour.write(HELP_INFO)
650
727
  sys.exit(0)
651
728
 
652
729
  else:
653
- colour.error(f'Invalid option: "{param}"', prefix=True)
730
+ colour.error(f'Invalid option: "[BOLD:{option}]"', prefix=True)
654
731
 
655
732
  # After the options, we either have a multigit command (prefixed with '+') or a git command
656
733
  # followed by parameter
@@ -687,6 +764,8 @@ COMMANDS = {
687
764
  'config': mg_config,
688
765
  'tag': mg_tag,
689
766
  'untag': mg_untag,
767
+ 'list': mg_list,
768
+ 'run': mg_run,
690
769
  }
691
770
 
692
771
  def main():
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: skilleter_thingy
3
- Version: 0.1.24
3
+ Version: 0.1.26
4
4
  Summary: A collection of useful utilities, mainly aimed at making Git more friendly
5
5
  Author-email: John Skilleter <john@skilleter.org.uk>
6
6
  Project-URL: Home, https://skilleter.org.uk
@@ -90,7 +90,11 @@ The command takes a number of options that can be used to select the list of wor
90
90
 
91
91
  `--tag TAG` / `-t TAG` Run only in working trees that are tagged with the specified tag
92
92
 
93
- `--subdir` / `-s` Run only in working trees that are in the current directory tree.
93
+ `--sub` / `-s` Run only in working trees that are in the current directory tree.
94
+
95
+ `--continue` / `-o` Continue if a git command returns an error (by default, executation terminates when a command fails)
96
+
97
+ `--path PATH` / `-C PATH` Run as if the command was started in PATH instead of the current working directory
94
98
 
95
99
  These options are AND-ed together, so specifying `--modified --branched --tag WOMBAT` will select only working trees that are modified AND branched AND tagged with `WOMBAT`, but the parameters to the `--repos` and `--tag` options are OR-ed together, so specifying `--tag WOMBAT --tag EMU` will select repos that are tagged as `WOMBAT` *OR* `EMU`.
96
100
 
@@ -106,12 +110,16 @@ Multigit supports a small list of subcommands, each of which are prefixed with a
106
110
 
107
111
  `+dir NAME` - Given the name of a working tree, output relative path(s) to one or more matching working trees. If `NAME` does NOT contains wildcard characters (`*` or `?`) then matching takes place as if `*` were prefixed and appended to it, otherwise, the wildcards are used as specified. If `NAME` is not specified then the location of the directory where the multigit configuration file resides is output.
108
112
 
113
+ `+list` - Return a list of the top level directories of each of the Git repos
114
+
109
115
  `+config` - Print the name and location of the multigit configuration file.
110
116
 
111
117
  `+tag TAG` - If no tag specified list tags applied to the specified working trees. If a tag *is* specified, then *apply* the tag to the specified working trees.
112
118
 
113
119
  `+untag TAG` - Remove the tag from the specified working trees (do nothing if the tag is not applied in the first place).
114
120
 
121
+ `+run COMMAND` - Run the specified command in each of the specified working trees
122
+
115
123
  Any command *not* prefixed with `+` is run in each of the working trees (filtered by the various multigit options) as a git command.
116
124
 
117
125
  For example; `multigit -m commit -ab` would run `git commit -a` in each of the working trees that is branched and contains modified files.
@@ -179,10 +187,10 @@ Note that the concept of the default branch `DEFAULT` mentioned above *only* app
179
187
  Improved version of 'git commit --amend'. Updates files that are already in the commit and, optionally, adds and commits additional files.
180
188
 
181
189
  usage: git-ca [-h] [--added] [--all] [--everything] [--ignored] [--patch] [--verbose] [--dry-run] [files ...]
182
-
190
+
183
191
  positional arguments:
184
192
  files List of files to add to the commit
185
-
193
+
186
194
  options:
187
195
  -h, --help show this help message and exit
188
196
  --added, -A Update files in the current commit, including files added with `git add`
@@ -198,11 +206,11 @@ Improved version of 'git commit --amend'. Updates files that are already in the
198
206
  List or delete branches that have already been merged and delete tracking branches that are no longer on the remote.
199
207
 
200
208
  git-cleanup [-h] [--delete] [--master MASTER] [--force] [--unmerged] [--yes] [--debug] [branches ...]
201
-
209
+
202
210
  positional arguments:
203
-
211
+
204
212
  branches List of branches to check (default is all branches)
205
-
213
+
206
214
  options:
207
215
  -h, --help show this help message and exit
208
216
  --delete, -d Delete all branches that have been merged
@@ -218,11 +226,11 @@ List or delete branches that have already been merged and delete tracking branch
218
226
  Equivalent to `git checkout` but with enhanced branch matching as described above. The command does not support the full range of options supported by the `git checkout` comamnd which should still be used where additional functionality is required.
219
227
 
220
228
  git-co [-h] [--branch] [--update] [--rebase] [--force] [--exact] [--debug] branchname
221
-
229
+
222
230
  positional arguments:
223
-
231
+
224
232
  branchname The branch name (or a partial name that matches uniquely against a local branch, remote branch, commit ID or tag)
225
-
233
+
226
234
  options:
227
235
  -h, --help show this help message and exit
228
236
  --branch, -b Create the specified branch
@@ -237,12 +245,12 @@ Equivalent to `git checkout` but with enhanced branch matching as described abov
237
245
  Attempt to determine the parent branch for the specified branch (defaulting to the current one).
238
246
 
239
247
  git-parent [-h] [--all] [--verbose] [branch]
240
-
248
+
241
249
  Attempt to determine the parent branch for the specified branch (defaulting to the current one)
242
-
250
+
243
251
  positional arguments:
244
252
  branch Branch, commit or commit (defaults to current branch; main)
245
-
253
+
246
254
  options:
247
255
  -h, --help show this help message and exit
248
256
  --all, -a Include feature branches as possible parents
@@ -324,7 +332,6 @@ Add or remove entries from a path list (e.g. as used by the PATH environment var
324
332
  --separator SEPARATOR
325
333
  Override the default path separator
326
334
 
327
-
328
335
  ## docker-purge
329
336
 
330
337
  Stop or kill docker instances and/or remove docker images.
@@ -25,7 +25,7 @@ skilleter_thingy/gl.py,sha256=9zbGpKxw6lX9RghLkdy-Q5sZlqtbB3uGFO04qTu1dH8,5954
25
25
  skilleter_thingy/linecount.py,sha256=ehTN6VD76i4U5k6dXuYoiqSRHI67_BP-bziklNAJSKY,4309
26
26
  skilleter_thingy/localphotosync.py,sha256=WF0TcCvLfl7cVOLzYYQK_t2WebLfQ-5FM6UB3r7Fpvw,5952
27
27
  skilleter_thingy/moviemover.py,sha256=QzUAWQzQ1AWWREIhl-VMaLo2h8MMhOekBnao5jGWV1s,4470
28
- skilleter_thingy/multigit.py,sha256=bPt0qGOb7tSR58RSBzhYRRCL1Jt_767bqiwEfNFyWv4,29097
28
+ skilleter_thingy/multigit.py,sha256=ZLL0AN2ZmrWY2BPBaHsdVqqGeyk3pJo1jMFRm2zZXoU,33056
29
29
  skilleter_thingy/photodupe.py,sha256=2hw4EhDKH37_BgdXKkPm9GrftfIORmubQi38Yn0b4Mg,4084
30
30
  skilleter_thingy/phototidier.py,sha256=BOu-cKHMivDlBqlRqv7sL3J6Ix1K2dxWWNcderldyZo,7818
31
31
  skilleter_thingy/py_audit.py,sha256=4CAdqBAIIVcpTCn_7dGm56bdfGpUtUJofqTGZomClkY,4417
@@ -61,9 +61,9 @@ skilleter_thingy/thingy/run.py,sha256=6SNKWF01fSxzB10GMU9ajraXYZqAL1w0PXkqjJdr1U
61
61
  skilleter_thingy/thingy/tfm_pane.py,sha256=XTTpSm71CyQyGmlVLuCthioOwech0jhUiFUXb-chS_Q,19792
62
62
  skilleter_thingy/thingy/tidy.py,sha256=AQ2RawsZJg6WHrgayi_ZptFL9occ7suSdCHbU3P-cys,5971
63
63
  skilleter_thingy/thingy/venv_template.py,sha256=SsVNvSwojd8NnFeQaZPCRQYTNdwJRplpZpygbUEXRnY,1015
64
- skilleter_thingy-0.1.24.dist-info/licenses/LICENSE,sha256=ljOS4DjXvqEo5VzGfdaRwgRZPbNScGBmfwyC8PChvmQ,32422
65
- skilleter_thingy-0.1.24.dist-info/METADATA,sha256=b2F4TO9R2l9fA0NlSOiFLhlZiFSOC4jlAYWqDbBF1xQ,29914
66
- skilleter_thingy-0.1.24.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
67
- skilleter_thingy-0.1.24.dist-info/entry_points.txt,sha256=mklrWFvNKw9Hyem9RG3x0PoVYjlx2fDnJ3xWMTMOmfs,2258
68
- skilleter_thingy-0.1.24.dist-info/top_level.txt,sha256=8-JhgToBBiWURunmvfpSxEvNkDHQQ7r25-aBXtZv61g,17
69
- skilleter_thingy-0.1.24.dist-info/RECORD,,
64
+ skilleter_thingy-0.1.26.dist-info/licenses/LICENSE,sha256=ljOS4DjXvqEo5VzGfdaRwgRZPbNScGBmfwyC8PChvmQ,32422
65
+ skilleter_thingy-0.1.26.dist-info/METADATA,sha256=F2AzaiFif-DiP2_J1ZKEGymC4jcf_eiQN49tKcxYpOM,30260
66
+ skilleter_thingy-0.1.26.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
67
+ skilleter_thingy-0.1.26.dist-info/entry_points.txt,sha256=mklrWFvNKw9Hyem9RG3x0PoVYjlx2fDnJ3xWMTMOmfs,2258
68
+ skilleter_thingy-0.1.26.dist-info/top_level.txt,sha256=8-JhgToBBiWURunmvfpSxEvNkDHQQ7r25-aBXtZv61g,17
69
+ skilleter_thingy-0.1.26.dist-info/RECORD,,