skilleter-thingy 0.0.96__tar.gz → 0.0.98__tar.gz

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.

Files changed (74) hide show
  1. {skilleter_thingy-0.0.96/skilleter_thingy.egg-info → skilleter_thingy-0.0.98}/PKG-INFO +99 -20
  2. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/README.md +98 -19
  3. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/pyproject.toml +1 -1
  4. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy/multigit.py +95 -57
  5. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy/thingy/colour.py +17 -3
  6. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy/thingy/git2.py +0 -4
  7. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98/skilleter_thingy.egg-info}/PKG-INFO +99 -20
  8. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/LICENSE +0 -0
  9. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/setup.cfg +0 -0
  10. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy/__init__.py +0 -0
  11. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy/addpath.py +0 -0
  12. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy/borger.py +0 -0
  13. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy/box.py +0 -0
  14. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy/console_colours.py +0 -0
  15. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy/diskspacecheck.py +0 -0
  16. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy/docker_purge.py +0 -0
  17. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy/ffind.py +0 -0
  18. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy/ggit.py +0 -0
  19. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy/ggrep.py +0 -0
  20. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy/git_br.py +0 -0
  21. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy/git_ca.py +0 -0
  22. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy/git_cleanup.py +0 -0
  23. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy/git_co.py +0 -0
  24. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy/git_common.py +0 -0
  25. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy/git_hold.py +0 -0
  26. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy/git_mr.py +0 -0
  27. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy/git_parent.py +0 -0
  28. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy/git_review.py +0 -0
  29. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy/git_update.py +0 -0
  30. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy/git_wt.py +0 -0
  31. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy/gitcmp_helper.py +0 -0
  32. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy/gitprompt.py +0 -0
  33. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy/gl.py +0 -0
  34. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy/gphotosync.py +0 -0
  35. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy/linecount.py +0 -0
  36. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy/moviemover.py +0 -0
  37. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy/photodupe.py +0 -0
  38. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy/phototidier.py +0 -0
  39. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy/py_audit.py +0 -0
  40. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy/readable.py +0 -0
  41. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy/remdir.py +0 -0
  42. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy/rmdupe.py +0 -0
  43. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy/rpylint.py +0 -0
  44. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy/splitpics.py +0 -0
  45. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy/strreplace.py +0 -0
  46. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy/sysmon.py +0 -0
  47. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy/tfm.py +0 -0
  48. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy/tfparse.py +0 -0
  49. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy/thingy/__init__.py +0 -0
  50. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy/thingy/dc_curses.py +0 -0
  51. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy/thingy/dc_defaults.py +0 -0
  52. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy/thingy/dc_util.py +0 -0
  53. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy/thingy/dircolors.py +0 -0
  54. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy/thingy/docker.py +0 -0
  55. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy/thingy/files.py +0 -0
  56. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy/thingy/git.py +0 -0
  57. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy/thingy/gitlab.py +0 -0
  58. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy/thingy/path.py +0 -0
  59. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy/thingy/popup.py +0 -0
  60. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy/thingy/process.py +0 -0
  61. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy/thingy/run.py +0 -0
  62. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy/thingy/tfm_pane.py +0 -0
  63. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy/thingy/tidy.py +0 -0
  64. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy/thingy/venv_template.py +0 -0
  65. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy/trimpath.py +0 -0
  66. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy/venv_create.py +0 -0
  67. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy/window_rename.py +0 -0
  68. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy/xchmod.py +0 -0
  69. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy/yamlcheck.py +0 -0
  70. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy.egg-info/SOURCES.txt +0 -0
  71. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy.egg-info/dependency_links.txt +0 -0
  72. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy.egg-info/entry_points.txt +0 -0
  73. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy.egg-info/requires.txt +0 -0
  74. {skilleter_thingy-0.0.96 → skilleter_thingy-0.0.98}/skilleter_thingy.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: skilleter_thingy
3
- Version: 0.0.96
3
+ Version: 0.0.98
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
@@ -36,53 +36,59 @@ This README just contains a summary of the functionality of each command.
36
36
 
37
37
  # Git Repo Management
38
38
 
39
- ## multigit
39
+ ## Multigit
40
40
 
41
- Manage a collection of related git working trees.
41
+ Multigit is a tool for managing a collection of related git working trees.
42
42
 
43
- This is intended for use in a situation where you have a collection of related git working trees organised in a directory hierarchy and not necessarily managed using git submodules or any other tool. It allows you to run git commands on multiple working trees at once, without navigating around the different working trees to do so.
43
+ This is intended for use in a situation where you have a collection of related git working trees organised in a directory hierarchy which aren't managed using git submodules or any other tool. It allows you to run git commands on multiple working trees at once, without navigating around the different working trees to do so and to select which working trees commands are run in.
44
+
45
+ ## Initialisation
44
46
 
45
47
  Start by running ensuring that the default branch (e.g. `main`) is checked out in each of the working trees and, in the top-level directory, run `multigit init` to create the configuration file which, by default is called `multigit.toml` - this is just a text file that sets the configuration for each working tree in terms of name, origin, default branch and location.
46
48
 
49
+ ## Multigit Command Line
50
+
47
51
  The multigit command line format is:
48
52
 
49
53
  multigit OPTIONS COMMAND
50
54
 
51
- Where COMMAND is an internal multigit command if it starts with a '+' and is a git command otherwise.
55
+ Where COMMAND is an internal multigit command if it starts with a `+` and is a git command otherwise (including the additional git commands described in this document).
52
56
 
53
57
  By default, when multigit is invoked with a git command, it runs a the command in each of the working trees selected by the command line options passed to multigit (if no options are specified then the command is run in *all* the working trees.
54
58
 
55
59
  The command takes a number of options that can be used to select the list of working trees that each of the subcommands that it supports runs in:
56
60
 
57
- *--repos REPO / -r REPO* Allows a list of working trees to be specfied, either by path, name or a wildcard matching either.
61
+ `--repos REPO` / `-r REPO` Allows a list of working trees to be specfied, either by path, name or a wildcard matching either.
58
62
 
59
- *--modified / -m* Run only in working trees containing locally modified files
63
+ `--modified` / `-m` Run only in working trees containing locally modified files
60
64
 
61
- *--branched / -b* Run only in working trees where the current branch that is checked out is NOT the default branch
65
+ `--branched` / `-b` Run only in working trees where the current branch that is checked out is NOT the default branch
62
66
 
63
- *--tag TAG / -t TAG* Run only in working trees that are tagged with the specified tag
67
+ `--tag TAG` / `-t TAG` Run only in working trees that are tagged with the specified tag
64
68
 
65
- 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`.
69
+ 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`.
66
70
 
67
71
  Multigit tags are stored in the configuration file, not within the working tree and each working tree can have multiple tags.
68
72
 
73
+ ## Multigit Commands
74
+
69
75
  Multigit supports a small list of subcommands, each of which are prefixed with a `+` to distinguish them from Git commands:
70
76
 
71
- *+init* - Create or update the configuration file
77
+ `+init` - Create or update the configuration file
72
78
 
73
- *+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.
79
+ `+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.
74
80
 
75
- *+config* - Print the name and location of the multigit configuration file.
81
+ `+config` - Print the name and location of the multigit configuration file.
76
82
 
77
- *+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.
83
+ `+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.
78
84
 
79
- *+untag TAG* - Remove the tag from the specified working trees (do nothing if the tag is not applied in the first place).
85
+ `+untag TAG` - Remove the tag from the specified working trees (do nothing if the tag is not applied in the first place).
80
86
 
81
- Any command not prefixed with '+' is run in each of the working trees (filtered by the various multigit options) as a git command.
87
+ Any command *not* prefixed with `+` is run in each of the working trees (filtered by the various multigit options) as a git command.
82
88
 
83
89
  For example; `multigit -m commit -ab` would run `git commit -a` in each of the working trees that is branched and contains modified files.
84
90
 
85
- The `+dir` command can be used with shell aliases (or their equivalent in the user's shell of choice) to create an alias to run, for example, `cd (multigit +dir "$@")` (Bash) or `cd (multigit +dir $argv)` (for the Fish shell) that would cd to the top level direcory.
91
+ The `+dir` command can be used with shell aliases (or their equivalent in the user's shell of choice) to create an alias to run, for example, `cd (multigit +dir "$@")` (Bash) or `cd (multigit +dir $argv)` (for the Fish shell) that would cd to the top level directory.
86
92
 
87
93
  # Miscellaneous Git Utilities
88
94
 
@@ -92,23 +98,96 @@ Output a string containing colour-coded shell nesting level, current directory a
92
98
 
93
99
  # Git Extensions
94
100
 
95
- Due to the way that the git command works, these can be run as they were additional git subcommands.
101
+ Due to the way that the git command works, these can be run as they were additional git subcommands, although, due to a limitation in git, the only things that does not work is the `--help` option where the command has to be run with a hyphen between `git` and the subcommand - for example `git ca --help` does not work, but `git-ca --help` does.
102
+
103
+ ## Branch Names
104
+
105
+ Where one of the git extensions takes an existing branch name as a parameter, the branch name can be abbreviated and the abbreviated form is expanded according to the following rules:
106
+
107
+ * If the specified branch name exactly matches an existing branch, tag or commit ID then that is used (this includes remote branches where appropriate, if no local branches match).
108
+ * Otherwise, the branch name is compared to existing branches (again, including remote branches where appropriate, if no local branches match) and, if the specified name uniquely partially matches an existing branch (optionally using `*` and `?` wildcard characters) that branch is used. If it matches multiple branches than an error is reported.
109
+
110
+ For example, given a repo with the following branches:
111
+
112
+ origin/wombat
113
+ origin/platypus
114
+ wombat
115
+ emu
116
+ battery
117
+ chaos
118
+
119
+ Then:
120
+
121
+ * 'emu' will match 'emu'
122
+ * 'wombat' will match 'wombat' but not 'origin/wombat' since the local branch takes precedence
123
+ * 'at' will match both 'wombat' and 'battery' and will report an error
124
+ * 'pus' will match 'origin/platypus'
125
+
126
+ This is most useful where branches contain ticket numbers so, for instance given a branch called `feature/SKIL-103` you can check it out using `git co 103` assuming no other local branches contain `103` in their name.
127
+
128
+ Note that the concept of the default branch `DEFAULT` mentioned above *only* applies when using the `multigit` command, although some of the commands will treat branches called `master` or `main` as special cases (see the individual command documentation).
96
129
 
97
130
  ## git ca
98
131
 
99
132
  Improved version of 'git commit --amend'. Updates files that are already in the commit and, optionally, adds and commits additional files.
100
133
 
134
+ usage: git-ca [-h] [--added] [--all] [--everything] [--ignored] [--patch] [--verbose] [--dry-run] [files ...]
135
+
136
+ positional arguments:
137
+ files List of files to add to the commit
138
+
139
+ options:
140
+ -h, --help show this help message and exit
141
+ --added, -A Update files in the current commit, including files added with `git add`
142
+ --all, -a Append all locally-modified, tracked files to the current commit
143
+ --everything, -e Append all modified and untracked files to the current commit (implies `~--all`)
144
+ --ignored, -i Include files normally hidden by `.gitignore`
145
+ --patch, -p Use the interactive patch selection interface to chose which changes to commit.
146
+ --verbose, -v Verbose mode
147
+ --dry-run, -D Dry-run
148
+
101
149
  ## git cleanup
102
150
 
103
151
  List or delete branches that have already been merged and delete tracking branches that are no longer on the remote.
104
152
 
153
+ git-cleanup [-h] [--delete] [--master MASTER] [--force] [--unmerged] [--yes] [--debug] [branches ...]
154
+
155
+ positional arguments:
156
+
157
+ branches List of branches to check (default is all branches)
158
+
159
+ options:
160
+ -h, --help show this help message and exit
161
+ --delete, -d Delete all branches that have been merged
162
+ --master MASTER, -m MASTER, --main MASTER
163
+ Specify the master branch (Attempts to read this from GitLab or defaults to "develop" if present or "master" or "main" otherwise
164
+ --force, -f Allow protected branches (e.g. master) to be removed
165
+ --unmerged, -u List branches that have NOT been merged
166
+ --yes, -y Assume "yes" in response to any prompts (e.g. to delete branches)
167
+ --debug Enable debug output
168
+
105
169
  ## git co
106
170
 
107
- Equivalent to 'git checkout' but with intelligent branch matching, so specifying a partial branch name will work if it uniquely matches an existing branch
171
+ 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.
172
+
173
+ git-co [-h] [--branch] [--update] [--rebase] [--force] [--exact] [--debug] branchname
174
+
175
+ positional arguments:
176
+
177
+ branchname The branch name (or a partial name that matches uniquely against a local branch, remote branch, commit ID or tag)
178
+
179
+ options:
180
+ -h, --help show this help message and exit
181
+ --branch, -b Create the specified branch
182
+ --update, -u If a remote branch exists, delete any local branch and check out the remote version
183
+ --rebase, -r Rebase the branch onto its parent after checking it out
184
+ --force, -f When using the update option, recreate the local branch even if it is owned by the current user (based on the author of the most recent commit)
185
+ --exact, -e Do not use branch name matching - check out the branch as specified (if it exists)
186
+ --debug Enable debug output
108
187
 
109
188
  ## git parent
110
189
 
111
- Attempt to determine the parent branch for the specified branch (defaulting to the current one)
190
+ Attempt to determine the parent branch for the specified branch (defaulting to the current one).
112
191
 
113
192
  ## git update
114
193
 
@@ -14,53 +14,59 @@ This README just contains a summary of the functionality of each command.
14
14
 
15
15
  # Git Repo Management
16
16
 
17
- ## multigit
17
+ ## Multigit
18
18
 
19
- Manage a collection of related git working trees.
19
+ Multigit is a tool for managing a collection of related git working trees.
20
20
 
21
- This is intended for use in a situation where you have a collection of related git working trees organised in a directory hierarchy and not necessarily managed using git submodules or any other tool. It allows you to run git commands on multiple working trees at once, without navigating around the different working trees to do so.
21
+ This is intended for use in a situation where you have a collection of related git working trees organised in a directory hierarchy which aren't managed using git submodules or any other tool. It allows you to run git commands on multiple working trees at once, without navigating around the different working trees to do so and to select which working trees commands are run in.
22
+
23
+ ## Initialisation
22
24
 
23
25
  Start by running ensuring that the default branch (e.g. `main`) is checked out in each of the working trees and, in the top-level directory, run `multigit init` to create the configuration file which, by default is called `multigit.toml` - this is just a text file that sets the configuration for each working tree in terms of name, origin, default branch and location.
24
26
 
27
+ ## Multigit Command Line
28
+
25
29
  The multigit command line format is:
26
30
 
27
31
  multigit OPTIONS COMMAND
28
32
 
29
- Where COMMAND is an internal multigit command if it starts with a '+' and is a git command otherwise.
33
+ Where COMMAND is an internal multigit command if it starts with a `+` and is a git command otherwise (including the additional git commands described in this document).
30
34
 
31
35
  By default, when multigit is invoked with a git command, it runs a the command in each of the working trees selected by the command line options passed to multigit (if no options are specified then the command is run in *all* the working trees.
32
36
 
33
37
  The command takes a number of options that can be used to select the list of working trees that each of the subcommands that it supports runs in:
34
38
 
35
- *--repos REPO / -r REPO* Allows a list of working trees to be specfied, either by path, name or a wildcard matching either.
39
+ `--repos REPO` / `-r REPO` Allows a list of working trees to be specfied, either by path, name or a wildcard matching either.
36
40
 
37
- *--modified / -m* Run only in working trees containing locally modified files
41
+ `--modified` / `-m` Run only in working trees containing locally modified files
38
42
 
39
- *--branched / -b* Run only in working trees where the current branch that is checked out is NOT the default branch
43
+ `--branched` / `-b` Run only in working trees where the current branch that is checked out is NOT the default branch
40
44
 
41
- *--tag TAG / -t TAG* Run only in working trees that are tagged with the specified tag
45
+ `--tag TAG` / `-t TAG` Run only in working trees that are tagged with the specified tag
42
46
 
43
- 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`.
47
+ 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`.
44
48
 
45
49
  Multigit tags are stored in the configuration file, not within the working tree and each working tree can have multiple tags.
46
50
 
51
+ ## Multigit Commands
52
+
47
53
  Multigit supports a small list of subcommands, each of which are prefixed with a `+` to distinguish them from Git commands:
48
54
 
49
- *+init* - Create or update the configuration file
55
+ `+init` - Create or update the configuration file
50
56
 
51
- *+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.
57
+ `+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.
52
58
 
53
- *+config* - Print the name and location of the multigit configuration file.
59
+ `+config` - Print the name and location of the multigit configuration file.
54
60
 
55
- *+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.
61
+ `+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.
56
62
 
57
- *+untag TAG* - Remove the tag from the specified working trees (do nothing if the tag is not applied in the first place).
63
+ `+untag TAG` - Remove the tag from the specified working trees (do nothing if the tag is not applied in the first place).
58
64
 
59
- Any command not prefixed with '+' is run in each of the working trees (filtered by the various multigit options) as a git command.
65
+ Any command *not* prefixed with `+` is run in each of the working trees (filtered by the various multigit options) as a git command.
60
66
 
61
67
  For example; `multigit -m commit -ab` would run `git commit -a` in each of the working trees that is branched and contains modified files.
62
68
 
63
- The `+dir` command can be used with shell aliases (or their equivalent in the user's shell of choice) to create an alias to run, for example, `cd (multigit +dir "$@")` (Bash) or `cd (multigit +dir $argv)` (for the Fish shell) that would cd to the top level direcory.
69
+ The `+dir` command can be used with shell aliases (or their equivalent in the user's shell of choice) to create an alias to run, for example, `cd (multigit +dir "$@")` (Bash) or `cd (multigit +dir $argv)` (for the Fish shell) that would cd to the top level directory.
64
70
 
65
71
  # Miscellaneous Git Utilities
66
72
 
@@ -70,23 +76,96 @@ Output a string containing colour-coded shell nesting level, current directory a
70
76
 
71
77
  # Git Extensions
72
78
 
73
- Due to the way that the git command works, these can be run as they were additional git subcommands.
79
+ Due to the way that the git command works, these can be run as they were additional git subcommands, although, due to a limitation in git, the only things that does not work is the `--help` option where the command has to be run with a hyphen between `git` and the subcommand - for example `git ca --help` does not work, but `git-ca --help` does.
80
+
81
+ ## Branch Names
82
+
83
+ Where one of the git extensions takes an existing branch name as a parameter, the branch name can be abbreviated and the abbreviated form is expanded according to the following rules:
84
+
85
+ * If the specified branch name exactly matches an existing branch, tag or commit ID then that is used (this includes remote branches where appropriate, if no local branches match).
86
+ * Otherwise, the branch name is compared to existing branches (again, including remote branches where appropriate, if no local branches match) and, if the specified name uniquely partially matches an existing branch (optionally using `*` and `?` wildcard characters) that branch is used. If it matches multiple branches than an error is reported.
87
+
88
+ For example, given a repo with the following branches:
89
+
90
+ origin/wombat
91
+ origin/platypus
92
+ wombat
93
+ emu
94
+ battery
95
+ chaos
96
+
97
+ Then:
98
+
99
+ * 'emu' will match 'emu'
100
+ * 'wombat' will match 'wombat' but not 'origin/wombat' since the local branch takes precedence
101
+ * 'at' will match both 'wombat' and 'battery' and will report an error
102
+ * 'pus' will match 'origin/platypus'
103
+
104
+ This is most useful where branches contain ticket numbers so, for instance given a branch called `feature/SKIL-103` you can check it out using `git co 103` assuming no other local branches contain `103` in their name.
105
+
106
+ Note that the concept of the default branch `DEFAULT` mentioned above *only* applies when using the `multigit` command, although some of the commands will treat branches called `master` or `main` as special cases (see the individual command documentation).
74
107
 
75
108
  ## git ca
76
109
 
77
110
  Improved version of 'git commit --amend'. Updates files that are already in the commit and, optionally, adds and commits additional files.
78
111
 
112
+ usage: git-ca [-h] [--added] [--all] [--everything] [--ignored] [--patch] [--verbose] [--dry-run] [files ...]
113
+
114
+ positional arguments:
115
+ files List of files to add to the commit
116
+
117
+ options:
118
+ -h, --help show this help message and exit
119
+ --added, -A Update files in the current commit, including files added with `git add`
120
+ --all, -a Append all locally-modified, tracked files to the current commit
121
+ --everything, -e Append all modified and untracked files to the current commit (implies `~--all`)
122
+ --ignored, -i Include files normally hidden by `.gitignore`
123
+ --patch, -p Use the interactive patch selection interface to chose which changes to commit.
124
+ --verbose, -v Verbose mode
125
+ --dry-run, -D Dry-run
126
+
79
127
  ## git cleanup
80
128
 
81
129
  List or delete branches that have already been merged and delete tracking branches that are no longer on the remote.
82
130
 
131
+ git-cleanup [-h] [--delete] [--master MASTER] [--force] [--unmerged] [--yes] [--debug] [branches ...]
132
+
133
+ positional arguments:
134
+
135
+ branches List of branches to check (default is all branches)
136
+
137
+ options:
138
+ -h, --help show this help message and exit
139
+ --delete, -d Delete all branches that have been merged
140
+ --master MASTER, -m MASTER, --main MASTER
141
+ Specify the master branch (Attempts to read this from GitLab or defaults to "develop" if present or "master" or "main" otherwise
142
+ --force, -f Allow protected branches (e.g. master) to be removed
143
+ --unmerged, -u List branches that have NOT been merged
144
+ --yes, -y Assume "yes" in response to any prompts (e.g. to delete branches)
145
+ --debug Enable debug output
146
+
83
147
  ## git co
84
148
 
85
- Equivalent to 'git checkout' but with intelligent branch matching, so specifying a partial branch name will work if it uniquely matches an existing branch
149
+ 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.
150
+
151
+ git-co [-h] [--branch] [--update] [--rebase] [--force] [--exact] [--debug] branchname
152
+
153
+ positional arguments:
154
+
155
+ branchname The branch name (or a partial name that matches uniquely against a local branch, remote branch, commit ID or tag)
156
+
157
+ options:
158
+ -h, --help show this help message and exit
159
+ --branch, -b Create the specified branch
160
+ --update, -u If a remote branch exists, delete any local branch and check out the remote version
161
+ --rebase, -r Rebase the branch onto its parent after checking it out
162
+ --force, -f When using the update option, recreate the local branch even if it is owned by the current user (based on the author of the most recent commit)
163
+ --exact, -e Do not use branch name matching - check out the branch as specified (if it exists)
164
+ --debug Enable debug output
86
165
 
87
166
  ## git parent
88
167
 
89
- Attempt to determine the parent branch for the specified branch (defaulting to the current one)
168
+ Attempt to determine the parent branch for the specified branch (defaulting to the current one).
90
169
 
91
170
  ## git update
92
171
 
@@ -7,7 +7,7 @@ name = "skilleter_thingy"
7
7
 
8
8
  # Version must be incremented to install updated Thingy
9
9
 
10
- version = "0.0.96"
10
+ version = "0.0.98"
11
11
 
12
12
  authors = [
13
13
  {name="John Skilleter", email="john@skilleter.org.uk"},
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env python3
2
2
 
3
- """mg - MultiGit - utility for managing multiple Git repos in a hierarchical directory tree"""
3
+ """mg - MultiGit - utility for managing multiple Git working trees in a hierarchical directory tree"""
4
4
 
5
5
  import os
6
6
  import sys
@@ -14,29 +14,32 @@ import thingy.colour as colour
14
14
 
15
15
  ################################################################################
16
16
 
17
- # DONE: / Output name of each git repo as it is processed as command sits there seeming to do nothing otherwise.
18
- # DONE: Better error-handling - e.g. continue/abort option after failure in one repo
17
+ # DONE: / Output name of each working tree as it is processed as command sits there seeming to do nothing otherwise.
18
+ # DONE: Better error-handling - e.g. continue/abort option after failure in one working tree
19
19
  # DONE: Currently doesn't handle single letter options in concatenated form - e.g. -dv
20
20
  # DONE: Don't save the configuration on exit if it hasn't changed
21
21
  # DONE: Don't use a fixed list of default branch names
22
22
  # 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
23
  # DONE: Use the configuration file
24
- # DONE: command to categorise repos then command line filter to only act on repos in category (in addition to other filtering options) - +tag <TAG> command tags all selected repors and updates the configuration, +untag <TAG> command to remove tags in the same way
24
+ # 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
25
  # DONE: init function
26
26
  # NOPE: Dry-run option - just pass the option to the Git command
27
27
  # 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
28
  # NOPE: Pull/fetch - only output after running command and only if something updated
29
29
  # NOPE: Switch to tomlkit
30
30
  # TODO: -j option to run in parallel - yes, but it will only work with non-interactive Git commands
31
- # TODO: Command that takes partial repo name and either returns full path or pops up window to autocomplete until single match found
31
+ # TODO: Command that takes partial working tree name and either returns full path or pops up window to autocomplete until single match found
32
32
  # TODO: Consistent colours in output
33
- # TODO: If run in a subdirectory, only process repos in that tree (or have an option to do so)
34
33
  # TODO: Option to +dir to return all matches so that caller can select one they want
35
34
  # TODO: Verbose option
36
35
  # TODO: When filtering by tag, if tag starts with '!' only match if tag isn't present (and don't allow '!' at start of tag otherwise)
37
- # TODO: When specifying list of repos, if repo name doesn't contain '/' prefix it with '*'?
36
+ # DONE: When specifying list of working trees, if name doesn't contain '/' prefix it with '*'?
38
37
  # TODO: select_git_repos() and +dir should use consist way of selecting repos if possible
39
38
  # TODO: +run command to do things other than git commands
39
+ # TODO: init option '--update' to update the configuration file with new working trees and remove ones that are no longer there
40
+ # TODO: init option '--set-default' to update the default branch to the current one for specified working trees
41
+ # TODO: Integrate completion with fzf if installed?
42
+ # TODO: 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)
40
43
  ################################################################################
41
44
 
42
45
  DEFAULT_CONFIG_FILE = 'multigit.toml'
@@ -48,7 +51,7 @@ DEFAULT_BRANCH = 'DEFAULT'
48
51
 
49
52
  ################################################################################
50
53
 
51
- HELP_INFO = """usage: multigit [-h] [--verbose] [--quiet] [--config CONFIG] [--directory DIRECTORY] [--repos REPOS] [--modified] [--branched] [--tag TAGS]
54
+ HELP_INFO = """usage: multigit [-h] [--verbose] [--quiet] [--config CONFIG] [--repos REPOS] [--modified] [--branched] [--tag TAGS]
52
55
  {+init, +config, +dir, GIT_COMMAND} ...
53
56
 
54
57
  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
@@ -59,8 +62,6 @@ options:
59
62
  --quiet, -q Minimal console output
60
63
  --config CONFIG, -c CONFIG
61
64
  The configuration file (defaults to multigit.toml)
62
- --directory DIRECTORY, --dir DIRECTORY
63
- The top-level directory of the multigit tree (defaults to the current directory)
64
65
  --repos REPOS, -r REPOS
65
66
  The repo names to work on (defaults to all repos and can contain shell wildcards and can be issued multiple times on the command line)
66
67
  --modified, -m Select repos that have local modifications
@@ -85,18 +86,38 @@ Sub-commands:
85
86
  class Arguments():
86
87
  """Data class to contain command line options and parameters"""
87
88
 
89
+ # Command line options for output noise
90
+
88
91
  quiet: bool = False
89
92
  verbose: bool = False
90
- configuration_file: str = DEFAULT_CONFIG_FILE
91
- directory: str = '.'
93
+
94
+ # True if we continue after a git command returns an error
95
+
96
+ error_continue: bool = False
97
+
98
+ # Default and current configuration file
99
+
100
+ default_configuration_file: str = DEFAULT_CONFIG_FILE
101
+ configuration_file: str = None
102
+
103
+ # Command line filter options
104
+
92
105
  repos: list[str] = field(default_factory=list)
93
106
  tag: list[str] = field(default_factory=list)
94
107
  modified: bool = False
95
108
  branched: bool = False
109
+
110
+ # Command to run with parameters
111
+
96
112
  command: str = None
97
- error_continue: bool = False
98
113
  parameters: list[str] = field(default_factory=list)
114
+
115
+ # True if running an internal command
116
+
99
117
  internal_command: bool = False
118
+
119
+ # True if the configuration data needs to be written back on completion
120
+
100
121
  config_modified: bool = False
101
122
 
102
123
  ################################################################################
@@ -109,21 +130,21 @@ def error(msg, status=1):
109
130
 
110
131
  ################################################################################
111
132
 
112
- def find_configuration(args):
133
+ def find_configuration(default_config_file):
113
134
  """If the configuration file name has path elements, try and read it, otherwise
114
135
  search up the directory tree looking for the configuration file.
115
136
  Returns configuration file path or None if the configuration file
116
137
  could not be found."""
117
138
 
118
- if '/' in args.configuration_file:
119
- config_file = args.configuration_file
139
+ if '/' in default_config_file:
140
+ config_file = default_config_file
120
141
  else:
121
142
  config_path = os.getcwd()
122
- config_file = os.path.join(config_path, args.configuration_file)
143
+ config_file = os.path.join(config_path, default_config_file)
123
144
 
124
145
  while not os.path.isfile(config_file) and config_path != '/':
125
146
  config_path = os.path.dirname(config_path)
126
- config_file = os.path.join(config_path, args.configuration_file)
147
+ config_file = os.path.join(config_path, default_config_file)
127
148
 
128
149
  return config_file if os.path.isfile(config_file) else None
129
150
 
@@ -132,18 +153,11 @@ def find_configuration(args):
132
153
  def show_progress(width, msg):
133
154
  """Show a single line progress message"""
134
155
 
135
- name = msg[:width-1]
136
-
137
- colour.write(f'{name}', newline=False)
138
-
139
- if len(name) < width-1:
140
- colour.write(' '*(width-len(name)), newline=False)
141
-
142
- colour.write('\r', newline=False)
156
+ colour.write(msg[:width-1], newline=False, cleareol=True, cr=True)
143
157
 
144
158
  ################################################################################
145
159
 
146
- def find_git_repos(args):
160
+ def find_working_trees(args):
147
161
  """Locate and return a list of '.git' directory parent directories in the
148
162
  specified path.
149
163
 
@@ -250,29 +264,49 @@ def mg_init(args, config, console):
250
264
 
251
265
  if args.modified or args.branched or args.tag:
252
266
  error('The "--tag", "--modified" and "--branched" options cannot be used with the "init" subcommand')
253
- elif not config:
254
- error(f'Unable to location configuration file "{args.configuration_file}"')
255
-
256
- # TODO: Update should remove or warn about repos that are no longer present
257
267
 
258
- # Search for .git directories
268
+ # Search for .git directories and add any that aren't already in the configuration
259
269
 
260
- for repo in find_git_repos(args):
270
+ repo_list = []
271
+ for repo in find_working_trees(args):
261
272
  if not args.quiet:
262
- show_progress(console.columns, repo.name)
273
+ show_progress(console.columns, repo)
274
+
275
+ repo_list.append(repo)
263
276
 
264
277
  if repo not in config:
278
+ default_branch = git.branch(path=repo)
279
+
265
280
  config[repo] = {
266
- 'default branch': git.branch(path=repo)
281
+ 'default branch': default_branch
267
282
  }
268
283
 
269
- remote = git.remotes(path=repo)
284
+ remote = git.remotes(path=repo)
270
285
 
271
- if 'origin' in remote:
272
- config[repo]['origin'] = remote['origin']
273
- config[repo]['repo name']= os.path.basename(remote['origin']).removesuffix('.git')
274
- else:
275
- config[repo]['repo name'] = os.path.basename(repo)
286
+ if 'origin' in remote:
287
+ config[repo]['origin'] = remote['origin']
288
+ config[repo]['repo name']= os.path.basename(remote['origin']).removesuffix('.git')
289
+ else:
290
+ config[repo]['repo name'] = os.path.basename(repo)
291
+
292
+ colour.write(f'Added [BOLD:{repo}] with default branch [BLUE:{default_branch}]')
293
+
294
+ if not args.quiet:
295
+ colour.write(cleareol=True)
296
+
297
+ # Look for configuration entries that are no longer present and delete them
298
+
299
+ removals = []
300
+
301
+ for repo in config:
302
+ if repo != 'DEFAULT' and repo not in repo_list:
303
+ removals.append(repo)
304
+
305
+ for entry in removals:
306
+ del config[repo]
307
+ colour.write(f'Removed [BOLD:{repo}] as it no longer exists')
308
+
309
+ # The configuration file needs to be updated
276
310
 
277
311
  args.config_modified = True
278
312
 
@@ -445,7 +479,7 @@ def parse_command_line():
445
479
  elif param in ('--config', '-c'):
446
480
  try:
447
481
  i += 1
448
- args.configuration_file = argv[i]
482
+ args.default_configuration_file = argv[i]
449
483
  except IndexError:
450
484
  error('--config - missing configuration file parameter')
451
485
 
@@ -499,37 +533,41 @@ def parse_command_line():
499
533
 
500
534
  args.parameters = argv[i+1:]
501
535
 
502
- args.configuration_file = find_configuration(args)
536
+ args.configuration_file = find_configuration(args.default_configuration_file)
503
537
 
504
538
  return args
505
539
 
506
540
  ################################################################################
507
541
 
542
+ COMMANDS = {
543
+ 'init': mg_init,
544
+ 'dir': mg_dir,
545
+ 'config': mg_config,
546
+ 'tag': mg_tag,
547
+ 'untag': mg_untag,
548
+ }
549
+
508
550
  def main():
509
551
  """Main function"""
510
552
 
511
- commands = {
512
- 'init': mg_init,
513
- 'dir': mg_dir,
514
- 'config': mg_config,
515
- 'tag': mg_tag,
516
- 'untag': mg_untag,
517
- }
518
-
519
553
  args = parse_command_line()
520
554
 
521
- if args.internal_command and args.command not in commands:
555
+ if args.internal_command and args.command not in COMMANDS:
522
556
  error(f'Invalid command "{args.command}"')
523
557
 
524
558
  # If the configuration file exists, read it
525
559
 
526
560
  config = configparser.ConfigParser()
527
561
 
528
- if not (args.internal_command and args.command == 'init'):
529
- if not args.configuration_file:
562
+ # If running the '+init' command without an existing configuration file
563
+ # use the default one (which may have been overridden on the command line)
564
+ # Otherwise, fail if we can't find the configuration file.
565
+
566
+ if not args.configuration_file:
567
+ if args.internal_command and args.command == 'init':
568
+ args.configuration_file = os.path.abspath(args.default_configuration_file)
569
+ else:
530
570
  error('Cannot locate configuration file')
531
- elif not os.path.isfile(args.configuration_file):
532
- error(f'Cannot read configuration file {args.configuration_file}')
533
571
 
534
572
  if os.path.isfile(args.configuration_file):
535
573
  config.read(args.configuration_file)
@@ -548,7 +586,7 @@ def main():
548
586
  if args.internal_command:
549
587
  # Run the subcommand
550
588
 
551
- commands[args.command](args, config, console)
589
+ COMMANDS[args.command](args, config, console)
552
590
 
553
591
  # Save the updated configuration file if it has changed (currently, only the init command will do this).
554
592
 
@@ -42,6 +42,8 @@ _ANSI_BMAGENTA = '\x1b[45m'
42
42
  _ANSI_BCYAN = '\x1b[46m'
43
43
  _ANSI_BWHITE = '\x1b[47m'
44
44
 
45
+ _ANSI_CLEAREOL = '\x1b[K'
46
+
45
47
  # Looking up tables for converting textual colour codes to ANSI codes
46
48
 
47
49
  ANSI_REGEXES = \
@@ -144,7 +146,7 @@ def format(txt):
144
146
 
145
147
  ################################################################################
146
148
 
147
- def write(txt=None, newline=True, stream=sys.stdout, indent=0, strip=False):
149
+ def write(txt=None, newline=True, stream=sys.stdout, indent=0, strip=False, cleareol=False, cr=False):
148
150
  """ Write to the specified stream (defaulting to stdout), converting colour codes to ANSI
149
151
  txt can be None, a string or a list of strings."""
150
152
 
@@ -163,10 +165,22 @@ def write(txt=None, newline=True, stream=sys.stdout, indent=0, strip=False):
163
165
 
164
166
  stream.write(line)
165
167
 
168
+ if cleareol:
169
+ stream.write(_ANSI_CLEAREOL)
170
+
166
171
  if newline or n < len(txt) - 1:
167
172
  stream.write('\n')
168
- elif newline:
169
- stream.write('\n')
173
+ elif cr:
174
+ stream.write('\r')
175
+
176
+ else:
177
+ if cleareol:
178
+ stream.write(_ANSI_CLEAREOL)
179
+
180
+ if newline:
181
+ stream.write('\n')
182
+ elif cr:
183
+ stream.write('\r')
170
184
 
171
185
  ################################################################################
172
186
 
@@ -1106,10 +1106,6 @@ def default_branch():
1106
1106
 
1107
1107
  return None
1108
1108
 
1109
- ################################################################################
1110
-
1111
- return None
1112
-
1113
1109
  ################################################################################
1114
1110
 
1115
1111
  def matching_branch(branchname, case=False):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: skilleter_thingy
3
- Version: 0.0.96
3
+ Version: 0.0.98
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
@@ -36,53 +36,59 @@ This README just contains a summary of the functionality of each command.
36
36
 
37
37
  # Git Repo Management
38
38
 
39
- ## multigit
39
+ ## Multigit
40
40
 
41
- Manage a collection of related git working trees.
41
+ Multigit is a tool for managing a collection of related git working trees.
42
42
 
43
- This is intended for use in a situation where you have a collection of related git working trees organised in a directory hierarchy and not necessarily managed using git submodules or any other tool. It allows you to run git commands on multiple working trees at once, without navigating around the different working trees to do so.
43
+ This is intended for use in a situation where you have a collection of related git working trees organised in a directory hierarchy which aren't managed using git submodules or any other tool. It allows you to run git commands on multiple working trees at once, without navigating around the different working trees to do so and to select which working trees commands are run in.
44
+
45
+ ## Initialisation
44
46
 
45
47
  Start by running ensuring that the default branch (e.g. `main`) is checked out in each of the working trees and, in the top-level directory, run `multigit init` to create the configuration file which, by default is called `multigit.toml` - this is just a text file that sets the configuration for each working tree in terms of name, origin, default branch and location.
46
48
 
49
+ ## Multigit Command Line
50
+
47
51
  The multigit command line format is:
48
52
 
49
53
  multigit OPTIONS COMMAND
50
54
 
51
- Where COMMAND is an internal multigit command if it starts with a '+' and is a git command otherwise.
55
+ Where COMMAND is an internal multigit command if it starts with a `+` and is a git command otherwise (including the additional git commands described in this document).
52
56
 
53
57
  By default, when multigit is invoked with a git command, it runs a the command in each of the working trees selected by the command line options passed to multigit (if no options are specified then the command is run in *all* the working trees.
54
58
 
55
59
  The command takes a number of options that can be used to select the list of working trees that each of the subcommands that it supports runs in:
56
60
 
57
- *--repos REPO / -r REPO* Allows a list of working trees to be specfied, either by path, name or a wildcard matching either.
61
+ `--repos REPO` / `-r REPO` Allows a list of working trees to be specfied, either by path, name or a wildcard matching either.
58
62
 
59
- *--modified / -m* Run only in working trees containing locally modified files
63
+ `--modified` / `-m` Run only in working trees containing locally modified files
60
64
 
61
- *--branched / -b* Run only in working trees where the current branch that is checked out is NOT the default branch
65
+ `--branched` / `-b` Run only in working trees where the current branch that is checked out is NOT the default branch
62
66
 
63
- *--tag TAG / -t TAG* Run only in working trees that are tagged with the specified tag
67
+ `--tag TAG` / `-t TAG` Run only in working trees that are tagged with the specified tag
64
68
 
65
- 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`.
69
+ 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`.
66
70
 
67
71
  Multigit tags are stored in the configuration file, not within the working tree and each working tree can have multiple tags.
68
72
 
73
+ ## Multigit Commands
74
+
69
75
  Multigit supports a small list of subcommands, each of which are prefixed with a `+` to distinguish them from Git commands:
70
76
 
71
- *+init* - Create or update the configuration file
77
+ `+init` - Create or update the configuration file
72
78
 
73
- *+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.
79
+ `+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.
74
80
 
75
- *+config* - Print the name and location of the multigit configuration file.
81
+ `+config` - Print the name and location of the multigit configuration file.
76
82
 
77
- *+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.
83
+ `+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.
78
84
 
79
- *+untag TAG* - Remove the tag from the specified working trees (do nothing if the tag is not applied in the first place).
85
+ `+untag TAG` - Remove the tag from the specified working trees (do nothing if the tag is not applied in the first place).
80
86
 
81
- Any command not prefixed with '+' is run in each of the working trees (filtered by the various multigit options) as a git command.
87
+ Any command *not* prefixed with `+` is run in each of the working trees (filtered by the various multigit options) as a git command.
82
88
 
83
89
  For example; `multigit -m commit -ab` would run `git commit -a` in each of the working trees that is branched and contains modified files.
84
90
 
85
- The `+dir` command can be used with shell aliases (or their equivalent in the user's shell of choice) to create an alias to run, for example, `cd (multigit +dir "$@")` (Bash) or `cd (multigit +dir $argv)` (for the Fish shell) that would cd to the top level direcory.
91
+ The `+dir` command can be used with shell aliases (or their equivalent in the user's shell of choice) to create an alias to run, for example, `cd (multigit +dir "$@")` (Bash) or `cd (multigit +dir $argv)` (for the Fish shell) that would cd to the top level directory.
86
92
 
87
93
  # Miscellaneous Git Utilities
88
94
 
@@ -92,23 +98,96 @@ Output a string containing colour-coded shell nesting level, current directory a
92
98
 
93
99
  # Git Extensions
94
100
 
95
- Due to the way that the git command works, these can be run as they were additional git subcommands.
101
+ Due to the way that the git command works, these can be run as they were additional git subcommands, although, due to a limitation in git, the only things that does not work is the `--help` option where the command has to be run with a hyphen between `git` and the subcommand - for example `git ca --help` does not work, but `git-ca --help` does.
102
+
103
+ ## Branch Names
104
+
105
+ Where one of the git extensions takes an existing branch name as a parameter, the branch name can be abbreviated and the abbreviated form is expanded according to the following rules:
106
+
107
+ * If the specified branch name exactly matches an existing branch, tag or commit ID then that is used (this includes remote branches where appropriate, if no local branches match).
108
+ * Otherwise, the branch name is compared to existing branches (again, including remote branches where appropriate, if no local branches match) and, if the specified name uniquely partially matches an existing branch (optionally using `*` and `?` wildcard characters) that branch is used. If it matches multiple branches than an error is reported.
109
+
110
+ For example, given a repo with the following branches:
111
+
112
+ origin/wombat
113
+ origin/platypus
114
+ wombat
115
+ emu
116
+ battery
117
+ chaos
118
+
119
+ Then:
120
+
121
+ * 'emu' will match 'emu'
122
+ * 'wombat' will match 'wombat' but not 'origin/wombat' since the local branch takes precedence
123
+ * 'at' will match both 'wombat' and 'battery' and will report an error
124
+ * 'pus' will match 'origin/platypus'
125
+
126
+ This is most useful where branches contain ticket numbers so, for instance given a branch called `feature/SKIL-103` you can check it out using `git co 103` assuming no other local branches contain `103` in their name.
127
+
128
+ Note that the concept of the default branch `DEFAULT` mentioned above *only* applies when using the `multigit` command, although some of the commands will treat branches called `master` or `main` as special cases (see the individual command documentation).
96
129
 
97
130
  ## git ca
98
131
 
99
132
  Improved version of 'git commit --amend'. Updates files that are already in the commit and, optionally, adds and commits additional files.
100
133
 
134
+ usage: git-ca [-h] [--added] [--all] [--everything] [--ignored] [--patch] [--verbose] [--dry-run] [files ...]
135
+
136
+ positional arguments:
137
+ files List of files to add to the commit
138
+
139
+ options:
140
+ -h, --help show this help message and exit
141
+ --added, -A Update files in the current commit, including files added with `git add`
142
+ --all, -a Append all locally-modified, tracked files to the current commit
143
+ --everything, -e Append all modified and untracked files to the current commit (implies `~--all`)
144
+ --ignored, -i Include files normally hidden by `.gitignore`
145
+ --patch, -p Use the interactive patch selection interface to chose which changes to commit.
146
+ --verbose, -v Verbose mode
147
+ --dry-run, -D Dry-run
148
+
101
149
  ## git cleanup
102
150
 
103
151
  List or delete branches that have already been merged and delete tracking branches that are no longer on the remote.
104
152
 
153
+ git-cleanup [-h] [--delete] [--master MASTER] [--force] [--unmerged] [--yes] [--debug] [branches ...]
154
+
155
+ positional arguments:
156
+
157
+ branches List of branches to check (default is all branches)
158
+
159
+ options:
160
+ -h, --help show this help message and exit
161
+ --delete, -d Delete all branches that have been merged
162
+ --master MASTER, -m MASTER, --main MASTER
163
+ Specify the master branch (Attempts to read this from GitLab or defaults to "develop" if present or "master" or "main" otherwise
164
+ --force, -f Allow protected branches (e.g. master) to be removed
165
+ --unmerged, -u List branches that have NOT been merged
166
+ --yes, -y Assume "yes" in response to any prompts (e.g. to delete branches)
167
+ --debug Enable debug output
168
+
105
169
  ## git co
106
170
 
107
- Equivalent to 'git checkout' but with intelligent branch matching, so specifying a partial branch name will work if it uniquely matches an existing branch
171
+ 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.
172
+
173
+ git-co [-h] [--branch] [--update] [--rebase] [--force] [--exact] [--debug] branchname
174
+
175
+ positional arguments:
176
+
177
+ branchname The branch name (or a partial name that matches uniquely against a local branch, remote branch, commit ID or tag)
178
+
179
+ options:
180
+ -h, --help show this help message and exit
181
+ --branch, -b Create the specified branch
182
+ --update, -u If a remote branch exists, delete any local branch and check out the remote version
183
+ --rebase, -r Rebase the branch onto its parent after checking it out
184
+ --force, -f When using the update option, recreate the local branch even if it is owned by the current user (based on the author of the most recent commit)
185
+ --exact, -e Do not use branch name matching - check out the branch as specified (if it exists)
186
+ --debug Enable debug output
108
187
 
109
188
  ## git parent
110
189
 
111
- Attempt to determine the parent branch for the specified branch (defaulting to the current one)
190
+ Attempt to determine the parent branch for the specified branch (defaulting to the current one).
112
191
 
113
192
  ## git update
114
193