skilleter-thingy 0.1.2__py3-none-any.whl → 0.1.4__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.
- skilleter_thingy/multigit.py +166 -51
- skilleter_thingy/thingy/git2.py +3 -3
- {skilleter_thingy-0.1.2.dist-info → skilleter_thingy-0.1.4.dist-info}/METADATA +5 -1
- {skilleter_thingy-0.1.2.dist-info → skilleter_thingy-0.1.4.dist-info}/RECORD +8 -8
- {skilleter_thingy-0.1.2.dist-info → skilleter_thingy-0.1.4.dist-info}/LICENSE +0 -0
- {skilleter_thingy-0.1.2.dist-info → skilleter_thingy-0.1.4.dist-info}/WHEEL +0 -0
- {skilleter_thingy-0.1.2.dist-info → skilleter_thingy-0.1.4.dist-info}/entry_points.txt +0 -0
- {skilleter_thingy-0.1.2.dist-info → skilleter_thingy-0.1.4.dist-info}/top_level.txt +0 -0
skilleter_thingy/multigit.py
CHANGED
|
@@ -14,6 +14,7 @@ import thingy.colour as colour
|
|
|
14
14
|
|
|
15
15
|
################################################################################
|
|
16
16
|
|
|
17
|
+
# DONE: ***MUST use relative paths in config file, or we can't store in git and clone and use somewhere else!***
|
|
17
18
|
# DONE: / Output name of each working tree as it is processed as command sits there seeming to do nothing otherwise.
|
|
18
19
|
# DONE: Better error-handling - e.g. continue/abort option after failure in one working tree
|
|
19
20
|
# DONE: Currently doesn't handle single letter options in concatenated form - e.g. -dv
|
|
@@ -21,29 +22,30 @@ import thingy.colour as colour
|
|
|
21
22
|
# DONE: Don't use a fixed list of default branch names
|
|
22
23
|
# DONE: If the config file isn't in the current directory then search up the directory tree for it but run in the current directory
|
|
23
24
|
# DONE: Use the configuration file
|
|
25
|
+
# DONE: When specifying list of working trees, if name doesn't contain '/' prefix it with '*'?
|
|
24
26
|
# 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
|
|
25
27
|
# DONE: init function
|
|
28
|
+
# NOPE: Clone to have option to update - as discussed, should be part of init
|
|
26
29
|
# NOPE: Dry-run option - just pass the option to the Git command
|
|
27
30
|
# NOPE: Is it going to be a problem if the same repo is checked out twice or more in the same workspace - user problem
|
|
28
31
|
# NOPE: Pull/fetch - only output after running command and only if something updated
|
|
29
32
|
# NOPE: Switch to tomlkit
|
|
30
|
-
# TODO:
|
|
31
|
-
# TODO:
|
|
32
|
-
# TODO:
|
|
33
|
-
# TODO:
|
|
34
|
-
# TODO:
|
|
35
|
-
# TODO:
|
|
36
|
-
#
|
|
37
|
-
# TODO:
|
|
38
|
-
# TODO:
|
|
39
|
-
# TODO:
|
|
40
|
-
# TODO:
|
|
41
|
-
# TODO:
|
|
42
|
-
# TODO:
|
|
43
|
-
# TODO:
|
|
44
|
-
# TODO:
|
|
45
|
-
# TODO: Use
|
|
46
|
-
# TODO: Shell autocomplete for +dir
|
|
33
|
+
# TODO: 2 .init option '--update' to update the configuration file with new working trees and remove ones that are no longer there
|
|
34
|
+
# TODO: 2. +run command to do things other than git commands
|
|
35
|
+
# 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)
|
|
36
|
+
# TODO: 2. select_git_repos() and +dir should use consist way of selecting repos if possible
|
|
37
|
+
# TODO: 3 .init option '--set-default' to update the default branch to the current one for specified working trees
|
|
38
|
+
# TODO: 3. Ability to read default configuration options from ~/.config/thingy/multigit.rc - these are insert before argv[1] before argparse called
|
|
39
|
+
# 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
|
+
# TODO: 3. Verbose option
|
|
41
|
+
# 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)
|
|
42
|
+
# TODO: 4. Option to +dir to return all matches so that caller can select one they want
|
|
43
|
+
# TODO: 4. Shell autocomplete for +dir
|
|
44
|
+
# 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
|
|
47
49
|
################################################################################
|
|
48
50
|
|
|
49
51
|
DEFAULT_CONFIG_FILE = 'multigit.toml'
|
|
@@ -54,9 +56,11 @@ DEFAULT_CONFIG_FILE = 'multigit.toml'
|
|
|
54
56
|
DEFAULT_BRANCH = 'DEFAULT'
|
|
55
57
|
|
|
56
58
|
################################################################################
|
|
59
|
+
# Command line help - we aren't using argparse since it isn't flexible enough to handle arbtirary git
|
|
60
|
+
# commands are parameters so we have to manually create the help and parse the command line
|
|
57
61
|
|
|
58
62
|
HELP_INFO = """usage: multigit [-h] [--verbose] [--quiet] [--config CONFIG] [--repos REPOS] [--modified] [--branched] [--sub] [--tag TAGS]
|
|
59
|
-
{+init, +config, +dir, GIT_COMMAND} ...
|
|
63
|
+
{+clone, +init, +config, +dir, GIT_COMMAND} ...
|
|
60
64
|
|
|
61
65
|
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
|
|
62
66
|
|
|
@@ -71,11 +75,12 @@ options:
|
|
|
71
75
|
--modified, -m Select repos that have local modifications
|
|
72
76
|
--branched, -b Select repos that do not have the default branch checked out
|
|
73
77
|
--tag TAG, -t TAG Select repos that have the specified tag (can be issued multiple times on the command line)
|
|
74
|
-
--continue, -C Continue if a git command returns an error (by default, executation terminates when a command fails)
|
|
75
78
|
--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)
|
|
76
80
|
|
|
77
81
|
Sub-commands:
|
|
78
|
-
{+init,+dir,+config,GIT_COMMAND}
|
|
82
|
+
{+clone, +init,+dir,+config, GIT_COMMAND}
|
|
83
|
+
+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
|
|
79
84
|
+init Build or update the configuration file using the current branch in each repo as the default branch
|
|
80
85
|
+config Return the name and location of the configuration file
|
|
81
86
|
+dir Return the location of a working tree, given the repo name, or if no parameter specified, the root directory of the multigit tree
|
|
@@ -136,6 +141,14 @@ def error(msg, status=1):
|
|
|
136
141
|
|
|
137
142
|
################################################################################
|
|
138
143
|
|
|
144
|
+
def absolute_repo_path(args, relative_path=''):
|
|
145
|
+
"""Given a path relative to the multigit configuration file, return
|
|
146
|
+
the absolute path thereto"""
|
|
147
|
+
|
|
148
|
+
return os.path.join(os.path.dirname(args.configuration_file), relative_path)
|
|
149
|
+
|
|
150
|
+
################################################################################
|
|
151
|
+
|
|
139
152
|
def find_configuration(default_config_file):
|
|
140
153
|
"""If the configuration file name has path elements, try and read it, otherwise
|
|
141
154
|
search up the directory tree looking for the configuration file.
|
|
@@ -157,7 +170,8 @@ def find_configuration(default_config_file):
|
|
|
157
170
|
################################################################################
|
|
158
171
|
|
|
159
172
|
def show_progress(width, msg):
|
|
160
|
-
"""Show a single line progress message
|
|
173
|
+
"""Show a single line progress message without moving the cursor to the next
|
|
174
|
+
line."""
|
|
161
175
|
|
|
162
176
|
colour.write(msg[:width-1], newline=False, cleareol=True, cr=True)
|
|
163
177
|
|
|
@@ -174,22 +188,25 @@ def find_working_trees(args):
|
|
|
174
188
|
|
|
175
189
|
repos = set()
|
|
176
190
|
|
|
177
|
-
for root, dirs, _ in os.walk(os.path.dirname(args.configuration_file)):
|
|
191
|
+
for root, dirs, _ in os.walk(os.path.dirname(args.configuration_file), topdown=True):
|
|
178
192
|
if '.git' in dirs:
|
|
179
|
-
|
|
180
|
-
root = root[2:]
|
|
193
|
+
relative_path = os.path.relpath(root)
|
|
181
194
|
|
|
182
195
|
if args.repos:
|
|
183
196
|
for card in args.repos:
|
|
184
|
-
if fnmatch.fnmatch(
|
|
185
|
-
if
|
|
186
|
-
yield
|
|
187
|
-
repos.add(
|
|
197
|
+
if fnmatch.fnmatch(relative_path, card):
|
|
198
|
+
if relative_path not in repos:
|
|
199
|
+
yield relative_path
|
|
200
|
+
repos.add(relative_path)
|
|
188
201
|
break
|
|
189
202
|
else:
|
|
190
|
-
if
|
|
191
|
-
yield
|
|
192
|
-
repos.add(
|
|
203
|
+
if relative_path not in repos:
|
|
204
|
+
yield relative_path
|
|
205
|
+
repos.add(relative_path)
|
|
206
|
+
|
|
207
|
+
# Don't recurse down into hidden directories
|
|
208
|
+
|
|
209
|
+
dirs[:] = [d for d in dirs if d[0] != '.']
|
|
193
210
|
|
|
194
211
|
################################################################################
|
|
195
212
|
|
|
@@ -250,7 +267,7 @@ def select_git_repos(args, config):
|
|
|
250
267
|
# If subdirectories specified, only match if the repo is in the current directory tree
|
|
251
268
|
|
|
252
269
|
if matching and args.subdirectories:
|
|
253
|
-
repo_path_rel = os.path.relpath(repo_path)
|
|
270
|
+
repo_path_rel = os.path.relpath(absolute_repo_path(args, repo_path))
|
|
254
271
|
|
|
255
272
|
if repo_path_rel == '..' or repo_path_rel.startswith('../'):
|
|
256
273
|
matching = False
|
|
@@ -269,6 +286,77 @@ def branch_name(name, default_branch):
|
|
|
269
286
|
|
|
270
287
|
################################################################################
|
|
271
288
|
|
|
289
|
+
def mg_clone(args, config, console):
|
|
290
|
+
"""Clone a repo, optionally check out a branch and attempt to read the
|
|
291
|
+
configuration file and clone all the repos listed therein, checkouting
|
|
292
|
+
the default branch in each one"""
|
|
293
|
+
|
|
294
|
+
_ = console
|
|
295
|
+
|
|
296
|
+
# Sanity checks
|
|
297
|
+
|
|
298
|
+
if not args.parameters:
|
|
299
|
+
error('The "clone" subcommand takes 1 or 2 parameters - the repo to clone and, optionally, the branch to check out')
|
|
300
|
+
|
|
301
|
+
if args.branched or args.modified:
|
|
302
|
+
error('The "modified" and "branched" options cannot be used with the "clone" subcommand')
|
|
303
|
+
|
|
304
|
+
# Destination directory is the last portion of the repo URL with the extension removed
|
|
305
|
+
|
|
306
|
+
directory = os.path.splitext(os.path.basename(args.parameters[0]))[0]
|
|
307
|
+
|
|
308
|
+
if os.path.exists(directory):
|
|
309
|
+
if os.path.isdir(directory):
|
|
310
|
+
error(f'The "[BLUE:{directory}]" directory already exists')
|
|
311
|
+
else:
|
|
312
|
+
error(f'[BLUE:{directory}]" already exists')
|
|
313
|
+
|
|
314
|
+
# Clone the repo and chdir into it
|
|
315
|
+
|
|
316
|
+
if not args.quiet:
|
|
317
|
+
colour.write(f'Cloning [BOLD:{args.parameters[0]}] into [BLUE:{directory}]')
|
|
318
|
+
|
|
319
|
+
git.clone(args.parameters[0], path=directory)
|
|
320
|
+
|
|
321
|
+
os.chdir(directory)
|
|
322
|
+
|
|
323
|
+
# Optionally checkout a branch, if specified
|
|
324
|
+
|
|
325
|
+
if len(args.parameters) > 1:
|
|
326
|
+
git.checkout(args.parameters[1])
|
|
327
|
+
|
|
328
|
+
# Open the configuration file in the repo (if no configuration file has been specified, use the default)
|
|
329
|
+
|
|
330
|
+
if not args.configuration_file:
|
|
331
|
+
args.configuration_file = args.default_configuration_file
|
|
332
|
+
|
|
333
|
+
if not os.path.isfile(args.configuration_file):
|
|
334
|
+
error(f'Cannot find the configuration file: [BOLD:{args.default_configuration_file}]')
|
|
335
|
+
|
|
336
|
+
config.read(args.configuration_file)
|
|
337
|
+
|
|
338
|
+
# Now iterate through the repos, creating directories and cloning them and checking
|
|
339
|
+
# out the default branch
|
|
340
|
+
|
|
341
|
+
for repo in select_git_repos(args, config):
|
|
342
|
+
if repo.name != '.':
|
|
343
|
+
directory = os.path.dirname(repo.name)
|
|
344
|
+
|
|
345
|
+
if directory:
|
|
346
|
+
os.makedirs(directory, exist_ok=True)
|
|
347
|
+
|
|
348
|
+
if not args.quiet:
|
|
349
|
+
colour.write(f'Cloning [BOLD:{repo["origin"]}] into [BLUE:{directory}]')
|
|
350
|
+
|
|
351
|
+
git.clone(repo['origin'], path=repo.name)
|
|
352
|
+
|
|
353
|
+
if not args.quiet:
|
|
354
|
+
colour.write(f' Checking out [BLUE:{repo["default branch"]}]')
|
|
355
|
+
|
|
356
|
+
git.checkout(repo['default branch'], path=repo.name)
|
|
357
|
+
|
|
358
|
+
################################################################################
|
|
359
|
+
|
|
272
360
|
def mg_init(args, config, console):
|
|
273
361
|
"""Create or update the configuration
|
|
274
362
|
By default, it scans the tree for git directories and adds or updates them
|
|
@@ -289,11 +377,17 @@ def mg_init(args, config, console):
|
|
|
289
377
|
repo_list.append(repo)
|
|
290
378
|
|
|
291
379
|
if repo not in config:
|
|
380
|
+
# Add a new configuration entry containing the default branch, remote origin
|
|
381
|
+
# (if there is one) and name
|
|
382
|
+
|
|
383
|
+
config[repo] = { }
|
|
384
|
+
|
|
292
385
|
default_branch = git.branch(path=repo)
|
|
293
386
|
|
|
294
|
-
|
|
295
|
-
'default branch'
|
|
296
|
-
|
|
387
|
+
if not default_branch:
|
|
388
|
+
error(f'Unable to determine default branch in [BLUE:{repo}]')
|
|
389
|
+
|
|
390
|
+
config['default branch']: default_branch
|
|
297
391
|
|
|
298
392
|
remote = git.remotes(path=repo)
|
|
299
393
|
|
|
@@ -331,14 +425,19 @@ def mg_dir(args, config, console):
|
|
|
331
425
|
of the tree if not
|
|
332
426
|
Returns an error unless there is a unique match"""
|
|
333
427
|
|
|
334
|
-
# DONE: Should return location relative to the current directory or as absolute path
|
|
335
|
-
|
|
336
428
|
_ = console
|
|
337
429
|
_ = config
|
|
338
430
|
|
|
339
431
|
if len(args.parameters) > 1:
|
|
340
432
|
error('The +dir command takes no more than one parameter - the name of the working tree to search for')
|
|
341
|
-
|
|
433
|
+
|
|
434
|
+
if args.modified or args.branched or args.tag or args.subdirectories:
|
|
435
|
+
error('The "--tag", "--modified" "--sub", and "--branched" options cannot be used with the "dir" subcommand')
|
|
436
|
+
|
|
437
|
+
# If a parameter is specified, look for matches, otherwise just return the location of the
|
|
438
|
+
# configuration file
|
|
439
|
+
|
|
440
|
+
if args.parameters:
|
|
342
441
|
location = []
|
|
343
442
|
wild_prefix_location = []
|
|
344
443
|
wild_location = []
|
|
@@ -377,7 +476,8 @@ def mg_dir(args, config, console):
|
|
|
377
476
|
dest_list = "\n\t".join([os.path.relpath(d) for d in destination])
|
|
378
477
|
error(f'Multiple matches with [BLUE:{search_name}]: \n\t{dest_list}')
|
|
379
478
|
|
|
380
|
-
colour.write(
|
|
479
|
+
colour.write(absolute_repo_path(args, destination[0]))
|
|
480
|
+
|
|
381
481
|
else:
|
|
382
482
|
colour.write(os.path.dirname(args.configuration_file))
|
|
383
483
|
|
|
@@ -445,17 +545,23 @@ def run_git_command(args, config, console):
|
|
|
445
545
|
"""Run a command in each of the working trees, optionally continuing if
|
|
446
546
|
there's an error"""
|
|
447
547
|
|
|
448
|
-
_ = config
|
|
449
548
|
_ = console
|
|
450
549
|
|
|
451
550
|
for repo in select_git_repos(args, config):
|
|
452
551
|
repo_command = [args.command]
|
|
552
|
+
|
|
553
|
+
# Replace 'DEFAULT' in the command with the default branch in the repo
|
|
554
|
+
|
|
453
555
|
for cmd in args.parameters:
|
|
454
556
|
repo_command.append(branch_name(cmd, repo['default branch']))
|
|
455
557
|
|
|
456
558
|
colour.write(f'\n[BOLD:{os.path.relpath(repo.name)}]\n')
|
|
457
559
|
|
|
458
|
-
|
|
560
|
+
# Run the command in the workng tree
|
|
561
|
+
|
|
562
|
+
repo_path = absolute_repo_path(args, repo.name)
|
|
563
|
+
|
|
564
|
+
_, status = git.git_run_status(repo_command, path=repo_path, redirect=False)
|
|
459
565
|
|
|
460
566
|
if status and not args.error_continue:
|
|
461
567
|
sys.exit(status)
|
|
@@ -479,7 +585,7 @@ def parse_command_line():
|
|
|
479
585
|
for c in arg[1:]:
|
|
480
586
|
argv.append('-' + c)
|
|
481
587
|
|
|
482
|
-
# Parse the command line
|
|
588
|
+
# Parse the command line, setting options in the args dataclass appropriately
|
|
483
589
|
|
|
484
590
|
i = 1
|
|
485
591
|
while i < len(argv):
|
|
@@ -525,7 +631,7 @@ def parse_command_line():
|
|
|
525
631
|
args.error_continue = True
|
|
526
632
|
|
|
527
633
|
elif param in ('--help', '-h'):
|
|
528
|
-
|
|
634
|
+
colour.write(HELP_INFO)
|
|
529
635
|
sys.exit(0)
|
|
530
636
|
|
|
531
637
|
elif param[0] == '-':
|
|
@@ -549,8 +655,12 @@ def parse_command_line():
|
|
|
549
655
|
except IndexError:
|
|
550
656
|
error('Missing command')
|
|
551
657
|
|
|
658
|
+
# Save the command parameters
|
|
659
|
+
|
|
552
660
|
args.parameters = argv[i+1:]
|
|
553
661
|
|
|
662
|
+
# Locate the configuration file
|
|
663
|
+
|
|
554
664
|
args.configuration_file = find_configuration(args.default_configuration_file)
|
|
555
665
|
|
|
556
666
|
return args
|
|
@@ -558,16 +668,20 @@ def parse_command_line():
|
|
|
558
668
|
################################################################################
|
|
559
669
|
|
|
560
670
|
COMMANDS = {
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
671
|
+
'clone': mg_clone,
|
|
672
|
+
'init': mg_init,
|
|
673
|
+
'dir': mg_dir,
|
|
674
|
+
'config': mg_config,
|
|
675
|
+
'tag': mg_tag,
|
|
676
|
+
'untag': mg_untag,
|
|
566
677
|
}
|
|
567
678
|
|
|
568
679
|
def main():
|
|
569
680
|
"""Main function"""
|
|
570
681
|
|
|
682
|
+
# Parse the command line and santity check the command to run
|
|
683
|
+
# (if it is an external command we let git worry about it)
|
|
684
|
+
|
|
571
685
|
args = parse_command_line()
|
|
572
686
|
|
|
573
687
|
if args.internal_command and args.command not in COMMANDS:
|
|
@@ -582,12 +696,13 @@ def main():
|
|
|
582
696
|
# Otherwise, fail if we can't find the configuration file.
|
|
583
697
|
|
|
584
698
|
if not args.configuration_file:
|
|
585
|
-
if args.internal_command
|
|
586
|
-
args.
|
|
699
|
+
if args.internal_command:
|
|
700
|
+
if args.command == 'init':
|
|
701
|
+
args.configuration_file = os.path.abspath(args.default_configuration_file)
|
|
587
702
|
else:
|
|
588
703
|
error('Cannot locate configuration file')
|
|
589
704
|
|
|
590
|
-
if os.path.isfile(args.configuration_file):
|
|
705
|
+
if args.configuration_file and os.path.isfile(args.configuration_file):
|
|
591
706
|
config.read(args.configuration_file)
|
|
592
707
|
|
|
593
708
|
# Get the console size
|
skilleter_thingy/thingy/git2.py
CHANGED
|
@@ -109,13 +109,13 @@ def git_run_status(cmd, stdout=None, stderr=None, path=None, redirect=True):
|
|
|
109
109
|
|
|
110
110
|
################################################################################
|
|
111
111
|
|
|
112
|
-
def clone(reponame,
|
|
112
|
+
def clone(reponame, path=None):
|
|
113
113
|
""" Clone a repo """
|
|
114
114
|
|
|
115
115
|
cmd = ['clone', reponame]
|
|
116
116
|
|
|
117
|
-
if
|
|
118
|
-
cmd.append(
|
|
117
|
+
if path:
|
|
118
|
+
cmd.append(path)
|
|
119
119
|
|
|
120
120
|
return git(cmd)
|
|
121
121
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: skilleter_thingy
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.4
|
|
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
|
|
@@ -89,6 +89,8 @@ The command takes a number of options that can be used to select the list of wor
|
|
|
89
89
|
|
|
90
90
|
`--tag TAG` / `-t TAG` Run only in working trees that are tagged with the specified tag
|
|
91
91
|
|
|
92
|
+
`--subdir` / `-s` Run only in working trees that are in the current directory tree.
|
|
93
|
+
|
|
92
94
|
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`.
|
|
93
95
|
|
|
94
96
|
Multigit tags are stored in the configuration file, not within the working tree and each working tree can have multiple tags.
|
|
@@ -97,6 +99,8 @@ Multigit tags are stored in the configuration file, not within the working tree
|
|
|
97
99
|
|
|
98
100
|
Multigit supports a small list of subcommands, each of which are prefixed with a `+` to distinguish them from Git commands:
|
|
99
101
|
|
|
102
|
+
`+clone` - Clone a repo containing a multigit configuration file then clone all the repos specified in the configuration, checking out the default branch in each one.
|
|
103
|
+
|
|
100
104
|
`+init` - Create or update the configuration file
|
|
101
105
|
|
|
102
106
|
`+dir` - Given the name of a working tree, output the location within the multigit tree of that working tree if the name matches uniquely, or the name of the directory where the multigit configuration file resides if no parameter is specified.
|
|
@@ -24,7 +24,7 @@ skilleter_thingy/gl.py,sha256=9zbGpKxw6lX9RghLkdy-Q5sZlqtbB3uGFO04qTu1dH8,5954
|
|
|
24
24
|
skilleter_thingy/gphotosync.py,sha256=M0yzt5IxCHezkCOQwz3Chn8oudY_M7PRffboIUFLedk,22477
|
|
25
25
|
skilleter_thingy/linecount.py,sha256=ehTN6VD76i4U5k6dXuYoiqSRHI67_BP-bziklNAJSKY,4309
|
|
26
26
|
skilleter_thingy/moviemover.py,sha256=QzUAWQzQ1AWWREIhl-VMaLo2h8MMhOekBnao5jGWV1s,4470
|
|
27
|
-
skilleter_thingy/multigit.py,sha256=
|
|
27
|
+
skilleter_thingy/multigit.py,sha256=fcBtZ32sy-GqQ6Qlgr2CbfSg-Qt63i_YGB1AZhBiycg,27659
|
|
28
28
|
skilleter_thingy/photodupe.py,sha256=l0hbzSLb2Vk2ceteg-x9fHXCEE1uUuFo84hz5rsZUPA,4184
|
|
29
29
|
skilleter_thingy/phototidier.py,sha256=BOu-cKHMivDlBqlRqv7sL3J6Ix1K2dxWWNcderldyZo,7818
|
|
30
30
|
skilleter_thingy/py_audit.py,sha256=xJm5k5qyeA6ii8mODa4dOkmP8L1drv94UHuxR54RsIM,4384
|
|
@@ -51,7 +51,7 @@ skilleter_thingy/thingy/dircolors.py,sha256=5NbXMsGWdABLvvZfB70VPmN6N5HyyihfpgoQ
|
|
|
51
51
|
skilleter_thingy/thingy/docker.py,sha256=9EFatudoVPfB1UbDEtzdJDB3o6ToHiNHv8-oLsUeqiQ,2449
|
|
52
52
|
skilleter_thingy/thingy/files.py,sha256=oW6E6WWwVFSUPdrZnKMx7P_w_hh3etjoN7RrqvYHCHc,4705
|
|
53
53
|
skilleter_thingy/thingy/git.py,sha256=5EYzj6kxXZCK8E7AhiNPOyLYydCB86amnU6uyDEPfS4,38902
|
|
54
|
-
skilleter_thingy/thingy/git2.py,sha256=
|
|
54
|
+
skilleter_thingy/thingy/git2.py,sha256=DE6osZamorZZ-351l8W8Z-bSCKSNKSy-45Z2-IVy5rM,37136
|
|
55
55
|
skilleter_thingy/thingy/gitlab.py,sha256=uXAF918xnPk6qQyiwPQDbMZfqtJzhiRqDS7yEtJEIAg,6079
|
|
56
56
|
skilleter_thingy/thingy/path.py,sha256=8uM2Q9zFRWv_SaVOX49PeecQXttl7J6lsmBuRXWsXKY,4732
|
|
57
57
|
skilleter_thingy/thingy/popup.py,sha256=jW-nbpdeswqEMTli7OmBv1J8XQsvFoMI0J33O6dOeu8,2529
|
|
@@ -60,9 +60,9 @@ skilleter_thingy/thingy/run.py,sha256=6SNKWF01fSxzB10GMU9ajraXYZqAL1w0PXkqjJdr1U
|
|
|
60
60
|
skilleter_thingy/thingy/tfm_pane.py,sha256=oqy5zBzKwfbjbGqetbbhpKi4x5He7sl4qkmhUeqtdZc,19789
|
|
61
61
|
skilleter_thingy/thingy/tidy.py,sha256=71DCyj0VJrj52RmjQyj1eOiQJIfy5EIPHuThOrS6ZTA,5876
|
|
62
62
|
skilleter_thingy/thingy/venv_template.py,sha256=SsVNvSwojd8NnFeQaZPCRQYTNdwJRplpZpygbUEXRnY,1015
|
|
63
|
-
skilleter_thingy-0.1.
|
|
64
|
-
skilleter_thingy-0.1.
|
|
65
|
-
skilleter_thingy-0.1.
|
|
66
|
-
skilleter_thingy-0.1.
|
|
67
|
-
skilleter_thingy-0.1.
|
|
68
|
-
skilleter_thingy-0.1.
|
|
63
|
+
skilleter_thingy-0.1.4.dist-info/LICENSE,sha256=ljOS4DjXvqEo5VzGfdaRwgRZPbNScGBmfwyC8PChvmQ,32422
|
|
64
|
+
skilleter_thingy-0.1.4.dist-info/METADATA,sha256=Q5vIUWc88QV0veyF2vOOLhZqkT4W51hXQGUHzOmu73Q,29686
|
|
65
|
+
skilleter_thingy-0.1.4.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
|
|
66
|
+
skilleter_thingy-0.1.4.dist-info/entry_points.txt,sha256=u5ymS-KPljIGTnprV5yJsAjz7qgeT2BZ-Qo_Con_PFM,2145
|
|
67
|
+
skilleter_thingy-0.1.4.dist-info/top_level.txt,sha256=8-JhgToBBiWURunmvfpSxEvNkDHQQ7r25-aBXtZv61g,17
|
|
68
|
+
skilleter_thingy-0.1.4.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|