Compare commits
58 Commits
rkiel-mast
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c8253b8ed3 | ||
|
|
3456564b20 | ||
|
|
ef8877b6e9 | ||
|
|
dc31933d78 | ||
|
|
995d4c779e | ||
|
|
780cd2eaff | ||
|
|
ebefe2acfc | ||
|
|
248bcfeda6 | ||
|
|
4cfb8975ad | ||
|
|
55f2118170 | ||
|
|
7e9338128d | ||
|
|
5b9d2b0711 | ||
|
|
438416bd41 | ||
|
|
2443a88ad7 | ||
|
|
308d62fc86 | ||
|
|
48d64da20b | ||
|
|
604d3d84c4 | ||
|
|
4c4a16af04 | ||
|
|
38dd62aea1 | ||
|
|
6d41728543 | ||
|
|
48f2d0ead0 | ||
|
|
67b09c2cd0 | ||
|
|
a688e646d3 | ||
|
|
fe909bf44f | ||
|
|
cfafb5d694 | ||
|
|
c3079f1e1e | ||
|
|
d2498b699e | ||
|
|
01f3712085 | ||
|
|
1fed862a5f | ||
|
|
0358d9a443 | ||
|
|
0015d4d0ff | ||
|
|
bfaf1a457f | ||
|
|
d5ee0ecc4d | ||
|
|
0bc0293d01 | ||
|
|
ccd3e88b44 | ||
|
|
21532a0334 | ||
|
|
6bbba03a59 | ||
|
|
31e18e7d62 | ||
|
|
ad83eac3ea | ||
|
|
b8702161e4 | ||
|
|
ec5f41c940 | ||
|
|
b606a6a9b6 | ||
|
|
35b68dadf2 | ||
|
|
0e31424185 | ||
|
|
8a4129a507 | ||
|
|
d94948aae1 | ||
|
|
8e0354be69 | ||
|
|
246142d6fd | ||
|
|
82973c3498 | ||
|
|
af91a01f8f | ||
|
|
8ab709a43e | ||
|
|
6c83679f45 | ||
|
|
5fa3c5f719 | ||
|
|
96739bdc76 | ||
|
|
b09accebd0 | ||
|
|
f753b647d3 | ||
|
|
877f06944d | ||
|
|
941aed3389 |
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
node_modules
|
||||
78
FEATURE.md
78
FEATURE.md
@@ -4,76 +4,97 @@
|
||||
|
||||
### Usage
|
||||
|
||||
This utility is built around the standard branch `master` and branches for releases that follow the format of MAJOR.MINOR.PATCH.
|
||||
This feature branch utility is built to work with a set of standard branches (`develop`,`main`,`master`,`release`).
|
||||
These are the starting point branches from which you can create feature branches.
|
||||
It is assumed that your starting point branch exists both locally and remotely.
|
||||
|
||||
Feature branches have specific format: USER-BASE-FEATURE.
|
||||
You can override the default set of standard branches by incorporating a `.git-utilities-rc` file (JSON) into your project repository.
|
||||
Branch names should be limited to a single word.
|
||||
|
||||
* USER is the username as specified by the USER environment variable
|
||||
* BASE is the standard branch or release branch to base the feature branch on
|
||||
* FEATURE is the name of the feature
|
||||
```json
|
||||
{
|
||||
"branches": ["develop", "test", "production"]
|
||||
}
|
||||
```
|
||||
|
||||
Feature branch names have a specific format: USER-BRANCH-DESCRIPTION.
|
||||
|
||||
- USER is the owner of the feature branch and is specified by either the FEATURE_USER or USER environment variables. This should prevent any feature branch name conflicts and make it easier to know who to talk to about deleting old/unused feature branches.
|
||||
- BRANCH is the standard branch from which the feature branch was started
|
||||
- DESCRIPTION is a series of one or more words which describe the feature. The description will be prepended to all commit messages.
|
||||
|
||||
#### Start
|
||||
|
||||
To start a new feature, go to the standard branch or a release branch.
|
||||
To start a new feature, checkout one of the standard branches.
|
||||
Use the `start` subcommand followed by a short series of words to describe the feature.
|
||||
For example, use a bug number and a short phrase as the description.
|
||||
|
||||
```
|
||||
git checkout master
|
||||
git checkout develop
|
||||
feature start 4365 update help
|
||||
```
|
||||
|
||||
Use the `start` subcommand with a feature name.
|
||||
In this example, user `bob` will create a new branch called `bob-develop-4365-update-help`.
|
||||
|
||||
If you start with a branch other than one of the standard branches you will get an error.
|
||||
For example,
|
||||
|
||||
```
|
||||
feature start my new feature
|
||||
```
|
||||
git checkout hotfixes
|
||||
feature start 4365 update help
|
||||
|
||||
For example, a new branch will be created called `rkiel-master-my-new-feature`
|
||||
ERROR: invalid base branch. must be one of: develop, main, master, release
|
||||
```
|
||||
|
||||
#### Commit
|
||||
|
||||
Use the `commit` subcommand to make it easier to write commit messages.
|
||||
No need to specify the `-m` parameter or wrapping the message in quotes.
|
||||
If you forget and pass in `-m` anyway, it will ignore it.
|
||||
Of course, if you forget and pass in `-m` anyway, it will be ignore it.
|
||||
The feature branch description will be prepended to your commit message.
|
||||
For example,
|
||||
|
||||
```
|
||||
feature commit this is a sample commit message
|
||||
feature commit -m this is a sample commit message
|
||||
feature commit corrected spelling mistakes
|
||||
```
|
||||
|
||||
generates the command `git commit -m "this is a sample commit message"`.
|
||||
|
||||
The commit message will be prepended with the feature name. For example,
|
||||
will generate the following commit message:
|
||||
|
||||
```
|
||||
my-feature-name: this is a sample commit message
|
||||
4365-update-help: corrected spelling mistakes
|
||||
```
|
||||
|
||||
If you need to by-pass any git pre-commit hooks, you can use the `-f` option to force the commit.
|
||||
This will invoke the commit with the `--no-verify` option.
|
||||
It will also add `(no-verify)` to the end of your commit message. For example,
|
||||
|
||||
```
|
||||
feature commit -f this is a sample commit message
|
||||
feature commit -m this is a sample commit message -f
|
||||
feature commit -f corrected spelling mistakes
|
||||
```
|
||||
|
||||
generates the command `git commit -m "this is a sample commit message (no-verify)" --no-verify`.
|
||||
will generate the following commit message:
|
||||
|
||||
```
|
||||
4365-update-help: corrected spelling mistakes (no-verify)
|
||||
```
|
||||
|
||||
#### Rebase
|
||||
|
||||
Use the `rebase` subcommand to pull down any changes from the standard branch and then rebase with your feature branch changes.
|
||||
In addition, a backup copy of your feature changes will be pushed out to `origin`.
|
||||
This backup should not be used to collaborate with others. It is just a personal backup and will be deleted and recreated with each `rebase`.
|
||||
This remote backup branch should NEVER be used to collaborate with others.
|
||||
It is just a personal backup and will be deleted and recreated with each `rebase`.
|
||||
|
||||
```
|
||||
feature rebase
|
||||
```
|
||||
|
||||
For example, `rkiel-master-my-new-feature` will be pushed out to `origin`.
|
||||
For example, the `bob-develop-4365-update-help` branch will be pushed out to `origin`.
|
||||
|
||||
#### Merge
|
||||
|
||||
Use the `merge` subcommand to merge your feature branch changes to the standard branch.
|
||||
A `rebase` will be performed automatically before the merge.
|
||||
|
||||
```
|
||||
feature merge
|
||||
@@ -94,11 +115,14 @@ feature end
|
||||
|
||||
Use the `trash` subcommand to forcibly close out the feature.
|
||||
The standard branch will be checkout and the local feature branch will be forcibly deleted.
|
||||
Make sure that your changes have been merged because they will be lost.
|
||||
If there is a backup copy on `origin`, it will also be removed.
|
||||
You must supply the name of the local feature branch on the command line as
|
||||
a confirmation.
|
||||
As a safety precaution, you must supply the name of the local feature branch on the command line as
|
||||
a confirmation. This will hopefully protect you from accidentally running `feature trash` when you meant `feature end`.
|
||||
|
||||
WARNING: Make sure that your changes have been merged because they will be lost.
|
||||
|
||||
For example,
|
||||
|
||||
```
|
||||
feature trash local-branch-confirmation
|
||||
feature trash bob-develop-4365-update-help
|
||||
```
|
||||
|
||||
21
LICENSE.txt
Normal file
21
LICENSE.txt
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2018 Robert Kiel
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
56
README.md
56
README.md
@@ -4,66 +4,38 @@ This is a collection of simple command-line scripts, bash aliases, and bash util
|
||||
|
||||
The command-line scripts include:
|
||||
|
||||
* [feature](FEATURE.md) - make working with feature branches easier
|
||||
* [release](RELEASE.md)- make working with release branches and tags easier
|
||||
* [xgrep](XGREP.md)- make using `git-grep` easier
|
||||
- [feature](FEATURE.md) - make working with feature branches easier
|
||||
- [release](RELEASE.md)- make working with release branches and tags easier (DEPRECATED)
|
||||
- [xgrep](XGREP.md)- make using `git-grep` easier
|
||||
- [xfind](XFIND.md)- make using `find` easier
|
||||
|
||||
The command-line scripts are written in Ruby 2.x using just the standard libraries and do not require any gems to be installed.
|
||||
For OS X users, these should just work out-of-box.
|
||||
|
||||
The `bash` utilities come directly from the [git source contrib](https://github.com/git/git/tree/master/contrib) and include:
|
||||
|
||||
* support for [tab completion](https://github.com/git/git/tree/master/contrib/completion/git-completion.bash)
|
||||
* support for repository status in your [shell prompt](https://github.com/git/git/tree/master/contrib/completion/git-prompt.sh)
|
||||
- support for [tab completion](https://github.com/git/git/tree/master/contrib/completion/git-completion.bash)
|
||||
- support for repository status in your [shell prompt](https://github.com/git/git/tree/master/contrib/completion/git-prompt.sh)
|
||||
|
||||
## Installation
|
||||
|
||||
Clone the repository
|
||||
|
||||
```
|
||||
mkdir -p ~/GitHub/rkiel
|
||||
cd ~/GitHub/rkiel
|
||||
mkdir -p ~/GitHub/rkiel && cd $_
|
||||
git clone https://github.com/rkiel/git-utilities.git
|
||||
```
|
||||
|
||||
To add the scripts to your path, add the following to `.bash_profile`
|
||||
To update your `.bash_profile` and `.bashrc`.
|
||||
|
||||
```
|
||||
export GIT_UTILITIES_BIN="~/GitHub/rkiel/git-utilities/bin"
|
||||
|
||||
export PATH=${GIT_UTILITIES_BIN}:$PATH
|
||||
cd ~/GitHub/rkiel/git-utilities
|
||||
./install/bin/setup $USER
|
||||
```
|
||||
|
||||
To enable `bash` tab completion for `git` commands, add the following to `.bash_profile` (OS X) or `.bashrc` (Linux)
|
||||
|
||||
```
|
||||
source ~/GitHub/rkiel/git-utilities/dotfiles/git-completion.bash
|
||||
```
|
||||
|
||||
To enable your `bash` prompt to display repository status, add the following to `.bash_profile` (OS X) or `.bashrc` (Linux).
|
||||
```
|
||||
source ~/GitHub/rkiel/git-utilities/dotfiles/git-prompt.sh
|
||||
```
|
||||
|
||||
Here's a sample prompt that includes the current branch (i.e. `$(__git_ps1 " %s")`)
|
||||
|
||||
```
|
||||
export PS1='[\[\e[0;35m\]\u@\h\[\e[0m\] \[\e[1;34m\]\W\[\e[0;32m\]$(__git_ps1 " %s")\[\e[0m\]]\$ '
|
||||
```
|
||||
|
||||
To include the `bash` aliases and enable tab completion for the `feature` script, add the following to `.bashrc`.
|
||||
|
||||
```
|
||||
source ~/GitHub/rkiel/git-utilities/dotfiles/bashrc
|
||||
```
|
||||
|
||||
If your user id (i.e. `env|grep USER`) is generic, such as `ec2-user` or `centos` or `ubuntu`, set a `FEATURE_USER` environment variable in your `.bash_profile`. Either your `USER` or `FEATURE_USER` should be unique relative to all the users who will be creating feature branches in your git repository.
|
||||
|
||||
```
|
||||
export FEATURE_USER=rkiel
|
||||
```
|
||||
## Documention
|
||||
|
||||
* [See feature](FEATURE.md)
|
||||
* [See release](RELEASE.md)
|
||||
* [See xgrep](XGREP.md)
|
||||
- [See feature](FEATURE.md)
|
||||
- [See release](RELEASE.md) (DEPRECATED)
|
||||
- [See xgrep](XGREP.md)
|
||||
- [See xfind](XFIND.md)
|
||||
|
||||
31
RELEASE.md
31
RELEASE.md
@@ -2,11 +2,13 @@
|
||||
|
||||
## Release
|
||||
|
||||
`release` is a command line utility to make working with releases easier. Releases are built and managed using branches and tags.
|
||||
NOTE: This command is DEPRECATED.
|
||||
|
||||
Official release versions are tagged using a simplified [Semantic Versioning](http://semver.org/) format. The tags start with the letter `v` followed by MAJOR.MINOR.PATCH.
|
||||
`release` is a command line utility to make working with releases easier. Releases are built and managed using branches and tags.
|
||||
|
||||
Before a release is tagged with a version, a release candidate branch can be created and used for development. The intent of the release candidate branch is to be short-term support for multiple developers and deployment to test environments. They are prefixed by `rc`.
|
||||
Official release versions are tagged using a simplified [Semantic Versioning](http://semver.org/) format. The tags start with the letter `v` followed by MAJOR.MINOR.PATCH.
|
||||
|
||||
Before a release is tagged with a version, a release candidate branch can be created and used for development. The intent of the release candidate branch is to be short-term support for multiple developers and deployment to test environments. They are prefixed by `rc`.
|
||||
|
||||
### Usage
|
||||
|
||||
@@ -17,7 +19,7 @@ release help
|
||||
release join version
|
||||
release leave
|
||||
release list
|
||||
release start (major|minor|patch) [from] version
|
||||
release start (major|minor|patch) from version [using master]
|
||||
release tab [pattern]
|
||||
release trash local-branch-confirmation
|
||||
```
|
||||
@@ -30,7 +32,7 @@ Create an official release tag.
|
||||
release create version
|
||||
```
|
||||
|
||||
You must be on the `master` branch. The latest code will be pulled from `master` and a tag created for the last commit. For example, the following command will create a `v1.0.0` tag.
|
||||
You must be on the `master` branch. The latest code will be pulled from `master` and a tag created for the last commit. For example, the following command will create a `v1.0.0` tag.
|
||||
|
||||
```bash
|
||||
git checkout master
|
||||
@@ -42,16 +44,23 @@ release create 1.0.0
|
||||
Create a shared, release candidate branch.
|
||||
|
||||
```bash
|
||||
release start (major|minor|patch) [from] version
|
||||
release start (major|minor|patch) from version [using master]
|
||||
```
|
||||
|
||||
The `version` specified must be an existing official release version. The `major`, `minor`, and `patch` options will increment the new version number accordingly. For example, to create a patch update, the following command will create a `rc1.0.1` release candidate branch.
|
||||
The `version` specified must be an existing official release version. The `major`, `minor`, and `patch` options will increment the new version number accordingly. For example, to create a patch update, the following command will create a `rc1.0.1` release candidate branch. If the optional `using master` is not specified, the release candiate branch will be created from the version tag (e.g. `v1.0.0`). Otherwise, the release candiate branch will be created from `master`. Also, if the repository contains a `package.json` file, the `version` property will automatically be set and committed.
|
||||
|
||||
```bash
|
||||
git checkout master
|
||||
release start patch from 1.0.0
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```bash
|
||||
git checkout master
|
||||
release start patch from 1.0.0 from master
|
||||
```
|
||||
|
||||
Once the shared release candidate branch has been created, use `feature` to create and manage personal feature branches.
|
||||
|
||||
#### Join
|
||||
@@ -62,7 +71,7 @@ Join in on using a shared, release candidate branch that someone else has previo
|
||||
release join version
|
||||
```
|
||||
|
||||
The `version` specified must be an existing release candidate branch version. A local tracking branch will be created. For example, the following command will create `rc1.0.1` as a local tracking branch.
|
||||
The `version` specified must be an existing release candidate branch version. A local tracking branch will be created. For example, the following command will create `rc1.0.1` as a local tracking branch.
|
||||
|
||||
```bash
|
||||
git checkout master
|
||||
@@ -79,7 +88,7 @@ Stop using a shared, release candidate branch but leave it intact for others to
|
||||
release leave
|
||||
```
|
||||
|
||||
Your local tracking branch will be forcibly removed. If there are any local changes on the branch, they will be lost. For example, the following command will remove `rc1.0.1` as a local tracking branch.
|
||||
Your local tracking branch will be forcibly removed. If there are any local changes on the branch, they will be lost. For example, the following command will remove `rc1.0.1` as a local tracking branch.
|
||||
|
||||
```bash
|
||||
git checkout rc1.0.1
|
||||
@@ -94,7 +103,7 @@ Finish the release candidate and create an official release.
|
||||
release finish
|
||||
```
|
||||
|
||||
The latest code from the release candidate branch will be pulled and a tag created. The shared release candidate branch will then be removed. For example, the following command will create `v1.0.1` version tag and removed `rc1.0.1` branch.
|
||||
The latest code from the release candidate branch will be pulled and a tag created. The shared release candidate branch will then be removed. For example, the following command will create `v1.0.1` version tag and removed `rc1.0.1` branch.
|
||||
|
||||
```bash
|
||||
git checkout rc1.0.1
|
||||
@@ -117,7 +126,7 @@ Throw away the release candidate.
|
||||
release trash local-branch-confirmation
|
||||
```
|
||||
|
||||
The shared release candidate branch will be forcibly removed and no version tag will be created. The release candidate branch must be checked out and entered as the `local-branch-confirmation`. For example, the following command will remove the `rc1.0.1` release candidate branch.
|
||||
The shared release candidate branch will be forcibly removed and no version tag will be created. The release candidate branch must be checked out and entered as the `local-branch-confirmation`. For example, the following command will remove the `rc1.0.1` release candidate branch.
|
||||
|
||||
```branch
|
||||
git checkout rc1.0.1
|
||||
|
||||
15
XFIND.md
Normal file
15
XFIND.md
Normal file
@@ -0,0 +1,15 @@
|
||||
[<<back](README.md)
|
||||
|
||||
## Xfind utility
|
||||
|
||||
This utility makes it easier to use find.
|
||||
|
||||
```bash
|
||||
Usage: xfind options term(s)
|
||||
-d, --[no-]debug
|
||||
-n NAME include NAME
|
||||
-N NAME exclude NAME
|
||||
-p PATH include PATH
|
||||
-P PATH exclude PATH
|
||||
-h, --help
|
||||
```
|
||||
12
XGREP.md
12
XGREP.md
@@ -3,3 +3,15 @@
|
||||
## Xgrep utility
|
||||
|
||||
This utility makes it easier to use git-grep.
|
||||
|
||||
```bash
|
||||
Usage: xgrep options term(s)
|
||||
-d, --[no-]debug
|
||||
-f, --file
|
||||
-i, --invert
|
||||
-p, --include-path PATHS
|
||||
-P, --exclude-path PATHS
|
||||
-t, --include-type TYPES
|
||||
-T, --exclude-type TYPES
|
||||
-h, --help
|
||||
```
|
||||
|
||||
9
bin/creature
Executable file
9
bin/creature
Executable file
@@ -0,0 +1,9 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const commander = require("commander");
|
||||
const program = new commander.Command();
|
||||
|
||||
program
|
||||
.command("start feature-words", "start a new feature")
|
||||
.command("end", "end a feature")
|
||||
.parse(process.argv);
|
||||
33
bin/creature-end
Executable file
33
bin/creature-end
Executable file
@@ -0,0 +1,33 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const _ = require("lodash");
|
||||
|
||||
const path = x => require("../" + x);
|
||||
const git = path("js/git");
|
||||
const shell = path("js/shell");
|
||||
const commander = path("js/commander");
|
||||
const validate = path("js/validate");
|
||||
|
||||
function endFeatureBranch(dp) {
|
||||
const cmds = [
|
||||
`git checkout ${dp.branch.standard}`,
|
||||
`git branch -d ${dp.branch.current}`
|
||||
];
|
||||
const remoteBranch = _.get(dp, "branch.remote", false);
|
||||
if (remoteBranch) {
|
||||
cmds.push(`git push origin :${remoteBranch}`);
|
||||
}
|
||||
return shell.pipeline(cmds);
|
||||
}
|
||||
|
||||
commander
|
||||
.start()
|
||||
.then(git.gather)
|
||||
.then(commander.echo)
|
||||
// .then(git.setCurrentBranch)
|
||||
// .then(git.parseCurrentBranch)
|
||||
// .then(validate.mustBeFeatureBranch)
|
||||
// .then(git.setStandardBranch)
|
||||
// .then(git.isBranchRemote)
|
||||
// .then(endFeatureBranch)
|
||||
.catch(err => console.error(err));
|
||||
28
bin/creature-start
Executable file
28
bin/creature-start
Executable file
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const _ = require("lodash");
|
||||
|
||||
const path = x => require("../" + x);
|
||||
const git = path("js/git");
|
||||
const shell = path("js/shell");
|
||||
const commander = path("js/commander");
|
||||
const validate = path("js/validate");
|
||||
|
||||
function createFeatureBranch(dp) {
|
||||
return shell.pipeline([
|
||||
"git fetch --prune --prune-tags --tags origin",
|
||||
`git merge origin/${dp.branch.current}`,
|
||||
"git push",
|
||||
`git checkout -b ${dp.branch.feature}`,
|
||||
`git push -u origin ${dp.branch.feature}`
|
||||
]);
|
||||
}
|
||||
|
||||
commander
|
||||
.start()
|
||||
.then(git.setCurrentBranch)
|
||||
.then(validate.currentIsStandardBranch)
|
||||
.then(git.setFeatureBranch)
|
||||
.then(validate.featureIsNotStandardBranch)
|
||||
.then(createFeatureBranch)
|
||||
.catch(err => console.error(err));
|
||||
17
bin/xfind
Executable file
17
bin/xfind
Executable file
@@ -0,0 +1,17 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
require_relative '../lib/xfind/commander'
|
||||
|
||||
if File.exist? './.xfind'
|
||||
project_argv = File.read('./.xfind').split(/\s/).reject { |x| x.strip == "" }
|
||||
argv = project_argv + ARGV
|
||||
else
|
||||
argv = ARGV
|
||||
end
|
||||
|
||||
commander = Xfind::Commander.new(argv)
|
||||
if commander.valid?
|
||||
commander.execute
|
||||
else
|
||||
commander.help
|
||||
end
|
||||
14
dotfiles/bash_profile
Normal file
14
dotfiles/bash_profile
Normal file
@@ -0,0 +1,14 @@
|
||||
export EDITOR=vim
|
||||
|
||||
# generated by ./bin/generate-bash-prompt
|
||||
# export PS1='[\[\e[0;35m\]\u@\h\[\e[0m\] \[\e[1;34m\]\W\[\e[0m\]]\$ '
|
||||
export PS1='[\[\e[0;35m\]\u@\h\[\e[0m\] \[\e[1;34m\]\W\[\e[0;32m\]$(__git_ps1 " %s")\[\e[0m\]]\$ '
|
||||
|
||||
if [ -f ~/.bashrc ]; then
|
||||
source ~/.bashrc
|
||||
fi
|
||||
|
||||
LOCALS=~/.bashrc_local
|
||||
if [ -f $LOCALS ]; then
|
||||
source $LOCALS
|
||||
fi
|
||||
@@ -1,30 +1,30 @@
|
||||
# alias add="git add"
|
||||
alias branch="git branch"
|
||||
alias checkout="git checkout"
|
||||
# alias commit="feature commit"
|
||||
alias pop="git stash pop --index"
|
||||
alias pull="git pull"
|
||||
alias push="git push"
|
||||
alias master="git checkout master"
|
||||
# alias develop="git checkout develop"
|
||||
# alias diff="clear; git diff -w"
|
||||
# alias linuxdiff="/usr/bin/diff"
|
||||
# alias sysdiff="/usr/bin/diff"
|
||||
# alias log="git log --graph --decorate --abbrev-commit --pretty=oneline"
|
||||
# alias log="git log --graph --date=short --pretty=format:'%C(yellow)%h %C(white)%ad %C(black)[%C(green)%an%C(black)] %C(blue)%s%C(yellow)%d'"
|
||||
alias stash="git stash save"
|
||||
# alias status="git status; echo; echo STASH:; git stash list; echo"
|
||||
alias h='history'
|
||||
alias lsa='ls -la'
|
||||
alias lsl='ls -l'
|
||||
alias more='less -RX'
|
||||
alias sl='ls'
|
||||
|
||||
alias a='git add'
|
||||
alias b="git branch"
|
||||
alias branch="git branch"
|
||||
alias c='feature commit'
|
||||
alias checkout="git checkout"
|
||||
alias co='git checkout'
|
||||
alias d='clear; git diff -w'
|
||||
alias l="git log --graph --date=short --pretty=format:'%C(yellow)%h %C(white)%ad %C(black)[%C(green)%an%C(black)] %C(blue)%s%C(yellow)%d'"
|
||||
alias log='git log -w -u'
|
||||
alias m='feature merge'
|
||||
alias master="git checkout master"
|
||||
alias pop="git stash pop --index"
|
||||
alias pull="git pull"
|
||||
alias push="git push"
|
||||
alias r='feature rebase'
|
||||
alias s='git status; echo; echo STASH:; git stash list; echo'
|
||||
alias show='git show -w'
|
||||
alias stash="git stash save"
|
||||
alias x='xgrep'
|
||||
|
||||
|
||||
alias sfind='find . -not \( -type d -name .git -prune \) -not \( -type d -name node_modes -prune \) -and \( -type f \)|sort -f'
|
||||
alias sgrep='find . -not \( -type d -name .git -prune \) -not \( -type d -name node_modes -prune \) -and \( -type f \)|sort -f|xargs grep --color=always'
|
||||
alias cgrep='grep --color=always'
|
||||
@@ -39,14 +39,9 @@ function get_feature_commands()
|
||||
fi
|
||||
}
|
||||
|
||||
function get_release_commands()
|
||||
{
|
||||
if [ -z $2 ] ; then
|
||||
COMPREPLY=(`release tab`)
|
||||
else
|
||||
COMPREPLY=(`release tab $2`)
|
||||
fi
|
||||
}
|
||||
|
||||
complete -F get_feature_commands feature
|
||||
complete -F get_release_commands release
|
||||
|
||||
LOCALS=~/.bashrc_locals
|
||||
if [ -f $LOCALS ]; then
|
||||
source $LOCALS
|
||||
fi
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
293
dotfiles/git-completion.zsh
Normal file
293
dotfiles/git-completion.zsh
Normal file
@@ -0,0 +1,293 @@
|
||||
#compdef git gitk
|
||||
|
||||
# zsh completion wrapper for git
|
||||
#
|
||||
# Copyright (c) 2012-2020 Felipe Contreras <felipe.contreras@gmail.com>
|
||||
#
|
||||
# The recommended way to install this script is to make a copy of it as a
|
||||
# file named '_git' inside any directory in your fpath.
|
||||
#
|
||||
# For example, create a directory '~/.zsh/', copy this file to '~/.zsh/_git',
|
||||
# and then add the following to your ~/.zshrc file:
|
||||
#
|
||||
# fpath=(~/.zsh $fpath)
|
||||
#
|
||||
# You need git's bash completion script installed. By default bash-completion's
|
||||
# location will be used (e.g. pkg-config --variable=completionsdir bash-completion).
|
||||
#
|
||||
# If your bash completion script is somewhere else, you can specify the
|
||||
# location in your ~/.zshrc:
|
||||
#
|
||||
# zstyle ':completion:*:*:git:*' script ~/.git-completion.bash
|
||||
#
|
||||
|
||||
zstyle -T ':completion:*:*:git:*' tag-order && \
|
||||
zstyle ':completion:*:*:git:*' tag-order 'common-commands'
|
||||
|
||||
zstyle -s ":completion:*:*:git:*" script script
|
||||
if [ -z "$script" ]; then
|
||||
local -a locations
|
||||
local e bash_completion
|
||||
|
||||
bash_completion=$(pkg-config --variable=completionsdir bash-completion 2>/dev/null) ||
|
||||
bash_completion='/usr/share/bash-completion/completions/'
|
||||
|
||||
locations=(
|
||||
"$(dirname ${funcsourcetrace[1]%:*})"/git-completion.bash
|
||||
"$HOME/.local/share/bash-completion/completions/git"
|
||||
"$bash_completion/git"
|
||||
'/etc/bash_completion.d/git' # old debian
|
||||
)
|
||||
for e in $locations; do
|
||||
test -f $e && script="$e" && break
|
||||
done
|
||||
fi
|
||||
|
||||
local old_complete="$functions[complete]"
|
||||
functions[complete]=:
|
||||
GIT_SOURCING_ZSH_COMPLETION=y . "$script"
|
||||
functions[complete]="$old_complete"
|
||||
|
||||
__gitcomp ()
|
||||
{
|
||||
emulate -L zsh
|
||||
|
||||
local cur_="${3-$cur}"
|
||||
|
||||
case "$cur_" in
|
||||
--*=)
|
||||
;;
|
||||
--no-*)
|
||||
local c IFS=$' \t\n'
|
||||
local -a array
|
||||
for c in ${=1}; do
|
||||
if [[ $c == "--" ]]; then
|
||||
continue
|
||||
fi
|
||||
c="$c${4-}"
|
||||
case $c in
|
||||
--*=|*.) ;;
|
||||
*) c="$c " ;;
|
||||
esac
|
||||
array+=("$c")
|
||||
done
|
||||
compset -P '*[=:]'
|
||||
compadd -Q -S '' -p "${2-}" -a -- array && _ret=0
|
||||
;;
|
||||
*)
|
||||
local c IFS=$' \t\n'
|
||||
local -a array
|
||||
for c in ${=1}; do
|
||||
if [[ $c == "--" ]]; then
|
||||
c="--no-...${4-}"
|
||||
array+=("$c ")
|
||||
break
|
||||
fi
|
||||
c="$c${4-}"
|
||||
case $c in
|
||||
--*=|*.) ;;
|
||||
*) c="$c " ;;
|
||||
esac
|
||||
array+=("$c")
|
||||
done
|
||||
compset -P '*[=:]'
|
||||
compadd -Q -S '' -p "${2-}" -a -- array && _ret=0
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
__gitcomp_direct ()
|
||||
{
|
||||
emulate -L zsh
|
||||
|
||||
compset -P '*[=:]'
|
||||
compadd -Q -S '' -- ${(f)1} && _ret=0
|
||||
}
|
||||
|
||||
__gitcomp_nl ()
|
||||
{
|
||||
emulate -L zsh
|
||||
|
||||
compset -P '*[=:]'
|
||||
compadd -Q -S "${4- }" -p "${2-}" -- ${(f)1} && _ret=0
|
||||
}
|
||||
|
||||
__gitcomp_file ()
|
||||
{
|
||||
emulate -L zsh
|
||||
|
||||
compadd -f -p "${2-}" -- ${(f)1} && _ret=0
|
||||
}
|
||||
|
||||
__gitcomp_direct_append ()
|
||||
{
|
||||
__gitcomp_direct "$@"
|
||||
}
|
||||
|
||||
__gitcomp_nl_append ()
|
||||
{
|
||||
__gitcomp_nl "$@"
|
||||
}
|
||||
|
||||
__gitcomp_file_direct ()
|
||||
{
|
||||
__gitcomp_file "$1" ""
|
||||
}
|
||||
|
||||
_git_zsh ()
|
||||
{
|
||||
__gitcomp "v1.1"
|
||||
}
|
||||
|
||||
__git_complete_command ()
|
||||
{
|
||||
emulate -L zsh
|
||||
|
||||
local command="$1"
|
||||
local completion_func="_git_${command//-/_}"
|
||||
if (( $+functions[$completion_func] )); then
|
||||
emulate ksh -c $completion_func
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
__git_zsh_bash_func ()
|
||||
{
|
||||
emulate -L ksh
|
||||
|
||||
local command=$1
|
||||
|
||||
__git_complete_command "$command" && return
|
||||
|
||||
local expansion=$(__git_aliased_command "$command")
|
||||
if [ -n "$expansion" ]; then
|
||||
words[1]=$expansion
|
||||
__git_complete_command "$expansion"
|
||||
fi
|
||||
}
|
||||
|
||||
__git_zsh_cmd_common ()
|
||||
{
|
||||
local -a list
|
||||
list=(
|
||||
add:'add file contents to the index'
|
||||
bisect:'find by binary search the change that introduced a bug'
|
||||
branch:'list, create, or delete branches'
|
||||
checkout:'checkout a branch or paths to the working tree'
|
||||
clone:'clone a repository into a new directory'
|
||||
commit:'record changes to the repository'
|
||||
diff:'show changes between commits, commit and working tree, etc'
|
||||
fetch:'download objects and refs from another repository'
|
||||
grep:'print lines matching a pattern'
|
||||
init:'create an empty Git repository or reinitialize an existing one'
|
||||
log:'show commit logs'
|
||||
merge:'join two or more development histories together'
|
||||
mv:'move or rename a file, a directory, or a symlink'
|
||||
pull:'fetch from and merge with another repository or a local branch'
|
||||
push:'update remote refs along with associated objects'
|
||||
rebase:'forward-port local commits to the updated upstream head'
|
||||
reset:'reset current HEAD to the specified state'
|
||||
restore:'restore working tree files'
|
||||
rm:'remove files from the working tree and from the index'
|
||||
show:'show various types of objects'
|
||||
status:'show the working tree status'
|
||||
switch:'switch branches'
|
||||
tag:'create, list, delete or verify a tag object signed with GPG')
|
||||
_describe -t common-commands 'common commands' list && _ret=0
|
||||
}
|
||||
|
||||
__git_zsh_cmd_alias ()
|
||||
{
|
||||
local -a list
|
||||
list=(${${(0)"$(git config -z --get-regexp '^alias\.*')"}#alias.})
|
||||
list=(${(f)"$(printf "%s:alias for '%s'\n" ${(f@)list})"})
|
||||
_describe -t alias-commands 'aliases' list && _ret=0
|
||||
}
|
||||
|
||||
__git_zsh_cmd_all ()
|
||||
{
|
||||
local -a list
|
||||
emulate ksh -c __git_compute_all_commands
|
||||
list=( ${=__git_all_commands} )
|
||||
_describe -t all-commands 'all commands' list && _ret=0
|
||||
}
|
||||
|
||||
__git_zsh_main ()
|
||||
{
|
||||
local curcontext="$curcontext" state state_descr line
|
||||
typeset -A opt_args
|
||||
local -a orig_words
|
||||
|
||||
orig_words=( ${words[@]} )
|
||||
|
||||
_arguments -C \
|
||||
'(-p --paginate --no-pager)'{-p,--paginate}'[pipe all output into ''less'']' \
|
||||
'(-p --paginate)--no-pager[do not pipe git output into a pager]' \
|
||||
'--git-dir=-[set the path to the repository]: :_directories' \
|
||||
'--bare[treat the repository as a bare repository]' \
|
||||
'(- :)--version[prints the git suite version]' \
|
||||
'--exec-path=-[path to where your core git programs are installed]:: :_directories' \
|
||||
'--html-path[print the path where git''s HTML documentation is installed]' \
|
||||
'--info-path[print the path where the Info files are installed]' \
|
||||
'--man-path[print the manpath (see `man(1)`) for the man pages]' \
|
||||
'--work-tree=-[set the path to the working tree]: :_directories' \
|
||||
'--namespace=-[set the git namespace]' \
|
||||
'--no-replace-objects[do not use replacement refs to replace git objects]' \
|
||||
'(- :)--help[prints the synopsis and a list of the most commonly used commands]: :->arg' \
|
||||
'(-): :->command' \
|
||||
'(-)*:: :->arg' && return
|
||||
|
||||
case $state in
|
||||
(command)
|
||||
_tags common-commands alias-commands all-commands
|
||||
while _tags; do
|
||||
_requested common-commands && __git_zsh_cmd_common
|
||||
_requested alias-commands && __git_zsh_cmd_alias
|
||||
_requested all-commands && __git_zsh_cmd_all
|
||||
let _ret || break
|
||||
done
|
||||
;;
|
||||
(arg)
|
||||
local command="${words[1]}" __git_dir
|
||||
|
||||
if (( $+opt_args[--bare] )); then
|
||||
__git_dir='.'
|
||||
else
|
||||
__git_dir=${opt_args[--git-dir]}
|
||||
fi
|
||||
|
||||
(( $+opt_args[--help] )) && command='help'
|
||||
|
||||
words=( ${orig_words[@]} )
|
||||
|
||||
__git_zsh_bash_func $command
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
_git ()
|
||||
{
|
||||
local _ret=1
|
||||
local cur cword prev
|
||||
|
||||
cur=${words[CURRENT]}
|
||||
prev=${words[CURRENT-1]}
|
||||
let cword=CURRENT-1
|
||||
|
||||
if (( $+functions[__${service}_zsh_main] )); then
|
||||
__${service}_zsh_main
|
||||
elif (( $+functions[__${service}_main] )); then
|
||||
emulate ksh -c __${service}_main
|
||||
elif (( $+functions[_${service}] )); then
|
||||
emulate ksh -c _${service}
|
||||
elif (( $+functions[_${service//-/_}] )); then
|
||||
emulate ksh -c _${service//-/_}
|
||||
fi
|
||||
|
||||
let _ret && _default && _ret=0
|
||||
return _ret
|
||||
}
|
||||
|
||||
_git
|
||||
@@ -66,6 +66,19 @@
|
||||
# git always compare HEAD to @{upstream}
|
||||
# svn always compare HEAD to your SVN upstream
|
||||
#
|
||||
# You can change the separator between the branch name and the above
|
||||
# state symbols by setting GIT_PS1_STATESEPARATOR. The default separator
|
||||
# is SP.
|
||||
#
|
||||
# When there is an in-progress operation such as a merge, rebase,
|
||||
# revert, cherry-pick, or bisect, the prompt will include information
|
||||
# related to the operation, often in the form "|<OPERATION-NAME>".
|
||||
#
|
||||
# When the repository has a sparse-checkout, a notification of the form
|
||||
# "|SPARSE" will be included in the prompt. This can be shortened to a
|
||||
# single '?' character by setting GIT_PS1_COMPRESSSPARSESTATE, or omitted
|
||||
# by setting GIT_PS1_OMITSPARSESTATE.
|
||||
#
|
||||
# By default, __git_ps1 will compare HEAD to your SVN upstream if it can
|
||||
# find one, or @{upstream} otherwise. Once you have set
|
||||
# GIT_PS1_SHOWUPSTREAM, you can override it on a per-repository basis by
|
||||
@@ -78,12 +91,14 @@
|
||||
# contains relative to newer annotated tag (v1.6.3.2~35)
|
||||
# branch relative to newer tag or branch (master~4)
|
||||
# describe relative to older annotated tag (v1.6.3.1-13-gdd42c2f)
|
||||
# tag relative to any older tag (v1.6.3.1-13-gdd42c2f)
|
||||
# default exactly matching tag
|
||||
#
|
||||
# If you would like a colored hint about the current dirty state, set
|
||||
# GIT_PS1_SHOWCOLORHINTS to a nonempty value. The colors are based on
|
||||
# the colored output of "git status -sb" and are available only when
|
||||
# using __git_ps1 for PROMPT_COMMAND or precmd.
|
||||
# using __git_ps1 for PROMPT_COMMAND or precmd in Bash,
|
||||
# but always available in Zsh.
|
||||
#
|
||||
# If you would like __git_ps1 to do nothing in the case when the current
|
||||
# directory is set up to be ignored by git, then set
|
||||
@@ -123,6 +138,7 @@ __git_ps1_show_upstream ()
|
||||
done <<< "$output"
|
||||
|
||||
# parse configuration values
|
||||
local option
|
||||
for option in ${GIT_PS1_SHOWUPSTREAM}; do
|
||||
case "$option" in
|
||||
git|svn) upstream="$option" ;;
|
||||
@@ -273,11 +289,43 @@ __git_ps1_colorize_gitstring ()
|
||||
r="$c_clear$r"
|
||||
}
|
||||
|
||||
# Helper function to read the first line of a file into a variable.
|
||||
# __git_eread requires 2 arguments, the file path and the name of the
|
||||
# variable, in that order.
|
||||
__git_eread ()
|
||||
{
|
||||
local f="$1"
|
||||
shift
|
||||
test -r "$f" && read "$@" <"$f"
|
||||
test -r "$1" && IFS=$'\r\n' read "$2" <"$1"
|
||||
}
|
||||
|
||||
# see if a cherry-pick or revert is in progress, if the user has committed a
|
||||
# conflict resolution with 'git commit' in the middle of a sequence of picks or
|
||||
# reverts then CHERRY_PICK_HEAD/REVERT_HEAD will not exist so we have to read
|
||||
# the todo file.
|
||||
__git_sequencer_status ()
|
||||
{
|
||||
local todo
|
||||
if test -f "$g/CHERRY_PICK_HEAD"
|
||||
then
|
||||
r="|CHERRY-PICKING"
|
||||
return 0;
|
||||
elif test -f "$g/REVERT_HEAD"
|
||||
then
|
||||
r="|REVERTING"
|
||||
return 0;
|
||||
elif __git_eread "$g/sequencer/todo" todo
|
||||
then
|
||||
case "$todo" in
|
||||
p[\ \ ]|pick[\ \ ]*)
|
||||
r="|CHERRY-PICKING"
|
||||
return 0
|
||||
;;
|
||||
revert[\ \ ]*)
|
||||
r="|REVERTING"
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
# __git_ps1 accepts 0 or 1 arguments (i.e., format string)
|
||||
@@ -351,8 +399,8 @@ __git_ps1 ()
|
||||
# incorrect.)
|
||||
#
|
||||
local ps1_expanded=yes
|
||||
[ -z "$ZSH_VERSION" ] || [[ -o PROMPT_SUBST ]] || ps1_expanded=no
|
||||
[ -z "$BASH_VERSION" ] || shopt -q promptvars || ps1_expanded=no
|
||||
[ -z "${ZSH_VERSION-}" ] || [[ -o PROMPT_SUBST ]] || ps1_expanded=no
|
||||
[ -z "${BASH_VERSION-}" ] || shopt -q promptvars || ps1_expanded=no
|
||||
|
||||
local repo_info rev_parse_exit_code
|
||||
repo_info="$(git rev-parse --git-dir --is-inside-git-dir \
|
||||
@@ -364,7 +412,7 @@ __git_ps1 ()
|
||||
return $exit
|
||||
fi
|
||||
|
||||
local short_sha
|
||||
local short_sha=""
|
||||
if [ "$rev_parse_exit_code" = "0" ]; then
|
||||
short_sha="${repo_info##*$'\n'}"
|
||||
repo_info="${repo_info%$'\n'*}"
|
||||
@@ -384,6 +432,13 @@ __git_ps1 ()
|
||||
return $exit
|
||||
fi
|
||||
|
||||
local sparse=""
|
||||
if [ -z "${GIT_PS1_COMPRESSSPARSESTATE}" ] &&
|
||||
[ -z "${GIT_PS1_OMITSPARSESTATE}" ] &&
|
||||
[ "$(git config --bool core.sparseCheckout)" = "true" ]; then
|
||||
sparse="|SPARSE"
|
||||
fi
|
||||
|
||||
local r=""
|
||||
local b=""
|
||||
local step=""
|
||||
@@ -392,11 +447,7 @@ __git_ps1 ()
|
||||
__git_eread "$g/rebase-merge/head-name" b
|
||||
__git_eread "$g/rebase-merge/msgnum" step
|
||||
__git_eread "$g/rebase-merge/end" total
|
||||
if [ -f "$g/rebase-merge/interactive" ]; then
|
||||
r="|REBASE-i"
|
||||
else
|
||||
r="|REBASE-m"
|
||||
fi
|
||||
r="|REBASE"
|
||||
else
|
||||
if [ -d "$g/rebase-apply" ]; then
|
||||
__git_eread "$g/rebase-apply/next" step
|
||||
@@ -411,10 +462,8 @@ __git_ps1 ()
|
||||
fi
|
||||
elif [ -f "$g/MERGE_HEAD" ]; then
|
||||
r="|MERGING"
|
||||
elif [ -f "$g/CHERRY_PICK_HEAD" ]; then
|
||||
r="|CHERRY-PICKING"
|
||||
elif [ -f "$g/REVERT_HEAD" ]; then
|
||||
r="|REVERTING"
|
||||
elif __git_sequencer_status; then
|
||||
:
|
||||
elif [ -f "$g/BISECT_LOG" ]; then
|
||||
r="|BISECTING"
|
||||
fi
|
||||
@@ -439,6 +488,8 @@ __git_ps1 ()
|
||||
git describe --contains HEAD ;;
|
||||
(branch)
|
||||
git describe --contains --all HEAD ;;
|
||||
(tag)
|
||||
git describe --tags HEAD ;;
|
||||
(describe)
|
||||
git describe HEAD ;;
|
||||
(* | default)
|
||||
@@ -459,6 +510,7 @@ __git_ps1 ()
|
||||
local i=""
|
||||
local s=""
|
||||
local u=""
|
||||
local h=""
|
||||
local c=""
|
||||
local p=""
|
||||
|
||||
@@ -472,10 +524,9 @@ __git_ps1 ()
|
||||
if [ -n "${GIT_PS1_SHOWDIRTYSTATE-}" ] &&
|
||||
[ "$(git config --bool bash.showDirtyState)" != "false" ]
|
||||
then
|
||||
git diff --no-ext-diff --quiet --exit-code || w="*"
|
||||
if [ -n "$short_sha" ]; then
|
||||
git diff-index --cached --quiet HEAD -- || i="+"
|
||||
else
|
||||
git diff --no-ext-diff --quiet || w="*"
|
||||
git diff --no-ext-diff --cached --quiet || i="+"
|
||||
if [ -z "$short_sha" ] && [ -z "$i" ]; then
|
||||
i="#"
|
||||
fi
|
||||
fi
|
||||
@@ -487,11 +538,16 @@ __git_ps1 ()
|
||||
|
||||
if [ -n "${GIT_PS1_SHOWUNTRACKEDFILES-}" ] &&
|
||||
[ "$(git config --bool bash.showUntrackedFiles)" != "false" ] &&
|
||||
git ls-files --others --exclude-standard --error-unmatch -- ':/*' >/dev/null 2>/dev/null
|
||||
git ls-files --others --exclude-standard --directory --no-empty-directory --error-unmatch -- ':/*' >/dev/null 2>/dev/null
|
||||
then
|
||||
u="%${ZSH_VERSION+%}"
|
||||
fi
|
||||
|
||||
if [ -n "${GIT_PS1_COMPRESSSPARSESTATE}" ] &&
|
||||
[ "$(git config --bool core.sparseCheckout)" = "true" ]; then
|
||||
h="?"
|
||||
fi
|
||||
|
||||
if [ -n "${GIT_PS1_SHOWUPSTREAM-}" ]; then
|
||||
__git_ps1_show_upstream
|
||||
fi
|
||||
@@ -499,9 +555,11 @@ __git_ps1 ()
|
||||
|
||||
local z="${GIT_PS1_STATESEPARATOR-" "}"
|
||||
|
||||
# NO color option unless in PROMPT_COMMAND mode
|
||||
if [ $pcmode = yes ] && [ -n "${GIT_PS1_SHOWCOLORHINTS-}" ]; then
|
||||
__git_ps1_colorize_gitstring
|
||||
# NO color option unless in PROMPT_COMMAND mode or it's Zsh
|
||||
if [ -n "${GIT_PS1_SHOWCOLORHINTS-}" ]; then
|
||||
if [ $pcmode = yes ] || [ -n "${ZSH_VERSION-}" ]; then
|
||||
__git_ps1_colorize_gitstring
|
||||
fi
|
||||
fi
|
||||
|
||||
b=${b##refs/heads/}
|
||||
@@ -510,8 +568,8 @@ __git_ps1 ()
|
||||
b="\${__git_ps1_branch_name}"
|
||||
fi
|
||||
|
||||
local f="$w$i$s$u"
|
||||
local gitstring="$c$b${f:+$z$f}$r$p"
|
||||
local f="$h$w$i$s$u"
|
||||
local gitstring="$c$b${f:+$z$f}${sparse}$r$p"
|
||||
|
||||
if [ $pcmode = yes ]; then
|
||||
if [ "${__git_printf_supports_v-}" != yes ]; then
|
||||
|
||||
15
dotfiles/zprofile
Normal file
15
dotfiles/zprofile
Normal file
@@ -0,0 +1,15 @@
|
||||
export EDITOR=vim
|
||||
|
||||
autoload -Uz vcs_info
|
||||
precmd_vcs_info() { vcs_info }
|
||||
precmd_functions+=( precmd_vcs_info )
|
||||
setopt prompt_subst
|
||||
zstyle ':vcs_info:git:*' formats '%b'
|
||||
|
||||
# generated by ./bin/generate-bash-prompt
|
||||
export PS1='[%B%F{magenta}%n@%m%f%b %B%F{blue}%1d%f%b %B%F{green}'\$vcs_info_msg_0_'%f%b]$ '
|
||||
|
||||
LOCALS=~/.zprofile_locals
|
||||
if [ -f $LOCALS ]; then
|
||||
source $LOCALS
|
||||
fi
|
||||
61
dotfiles/zshrc
Normal file
61
dotfiles/zshrc
Normal file
@@ -0,0 +1,61 @@
|
||||
GIT_UTILITIES_BIN=~/GitHub/rkiel/git-utilities/bin
|
||||
export PATH=${GIT_UTILITIES_BIN}:$PATH
|
||||
|
||||
export EDITOR=vim
|
||||
|
||||
autoload -Uz vcs_info
|
||||
precmd_vcs_info() { vcs_info }
|
||||
precmd_functions+=( precmd_vcs_info )
|
||||
setopt prompt_subst
|
||||
zstyle ':vcs_info:git:*' formats '%b'
|
||||
|
||||
# generated by ./bin/generate-bash-prompt
|
||||
export PS1='[%B%F{magenta}%n@%m%f%b %B%F{blue}%1d%f%b %B%F{green}'\$vcs_info_msg_0_'%f%b]$ '
|
||||
|
||||
alias h='history'
|
||||
alias lsa='ls -la'
|
||||
alias lsl='ls -l'
|
||||
alias more='less -RX'
|
||||
alias sl='ls'
|
||||
|
||||
alias a='git add'
|
||||
alias b="git branch"
|
||||
alias branch="git branch"
|
||||
alias c='feature commit'
|
||||
alias checkout="git checkout"
|
||||
alias co='git checkout'
|
||||
alias d='clear; git diff -w'
|
||||
alias l="git log --graph --date=short --pretty=format:'%C(yellow)%h %C(white)%ad %C(black)[%C(green)%an%C(black)] %C(blue)%s%C(yellow)%d'"
|
||||
alias log='git log -w -u'
|
||||
alias m='feature merge'
|
||||
alias master="git checkout master"
|
||||
alias pop="git stash pop --index"
|
||||
alias pull="git pull"
|
||||
alias push="git push"
|
||||
alias r='feature rebase'
|
||||
alias s='git status; echo; echo STASH:; git stash list; echo'
|
||||
alias show='git show -w'
|
||||
alias stash="git stash save"
|
||||
alias x='xgrep'
|
||||
|
||||
|
||||
alias sfind='find . -not \( -type d -name .git -prune \) -not \( -type d -name node_modes -prune \) -and \( -type f \)|sort -f'
|
||||
alias sgrep='find . -not \( -type d -name .git -prune \) -not \( -type d -name node_modes -prune \) -and \( -type f \)|sort -f|xargs grep --color=always'
|
||||
alias cgrep='grep --color=always'
|
||||
alias vgrep='grep -v'
|
||||
|
||||
function get_feature_commands()
|
||||
{
|
||||
if [ -z $2 ] ; then
|
||||
COMPREPLY=(`feature tab`)
|
||||
else
|
||||
COMPREPLY=(`feature tab $2`)
|
||||
fi
|
||||
}
|
||||
|
||||
complete -F get_feature_commands feature
|
||||
|
||||
LOCALS=~/.zshrc_locals
|
||||
if [ -f $LOCALS ]; then
|
||||
source $LOCALS
|
||||
fi
|
||||
44
install/bin/setup
Executable file
44
install/bin/setup
Executable file
@@ -0,0 +1,44 @@
|
||||
REPO="~/GitHub/rkiel/git-utilities"
|
||||
GIT="~/GitHub/git/git"
|
||||
|
||||
# mkdir ~/GitHub/git && cd $_
|
||||
# git clone https://github.com/git/git.git
|
||||
# cd git
|
||||
# ls|grep -v contrib|xargs rm -rf
|
||||
|
||||
if [ "$2" == "zsh" ] ; then
|
||||
# FILE=~/.zprofile
|
||||
# echo >> $FILE
|
||||
# if [ ! -z "$1" ] ; then
|
||||
# echo "export FEATURE_USER=$1" >> $FILE
|
||||
# fi
|
||||
# echo "GIT_UTILITIES_BIN=${REPO}/bin" >> $FILE
|
||||
# echo "export PATH=${GIT_UTILITIES_BIN}:$PATH" >> $FILE
|
||||
# # echo "source ${REPO}/dotfiles/git-completion.zsh" >> $FILE
|
||||
# # echo "source ${REPO}/dotfiles/git-prompt.sh" >> $FILE
|
||||
# echo "source ${REPO}/dotfiles/zprofile" >> $FILE
|
||||
|
||||
FILE=~/.zshrc
|
||||
echo >> $FILE
|
||||
if [ ! -z "$1" ] ; then
|
||||
echo "export FEATURE_USER=$1" >> $FILE
|
||||
fi
|
||||
echo "GIT_UTILITIES=${REPO}" >> $FILE
|
||||
echo 'source ${GIT_UTILITIES}/dotfiles/zshrc' >> $FILE
|
||||
else
|
||||
FILE=~/.bash_profile
|
||||
echo >> $FILE
|
||||
if [ ! -z "$1" ] ; then
|
||||
echo "export FEATURE_USER=$1" >> $FILE
|
||||
fi
|
||||
echo "GIT_UTILITIES=${REPO}" >> $FILE
|
||||
echo 'export PATH=${GIT_UTILITIES}/bin:$PATH' >> $FILE
|
||||
echo 'source ${GIT_UTILITIES}/dotfiles/git-completion.bash' >> $FILE
|
||||
echo 'source ${GIT_UTILITIES}/dotfiles/git-prompt.sh' >> $FILE
|
||||
echo 'source ${GIT_UTILITIES}/dotfiles/bash_profile' >> $FILE
|
||||
|
||||
FILE=~/.bashrc
|
||||
echo >> $FILE
|
||||
echo "GIT_UTILITIES=${REPO}" >> $FILE
|
||||
echo 'source ${GIT_UTILITIES}/dotfiles/bashrc' >> $FILE
|
||||
fi
|
||||
89
install/lib/setup/commander.rb
Normal file
89
install/lib/setup/commander.rb
Normal file
@@ -0,0 +1,89 @@
|
||||
require 'ostruct'
|
||||
require 'optparse'
|
||||
require 'json'
|
||||
|
||||
require_relative './prompt'
|
||||
|
||||
module Setup
|
||||
|
||||
class Commander
|
||||
|
||||
attr_accessor :options
|
||||
|
||||
def initialize (argv)
|
||||
@options = OpenStruct.new
|
||||
|
||||
@option_parser = OptionParser.new do |op|
|
||||
op.banner = "Usage: setup options"
|
||||
|
||||
op.on('-u','--user USER') do |argument|
|
||||
options.user = argument
|
||||
end
|
||||
|
||||
op.on_tail('-h','--help') do |argument|
|
||||
puts op
|
||||
exit
|
||||
end
|
||||
end
|
||||
|
||||
@option_parser.parse!(argv)
|
||||
options.terms = argv # must be after parse!
|
||||
end
|
||||
|
||||
def valid?
|
||||
options.user
|
||||
end
|
||||
|
||||
def help
|
||||
puts @option_parser
|
||||
exit
|
||||
end
|
||||
|
||||
def execute
|
||||
action = options.action
|
||||
|
||||
|
||||
File.open("#{ENV['HOME']}/.bash_profile", "a") do |f|
|
||||
f.puts
|
||||
f.puts "# added by ~/GitHub/rkiel/git-utilities/install/bin/setup"
|
||||
f.puts 'export GIT_UTILITIES_BIN="~/GitHub/rkiel/git-utilities/bin"'
|
||||
f.puts 'export PATH=${GIT_UTILITIES_BIN}:$PATH'
|
||||
f.puts 'source ~/GitHub/rkiel/git-utilities/dotfiles/git-completion.bash'
|
||||
f.puts 'source ~/GitHub/rkiel/git-utilities/dotfiles/git-prompt.sh'
|
||||
f.puts "export FEATURE_USER=#{options.user}" if options.user
|
||||
f.puts "export PS1='#{Setup::Prompt.new.generate(options)}'"
|
||||
f.puts
|
||||
end
|
||||
|
||||
|
||||
File.open("#{ENV['HOME']}/.bashrc", "a") do |f|
|
||||
f.puts
|
||||
f.puts "# added by ~/GitHub/rkiel/git-utilities/install/bin/setup"
|
||||
f.puts 'source ~/GitHub/rkiel/git-utilities/dotfiles/bashrc'
|
||||
f.puts
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def run_cmd ( cmd )
|
||||
puts
|
||||
puts cmd
|
||||
success = system cmd
|
||||
unless success
|
||||
error "(see above)"
|
||||
end
|
||||
puts
|
||||
end
|
||||
|
||||
def error ( msg )
|
||||
puts
|
||||
puts "ERROR: #{msg}"
|
||||
puts
|
||||
exit
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
114
install/lib/setup/prompt.rb
Normal file
114
install/lib/setup/prompt.rb
Normal file
@@ -0,0 +1,114 @@
|
||||
module Setup
|
||||
|
||||
class Prompt
|
||||
USERNAME = '\u'
|
||||
ABSOLUTE = '\w'
|
||||
RELATIVE = '\W'
|
||||
PROMPT = '\$'
|
||||
HOSTNAME = '\h'
|
||||
GIT = '$(__git_ps1 " %s")'
|
||||
|
||||
# Reset
|
||||
Color_Off='\e[0m' # Text Reset
|
||||
|
||||
# Regular Colors
|
||||
Black='\e[0;30m' # Black
|
||||
Red='\e[0;31m' # Red
|
||||
Green='\e[0;32m' # Green
|
||||
Yellow='\e[0;33m' # Yellow
|
||||
Blue='\e[0;34m' # Blue
|
||||
Purple='\e[0;35m' # Purple
|
||||
Cyan='\e[0;36m' # Cyan
|
||||
White='\e[0;37m' # White
|
||||
|
||||
# Bold
|
||||
BBlack='\e[1;30m' # Black
|
||||
BRed='\e[1;31m' # Red
|
||||
BGreen='\e[1;32m' # Green
|
||||
BYellow='\e[1;33m' # Yellow
|
||||
BBlue='\e[1;34m' # Blue
|
||||
BPurple='\e[1;35m' # Purple
|
||||
BCyan='\e[1;36m' # Cyan
|
||||
BWhite='\e[1;37m' # White
|
||||
|
||||
# Underline
|
||||
UBlack='\e[4;30m' # Black
|
||||
URed='\e[4;31m' # Red
|
||||
UGreen='\e[4;32m' # Green
|
||||
UYellow='\e[4;33m' # Yellow
|
||||
UBlue='\e[4;34m' # Blue
|
||||
UPurple='\e[4;35m' # Purple
|
||||
UCyan='\e[4;36m' # Cyan
|
||||
UWhite='\e[4;37m' # White
|
||||
|
||||
# Background
|
||||
On_Black='\e[40m' # Black
|
||||
On_Red='\e[41m' # Red
|
||||
On_Green='\e[42m' # Green
|
||||
On_Yellow='\e[43m' # Yellow
|
||||
On_Blue='\e[44m' # Blue
|
||||
On_Purple='\e[45m' # Purple
|
||||
On_Cyan='\e[46m' # Cyan
|
||||
On_White='\e[47m' # White
|
||||
|
||||
# High Intensity
|
||||
IBlack='\e[0;90m' # Black
|
||||
IRed='\e[0;91m' # Red
|
||||
IGreen='\e[0;92m' # Green
|
||||
IYellow='\e[0;93m' # Yellow
|
||||
IBlue='\e[0;94m' # Blue
|
||||
IPurple='\e[0;95m' # Purple
|
||||
ICyan='\e[0;96m' # Cyan
|
||||
IWhite='\e[0;97m' # White
|
||||
|
||||
# Bold High Intensity
|
||||
BIBlack='\e[1;90m' # Black
|
||||
BIRed='\e[1;91m' # Red
|
||||
BIGreen='\e[1;92m' # Green
|
||||
BIYellow='\e[1;93m' # Yellow
|
||||
BIBlue='\e[1;94m' # Blue
|
||||
BIPurple='\e[1;95m' # Purple
|
||||
BICyan='\e[1;96m' # Cyan
|
||||
BIWhite='\e[1;97m' # White
|
||||
|
||||
# High Intensity backgrounds
|
||||
On_IBlack='\e[0;100m' # Black
|
||||
On_IRed='\e[0;101m' # Red
|
||||
On_IGreen='\e[0;102m' # Green
|
||||
On_IYellow='\e[0;103m' # Yellow
|
||||
On_IBlue='\e[0;104m' # Blue
|
||||
On_IPurple='\e[0;105m' # Purple
|
||||
On_ICyan='\e[0;106m' # Cyan
|
||||
On_IWhite='\e[0;107m' # White
|
||||
|
||||
def generate (options)
|
||||
values = []
|
||||
values << '['
|
||||
values << color(Purple)
|
||||
values << USERNAME
|
||||
values << '@'
|
||||
values << HOSTNAME
|
||||
values << color(Color_Off)
|
||||
values << ' '
|
||||
values << color(BBlue)
|
||||
values << RELATIVE
|
||||
values << color(Green)
|
||||
values << GIT
|
||||
values << color(Color_Off)
|
||||
values << ']'
|
||||
values << PROMPT
|
||||
values << ' '
|
||||
|
||||
values.join('')
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def color (value)
|
||||
'\['+value+'\]'
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
18
js/branch.js
Normal file
18
js/branch.js
Normal file
@@ -0,0 +1,18 @@
|
||||
let lib;
|
||||
|
||||
// TODO: read from .git-utilities
|
||||
function standard() {
|
||||
return ["master", "release", "main", "develop"];
|
||||
}
|
||||
|
||||
function isStandard(b) {
|
||||
return lib.standard().includes(b);
|
||||
}
|
||||
|
||||
function isNonStandard(b) {
|
||||
return !lib.isStandard(b);
|
||||
}
|
||||
|
||||
lib = { standard, isStandard, isNonStandard };
|
||||
|
||||
module.exports = lib;
|
||||
45
js/commander.js
Normal file
45
js/commander.js
Normal file
@@ -0,0 +1,45 @@
|
||||
const commander = require("commander");
|
||||
const program = new commander.Command();
|
||||
const something = program.parse(process.argv);
|
||||
|
||||
let lib;
|
||||
|
||||
function args() {
|
||||
return something.args;
|
||||
}
|
||||
|
||||
function featureName() {
|
||||
return args().join("-");
|
||||
}
|
||||
|
||||
function parse() {
|
||||
return { program: something };
|
||||
}
|
||||
|
||||
function prefix() {
|
||||
return process.env.FEATURE_USER || process.env.USER;
|
||||
}
|
||||
|
||||
function toPromise(dp) {
|
||||
return Promise.resolve(dp);
|
||||
}
|
||||
|
||||
function echo(dp) {
|
||||
console.log(JSON.stringify(dp, null, 2));
|
||||
return dp;
|
||||
}
|
||||
|
||||
function start() {
|
||||
return toPromise(parse());
|
||||
}
|
||||
|
||||
lib = {
|
||||
args,
|
||||
parse,
|
||||
featureName,
|
||||
prefix,
|
||||
start,
|
||||
echo
|
||||
};
|
||||
|
||||
module.exports = lib;
|
||||
17
js/file.js
Normal file
17
js/file.js
Normal file
@@ -0,0 +1,17 @@
|
||||
const fs = require("fs");
|
||||
const util = require("util");
|
||||
|
||||
let lib;
|
||||
|
||||
function exists(path) {
|
||||
const stat = util.promisify(fs.stat);
|
||||
return stat(path);
|
||||
}
|
||||
|
||||
function read(path) {
|
||||
const readFile = util.promisify(fs.readFile);
|
||||
return readFile(path).then(buffer => buffer.toString("utf-8"));
|
||||
}
|
||||
|
||||
lib = { exists, read };
|
||||
module.exports = lib;
|
||||
130
js/git.js
Normal file
130
js/git.js
Normal file
@@ -0,0 +1,130 @@
|
||||
const _ = require("lodash");
|
||||
|
||||
const path = x => require("../" + x);
|
||||
const commander = path("js/commander");
|
||||
const immutable = path("js/immutable");
|
||||
const shell = path("js/shell");
|
||||
const file = path("js/file");
|
||||
const branch = path("js/branch");
|
||||
|
||||
let lib;
|
||||
|
||||
function setBranch(dp, field, branch) {
|
||||
return immutable.set(dp, `branch.${field}`, branch);
|
||||
}
|
||||
|
||||
function setCurrentBranch(dp) {
|
||||
return file
|
||||
.read(".git/HEAD")
|
||||
.then(contents => contents.split("/"))
|
||||
.then(parts => _.last(parts))
|
||||
.then(last => last.trim())
|
||||
.then(branch => immutable.set(dp, "branch.current", branch));
|
||||
}
|
||||
|
||||
function setStandardAndFeature(dp) {
|
||||
const current = _.get(dp, "branch.current");
|
||||
if (branch.isStandard(current)) {
|
||||
return immutable.set(
|
||||
immutable.set(dp, "branch.standard", current),
|
||||
"branch.feature",
|
||||
false
|
||||
);
|
||||
} else {
|
||||
const parts = current.split("-");
|
||||
if (
|
||||
parts.length > 2 &&
|
||||
commander.prefix() === parts[0] &&
|
||||
branch.isStandard(parts[1])
|
||||
) {
|
||||
return immutable.set(
|
||||
immutable.set(dp, "branch.standard", parts[1]),
|
||||
"branch.feature",
|
||||
current
|
||||
);
|
||||
} else {
|
||||
return immutable.set(
|
||||
immutable.set(dp, "branch.standard", false),
|
||||
"branch.feature",
|
||||
false
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function setRemote(dp) {
|
||||
const current = _.get(dp, "branch.current");
|
||||
if (branch.isStandard(current)) {
|
||||
return immutable.set(dp, "branch.remote", false);
|
||||
} else {
|
||||
return file
|
||||
.exists(`.git/refs/remotes/origin/${current}`)
|
||||
.then(() => immutable.set(dp, "branch.remote", current))
|
||||
.catch(() => immutable.set(dp, "branch.remote", false));
|
||||
}
|
||||
}
|
||||
|
||||
function gather(dp) {
|
||||
return file
|
||||
.exists(".git")
|
||||
.then(() => ({}))
|
||||
.then(lib.setCurrentBranch)
|
||||
.then(lib.setStandardAndFeature)
|
||||
.then(lib.setRemote)
|
||||
.catch(() => {
|
||||
throw "not in GIT_ROOT";
|
||||
});
|
||||
}
|
||||
|
||||
// function setCurrentBranch(dp) {
|
||||
// const cmd = "git rev-parse --abbrev-ref HEAD";
|
||||
//
|
||||
// return shell.capture(cmd).then(x => immutable.set(dp, "branch.current", x));
|
||||
// }
|
||||
|
||||
function setFeatureBranch(dp) {
|
||||
const fb = [
|
||||
commander.prefix(),
|
||||
dp.branch.current,
|
||||
commander.featureName()
|
||||
].join("-");
|
||||
return immutable.set(dp, "branch.feature", fb);
|
||||
}
|
||||
|
||||
function parseCurrentBranch(dp) {
|
||||
const parts = dp.branch.current.split("-");
|
||||
return immutable.set(dp, "branch.parts", parts);
|
||||
}
|
||||
|
||||
function setStandardBranch(dp) {
|
||||
const parts = _.get(dp, "branch.parts", []);
|
||||
return immutable.set(dp, "branch.standard", parts[1]);
|
||||
}
|
||||
|
||||
function isBranchRemote(dp) {
|
||||
const branch = _.get(dp, "branch.current");
|
||||
const cmd = `git branch -r|grep origin|grep -v 'HEAD'|grep ${branch}`;
|
||||
return shell
|
||||
.capture(cmd)
|
||||
.then(x => x.trim())
|
||||
.then(x =>
|
||||
x === ""
|
||||
? immutable.set(dp, "branch.remote", false)
|
||||
: immutable.set(dp, "branch.remote", branch)
|
||||
);
|
||||
}
|
||||
|
||||
lib = {
|
||||
//setCurrentBranch,
|
||||
setFeatureBranch,
|
||||
setStandardBranch,
|
||||
parseCurrentBranch,
|
||||
isBranchRemote,
|
||||
gather,
|
||||
setStandardAndFeature,
|
||||
setCurrentBranch,
|
||||
setRemote,
|
||||
setBranch: _.curry(setBranch)
|
||||
};
|
||||
|
||||
module.exports = lib;
|
||||
13
js/immutable.js
Normal file
13
js/immutable.js
Normal file
@@ -0,0 +1,13 @@
|
||||
const _ = require("lodash");
|
||||
|
||||
let lib;
|
||||
|
||||
function set(dp, path, value) {
|
||||
return _.set(_.assign({}, dp), path, value);
|
||||
}
|
||||
|
||||
lib = {
|
||||
set
|
||||
};
|
||||
|
||||
module.exports = lib;
|
||||
47
js/shell.js
Normal file
47
js/shell.js
Normal file
@@ -0,0 +1,47 @@
|
||||
const _ = require("lodash");
|
||||
const util = require("util");
|
||||
const child_process = require("child_process");
|
||||
const exec = util.promisify(child_process.exec);
|
||||
|
||||
let lib;
|
||||
|
||||
function run(cmd) {
|
||||
return exec(cmd);
|
||||
}
|
||||
|
||||
function capture(cmd) {
|
||||
return lib.run(cmd).then(x => x.stdout.trim());
|
||||
}
|
||||
|
||||
function _something(dp) {
|
||||
return function() {
|
||||
return dp;
|
||||
};
|
||||
}
|
||||
|
||||
function something(cmd, dp) {
|
||||
return lib.run(cmd).then(lib._something(dp));
|
||||
}
|
||||
|
||||
function pipeline(cmds) {
|
||||
return _.reduce(
|
||||
cmds,
|
||||
(accum, elem) => {
|
||||
return accum
|
||||
.then(() => console.log())
|
||||
.then(() => console.log(elem))
|
||||
.then(() => exec(elem));
|
||||
},
|
||||
Promise.resolve({})
|
||||
).then(() => console.log());
|
||||
}
|
||||
|
||||
lib = {
|
||||
_something,
|
||||
run,
|
||||
capture,
|
||||
pipeline,
|
||||
something: _.curry(something)
|
||||
};
|
||||
|
||||
module.exports = lib;
|
||||
50
js/validate.js
Normal file
50
js/validate.js
Normal file
@@ -0,0 +1,50 @@
|
||||
const path = x => require("../" + x);
|
||||
const branch = path("js/branch");
|
||||
const commander = path("js/commander");
|
||||
|
||||
let lib;
|
||||
|
||||
function currentIsStandardBranch(dp) {
|
||||
if (branch.isNonStandard(dp.branch.current)) {
|
||||
const branches = branch
|
||||
.standard()
|
||||
.sort()
|
||||
.join(", ");
|
||||
throw `ERROR: starting branch must be one of: ${branches}`;
|
||||
} else {
|
||||
return dp;
|
||||
}
|
||||
}
|
||||
|
||||
function featureIsNotStandardBranch(dp) {
|
||||
if (branch.isStandard(commander.featureName())) {
|
||||
const branches = branch
|
||||
.standard()
|
||||
.sort()
|
||||
.join(", ");
|
||||
throw `ERROR: feature branch cannot be any of: ${branches}`;
|
||||
} else {
|
||||
return dp;
|
||||
}
|
||||
}
|
||||
|
||||
function mustBeFeatureBranch(dp) {
|
||||
const parts = dp.branch.parts;
|
||||
if (
|
||||
parts.length > 2 &&
|
||||
commander.prefix() === parts[0] &&
|
||||
branch.isStandard(parts[1])
|
||||
) {
|
||||
return dp;
|
||||
} else {
|
||||
throw `ERROR: ${dp.branch.current} is not a feature branch`;
|
||||
}
|
||||
}
|
||||
|
||||
lib = {
|
||||
currentIsStandardBranch,
|
||||
mustBeFeatureBranch,
|
||||
featureIsNotStandardBranch
|
||||
};
|
||||
|
||||
module.exports = lib;
|
||||
@@ -10,6 +10,7 @@ module Feature
|
||||
:help,
|
||||
:end,
|
||||
:rebase,
|
||||
:republish,
|
||||
:merge,
|
||||
:start,
|
||||
:tab,
|
||||
|
||||
@@ -14,18 +14,27 @@ module Feature
|
||||
def execute
|
||||
parts = parse_branch(current_branch)
|
||||
|
||||
standard_branch = parts[:standard]
|
||||
feature_branch = current_branch
|
||||
remote_branch = remote_branch(feature_branch)
|
||||
|
||||
if argv.size == 2
|
||||
merge_to_branch = argv[1]
|
||||
elsif argv.size == 1
|
||||
merge_to_branch = parts[:standard]
|
||||
end
|
||||
|
||||
feature_branch = current_branch
|
||||
|
||||
error "invalid branch: #{merge_to_branch}" unless standard_branches.include? merge_to_branch or merge_to_branch =~ /\d+\.\d+\.\d+/
|
||||
|
||||
# should match rebase
|
||||
git_fetch
|
||||
git_rebase ['origin', standard_branch].join('/')
|
||||
if remote_branch != ""
|
||||
git_remote_branch_delete feature_branch
|
||||
end
|
||||
git_push feature_branch
|
||||
|
||||
git_checkout merge_to_branch
|
||||
git_pull merge_to_branch
|
||||
git_merge feature_branch
|
||||
git_push merge_to_branch
|
||||
git_push_tags
|
||||
|
||||
@@ -21,16 +21,13 @@ module Feature
|
||||
error "USAGE: feature rebase" unless standard_branch
|
||||
error "invalid feature branch: #{feature_branch}" if standard_branches.include? feature_branch
|
||||
|
||||
git_checkout standard_branch
|
||||
git_pull standard_branch
|
||||
git_checkout feature_branch
|
||||
git_rebase standard_branch
|
||||
|
||||
git_fetch
|
||||
git_rebase ['origin', standard_branch].join('/')
|
||||
if remote_branch != ""
|
||||
git_remote_branch_delete feature_branch
|
||||
end
|
||||
|
||||
git_push feature_branch
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
73
lib/feature/republish.rb
Normal file
73
lib/feature/republish.rb
Normal file
@@ -0,0 +1,73 @@
|
||||
require_relative './base'
|
||||
|
||||
module Feature
|
||||
|
||||
class Republish < Feature::Base
|
||||
def valid?
|
||||
argv.size == 1
|
||||
end
|
||||
|
||||
def help
|
||||
"feature republish"
|
||||
end
|
||||
|
||||
def execute
|
||||
parts = parse_branch(current_branch)
|
||||
|
||||
standard_branch = parts[:standard]
|
||||
feature_branch = current_branch
|
||||
remote_branch = remote_branch(feature_branch)
|
||||
|
||||
error "USAGE: feature republish" unless standard_branch
|
||||
error "invalid feature branch: #{feature_branch}" if standard_branches.include? feature_branch
|
||||
|
||||
git_checkout standard_branch
|
||||
git_fetch
|
||||
git_pull standard_branch
|
||||
git_checkout feature_branch
|
||||
git_rebase standard_branch
|
||||
|
||||
if remote_branch != ""
|
||||
git_remote_branch_delete feature_branch
|
||||
end
|
||||
|
||||
git_push feature_branch
|
||||
|
||||
version = package_json_version('0.0.0-0')
|
||||
tags = `git tag -l`.strip.split("\n").select {|x| x.start_with? version}
|
||||
tags = tags.map {|x| x =~ /^\d+.\d+.\d+[-]\d+$/ ? x.split('-').last : '0'}
|
||||
tags = tags.map {|x| x.to_i }
|
||||
tags << 0
|
||||
new_number = tags.uniq.max + 1
|
||||
new_tag = "#{version}-#{new_number}"
|
||||
|
||||
git_local_tag new_tag
|
||||
git_push_tags
|
||||
|
||||
data = republish_push
|
||||
data['push_to'].each do |repo|
|
||||
puts "updating #{repo}"
|
||||
repo_dir = File.join(Dir.pwd, '..', repo)
|
||||
json = package_json_file repo_dir
|
||||
update_tag data['name'], json['dependencies'], new_tag
|
||||
update_tag data['name'], json['devDependencies'], new_tag
|
||||
save_package_json_file json, repo_dir
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def update_tag name, dependencies, new_tag
|
||||
dependencies.keys.each do |key|
|
||||
if key == name
|
||||
value = dependencies[key]
|
||||
parts = value.split('#')
|
||||
dependencies[key] = [parts.first,'#',new_tag].join
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
@@ -17,14 +17,15 @@ module Feature
|
||||
feature_name = feature_words.join('-')
|
||||
feature_branch = "#{ENV['FEATURE_USER']||ENV['USER']}-#{current_branch}-#{feature_name}"
|
||||
|
||||
error "invalid base branch: #{current_branch}" unless standard_branches.include? current_branch or current_branch =~ /\d+\.\d+\.\d+/
|
||||
error "invalid base branch. must be one of: #{standard_branches.sort.join(', ')}" unless standard_branches.include? current_branch or current_branch =~ /\d+\.\d+\.\d+/
|
||||
error "invalid feature branch: #{feature_name}" if standard_branches.include? feature_name
|
||||
|
||||
git_pull current_branch
|
||||
|
||||
git_local_branch_create feature_branch
|
||||
|
||||
git_fetch
|
||||
git_merge ['origin', current_branch].join('/')
|
||||
git_branch feature_branch
|
||||
git_checkout feature_branch
|
||||
git_push feature_branch
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -63,6 +63,9 @@ module Release
|
||||
error "Version branch already exists: #{branch}" if remote_branch(branch) != ""
|
||||
end
|
||||
|
||||
def validate_branch_is_master (branch)
|
||||
error "Branch must be master: #{branch}" if branch != "master"
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
@@ -17,11 +17,11 @@ module Release
|
||||
validate_version_format version
|
||||
|
||||
validate_current_branch_master
|
||||
git_pull current_branch
|
||||
git_fetch_and_merge current_branch
|
||||
|
||||
validate_version_is_new version
|
||||
|
||||
update_package_json version
|
||||
update_package_json version, version
|
||||
|
||||
git_local_tag release_tag_from_version(version)
|
||||
|
||||
|
||||
@@ -16,16 +16,15 @@ module Release
|
||||
|
||||
validate_current_branch_is_release
|
||||
|
||||
git_pull release_branch
|
||||
|
||||
update_package_json version_from_release_branch(release_branch)
|
||||
git_fetch_and_merge release_branch
|
||||
|
||||
git_local_tag release_tag_from_version(version_from_release_branch(release_branch))
|
||||
|
||||
git_push release_branch
|
||||
git_push_tags
|
||||
|
||||
git_checkout "master"
|
||||
git_checkout :master
|
||||
git_fetch_and_merge :master
|
||||
|
||||
git_local_branch_delete release_branch
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ module Release
|
||||
subcommand, version = *argv
|
||||
|
||||
validate_current_branch_master
|
||||
git_pull current_branch
|
||||
git_fetch_and_merge current_branch
|
||||
|
||||
git_checkout_track release_branch_from_version(version)
|
||||
end
|
||||
|
||||
@@ -4,19 +4,30 @@ module Release
|
||||
|
||||
class Leave < Release::Base
|
||||
def valid?
|
||||
argv.size == 1
|
||||
argv.size == 2
|
||||
end
|
||||
|
||||
def help
|
||||
"release leave"
|
||||
"release leave local-branch-confirmation"
|
||||
end
|
||||
|
||||
def execute
|
||||
if argv.size == 2
|
||||
confirmation_branch = argv[1]
|
||||
else
|
||||
confirmation_branch = ''
|
||||
end
|
||||
|
||||
release_branch = current_branch
|
||||
|
||||
error "Missing confirmation of branch: #{release_branch}" if confirmation_branch == ''
|
||||
error "Confirmation branch does not match current branch: #{confirmation_branch} vs #{release_branch}" if release_branch != confirmation_branch
|
||||
validate_current_branch_is_release
|
||||
|
||||
git_checkout "master"
|
||||
|
||||
git_local_branch_trash current_branch
|
||||
git_checkout :master
|
||||
git_fetch_and_merge :master
|
||||
|
||||
git_local_branch_trash release_branch
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -13,8 +13,8 @@ module Release
|
||||
|
||||
def execute
|
||||
validate_current_branch_master
|
||||
git_pull current_branch
|
||||
|
||||
git_fetch_and_merge current_branch
|
||||
|
||||
puts
|
||||
puts show_existing_tags
|
||||
puts
|
||||
|
||||
@@ -4,25 +4,27 @@ module Release
|
||||
|
||||
class Start < Release::Base
|
||||
def valid?
|
||||
argv.size == 3 or argv.size == 4
|
||||
argv.size == 4 or argv.size == 6
|
||||
end
|
||||
|
||||
def help
|
||||
"release start (major|minor|patch) [from] version"
|
||||
"release start (major|minor|patch) from version [using master]"
|
||||
end
|
||||
|
||||
def execute
|
||||
case argv.size
|
||||
when 3
|
||||
subcommand, level, version = *argv
|
||||
when 4
|
||||
subcommand, level, verb, version = *argv
|
||||
starting_branch = nil
|
||||
when 6
|
||||
subcommand, level, verb, version, verb2, starting_branch = *argv
|
||||
validate_branch_is_master(starting_branch)
|
||||
end
|
||||
|
||||
validate_version_format version
|
||||
|
||||
validate_current_branch_master
|
||||
git_pull current_branch
|
||||
git_fetch_and_merge current_branch
|
||||
|
||||
validate_version_exists version
|
||||
|
||||
@@ -38,11 +40,16 @@ module Release
|
||||
error "unknow release level: #{level}"
|
||||
end
|
||||
|
||||
starting_branch = release_tag_from_version(version) unless starting_branch
|
||||
|
||||
validate_version_does_not_exist new_version
|
||||
validate_release_branch_does_not_exist(release_branch_from_version(new_version))
|
||||
|
||||
git_local_branch_create release_branch_from_version(new_version), release_tag_from_version(version)
|
||||
git_local_branch_create release_branch_from_version(new_version), starting_branch
|
||||
git_push_upstream(release_branch_from_version(new_version))
|
||||
|
||||
update_package_json new_version, "#{new_version} started"
|
||||
git_push(release_branch_from_version(new_version))
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
@@ -24,7 +24,8 @@ module Release
|
||||
error "Confirmation branch does not match current branch: #{confirmation_branch} vs #{release_branch}" if release_branch != confirmation_branch
|
||||
validate_current_branch_is_release
|
||||
|
||||
git_checkout 'master'
|
||||
git_checkout :master
|
||||
git_fetch_and_merge :master
|
||||
|
||||
git_local_branch_trash release_branch
|
||||
|
||||
|
||||
@@ -10,7 +10,14 @@ module Shared
|
||||
end
|
||||
|
||||
def standard_branches
|
||||
['master']
|
||||
defaults = ['master','release','main','develop']
|
||||
dot_file = ".git-utilities-rc"
|
||||
if File.exist? dot_file
|
||||
json = JSON.parse(File.read(dot_file))
|
||||
json['branches'] or defaults
|
||||
else
|
||||
defaults
|
||||
end
|
||||
end
|
||||
|
||||
def version_pattern
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
require 'json'
|
||||
require 'yaml'
|
||||
|
||||
module Shared
|
||||
|
||||
@@ -21,14 +22,50 @@ module Shared
|
||||
exit
|
||||
end
|
||||
|
||||
def update_package_json (version)
|
||||
def update_package_json (version, message)
|
||||
if File.exist? 'package.json'
|
||||
package_json = File.read('package.json')
|
||||
json = JSON.parse(package_json)
|
||||
json['version'] = version
|
||||
File.write('package.json', JSON.pretty_generate(json))
|
||||
git_add 'package.json'
|
||||
git_commit version
|
||||
git_commit message, true
|
||||
end
|
||||
end
|
||||
|
||||
def package_json_version (default_value)
|
||||
if File.exist? 'package.json'
|
||||
package_json = File.read('package.json')
|
||||
json = JSON.parse(package_json)
|
||||
json['version']
|
||||
else
|
||||
default_value
|
||||
end
|
||||
end
|
||||
|
||||
def package_json_file (dir = '.')
|
||||
name = File.join(dir, 'package.json')
|
||||
if File.exist? name
|
||||
package_json = File.read(name)
|
||||
JSON.parse(package_json)
|
||||
else
|
||||
{}
|
||||
end
|
||||
end
|
||||
|
||||
def save_package_json_file (json, dir = '.')
|
||||
name = File.join(dir, 'package.json')
|
||||
if File.exist? name
|
||||
File.write(name, JSON.pretty_generate(json))
|
||||
end
|
||||
end
|
||||
|
||||
def republish_push
|
||||
name = '.republish_push.yml'
|
||||
if File.exist? name
|
||||
contents = YAML.load_file(name)
|
||||
else
|
||||
{ "push_to" => [] }
|
||||
end
|
||||
end
|
||||
|
||||
@@ -36,10 +73,6 @@ module Shared
|
||||
run_cmd "git add #{path}"
|
||||
end
|
||||
|
||||
def git_commit (msg)
|
||||
run_cmd "git commit -m '#{msg}'"
|
||||
end
|
||||
|
||||
def git_show_branches
|
||||
run_cmd "git branch"
|
||||
end
|
||||
@@ -48,6 +81,25 @@ module Shared
|
||||
run_cmd "git checkout #{branch}"
|
||||
end
|
||||
|
||||
def git_fetch
|
||||
run_cmd "git fetch origin -p && git fetch origin --tags"
|
||||
end
|
||||
|
||||
def git_remote_merge ( branch )
|
||||
run_cmd "git merge origin/#{branch} -m 'merged by release'"
|
||||
end
|
||||
|
||||
def is_remote_branch (branch)
|
||||
`git branch -r|grep origin|grep -v 'HEAD'|grep #{branch}`.strip != ""
|
||||
end
|
||||
|
||||
def git_fetch_and_merge (branch)
|
||||
git_fetch
|
||||
if is_remote_branch(branch)
|
||||
git_remote_merge branch
|
||||
end
|
||||
end
|
||||
|
||||
def git_remote_branch_delete ( branch )
|
||||
run_cmd "git push origin :#{branch}"
|
||||
end
|
||||
@@ -84,6 +136,10 @@ module Shared
|
||||
run_cmd "git merge #{branch}"
|
||||
end
|
||||
|
||||
def git_branch (branch)
|
||||
run_cmd "git branch #{branch}"
|
||||
end
|
||||
|
||||
def git_push (branch)
|
||||
run_cmd "git push origin #{branch}"
|
||||
end
|
||||
|
||||
117
lib/xfind/commander.rb
Normal file
117
lib/xfind/commander.rb
Normal file
@@ -0,0 +1,117 @@
|
||||
require 'ostruct'
|
||||
require 'optparse'
|
||||
|
||||
module Xfind
|
||||
|
||||
class Commander
|
||||
|
||||
attr_accessor :options
|
||||
|
||||
def initialize (argv)
|
||||
@options = OpenStruct.new
|
||||
options.debug = false
|
||||
options.names = []
|
||||
options.paths = [
|
||||
{exclude: true, pattern: '.git'},
|
||||
{exclude: true, pattern: 'node_modules'}
|
||||
]
|
||||
|
||||
@option_parser = OptionParser.new do |op|
|
||||
op.banner = "Usage: xfind options term(s)"
|
||||
|
||||
op.on('-d','--[no-]debug') do |argument|
|
||||
options.debug = argument
|
||||
end
|
||||
|
||||
op.on('-n NAME', 'include NAME') do |argument|
|
||||
options.names << {exclude: false, pattern: argument}
|
||||
end
|
||||
|
||||
op.on('-N NAME','exclude NAME') do |argument|
|
||||
options.names << {exclude: true, pattern: argument}
|
||||
end
|
||||
|
||||
op.on('-p PATH','include PATH') do |argument|
|
||||
options.paths << {exclude: false, pattern: argument}
|
||||
end
|
||||
|
||||
op.on('-P PATH','exclude PATH') do |argument|
|
||||
options.paths << {exclude: true, pattern: argument}
|
||||
end
|
||||
|
||||
op.on_tail('-h','--help') do |argument|
|
||||
puts op
|
||||
exit
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@option_parser.parse!(argv)
|
||||
options.terms = argv # must be after parse!
|
||||
end
|
||||
|
||||
def valid?
|
||||
true #options.terms.size > 0
|
||||
end
|
||||
|
||||
def help
|
||||
puts @option_parser
|
||||
exit
|
||||
end
|
||||
|
||||
def execute
|
||||
include_paths = options.paths.reject {|x| x[:exclude] }.map {|x| "-path '*/#{x[:pattern]}/*'"}
|
||||
if include_paths.size > 1
|
||||
include_paths = include_paths.join(' -o ')
|
||||
include_paths = ['\(', include_paths, '\)']
|
||||
end
|
||||
include_paths = include_paths.join(' ')
|
||||
|
||||
exclude_paths = options.paths.select {|x| x[:exclude] }.map {|x| "! -path '*/#{x[:pattern]}/*'"}
|
||||
if exclude_paths.size > 1
|
||||
exclude_paths = exclude_paths.join(' -a ')
|
||||
exclude_paths = ['\(', exclude_paths, '\)']
|
||||
end
|
||||
exclude_paths = exclude_paths.join(' ')
|
||||
|
||||
include_names = options.names.reject {|x| x[:exclude] }.map {|x| "-name '*.#{x[:pattern]}'"}
|
||||
if include_names.size > 1
|
||||
include_names = include_names.join(' -o ')
|
||||
include_names = ['\(', include_names, '\)']
|
||||
end
|
||||
include_names = include_names.join(' ')
|
||||
|
||||
exclude_names = options.names.select {|x| x[:exclude] }.map {|x| "! -name '*.#{x[:pattern]}'"}
|
||||
if exclude_names.size > 1
|
||||
exclude_names = exclude_names.join(' -a ')
|
||||
exclude_names = ['\(', exclude_names, '\)']
|
||||
end
|
||||
exclude_names = exclude_names.join(' ')
|
||||
|
||||
|
||||
commands = [
|
||||
["find", ".", "-type f", include_names, exclude_names, include_paths, exclude_paths].join(" "),
|
||||
"sort",
|
||||
]
|
||||
if options.terms.size > 0
|
||||
terms = options.terms.map {|x| "grep --color=auto #{x}"}.join(' | ')
|
||||
commands << ["xargs", terms].join(' ')
|
||||
end
|
||||
|
||||
command = commands.join('|')
|
||||
|
||||
if options.debug
|
||||
puts command
|
||||
else
|
||||
system command
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def default_environment
|
||||
Xfind::SimpleEnv.new
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
18
package-lock.json
generated
Normal file
18
package-lock.json
generated
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "git-utilities",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"commander": {
|
||||
"version": "2.20.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz",
|
||||
"integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ=="
|
||||
},
|
||||
"lodash": {
|
||||
"version": "4.17.20",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
|
||||
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA=="
|
||||
}
|
||||
}
|
||||
}
|
||||
27
package.json
Normal file
27
package.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"name": "git-utilities",
|
||||
"version": "1.0.0",
|
||||
"description": "This is a collection of simple command-line scripts, bash aliases, and bash utilities that make using `git` even easier.",
|
||||
"main": "index.js",
|
||||
"directories": {
|
||||
"lib": "lib"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/rkiel/git-utilities.git"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"bugs": {
|
||||
"url": "https://github.com/rkiel/git-utilities/issues"
|
||||
},
|
||||
"homepage": "https://github.com/rkiel/git-utilities#readme",
|
||||
"dependencies": {
|
||||
"commander": "^2.20.0",
|
||||
"lodash": "^4.17.20"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user