Merge remote-tracking branch 'origin/master' into refactor_of_git_status
This commit is contained in:
17
.travis.yml
17
.travis.yml
@@ -1,3 +1,16 @@
|
||||
script: ./run_tests.sh
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
|
||||
env:
|
||||
- TEST_SHELLS=bash
|
||||
- TEST_SHELLS=zsh
|
||||
|
||||
install:
|
||||
- ./test/support/travisci_deps.sh
|
||||
|
||||
before_script:
|
||||
- sudo apt-get install zsh
|
||||
- echo -e "test_repo_11\ntest_repo_1" | sort
|
||||
|
||||
script:
|
||||
- ./run_tests.sh
|
||||
|
||||
357
README.markdown
357
README.markdown
@@ -1,41 +1,81 @@
|
||||
# SCM Breeze [](http://travis-ci.org/ndbroadbent/scm_breeze)
|
||||
### Streamline your SCM workflow.
|
||||
|
||||
**SCM Breeze** is a set of shell scripts (for `bash` and `zsh`) that enhance your interaction with git. It integrates with your shell to give you numbered file shortcuts,
|
||||
a repository index with tab completion, and many other useful features.
|
||||
|
||||
<hr/>
|
||||
|
||||
## Demo video
|
||||
|
||||
<center><a href="http://www.youtube.com/watch?v=iKdp6uBfrvc" target="_blank"><img src="http://i.imgur.com/l7aGG.png"></a></center>
|
||||
|
||||
<hr/>
|
||||
|
||||
## File Shortcuts
|
||||
|
||||
SCM Breeze makes it really easy to work with changed files, and groups of changed files.
|
||||
Whenever you view your SCM status, each modified path is stored in a numbered environment variable.
|
||||
You can configure the variable prefix, which is 'e' by default.
|
||||
<img src="https://user-images.githubusercontent.com/139536/30827652-08e9b684-a265-11e7-95fb-50cbd2fb7c0d.png" width="200" height="200">
|
||||
|
||||
|
||||
### Git Status Shortcuts:
|
||||
|
||||
# SCM Breeze [](http://travis-ci.org/scmbreeze/scm_breeze)
|
||||
|
||||
> Streamline your SCM workflow.
|
||||
|
||||
**SCM Breeze** is a set of shell scripts (for `bash` and `zsh`) that enhance
|
||||
your interaction with git. It integrates with your shell to give you numbered
|
||||
file shortcuts, a repository index with tab completion, and many other useful
|
||||
features.
|
||||
|
||||

|
||||
|
||||
|
||||
- [Installation](#installation)
|
||||
- [Usage](#usage)
|
||||
- [File Shortcuts](#file-shortcuts)
|
||||
- [Keyboard bindings](#keyboard-bindings)
|
||||
- [Repository Index](#repository-index)
|
||||
- [Linking External Project Design Directories](#linking-external-project-design-directories)
|
||||
- [Configuration](#configuration)
|
||||
- [Updating](#updating)
|
||||
- [Uninstalling](#uninstalling)
|
||||
- [Notes about Tab Completion for Aliases](#notes-about-tab-completion-for-aliases)
|
||||
- [Contributing](#contributing)
|
||||
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
git clone git://github.com/scmbreeze/scm_breeze.git ~/.scm_breeze
|
||||
~/.scm_breeze/install.sh
|
||||
source ~/.bashrc # or source ~/.zshrc
|
||||
```
|
||||
|
||||
The install script creates required default configs and adds the following line
|
||||
to your `.bashrc` or `.zshrc`:
|
||||
|
||||
`[ -s "$HOME/.scm_breeze/scm_breeze.sh" ] && source "$HOME/.scm_breeze/scm_breeze.sh"`
|
||||
|
||||
**Note:** SCM Breeze performs much faster if you have ruby installed.
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
<center><a href="http://www.youtube.com/watch?v=iKdp6uBfrvc"
|
||||
target="_blank"><img src="http://i.imgur.com/l7aGG.png"></a></center>
|
||||
|
||||
### File Shortcuts
|
||||
|
||||
SCM Breeze makes it really easy to work with changed files, and groups of
|
||||
changed files. Whenever you view your SCM status, each modified path is stored
|
||||
in a numbered environment variable. You can configure the variable prefix,
|
||||
which is 'e' by default.
|
||||
|
||||
|
||||
#### Git Status Shortcuts:
|
||||
|
||||
<div class="centered">
|
||||
<img src="http://madebynathan.com/images/posts/2011/10/status_with_shortcuts-resized-post.png" width="590" alt="Git Status With Shortcuts" />
|
||||
</div>
|
||||
<br/>
|
||||
|
||||
### 'ls' shortcuts:
|
||||
|
||||
#### 'ls' shortcuts:
|
||||
|
||||
<div class="centered">
|
||||
<img src="http://i.imgur.com/72GE1.png" alt="Ls With Shortcuts" />
|
||||
</div>
|
||||
<br/>
|
||||
|
||||
These numbers (or ranges of numbers) can be used with any SCM or system command.
|
||||
These numbers (or ranges of numbers) can be used with any SCM or system
|
||||
command.
|
||||
|
||||
For example, if `ga` was your alias for `git add`, instead of typing something like:
|
||||
For example, if `ga` was your alias for `git add`, instead of typing something
|
||||
like:
|
||||
|
||||
```bash
|
||||
$ ga assets/git_breeze/config* assets/git_breeze/install.sh
|
||||
@@ -47,8 +87,8 @@ You can type this instead:
|
||||
$ ga $e2 $e3 $e11
|
||||
```
|
||||
|
||||
But SCM Breeze aliases `ga` to the `git_add_shortcuts` function,
|
||||
which is smart enough to expand integers and ranges, so all you need to type is:
|
||||
But SCM Breeze aliases `ga` to the `git_add_shortcuts` function, which is smart
|
||||
enough to expand integers and ranges, so all you need to type is:
|
||||
|
||||
```bash
|
||||
$ ga 2 3 11
|
||||
@@ -60,8 +100,8 @@ And if you want to add all unstaged changes (files 1 to 10):
|
||||
$ ga 1-10
|
||||
```
|
||||
|
||||
(Note that `ga` will also remove deleted files, unlike the standard `git add` command.
|
||||
This behaviour can be turned off if you don't like it.)
|
||||
(Note that `ga` will also remove deleted files, unlike the standard `git add`
|
||||
command. This behaviour can be turned off if you don't like it.)
|
||||
|
||||
|
||||
You can also diff, reset or checkout a file by typing:
|
||||
@@ -73,8 +113,8 @@ $ gco 5
|
||||
```
|
||||
|
||||
|
||||
You can use these shortcuts with system commands by passing your command through `exec_scmb_expand_args`
|
||||
(default alias is 'ge'):
|
||||
You can use these shortcuts with system commands by passing your command
|
||||
through `exec_scmb_expand_args` (default alias is `ge`):
|
||||
|
||||
|
||||
```bash
|
||||
@@ -88,19 +128,21 @@ $ ge echo 1-3
|
||||
```
|
||||
|
||||
|
||||
### Other shortcuts
|
||||
#### Other shortcuts
|
||||
|
||||
SCM Breeze adds a number of aliases to your shell. Use `list_aliases` to view all the aliases and their corresponding commands.
|
||||
You can filter aliases by adding a search string: `list_aliases git log`
|
||||
SCM Breeze adds a number of aliases to your shell. Use `list_aliases` to view
|
||||
all the aliases and their corresponding commands. You can filter aliases by
|
||||
adding a search string: `list_aliases git log`
|
||||
|
||||
There's also a `git_aliases` command, which just shows aliases for `git` commands. You can also pass in additional filters, e.g. `git_aliases log`.
|
||||
There's also a `git_aliases` command, which just shows aliases for `git`
|
||||
commands. You can also pass in additional filters, e.g. `git_aliases log`.
|
||||
|
||||
|
||||
## Keyboard bindings
|
||||
### Keyboard bindings
|
||||
|
||||
Some of my most common git commands are `git add` and `git commit`, so I wanted these
|
||||
to be as streamlined as possible. One way of speeding up commonly used commands is by binding them to
|
||||
keyboard shortcuts.
|
||||
Some of my most common git commands are `git add` and `git commit`, so I wanted
|
||||
these to be as streamlined as possible. One way of speeding up commonly used
|
||||
commands is by binding them to keyboard shortcuts.
|
||||
|
||||
Here are the default key bindings:
|
||||
|
||||
@@ -108,14 +150,13 @@ Here are the default key bindings:
|
||||
* `CTRL`+`x` `SPACE` => `git_commit_all` - commit everything
|
||||
|
||||
|
||||
The commit shortcuts use the `git_commit_prompt` function, which gives a simple prompt like this:
|
||||
The commit shortcuts use the `git_commit_prompt` function, which gives a simple
|
||||
prompt like this:
|
||||
|
||||
<div class="centered">
|
||||
<img src="http://madebynathan.com/images/posts/2011/10/git_commit_all-resized-post.png" alt="Git Commit All" />
|
||||
</div>
|
||||
<br/>
|
||||
(When using bash, this commit prompt gives you access to your bash history via the arrow keys.)
|
||||
<br/>
|
||||
<div class="centered"> <img
|
||||
src="http://madebynathan.com/images/posts/2011/10/git_commit_all-resized-post.png"
|
||||
alt="Git Commit All" /> </div> <br/> (When using bash, this commit prompt gives
|
||||
you access to your bash history via the arrow keys.) <br/>
|
||||
|
||||
And if you really want to speed up your workflow, you can type this:
|
||||
|
||||
@@ -131,23 +172,26 @@ This sends the `HOME` key, followed by `git_add_and_commit`:
|
||||
<br/>
|
||||
|
||||
|
||||
## Repository Index
|
||||
### Repository Index
|
||||
|
||||
The second feature is a repository index for all of your projects and submodules.
|
||||
This gives you super-fast switching between your project directories, with tab completion,
|
||||
and it can even tab-complete down to project subdirectories.
|
||||
This means that you can keep your projects organized in subfolders,
|
||||
but switch between them as easily as if they were all in one folder.
|
||||
The second feature is a repository index for all of your projects and
|
||||
submodules. This gives you super-fast switching between your project
|
||||
directories, with tab completion, and it can even tab-complete down to project
|
||||
subdirectories. This means that you can keep your projects organized in
|
||||
subfolders, but switch between them as easily as if they were all in one
|
||||
folder.
|
||||
|
||||
It's similar to [autojump](https://github.com/joelthelion/autojump), but it doesn't need to 'learn' anything,
|
||||
and it can do SCM-specific stuff like:
|
||||
It's similar to [autojump](https://github.com/joelthelion/autojump), but it
|
||||
doesn't need to 'learn' anything, and it can do SCM-specific stuff like:
|
||||
|
||||
* Running a command for all of your repos (useful if you ever need to update a lot of remote URLs)
|
||||
* Running a command for all of your repos (useful if you ever need to update a
|
||||
lot of remote URLs)
|
||||
* Update all of your repositories via a cron task
|
||||
|
||||
The default alias for `git_index` is 'c', which might stand for 'code'
|
||||
|
||||
You will first need to configure your repository directory, and then build the index:
|
||||
You will first need to configure your repository directory, and then build the
|
||||
index:
|
||||
|
||||
```bash
|
||||
$ c --rebuild
|
||||
@@ -155,10 +199,12 @@ $ c --rebuild
|
||||
# => ===== Indexed 64 repos in /home/ndbroadbent/code/.git_index
|
||||
```
|
||||
|
||||
Then you'll be able to switch between your projects, or show the list of indexed repos.
|
||||
Then you'll be able to switch between your projects, or show the list of
|
||||
indexed repos.
|
||||
|
||||
To switch to a project directory, you don't need to type the full project name. For example,
|
||||
to switch to the `capistrano` project, you could type any of the following:
|
||||
To switch to a project directory, you don't need to type the full project name.
|
||||
For example, to switch to the `capistrano` project, you could type any of the
|
||||
following:
|
||||
|
||||
```bash
|
||||
$ c capistrano
|
||||
@@ -177,19 +223,20 @@ $ c capistrano/lib/
|
||||
# => cd ~/code/gems/capistrano/lib
|
||||
```
|
||||
|
||||
Or if you want to go to a subdirectory within the `~/code` directory, prefix the first argument with a `/`:
|
||||
Or if you want to go to a subdirectory within the `~/code` directory, prefix
|
||||
the first argument with a `/`:
|
||||
|
||||
```bash
|
||||
~ $ c /gems
|
||||
~/code/gems $
|
||||
```
|
||||
|
||||
## Linking External Project Design Directories
|
||||
### Linking External Project Design Directories
|
||||
|
||||
When you're creating logos or icons for a project that uses `git`,
|
||||
have you ever wondered where you should store those `.psd` or `.xcf` files?
|
||||
Do you commit all of your raw design files, or does it put you off that any changes to those files
|
||||
will bloat your repository?
|
||||
When you're creating logos or icons for a project that uses `git`, have you
|
||||
ever wondered where you should store those `.psd` or `.xcf` files? Do you
|
||||
commit all of your raw design files, or does it put you off that any changes to
|
||||
those files will bloat your repository?
|
||||
|
||||
Here were my goals when I set out to find a solution:
|
||||
|
||||
@@ -198,164 +245,168 @@ Here were my goals when I set out to find a solution:
|
||||
* The design directory needed to be synchronized across all of my machines
|
||||
|
||||
The simplest way for me to synchronize files was via my Dropbox account.
|
||||
However, if you work with a larger team, you could set up a shared design directory on one
|
||||
of your servers and synchronize it with `rsync`.
|
||||
However, if you work with a larger team, you could set up a shared design
|
||||
directory on one of your servers and synchronize it with `rsync`.
|
||||
|
||||
|
||||
### 1) Create and configure a root design directory
|
||||
#### 1) Create and configure a root design directory
|
||||
|
||||
I created my root design directory at `~/Dropbox/Design`.
|
||||
|
||||
After you've created your root design directory, edit `~/.scmbrc` and set `root_design_dir`
|
||||
to the directory you just created.
|
||||
You can also configure the design directory that's created in each of your projects
|
||||
(default: `design_assets`), as well as the subdirectories you would like to use.
|
||||
The default base subdirectories are: Images, Backgrounds, Logos, Icons, Mockups, and Screenshots.
|
||||
After you've created your root design directory, edit `~/.scmbrc` and set
|
||||
`root_design_dir` to the directory you just created. You can also configure
|
||||
the design directory that's created in each of your projects (default:
|
||||
`design_assets`), as well as the subdirectories you would like to use. The
|
||||
default base subdirectories are: Images, Backgrounds, Logos, Icons, Mockups,
|
||||
and Screenshots.
|
||||
|
||||
After you have changed these settings, remember to run `source ~/.bashrc` or `source ~/.zshrc`.
|
||||
After you have changed these settings, remember to run `source ~/.bashrc` or
|
||||
`source ~/.zshrc`.
|
||||
|
||||
|
||||
### 2) Initialize design directories for your projects
|
||||
#### 2) Initialize design directories for your projects
|
||||
|
||||
To set up the design directories and symlinks, go to a project's directory and run:
|
||||
To set up the design directories and symlinks, go to a project's directory and
|
||||
run:
|
||||
|
||||
```bash
|
||||
design init
|
||||
```
|
||||
|
||||
If your root directory is `~/Dropbox/Design`, directories will be created at
|
||||
`~/Dropbox/Design/projects/my_project/Backgrounds`, `~/Dropbox/Design/projects/my_project/Icons`, etc.
|
||||
`~/Dropbox/Design/projects/my_project/Backgrounds`,
|
||||
`~/Dropbox/Design/projects/my_project/Icons`, etc.
|
||||
|
||||
It will then symlink the project from your root design directory into your project's design directory,
|
||||
so you end up with:
|
||||
It will then symlink the project from your root design directory into your
|
||||
project's design directory, so you end up with:
|
||||
|
||||
* `my_project/design_assets` -> `~/Dropbox/Design/projects/my_project`
|
||||
|
||||
It also adds this directory to `.git/info/exclude` so that git ignores it.
|
||||
|
||||
|
||||
If you use the git repository index,
|
||||
you can run the following batch command to set up these directories for all of your git repos at once:
|
||||
If you use the git repository index, you can run the following batch command to
|
||||
set up these directories for all of your git repos at once:
|
||||
|
||||
```bash
|
||||
git_index --batch-cmd design init
|
||||
```
|
||||
|
||||
|
||||
If you want to remove any empty design directories, run:
|
||||
|
||||
```bash
|
||||
design trim
|
||||
```
|
||||
|
||||
And if you want to remove all of a project's design directories, even if they contain files:
|
||||
And if you want to remove all of a project's design directories, even if they
|
||||
contain files:
|
||||
|
||||
```bash
|
||||
design rm
|
||||
```
|
||||
|
||||
|
||||
### 3) Link existing design directories into your projects
|
||||
#### 3) Link existing design directories into your projects
|
||||
|
||||
If you've set up your design directories on one machine, you'll want them
|
||||
to be synchronized across all of your other development machines.
|
||||
If you've set up your design directories on one machine, you'll want them to be
|
||||
synchronized across all of your other development machines.
|
||||
|
||||
Just run the following command on your other machines after you've configured the root design directory:
|
||||
Just run the following command on your other machines after you've configured
|
||||
the root design directory:
|
||||
|
||||
```bash
|
||||
design link
|
||||
```
|
||||
|
||||
This uses your git index to figure out where to create the symlinks.
|
||||
If you don't use the git index, the same outcome could be achieved by running 'design init'
|
||||
for each of the projects.
|
||||
This uses your git index to figure out where to create the symlinks. If you
|
||||
don't use the git index, the same outcome could be achieved by running 'design
|
||||
init' for each of the projects.
|
||||
|
||||
|
||||
## Configuration
|
||||
|
||||
## Contributing tools / scripts
|
||||
SCM Breeze is configured via automatically installed `~/.*.scmbrc` files. To
|
||||
change git configuration, edit `~/.git.scmbrc`.
|
||||
|
||||
If you have any awesome SCM scripts lurking in your `.bashrc` or `.zshrc`,
|
||||
please feel free to send me a pull request.
|
||||
It would be cool to make this project into an [oh-my-zsh](https://github.com/robbyrussell/oh-my-zsh) for SCMs.
|
||||
Each feature is modular, so you are free to ignore the parts you don't want to
|
||||
use. Just comment out the relevant line in `~/.scm_breeze/scm_breeze.sh`.
|
||||
|
||||
**Note:** After changing any settings, you will need to run `source ~/.bashrc`
|
||||
(or `source ~/.zshrc`)
|
||||
|
||||
I know we grow attached to the aliases we use every day, so I've made the alias
|
||||
system completely customizable. You have two options when it comes to aliases:
|
||||
|
||||
|
||||
# Installation
|
||||
### 1) Configure and use the provided SCM Breeze aliases
|
||||
|
||||
```bash
|
||||
git clone git://github.com/ndbroadbent/scm_breeze.git ~/.scm_breeze
|
||||
~/.scm_breeze/install.sh
|
||||
source ~/.bashrc # or source ~/.zshrc
|
||||
```
|
||||
|
||||
The install script just adds the following line to your `.bashrc` or `.zshrc`:
|
||||
|
||||
`[ -s "$HOME/.scm_breeze/scm_breeze.sh" ] && source "$HOME/.scm_breeze/scm_breeze.sh"`
|
||||
Just tweak the aliases in `~/.git.scmbrc`. You can also change or remove any
|
||||
keyboard shortcuts. These aliases also come with tab completion. For example,
|
||||
you can type `gco <tab>` to tab complete your list of branches.
|
||||
|
||||
|
||||
# Updating
|
||||
### 2) Use your own aliases
|
||||
|
||||
Please run `update_scm_breeze` to fetch the latest code. This will update SCM Breeze from Github,
|
||||
and will create or patch your `~/.*.scmbrc` config files if any new settings are added.
|
||||
In your `git.scmbrc` config file, just set the `git_setup_aliases` option to
|
||||
`no`. Your existing git aliases will then be used, and you will still be able
|
||||
to use the numeric shortcuts feature. SCM Breeze creates a function to wrap
|
||||
the 'git' command, which expands numeric arguments, and uses `hub` if
|
||||
available.
|
||||
|
||||
# Uninstall
|
||||
A few aliases will still be defined for the central SCM Breeze features, such
|
||||
as `gs` for the extended `git status`, and `ga` for the `git add` function.
|
||||
|
||||
If you already have an alias like `alias gco="git checkout"`, you can now type
|
||||
`gco 1` to checkout the first file in the output of SCM Breeze's `git status`.
|
||||
|
||||
|
||||
## Notes about Tab Completion for Aliases
|
||||
|
||||
### Bash
|
||||
|
||||
If you use your own aliases, SCM Breeze will **not** set up bash tab completion
|
||||
for your aliases. You will need to set that up yourself.
|
||||
|
||||
|
||||
### Zsh
|
||||
|
||||
You just need to set the option: `setopt no_complete_aliases` (oh-my-zsh sets
|
||||
this by default). Zsh will then expand aliases like `gb` to `git branch`, and
|
||||
use the completion for that.
|
||||
|
||||
|
||||
## Updating
|
||||
|
||||
Please run `update_scm_breeze` to fetch the latest code. This will update SCM
|
||||
Breeze from Github, and will create or patch your `~/.*.scmbrc` config files if
|
||||
any new settings are added.
|
||||
|
||||
|
||||
## Uninstalling
|
||||
|
||||
```bash
|
||||
~/.scm_breeze/uninstall.sh
|
||||
```
|
||||
|
||||
The uninstall script removes the following line from your `.bashrc` or `.zshrc`:
|
||||
The uninstall script removes the following line from your `.bashrc` or
|
||||
`.zshrc`:
|
||||
|
||||
`[ -s "$HOME/.scm_breeze/scm_breeze.sh" ] && source "$HOME/.scm_breeze/scm_breeze.sh"`
|
||||
|
||||
# Configuration
|
||||
|
||||
SCM Breeze is configured via automatically installed `~/.*.scmbrc` files.
|
||||
To change git configuration, edit `~/.git.scmbrc`.
|
||||
## Contributing
|
||||
|
||||
Each feature is modular, so you are free to ignore the parts you don't want to use.
|
||||
Just comment out the relevant line in `~/.scm_breeze/scm_breeze.sh`.
|
||||
SCM Breeze lives on Github at
|
||||
[`scmbreeze/scm_breeze`](https://github.com/scmbreeze/scm_breeze)
|
||||
|
||||
**Note:** After changing any settings, you will need to run `source ~/.bashrc` (or `source ~/.zshrc`)
|
||||
If you have any awesome SCM scripts lurking in your `.bashrc` or `.zshrc`,
|
||||
please feel free to send me a pull request. It would be cool to make this
|
||||
project into an [oh-my-zsh](https://github.com/robbyrussell/oh-my-zsh) for
|
||||
SCMs.
|
||||
|
||||
I know we grow attached to the aliases we use every day, so I've made the alias system completely customizable.
|
||||
You have two options when it comes to aliases:
|
||||
***Enjoy!***
|
||||
|
||||
### 1) Configure and use the provided SCM Breeze aliases
|
||||
|
||||
Just tweak the aliases in `~/.git.scmbrc`. You can also change or remove any keyboard shortcuts.
|
||||
These aliases also come with tab completion. For example, you can type `gco <tab>` to tab complete your list of branches.
|
||||
|
||||
### 2) Use your own aliases
|
||||
|
||||
In your `git.scmbrc` config file, just set the `git_setup_aliases` option to `no`.
|
||||
Your existing git aliases will then be used, and you will still be able to use the numeric shortcuts feature.
|
||||
SCM Breeze creates a function to wrap the 'git' command, which expands numeric arguments, and uses `hub` if available.
|
||||
|
||||
A few aliases will still be defined for the central SCM Breeze features, such as `gs` for the extended `git status`,
|
||||
and `ga` for the `git add` function.
|
||||
|
||||
If you already have an alias like `alias gco="git checkout"`,
|
||||
you can now type `gco 1` to checkout the first file in the output of SCM Breeze's `git status`.
|
||||
|
||||
# Notes about Tab Completion for Aliases
|
||||
|
||||
### Bash
|
||||
|
||||
If you use your own aliases, SCM Breeze will **not** set up bash tab completion for your aliases.
|
||||
You will need to set that up yourself.
|
||||
|
||||
### Zsh
|
||||
|
||||
You just need to set the option: `setopt no_complete_aliases` (oh-my-zsh sets this by default).
|
||||
Zsh will then expand aliases like `gb` to `git branch`, and use the completion for that.
|
||||
|
||||
# Contributing
|
||||
|
||||
SCM Breeze lives on Github at [https://github.com/ndbroadbent/scm_breeze](https://github.com/ndbroadbent/scm_breeze)
|
||||
|
||||
Please feel free to fork and send pull requests, especially if you would like to build these features
|
||||
for Mercurial, SVN, etc.
|
||||
|
||||
|
||||
## Enjoy!
|
||||
## Alternative Projects
|
||||
|
||||
1. https://github.com/shinriyo/breeze `fish` support
|
||||
1. https://github.com/mroth/scmpuff static go binary
|
||||
|
||||
@@ -34,13 +34,13 @@ git_alias="g"
|
||||
# 1. 'SCM Breeze' functions
|
||||
git_status_shortcuts_alias="gs"
|
||||
git_add_shortcuts_alias="ga"
|
||||
git_add_patch_alias="gap"
|
||||
git_add_updated_alias="gau"
|
||||
git_show_files_alias="gsf"
|
||||
exec_scmb_expand_args_alias="ge"
|
||||
git_show_files_alias="gsf"
|
||||
git_commit_all_alias="gca"
|
||||
git_grep_shortcuts_alias="gtrep"
|
||||
# 2. Commands that handle paths (with shortcut args expanded)
|
||||
git_checkout_alias="gco"
|
||||
git_checkout_branch_alias="gcob"
|
||||
git_checkout_branch_alias="gcb"
|
||||
git_commit_alias="gc"
|
||||
git_commit_verbose_alias="gcv"
|
||||
git_reset_alias="grs"
|
||||
@@ -48,6 +48,8 @@ git_reset_hard_alias="grsh"
|
||||
git_rm_alias="grm"
|
||||
git_blame_alias="gbl"
|
||||
git_diff_alias="gd"
|
||||
git_diff_no_whitespace_alias="gdnw"
|
||||
git_diff_file_alias="gdf"
|
||||
git_diff_word_alias="gdw"
|
||||
git_diff_cached_alias="gdc"
|
||||
git_difftool_alias="gdt"
|
||||
@@ -57,6 +59,7 @@ git_fetch_alias="gf"
|
||||
git_fetch_all_alias="gfa"
|
||||
git_fetch_and_rebase_alias="gfr"
|
||||
git_pull_alias="gpl"
|
||||
git_pull_rebase_alias="gplr"
|
||||
git_push_alias="gps"
|
||||
git_push_force_alias="gpsf"
|
||||
git_pull_then_push_alias="gpls"
|
||||
@@ -65,7 +68,8 @@ git_status_short_alias="gss"
|
||||
git_clean_alias="gce"
|
||||
git_clean_force_alias="gcef"
|
||||
git_add_all_alias="gaa"
|
||||
git_commit_all_alias="gca"
|
||||
git_add_patch_alias="gap"
|
||||
git_add_updated_alias="gau"
|
||||
git_commit_amend_alias="gcm"
|
||||
git_commit_amend_no_msg_alias="gcmh"
|
||||
git_commit_no_msg_alias="gch"
|
||||
@@ -86,7 +90,7 @@ git_merge_only_fast_forward_alias="gmff"
|
||||
git_cherry_pick_alias="gcp"
|
||||
git_log_alias="gl"
|
||||
git_log_all_alias="gla"
|
||||
git_log_stat_alias="gls"
|
||||
git_log_stat_alias="glst"
|
||||
git_log_graph_alias="glg"
|
||||
git_show_alias="gsh"
|
||||
git_show_summary="gsm" # (gss taken by git status short)
|
||||
@@ -95,6 +99,13 @@ git_stash_apply_alias="gasha"
|
||||
git_stash_pop_alias="gashp"
|
||||
git_stash_list_alias="gashl"
|
||||
git_tag_alias="gt"
|
||||
git_submodule_update_alias="gsu"
|
||||
git_submodule_update_rec_alias="gsur"
|
||||
git_top_level_alias="gtop"
|
||||
git_whatchanged_alias="gwc"
|
||||
git_apply_alias="gapp"
|
||||
# Hub aliases (https://github.com/github/hub)
|
||||
git_pull_request_alias="gpr"
|
||||
|
||||
|
||||
# Git Keyboard Shortcuts
|
||||
@@ -112,3 +123,5 @@ git_commit_all_with_ci_skip_keys="\C-xv" # CTRL+x, v (Appends [ci skip] to c
|
||||
shell_command_wrapping_enabled="true"
|
||||
# Here you can tweak the list of wrapped commands.
|
||||
scmb_wrapped_shell_commands="vim emacs gedit cat rm cp mv ln cd"
|
||||
# Add numbered shortcuts to output of ls -l, just like 'git status'
|
||||
shell_ls_aliases_enabled="true"
|
||||
|
||||
29
install.sh
29
install.sh
@@ -10,11 +10,19 @@ fi
|
||||
# This loads SCM Breeze into the shell session.
|
||||
exec_string="[ -s \"$HOME/.scm_breeze/scm_breeze.sh\" ] && source \"$HOME/.scm_breeze/scm_breeze.sh\""
|
||||
|
||||
# Add line to bashrc and zshrc if not already present.
|
||||
for rc in bashrc zshrc; do
|
||||
if [ -s "$HOME/.$rc" ] && ! grep -q "$exec_string" "$HOME/.$rc"; then
|
||||
printf "\n$exec_string\n" >> "$HOME/.$rc"
|
||||
printf "== Added SCM Breeze to '~/.$rc'\n"
|
||||
# Add line to bashrc, zshrc, and bash_profile if not already present.
|
||||
added_to_profile=false
|
||||
already_present=false
|
||||
for rc in bashrc zshrc bash_profile; do
|
||||
if [ -s "$HOME/.$rc" ]; then
|
||||
if grep -q "$exec_string" "$HOME/.$rc"; then
|
||||
printf "== Already installed in '~/.$rc'\n"
|
||||
already_present=true
|
||||
else
|
||||
printf "\n$exec_string\n" >> "$HOME/.$rc"
|
||||
printf "== Added SCM Breeze to '~/.$rc'\n"
|
||||
added_to_profile=true
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
@@ -23,5 +31,12 @@ source "$scmbDir/lib/scm_breeze.sh"
|
||||
# Create '~/.*.scmbrc' files from example files
|
||||
_create_or_patch_scmbrc
|
||||
|
||||
|
||||
echo "== Run 'source ~/.bashrc' or 'source ~/.zshrc' to load SCM Breeze into your current shell."
|
||||
if [ "$added_to_profile" = true ] || [ "$already_present" = true ]; then
|
||||
echo "== SCM Breeze Installed! Run 'source ~/.bashrc || source ~/.bash_profile' or 'source ~/.zshrc'"
|
||||
echo " to load SCM Breeze into your current shell."
|
||||
else
|
||||
echo "== Error:"
|
||||
echo " Found no profile to add SCM Breeze to."
|
||||
echo " Add line to your shell profile and source it to install manually:"
|
||||
printf " $exec_string\n"
|
||||
fi
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
# Add ignore rule to .git/info/exclude if not already present
|
||||
_design_add_git_exclude(){
|
||||
local git_dir="$(cd $1 && readlink -m $(git rev-parse --git-dir))"
|
||||
local git_dir="$(cd $1 && cd `git rev-parse --git-dir` && pwd -P)"
|
||||
if [ -e "$git_dir/info/exclude" ] && ! $(grep -q "$project_design_dir" "$git_dir/info/exclude"); then
|
||||
echo "$project_design_dir" >> "$git_dir/info/exclude"
|
||||
fi
|
||||
@@ -102,5 +102,6 @@ design() {
|
||||
printf "Invalid command.\n\n"
|
||||
design
|
||||
fi
|
||||
unset IFS
|
||||
}
|
||||
|
||||
|
||||
@@ -21,12 +21,14 @@ export _git_cmd="$(\which git)"
|
||||
# Wrap git with the 'hub' github wrapper, if installed (https://github.com/defunkt/hub)
|
||||
if type hub > /dev/null 2>&1; then export _git_cmd="hub"; fi
|
||||
|
||||
# gh is now deprecated, and merged into the `hub` command line tool.
|
||||
#if type gh > /dev/null 2>&1; then export _git_cmd="gh"; fi
|
||||
|
||||
# Create 'git' function that calls hub if defined, and expands all numeric arguments
|
||||
function git(){
|
||||
# Only expand args for git commands that deal with paths or branches
|
||||
case $1 in
|
||||
commit|blame|add|log|rebase|merge)
|
||||
commit|blame|add|log|rebase|merge|difftool)
|
||||
exec_scmb_expand_args "$_git_cmd" "$@";;
|
||||
checkout|diff|rm|reset)
|
||||
exec_scmb_expand_args --relative "$_git_cmd" "$@";;
|
||||
@@ -37,7 +39,7 @@ function git(){
|
||||
esac
|
||||
}
|
||||
|
||||
_alias $git_alias='git'
|
||||
_alias "$git_alias" "git"
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
@@ -64,91 +66,111 @@ _git
|
||||
# Usage: __git_alias <alias> <command_prefix> <command>
|
||||
__git_alias () {
|
||||
if [ -n "$1" ]; then
|
||||
local alias_str="$1"; local cmd_prefix="$2"; local cmd="$3"; local cmd_args="${4-}"
|
||||
alias $alias_str="$cmd_prefix $cmd${cmd_args:+ }$cmd_args"
|
||||
local alias_str cmd_prefix cmd cmd_args
|
||||
|
||||
alias_str="$1"; cmd_prefix="$2"; cmd="$3";
|
||||
if [ $# -gt 2 ]; then
|
||||
shift 3 2>/dev/null
|
||||
cmd_args=$@
|
||||
fi
|
||||
|
||||
alias $alias_str="$cmd_prefix $cmd${cmd_args:+ }${cmd_args[*]}"
|
||||
if [ "$shell" = "bash" ]; then
|
||||
__define_git_completion $alias_str $cmd
|
||||
complete -o default -o nospace -F _git_"$alias_str"_shortcut $alias_str
|
||||
__define_git_completion "$alias_str" "$cmd"
|
||||
complete -o default -o nospace -F _git_"$alias_str"_shortcut "$alias_str"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# SCM Breeze functions
|
||||
_alias $git_status_shortcuts_alias="git_status_shortcuts"
|
||||
_alias $git_add_shortcuts_alias="git_add_shortcuts"
|
||||
_alias $exec_scmb_expand_args_alias="exec_scmb_expand_args"
|
||||
_alias $git_show_files_alias="git_show_affected_files"
|
||||
_alias $git_commit_all_alias='git_commit_all'
|
||||
_alias "$git_status_shortcuts_alias" 'git_status_shortcuts'
|
||||
_alias "$git_add_shortcuts_alias" 'git_add_shortcuts'
|
||||
_alias "$exec_scmb_expand_args_alias" 'exec_scmb_expand_args'
|
||||
_alias "$git_show_files_alias" 'git_show_affected_files'
|
||||
_alias "$git_commit_all_alias" 'git_commit_all'
|
||||
_alias "$git_grep_shortcuts_alias" 'git_grep_shortcuts'
|
||||
|
||||
# Git Index alias
|
||||
_alias $git_index_alias="git_index"
|
||||
_alias "$git_index_alias" 'git_index'
|
||||
|
||||
# Only set up the following aliases if 'git_setup_aliases' is 'yes'
|
||||
if [ "$git_setup_aliases" = "yes" ]; then
|
||||
|
||||
# Commands that deal with paths
|
||||
__git_alias "$git_checkout_alias" "git" "checkout"
|
||||
__git_alias "$git_commit_alias" "git" "commit"
|
||||
__git_alias "$git_commit_verbose_alias" "git" "commit" "--verbose"
|
||||
__git_alias "$git_reset_alias" "git" "reset" "--"
|
||||
__git_alias "$git_reset_hard_alias" "git" "reset" "--hard"
|
||||
__git_alias "$git_rm_alias" "git" "rm"
|
||||
__git_alias "$git_blame_alias" "git" "blame"
|
||||
__git_alias "$git_diff_alias" "git" "diff" "--"
|
||||
__git_alias "$git_diff_word_alias" "git" "diff" "--word-diff"
|
||||
__git_alias "$git_diff_cached_alias" "git" "diff" "--cached --"
|
||||
__git_alias "$git_add_patch_alias" "git" "add" "-p"
|
||||
__git_alias "$git_add_updated_alias" "git" "add" "-u"
|
||||
__git_alias "$git_difftool_alias" "git" "difftool"
|
||||
__git_alias "$git_checkout_alias" 'git' 'checkout'
|
||||
__git_alias "$git_commit_alias" 'git' 'commit'
|
||||
__git_alias "$git_commit_verbose_alias" 'git' 'commit' '--verbose'
|
||||
__git_alias "$git_reset_alias" 'git' 'reset'
|
||||
__git_alias "$git_reset_hard_alias" 'git' 'reset' '--hard'
|
||||
__git_alias "$git_rm_alias" 'git' 'rm'
|
||||
__git_alias "$git_blame_alias" 'git' 'blame'
|
||||
__git_alias "$git_diff_no_whitespace_alias" 'git' 'diff' '-w'
|
||||
__git_alias "$git_diff_alias" 'git' 'diff'
|
||||
__git_alias "$git_diff_file_alias" 'git' 'diff'
|
||||
__git_alias "$git_diff_word_alias" 'git' 'diff' '--word-diff'
|
||||
__git_alias "$git_diff_cached_alias" 'git' 'diff' '--cached'
|
||||
__git_alias "$git_add_patch_alias" 'git' 'add' '-p'
|
||||
__git_alias "$git_add_updated_alias" 'git' 'add' '-u'
|
||||
__git_alias "$git_difftool_alias" 'git' 'difftool'
|
||||
|
||||
# Custom default format for git log
|
||||
git_log_command="log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"
|
||||
__git_alias "$git_log_alias" "git" "$git_log_command"
|
||||
__git_alias "$git_log_alias" 'git' "$git_log_command"
|
||||
|
||||
# Same as the above, but displays all the branches and remotes
|
||||
__git_alias "$git_log_all_alias" "git" "$git_log_command" "--branches" "--remotes"
|
||||
__git_alias "$git_log_all_alias" 'git' "$git_log_command" '--branches' '--remotes'
|
||||
|
||||
# Standard commands
|
||||
__git_alias "$git_clone_alias" "git" 'clone'
|
||||
__git_alias "$git_fetch_alias" "git" 'fetch'
|
||||
__git_alias "$git_checkout_branch_alias" "git" 'checkout' "-b"
|
||||
__git_alias "$git_pull_alias" "git" 'pull'
|
||||
__git_alias "$git_push_alias" "git" 'push'
|
||||
__git_alias "$git_push_force_alias" "git" 'push' '-f'
|
||||
__git_alias "$git_status_original_alias" "git" 'status' # (Standard git status)
|
||||
__git_alias "$git_status_short_alias" "git" 'status' '-s'
|
||||
__git_alias "$git_clean_alias" "git" "clean"
|
||||
__git_alias "$git_clean_force_alias" "git" "clean" "-fd"
|
||||
__git_alias "$git_remote_alias" "git" 'remote' '-v'
|
||||
__git_alias "$git_rebase_alias" "git" 'rebase'
|
||||
__git_alias "$git_rebase_interactive_alias" "git" 'rebase' "-i"
|
||||
__git_alias "$git_rebase_alias_continue" "git" 'rebase' "--continue"
|
||||
__git_alias "$git_rebase_alias_abort" "git" 'rebase' "--abort"
|
||||
__git_alias "$git_reset_last_commit" "git" "reset HEAD~"
|
||||
__git_alias "$git_merge_alias" "git" 'merge'
|
||||
__git_alias "$git_merge_no_fast_forward_alias" "git" "merge" "--no-ff"
|
||||
__git_alias "$git_merge_only_fast_forward_alias" "git" "merge" "--ff"
|
||||
__git_alias "$git_cherry_pick_alias" "git" 'cherry-pick'
|
||||
__git_alias "$git_show_alias" "git" 'show'
|
||||
__git_alias "$git_show_summary" "git" 'show' '--summary'
|
||||
__git_alias "$git_stash_alias" "git" 'stash'
|
||||
__git_alias "$git_stash_apply_alias" "git" 'stash' 'apply'
|
||||
__git_alias "$git_stash_pop_alias" "git" 'stash' 'pop'
|
||||
__git_alias "$git_stash_list_alias" "git" 'stash' 'list'
|
||||
__git_alias "$git_tag_alias" "git" 'tag'
|
||||
|
||||
__git_alias "$git_clone_alias" 'git' 'clone'
|
||||
__git_alias "$git_fetch_alias" 'git' 'fetch'
|
||||
__git_alias "$git_checkout_branch_alias" 'git' 'checkout' '-b'
|
||||
__git_alias "$git_pull_alias" 'git' 'pull'
|
||||
__git_alias "$git_pull_rebase_alias" 'git' 'pull' '--rebase'
|
||||
__git_alias "$git_push_alias" 'git' 'push'
|
||||
__git_alias "$git_push_force_alias" 'git' 'push' '-f'
|
||||
__git_alias "$git_status_original_alias" 'git' 'status' # (Standard git status)
|
||||
__git_alias "$git_status_short_alias" 'git' 'status' '-s'
|
||||
__git_alias "$git_clean_alias" 'git' 'clean'
|
||||
__git_alias "$git_clean_force_alias" 'git' 'clean' '-fd'
|
||||
__git_alias "$git_remote_alias" 'git' 'remote' '-v'
|
||||
__git_alias "$git_rebase_alias" 'git' 'rebase'
|
||||
__git_alias "$git_rebase_interactive_alias" 'git' 'rebase' '-i'
|
||||
__git_alias "$git_rebase_alias_continue" 'git' 'rebase' '--continue'
|
||||
__git_alias "$git_rebase_alias_abort" 'git' 'rebase' '--abort'
|
||||
__git_alias "$git_reset_last_commit" 'git' 'reset HEAD~'
|
||||
__git_alias "$git_top_level_alias" 'git' 'rev-parse' '--show-toplevel'
|
||||
__git_alias "$git_merge_alias" 'git' 'merge'
|
||||
__git_alias "$git_merge_no_fast_forward_alias" 'git' 'merge' '--no-ff'
|
||||
__git_alias "$git_merge_only_fast_forward_alias" 'git' 'merge' '--ff'
|
||||
__git_alias "$git_cherry_pick_alias" 'git' 'cherry-pick'
|
||||
__git_alias "$git_show_alias" 'git' 'show'
|
||||
__git_alias "$git_show_summary" 'git' 'show' '--summary'
|
||||
__git_alias "$git_stash_alias" 'git' 'stash'
|
||||
__git_alias "$git_stash_apply_alias" 'git' 'stash' 'apply'
|
||||
__git_alias "$git_stash_pop_alias" 'git' 'stash' 'pop'
|
||||
__git_alias "$git_stash_list_alias" 'git' 'stash' 'list'
|
||||
__git_alias "$git_tag_alias" 'git' 'tag'
|
||||
__git_alias "$git_submodule_update_alias" 'git' 'submodule' 'update' '--init'
|
||||
__git_alias "$git_submodule_update_rec_alias" 'git' 'submodule' 'update' '--init' '--recursive'
|
||||
__git_alias "$git_whatchanged_alias" 'git' 'whatchanged'
|
||||
__git_alias "$git_apply_alias" 'git' 'apply'
|
||||
|
||||
# Compound/complex commands
|
||||
_alias $git_fetch_all_alias="git fetch --all"
|
||||
_alias $git_pull_then_push_alias="git pull && git push"
|
||||
_alias $git_fetch_and_rebase_alias='git fetch && git rebase'
|
||||
_alias $git_commit_amend_alias='git commit --amend'
|
||||
_alias "$git_fetch_all_alias" 'git fetch --all'
|
||||
_alias "$git_pull_then_push_alias" 'git pull && git push'
|
||||
_alias "$git_fetch_and_rebase_alias" 'git fetch && git rebase'
|
||||
_alias "$git_commit_amend_alias" 'git commit --amend'
|
||||
|
||||
# Add staged changes to latest commit without prompting for message
|
||||
_alias $git_commit_amend_no_msg_alias='git commit --amend -C HEAD'
|
||||
_alias $git_commit_no_msg_alias='git commit -C HEAD'
|
||||
_alias $git_log_stat_alias='git log --stat --max-count=5'
|
||||
_alias $git_log_graph_alias='git log --graph --max-count=5'
|
||||
_alias $git_add_all_alias='git add -A'
|
||||
_alias "$git_commit_amend_no_msg_alias" 'git commit --amend -C HEAD'
|
||||
_alias "$git_commit_no_msg_alias" 'git commit -C HEAD'
|
||||
_alias "$git_log_stat_alias" 'git log --stat --max-count=5'
|
||||
_alias "$git_log_graph_alias" 'git log --graph --max-count=5'
|
||||
_alias "$git_add_all_alias" 'git add --all .'
|
||||
|
||||
# Hub aliases (https://github.com/github/hub)
|
||||
_alias "$git_pull_request_alias" 'git pull-request'
|
||||
fi
|
||||
|
||||
|
||||
@@ -168,4 +190,3 @@ if [ $shell = "bash" ]; then
|
||||
else
|
||||
compdef _git_index_tab_completion git_index $git_index_alias
|
||||
fi
|
||||
|
||||
|
||||
@@ -13,8 +13,9 @@
|
||||
unalias $git_branch_alias > /dev/null 2>&1; unset -f $git_branch_alias > /dev/null 2>&1
|
||||
function _scmb_git_branch_shortcuts {
|
||||
fail_if_not_git_repo || return 1
|
||||
|
||||
# Fall back to normal git branch, if any unknown args given
|
||||
if [[ -n "$@" ]] && [[ "$@" != "-a" ]]; then
|
||||
if [[ "$($_git_cmd branch | wc -l)" -gt 300 ]] || ([[ -n "$@" ]] && [[ "$@" != "-a" ]]); then
|
||||
exec_scmb_expand_args $_git_cmd branch "$@"
|
||||
return 1
|
||||
fi
|
||||
@@ -32,14 +33,16 @@ EOF
|
||||
|
||||
# Set numbered file shortcut in variable
|
||||
local e=1
|
||||
IFS=$'\n'
|
||||
for branch in $($_git_cmd branch "$@" | sed "s/^[* ]\{2\}//"); do
|
||||
export $git_env_char$e="$branch"
|
||||
if [ "${scmbDebug:-}" = "true" ]; then echo "Set \$$git_env_char$e => $file"; fi
|
||||
let e++
|
||||
done
|
||||
unset IFS
|
||||
}
|
||||
|
||||
__git_alias "$git_branch_alias" "_scmb_git_branch_shortcuts"
|
||||
__git_alias "$git_branch_alias" "_scmb_git_branch_shortcuts" ""
|
||||
__git_alias "$git_branch_all_alias" "_scmb_git_branch_shortcuts" "-a"
|
||||
__git_alias "$git_branch_move_alias" "_scmb_git_branch_shortcuts" "-m"
|
||||
__git_alias "$git_branch_delete_alias" "_scmb_git_branch_shortcuts" "-d"
|
||||
|
||||
4
lib/git/fallback/status_shortcuts_shell.sh
Normal file → Executable file
4
lib/git/fallback/status_shortcuts_shell.sh
Normal file → Executable file
@@ -114,7 +114,7 @@ git_status_shortcuts() {
|
||||
# so just use plain 'git status'
|
||||
git status
|
||||
fi
|
||||
IFS=$' \t\n'
|
||||
unset IFS
|
||||
zsh_reset # Reset zsh environment to default
|
||||
}
|
||||
# Template function for 'git_status_shortcuts'.
|
||||
@@ -127,7 +127,7 @@ _gs_output_file_group() {
|
||||
if [ -z "$project_root" ]; then
|
||||
relative="${stat_file[$i]}"
|
||||
else
|
||||
dest="$project_root/${stat_file[$i]}"
|
||||
dest=$(readlink -f "$project_root/${stat_file[$i]}")
|
||||
local pwd=$(readlink -f "$PWD")
|
||||
relative="$(_gs_relative_path "$pwd" "$dest" )"
|
||||
fi
|
||||
|
||||
47
lib/git/grep_shortcuts.rb
Normal file
47
lib/git/grep_shortcuts.rb
Normal file
@@ -0,0 +1,47 @@
|
||||
#!/usr/bin/env ruby
|
||||
# encoding: UTF-8
|
||||
|
||||
PROJECT_ROOT = File.exist?(".git") ? Dir.pwd : `\git rev-parse --show-toplevel 2> /dev/null`.strip
|
||||
|
||||
COLORS = {
|
||||
:rst => "\033[0m",
|
||||
:del => "\033[0;31m",
|
||||
:mod => "\033[0;32m",
|
||||
:new => "\033[0;33m",
|
||||
:ren => "\033[0;34m",
|
||||
:cpy => "\033[0;33m",
|
||||
:typ => "\033[0;35m",
|
||||
:unt => "\033[0;36m",
|
||||
:dark => "\033[2;37m",
|
||||
:branch => "\033[1m",
|
||||
:header => "\033[0m"
|
||||
}
|
||||
|
||||
COLOR_MATCH = /\e\[[0-9;]*[mK]/
|
||||
|
||||
output_files = []
|
||||
|
||||
stdin = STDIN.set_encoding(Encoding::ASCII_8BIT)
|
||||
|
||||
while stdin.gets
|
||||
if $. > 1000
|
||||
puts "Only showing first 1000 results. Please refine your search."
|
||||
break
|
||||
end
|
||||
print "#{COLORS[:dark]}[#{COLORS[:rst]}#{$.}#{COLORS[:dark]}]#{COLORS[:rst]} "
|
||||
matches = $_.match(/(^.+?)#{COLOR_MATCH}?:#{COLOR_MATCH}?(\d+)?/)
|
||||
file = matches[1]
|
||||
line = matches[2]
|
||||
output_files << "#{file}#{line ? ":#{line}" : ""}"
|
||||
puts $_
|
||||
end
|
||||
|
||||
print "@@filelist@@::"
|
||||
|
||||
output_files.each_with_index {|f,i|
|
||||
# If file starts with a '~', treat it as a relative path.
|
||||
# This is important when dealing with symlinks
|
||||
print "|" unless i == 0
|
||||
print f.start_with?("~") ? f.sub(/~/, '') : File.join(PROJECT_ROOT, f)
|
||||
}
|
||||
puts
|
||||
24
lib/git/grep_shortcuts.sh
Normal file
24
lib/git/grep_shortcuts.sh
Normal file
@@ -0,0 +1,24 @@
|
||||
git_grep_shortcuts() {
|
||||
fail_if_not_git_repo || return 1
|
||||
git_clear_vars
|
||||
# Run ruby script, store output
|
||||
tmp_grep_results="$(git rev-parse --git-dir)/tmp_grep_results_$$"
|
||||
git grep -n --color=always "$@" |
|
||||
/usr/bin/env ruby "$scmbDir/lib/git/grep_shortcuts.rb" >"$tmp_grep_results"
|
||||
|
||||
# Fetch list of files from last line of script output
|
||||
files="$(tail -1 "$tmp_grep_results" | sed 's%@@filelist@@::%%g')"
|
||||
|
||||
# Export numbered env variables for each file
|
||||
IFS="|"
|
||||
local e=1
|
||||
for file in ${=files}; do
|
||||
export $git_env_char$e="$file"
|
||||
let e++
|
||||
done
|
||||
IFS=$' \t\n'
|
||||
|
||||
# Print status
|
||||
cat "$tmp_grep_results" | sed '$d' | less -SfRMXFi
|
||||
rm -f "$tmp_grep_results"
|
||||
}
|
||||
@@ -27,13 +27,13 @@ if [[ "$git_keyboard_shortcuts_enabled" = "true" ]]; then
|
||||
# Uses emacs style keybindings, so vi mode is not supported for now
|
||||
if ! set -o | grep -q '^vi .*on$'; then
|
||||
if [[ $shell == "zsh" ]]; then
|
||||
_bind "$git_commit_all_keys" " git_commit_all""\n"
|
||||
_bind "$git_add_and_commit_keys" " \033[1~ git_add_and_commit ""\n"
|
||||
_bind "$git_commit_all_with_ci_skip_keys" " \033[1~ APPEND='[ci skip]' git_commit_all ""\n"
|
||||
_bind "$git_commit_all_keys" " git_commit_all""^M"
|
||||
_bind "$git_add_and_commit_keys" " \033[1~ git_add_and_commit ""^M"
|
||||
_bind "$git_commit_all_with_ci_skip_keys" " \033[1~ APPEND='[ci skip]' git_commit_all ""^M"
|
||||
else
|
||||
_bind "$git_commit_all_keys" "\" git_commit_all\n\""
|
||||
_bind "$git_add_and_commit_keys" "\"\033[1~ git_add_and_commit \n\""
|
||||
_bind "$git_commit_all_with_ci_skip_keys" "\"\033[1~ APPEND='[ci skip]' git_commit_all \n\""
|
||||
_bind "$git_commit_all_keys" "\" git_commit_all^M\""
|
||||
_bind "$git_add_and_commit_keys" "\"\C-A git_add_and_commit ^M\""
|
||||
_bind "$git_commit_all_with_ci_skip_keys" "\"\C-A APPEND='[ci skip]' git_commit_all ^M\""
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
@@ -68,8 +68,8 @@ function git_index() {
|
||||
elif [ "$1" = "--list" ] || [ "$1" = "-l" ]; then
|
||||
echo -e "$_bld_col$(_git_index_count)$_txt_col Git repositories in $_bld_col$GIT_REPO_DIR$_txt_col:\n"
|
||||
for repo in $(_git_index_dirs_without_home); do
|
||||
echo $(basename $repo) : $repo
|
||||
done | sort | column -t -s ':'
|
||||
echo $(basename $repo | sed "s/ /_/g") : $repo
|
||||
done | sort -t ":" -k1,1 | column -t -s ':'
|
||||
elif [ "$1" = "--count-by-host" ]; then
|
||||
echo -e "=== Producing a report of the number of repos per host...\n"
|
||||
_git_index_batch_cmd git remote -v | \grep "origin.*(fetch)" |
|
||||
@@ -116,7 +116,7 @@ function git_index() {
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
IFS=$' \t\n'
|
||||
unset IFS
|
||||
}
|
||||
|
||||
_git_index_dirs_without_home() {
|
||||
@@ -127,11 +127,11 @@ _git_index_dirs_without_home() {
|
||||
function _find_git_repos() {
|
||||
# Find all unarchived projects
|
||||
IFS=$'\n'
|
||||
for repo in $(find -L "$GIT_REPO_DIR" -maxdepth 4 -name ".git" -type d \! -wholename '*/archive/*'); do
|
||||
for repo in $(find -L "$GIT_REPO_DIR" -maxdepth 5 -name ".git" -type d \! -wholename '*/archive/*'); do
|
||||
echo ${repo%/.git} # Return project folder, with trailing ':'
|
||||
_find_git_submodules $repo # Detect any submodules
|
||||
done
|
||||
IFS=$' \t\n'
|
||||
unset IFS
|
||||
}
|
||||
|
||||
# List all submodules for a git repo, if any.
|
||||
@@ -148,9 +148,9 @@ function _rebuild_git_index() {
|
||||
# Get repos from src dir and custom dirs, then sort by basename
|
||||
IFS=$'\n'
|
||||
for repo in $(echo -e "$(_find_git_repos)\n$(echo $GIT_REPOS | sed "s/:/\\\\n/g")"); do
|
||||
echo $(basename $repo | sed "s/ /_/g") $repo
|
||||
done | sort | cut -d " " -f2- > "$GIT_REPO_DIR/.git_index"
|
||||
IFS=$' \t\n'
|
||||
echo $(basename $repo | sed "s/ /_/g"):$repo
|
||||
done | sort -t ":" -k1,1 | cut -d ":" -f2- >| "$GIT_REPO_DIR/.git_index"
|
||||
unset IFS
|
||||
|
||||
if [ "$1" != "--silent" ]; then
|
||||
echo -e "===== Indexed $_bld_col$(_git_index_count)$_txt_col repos in $GIT_REPO_DIR/.git_index"
|
||||
@@ -225,7 +225,7 @@ _git_index_update_all_branches() {
|
||||
echo "=== Skipping $branch: remote and merge refs are not configured."
|
||||
fi
|
||||
done
|
||||
IFS=$' \t\n'
|
||||
unset IFS
|
||||
|
||||
# Update all remotes if there are any branches to update
|
||||
if [ -n "${branches[*]}" ]; then git fetch --all 2> /dev/null; fi
|
||||
@@ -268,7 +268,7 @@ function _git_index_batch_cmd() {
|
||||
cwd="$PWD"
|
||||
if [ -n "$1" ]; then
|
||||
echo -e "== Running command for $_bld_col$(_git_index_count)$_txt_col repos...\n"
|
||||
IFS=$' \t\n'
|
||||
unset IFS
|
||||
local base_path
|
||||
for base_path in $(sed -e "s/--.*//" "$GIT_REPO_DIR/.git_index" | \grep . | sort); do
|
||||
builtin cd "$base_path"
|
||||
@@ -313,7 +313,7 @@ if [ $shell = 'bash' ]; then
|
||||
else
|
||||
COMPREPLY=($(compgen -W '$(sed -e "s:.*/::" -e "s:$:/:" "$GIT_REPO_DIR/.git_index" | sort)' -- $curw))
|
||||
fi
|
||||
IFS=$' \t\n'
|
||||
unset IFS
|
||||
return 0
|
||||
}
|
||||
else
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
|
||||
if test | sed -E 's///g' 2>/dev/null; then
|
||||
if sed -E 's///g' </dev/null &>/dev/null; then
|
||||
SED_REGEX_ARG="E"
|
||||
elif test | sed -r 's///g' 2>/dev/null; then
|
||||
elif sed -r 's///g' </dev/null &>/dev/null; then
|
||||
SED_REGEX_ARG="r"
|
||||
else
|
||||
echo "Cannot determine extended regex argument for sed! (Doesn't respond to either -E or -r)"
|
||||
@@ -21,7 +21,7 @@ if [ "$shell_command_wrapping_enabled" = "true" ] || [ "$bash_command_wrapping_e
|
||||
# Do it in a function so we don't bleed variables
|
||||
function _git_wrap_commands() {
|
||||
# Define 'whence' for bash, to get the value of an alias
|
||||
type whence > /dev/null 2>&1 || function whence() { type "$@" | sed -$SED_REGEX_ARG -e "s/.*is aliased to \`//" -e "s/'$//"; }
|
||||
type whence > /dev/null 2>&1 || function whence() { LC_MESSAGES="C" type "$@" | sed -$SED_REGEX_ARG -e "s/.*is aliased to \`//" -e "s/'$//"; }
|
||||
local cmd=''
|
||||
for cmd in $(echo $scmb_wrapped_shell_commands); do
|
||||
if [ "${scmbDebug:-}" = "true" ]; then echo "SCMB: Wrapping $cmd..."; fi
|
||||
@@ -35,7 +35,7 @@ if [ "$shell_command_wrapping_enabled" = "true" ] || [ "$bash_command_wrapping_e
|
||||
fi
|
||||
fi
|
||||
|
||||
case "$(type $cmd 2>&1)" in
|
||||
case "$(LC_MESSAGES="C" type $cmd 2>&1)" in
|
||||
|
||||
# Don't do anything if command already aliased, or not found.
|
||||
*'exec_scmb_expand_args'*)
|
||||
@@ -52,7 +52,7 @@ if [ "$shell_command_wrapping_enabled" = "true" ] || [ "$bash_command_wrapping_e
|
||||
unalias $cmd
|
||||
|
||||
# Detect original $cmd type, and escape
|
||||
case "$(type $cmd 2>&1)" in
|
||||
case "$(LC_MESSAGES="C" type $cmd 2>&1)" in
|
||||
# Escape shell builtins with 'builtin'
|
||||
*'is a shell builtin'*) local escaped_cmd="builtin $cmd";;
|
||||
# Get full path for files with 'find_binary' function
|
||||
@@ -108,50 +108,51 @@ fi
|
||||
|
||||
# Function wrapper around 'll'
|
||||
# Adds numbered shortcuts to output of ls -l, just like 'git status'
|
||||
unalias ll > /dev/null 2>&1; unset -f ll > /dev/null 2>&1
|
||||
function ls_with_file_shortcuts {
|
||||
local ll_output
|
||||
if [ "$_ls_bsd" != "BSD" ]; then
|
||||
ll_output="$(\ls -lhv --group-directories-first --color "$@")"
|
||||
else
|
||||
ll_output="$(CLICOLOR_FORCE=1 \ls -l -G "$@")"
|
||||
fi
|
||||
if [ "$shell_ls_aliases_enabled" = "true" ] && which ruby > /dev/null 2>&1; then
|
||||
unalias ll > /dev/null 2>&1; unset -f ll > /dev/null 2>&1
|
||||
function ls_with_file_shortcuts {
|
||||
local ll_output
|
||||
if [ "$_ls_bsd" != "BSD" ]; then
|
||||
ll_output="$(\ls -lhv --group-directories-first --color "$@")"
|
||||
else
|
||||
ll_output="$(CLICOLOR_FORCE=1 \ls -l -G "$@")"
|
||||
fi
|
||||
|
||||
if [[ $shell == "zsh" ]]; then
|
||||
# Ensure sh_word_split is on
|
||||
if setopt | grep -q shwordsplit; then SHWORDSPLIT_ON=true; fi
|
||||
setopt shwordsplit
|
||||
fi
|
||||
if [[ $shell == "zsh" ]]; then
|
||||
# Ensure sh_word_split is on
|
||||
if setopt | grep -q shwordsplit; then SHWORDSPLIT_ON=true; fi
|
||||
setopt shwordsplit
|
||||
fi
|
||||
|
||||
# Parse path from args
|
||||
OLDIFS="$IFS"; IFS=$'\n'
|
||||
for arg in $@; do
|
||||
if [ -d "$arg" ]; then local rel_path="${arg%/}"; fi
|
||||
done
|
||||
IFS="$OLDIFS"
|
||||
# Parse path from args
|
||||
IFS=$'\n'
|
||||
for arg in $@; do
|
||||
if [ -d "$arg" ]; then local rel_path="${arg%/}"; fi
|
||||
done
|
||||
unset IFS
|
||||
|
||||
# Replace user/group with user symbol, if defined at ~/.user_sym
|
||||
# Before : -rw-rw-r-- 1 ndbroadbent ndbroadbent 1.1K Sep 19 21:39 scm_breeze.sh
|
||||
# After : -rw-rw-r-- 1 𝐍 𝐍 1.1K Sep 19 21:39 scm_breeze.sh
|
||||
if [ -e $HOME/.user_sym ]; then
|
||||
# Little bit of ruby golf to rejustify the user/group/size columns after replacement
|
||||
function rejustify_ls_columns(){
|
||||
ruby -e "o=STDIN.read;re=/^(([^ ]* +){2})(([^ ]* +){3})/;\
|
||||
u,g,s=o.lines.map{|l|l[re,3]}.compact.map(&:split).transpose.map{|a|a.map(&:size).max+1};\
|
||||
puts o.lines.map{|l|l.sub(re){|m|\"%s%-#{u}s %-#{g}s%#{s}s \"%[\$1,*\$3.split]}}"
|
||||
}
|
||||
# Replace user/group with user symbol, if defined at ~/.user_sym
|
||||
# Before : -rw-rw-r-- 1 ndbroadbent ndbroadbent 1.1K Sep 19 21:39 scm_breeze.sh
|
||||
# After : -rw-rw-r-- 1 𝐍 𝐍 1.1K Sep 19 21:39 scm_breeze.sh
|
||||
if [ -e $HOME/.user_sym ]; then
|
||||
# Little bit of ruby golf to rejustify the user/group/size columns after replacement
|
||||
function rejustify_ls_columns(){
|
||||
ruby -e "o=STDIN.read;re=/^(([^ ]* +){2})(([^ ]* +){3})/;\
|
||||
u,g,s=o.lines.map{|l|l[re,3]}.compact.map(&:split).transpose.map{|a|a.map(&:size).max+1};\
|
||||
puts o.lines.map{|l|l.sub(re){|m|\"%s%-#{u}s %-#{g}s%#{s}s \"%[\$1,*\$3.split]}}"
|
||||
}
|
||||
|
||||
ll_output=$(echo "$ll_output" | \sed -$SED_REGEX_ARG "s/ $USER/ $(/bin/cat $HOME/.user_sym)/g" | rejustify_ls_columns)
|
||||
fi
|
||||
ll_output=$(echo "$ll_output" | \sed -$SED_REGEX_ARG "s/ $USER/ $(/bin/cat $HOME/.user_sym)/g" | rejustify_ls_columns)
|
||||
fi
|
||||
|
||||
if [ "$(echo "$ll_output" | wc -l)" -gt "50" ]; then
|
||||
echo -e "\033[33mToo many files to create shortcuts. Running plain ll command...\033[0m"
|
||||
echo "$ll_output"
|
||||
return 1
|
||||
fi
|
||||
if [ "$(echo "$ll_output" | wc -l)" -gt "50" ]; then
|
||||
echo -e "\033[33mToo many files to create shortcuts. Running plain ll command...\033[0m"
|
||||
echo "$ll_output"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Use ruby to inject numbers into ls output
|
||||
echo "$ll_output" | ruby -e "$( \cat <<EOF
|
||||
# Use ruby to inject numbers into ls output
|
||||
echo "$ll_output" | ruby -e "$( \cat <<EOF
|
||||
output = STDIN.read
|
||||
e = 1
|
||||
re = /^(([^ ]* +){8})/
|
||||
@@ -163,30 +164,31 @@ end
|
||||
EOF
|
||||
)"
|
||||
|
||||
# Set numbered file shortcut in variable
|
||||
local e=1
|
||||
local ll_files=''
|
||||
local file=''
|
||||
# Set numbered file shortcut in variable
|
||||
local e=1
|
||||
local ll_files=''
|
||||
local file=''
|
||||
|
||||
if [ -z $_ls_bsd ]; then
|
||||
ll_files="$(\ls -v --group-directories-first --color=never "$@")"
|
||||
else
|
||||
ll_files="$(\ls "$@")"
|
||||
fi
|
||||
if [ -z $_ls_bsd ]; then
|
||||
ll_files="$(\ls -v --group-directories-first --color=never "$@")"
|
||||
else
|
||||
ll_files="$(\ls "$@")"
|
||||
fi
|
||||
|
||||
OLDIFS="$IFS"; IFS=$'\n'
|
||||
for file in $ll_files; do
|
||||
if [ -n "$rel_path" ]; then file="$rel_path/$file"; fi
|
||||
export $git_env_char$e="$(eval $_abs_path_command \"${file//\"/\\\"}\")"
|
||||
if [ "${scmbDebug:-}" = "true" ]; then echo "Set \$$git_env_char$e => $file"; fi
|
||||
let e++
|
||||
done
|
||||
IFS="$OLDIFS"
|
||||
IFS=$'\n'
|
||||
for file in $ll_files; do
|
||||
if [ -n "$rel_path" ]; then file="$rel_path/$file"; fi
|
||||
export $git_env_char$e="$(eval $_abs_path_command \"${file//\"/\\\"}\")"
|
||||
if [ "${scmbDebug:-}" = "true" ]; then echo "Set \$$git_env_char$e => $file"; fi
|
||||
let e++
|
||||
done
|
||||
unset IFS
|
||||
|
||||
# Turn off shwordsplit unless it was on previously
|
||||
if [[ $shell == "zsh" ]] && [ -z "$SHWORDSPLIT_ON" ]; then unsetopt shwordsplit; fi
|
||||
}
|
||||
# Turn off shwordsplit unless it was on previously
|
||||
if [[ $shell == "zsh" ]] && [ -z "$SHWORDSPLIT_ON" ]; then unsetopt shwordsplit; fi
|
||||
}
|
||||
|
||||
# Setup aliases
|
||||
alias ll="exec_scmb_expand_args ls_with_file_shortcuts"
|
||||
alias la="ll -A"
|
||||
# Setup aliases
|
||||
alias ll="exec_scmb_expand_args ls_with_file_shortcuts"
|
||||
alias la="ll -A"
|
||||
fi
|
||||
|
||||
@@ -43,7 +43,7 @@ git_status_shortcuts() {
|
||||
if [ "${scmbDebug:-}" = "true" ]; then echo "Set \$$git_env_char$e => $file"; fi
|
||||
let e++
|
||||
done
|
||||
IFS=$' \t\n'
|
||||
unset IFS
|
||||
|
||||
if [ "${scmbDebug:-}" = "true" ]; then echo "------------------------"; fi
|
||||
# Print status
|
||||
@@ -91,7 +91,7 @@ git_silent_add_shortcuts() {
|
||||
echo -e "# Added '$file'"
|
||||
fi
|
||||
done
|
||||
IFS=$' \t\n'
|
||||
unset IFS
|
||||
echo "#"
|
||||
fi
|
||||
}
|
||||
@@ -158,7 +158,7 @@ _print_path() {
|
||||
# Execute a command with expanded args, e.g. Delete files 6 to 12: $ ge rm 6-12
|
||||
# Fails if command is a number or range (probably not worth fixing)
|
||||
exec_scmb_expand_args() {
|
||||
eval "$(scmb_expand_args "$@" | sed -e "s/\([][()<>^ \"']\)/"'\\\1/g')"
|
||||
eval "$(scmb_expand_args "$@" | sed -e "s/\([][|;()<>^ \"'&]\)/"'\\\1/g')"
|
||||
}
|
||||
|
||||
# Clear numbered env variables
|
||||
@@ -166,7 +166,12 @@ git_clear_vars() {
|
||||
local i
|
||||
for (( i=1; i<=$gs_max_changes; i++ )); do
|
||||
# Stop clearing after first empty var
|
||||
if [[ -z "$(eval echo "\${$git_env_char$i:-}")" ]]; then break; fi
|
||||
local env_var_i=${git_env_char}${i}
|
||||
if [[ -z "$(eval echo "\${$env_var_i:-}")" ]]; then
|
||||
break
|
||||
else
|
||||
unset $env_var_i
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
@@ -181,7 +186,7 @@ _git_resolve_merge_conflict() {
|
||||
git add "$file"
|
||||
echo -e "# Added $1 version of '$file'"
|
||||
done
|
||||
IFS=$' \t\n'
|
||||
unset IFS
|
||||
echo -e "# -- If you have finished resolving conflicts, commit the resolutions with 'git commit'"
|
||||
fi
|
||||
}
|
||||
@@ -233,7 +238,7 @@ git_commit_all() {
|
||||
local appending=" | \033[0;36mappending '\033[1;36m$APPEND\033[0;36m' to commit message.\033[0m"
|
||||
fi
|
||||
echo -e "\033[0;33mCommitting all files (\033[0;31m$changes\033[0;33m)\033[0m$appending"
|
||||
git_commit_prompt "git add -A"
|
||||
git_commit_prompt "git add --all ."
|
||||
else
|
||||
echo "# No changed files to commit."
|
||||
fi
|
||||
|
||||
@@ -10,7 +10,13 @@ enable_nullglob() { if [ $shell = "zsh" ]; then setopt NULL_GLOB; else shopt
|
||||
disable_nullglob() { if [ $shell = "zsh" ]; then unsetopt NULL_GLOB; else shopt -u nullglob; fi; }
|
||||
|
||||
# Alias wrapper that ignores errors if alias is not defined.
|
||||
_alias(){ alias "$@" 2> /dev/null; }
|
||||
_safe_alias(){ alias "$@" 2> /dev/null; }
|
||||
_alias() {
|
||||
if [ -n "$1" ]; then
|
||||
local alias_str="$1"; local cmd="$2"
|
||||
_safe_alias $alias_str="$cmd"
|
||||
fi
|
||||
}
|
||||
|
||||
find_binary(){
|
||||
if [ $shell = "zsh" ]; then
|
||||
@@ -48,7 +54,7 @@ _create_or_patch_scmbrc() {
|
||||
# If file exists, attempt to update it with any new settings
|
||||
elif [ -n "$1" ]; then
|
||||
# Create diff of example file, substituting example file for user's config.
|
||||
git diff $1 "$prefix""scmbrc.example" | sed "s/$prefix""scmbrc.example/.$prefix""scmbrc/g" > $patchfile
|
||||
git diff $1 "$prefix""scmbrc.example" | sed "s/$prefix""scmbrc.example/.$prefix""scmbrc/g" >| $patchfile
|
||||
if [ -s $patchfile ]; then # If patchfile is not empty
|
||||
cd "$HOME"
|
||||
# If the patch cannot be applied cleanly, show the updates and tell user to update file manually.
|
||||
|
||||
15
run_tests.sh
15
run_tests.sh
@@ -3,8 +3,15 @@
|
||||
|
||||
failed=false
|
||||
|
||||
# allow list of shells to run tests in to be overriden by environment variable
|
||||
# if empty or null, use defaults
|
||||
if [ -z "$TEST_SHELLS" ]; then
|
||||
TEST_SHELLS="bash zsh"
|
||||
fi
|
||||
|
||||
echo "== Will run all tests with following shells: ${TEST_SHELLS}"
|
||||
for test in $(find test/lib -name *_test.sh); do
|
||||
for shell in bash zsh; do
|
||||
for shell in $TEST_SHELLS; do
|
||||
echo "== Running tests with [$shell]: $test"
|
||||
$shell $test || failed=true
|
||||
done
|
||||
@@ -12,8 +19,8 @@ done
|
||||
|
||||
if [ "$failed" = "true" ]; then
|
||||
echo "Tests failed!"
|
||||
return 1;
|
||||
false
|
||||
else
|
||||
echo "All tests passed!"
|
||||
return 0;
|
||||
fi
|
||||
true
|
||||
fi
|
||||
|
||||
25
scm_breeze.plugin.zsh
Normal file
25
scm_breeze.plugin.zsh
Normal file
@@ -0,0 +1,25 @@
|
||||
#########################################################
|
||||
# Forked from http://github.com/ndbroadbent/scm_breeze #
|
||||
# #
|
||||
# File Copied and modified from ./install.sh #
|
||||
# to be compatible with oh-my-zsh's plugin system #
|
||||
#########################################################
|
||||
|
||||
#!/bin/bash
|
||||
#locate the dir where this script is stored
|
||||
export scmbDir="$( cd -P "$( dirname "$0" )" && pwd )"
|
||||
|
||||
# Symlink to ~/.scm_breeze if installing from another path
|
||||
if [ ! -s "$HOME/.scm_breeze" ] && [ "$scmbDir" != "$HOME/.scm_breeze" ]; then
|
||||
ln -fs "$scmbDir" "$HOME/.scm_breeze"
|
||||
|
||||
# Load SCM Breeze update scripts
|
||||
source "$scmbDir/lib/scm_breeze.sh"
|
||||
# Create '~/.*.scmbrc' files from example files
|
||||
_create_or_patch_scmbrc
|
||||
fi
|
||||
|
||||
# This loads SCM Breeze into the shell session.
|
||||
[ -s "$HOME/.scm_breeze/scm_breeze.sh" ] && source "$HOME/.scm_breeze/scm_breeze.sh"
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ if [[ -s "$HOME/.git.scmbrc" ]]; then
|
||||
source "$scmbDir/lib/git/keybindings.sh"
|
||||
source "$scmbDir/lib/git/status_shortcuts.sh"
|
||||
source "$scmbDir/lib/git/branch_shortcuts.sh"
|
||||
source "$scmbDir/lib/git/grep_shortcuts.sh"
|
||||
source "$scmbDir/lib/git/shell_shortcuts.sh"
|
||||
source "$scmbDir/lib/git/repo_index.sh"
|
||||
source "$scmbDir/lib/git/tools.sh"
|
||||
|
||||
@@ -7,10 +7,14 @@
|
||||
#
|
||||
# Unit tests for git shell scripts
|
||||
|
||||
export scmbDir="$( cd -P "$( dirname "$0" )" && pwd )/../../.."
|
||||
export scmbDir="$(cd -P "$(dirname "$0")" && pwd)/../../.."
|
||||
|
||||
# Zsh compatibility
|
||||
if [ -n "${ZSH_VERSION:-}" ]; then shell="zsh"; SHUNIT_PARENT=$0; setopt shwordsplit; fi
|
||||
if [ -n "${ZSH_VERSION:-}" ]; then
|
||||
shell="zsh"
|
||||
SHUNIT_PARENT=$0
|
||||
setopt shwordsplit
|
||||
fi
|
||||
|
||||
# Load test helpers
|
||||
source "$scmbDir/test/support/test_helper.sh"
|
||||
@@ -19,7 +23,6 @@ source "$scmbDir/test/support/test_helper.sh"
|
||||
source "$scmbDir/lib/scm_breeze.sh"
|
||||
source "$scmbDir/lib/git/repo_index.sh"
|
||||
|
||||
|
||||
# Setup and tear down
|
||||
#-----------------------------------------------------------------------------
|
||||
oneTimeSetUp() {
|
||||
@@ -34,7 +37,10 @@ oneTimeSetUp() {
|
||||
cd $GIT_REPO_DIR
|
||||
# Setup test repos in temp repo dir
|
||||
for repo in github bitbucket source_forge TestCaps; do
|
||||
mkdir $repo; cd $repo; git init; cd - > /dev/null
|
||||
mkdir $repo
|
||||
cd $repo
|
||||
git init
|
||||
cd - >/dev/null
|
||||
done
|
||||
|
||||
# Add some nested dirs for testing resursive tab completion
|
||||
@@ -47,7 +53,7 @@ oneTimeSetUp() {
|
||||
mkdir submodules_everywhere
|
||||
cd submodules_everywhere
|
||||
git init
|
||||
cat > .gitmodules <<EOF
|
||||
cat >.gitmodules <<EOF
|
||||
[submodule "very/nested/directory/red_submodule"]
|
||||
[submodule "very/nested/directory/green_submodule"]
|
||||
[submodule "very/nested/directory/blue_submodule"]
|
||||
@@ -55,15 +61,20 @@ EOF
|
||||
mkdir -p "very/nested/directory"
|
||||
cd "very/nested/directory"
|
||||
for repo in red_submodule green_submodule blue_submodule; do
|
||||
mkdir $repo; cd $repo; git init; cd - > /dev/null
|
||||
mkdir $repo
|
||||
cd $repo
|
||||
git init
|
||||
cd - >/dev/null
|
||||
done
|
||||
|
||||
# Setup some custom repos outside the main repo dir
|
||||
IFS=":"
|
||||
for dir in $GIT_REPOS; do
|
||||
mkdir -p $dir; cd $dir; git init;
|
||||
mkdir -p $dir
|
||||
cd $dir
|
||||
git init
|
||||
done
|
||||
IFS=$' \t\n'
|
||||
unset IFS
|
||||
|
||||
verboseGitCommands
|
||||
|
||||
@@ -74,7 +85,7 @@ oneTimeTearDown() {
|
||||
rm -rf "${GIT_REPO_DIR}"
|
||||
IFS=":"
|
||||
for dir in $GIT_REPOS; do rm -rf $dir; done
|
||||
IFS=$' \t\n'
|
||||
unset IFS
|
||||
}
|
||||
|
||||
ensureIndex() {
|
||||
@@ -85,30 +96,32 @@ index_no_newlines() {
|
||||
tr "\\n" " " < $git_index_file
|
||||
}
|
||||
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Unit tests
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
test_repo_index_command() {
|
||||
git_index --rebuild > /dev/null
|
||||
git_index --rebuild >/dev/null
|
||||
|
||||
# Test that all repos are detected, and sorted alphabetically
|
||||
assertIncludes "$(index_no_newlines)" "bitbucket.*\
|
||||
blue_submodule.*\
|
||||
github.*\
|
||||
green_submodule.*\
|
||||
red_submodule.*\
|
||||
source_forge.*\
|
||||
submodules_everywhere.*\
|
||||
test_repo_11.*\
|
||||
test_repo_1"
|
||||
|
||||
assertIncludes "$(index_no_newlines)" $(
|
||||
cat <<EXPECT | sort -t "." -k1,1 | tr -d '\n' | awk '{print ".*"$1}'
|
||||
bitbucket.*
|
||||
blue_submodule.*
|
||||
github.*
|
||||
green_submodule.*
|
||||
red_submodule.*
|
||||
source_forge.*
|
||||
submodules_everywhere.*
|
||||
test_repo_11.*
|
||||
test_repo_1.*
|
||||
EXPECT
|
||||
)
|
||||
}
|
||||
|
||||
test_check_git_index() {
|
||||
ensureIndex
|
||||
echo "should not be regenerated" >> $git_index_file
|
||||
echo "should not be regenerated" >>$git_index_file
|
||||
_check_git_index
|
||||
# Test that index is not rebuilt unless empty
|
||||
assertIncludes "$(index_no_newlines)" "should not be regenerated"
|
||||
@@ -125,7 +138,7 @@ test_git_index_count() {
|
||||
test_repo_list() {
|
||||
ensureIndex
|
||||
list=$(git_index --list)
|
||||
assertIncludes "$list" "bitbucket" || return
|
||||
assertIncludes "$list" "bitbucket" || return
|
||||
assertIncludes "$list" "blue_submodule" || return
|
||||
assertIncludes "$list" "test_repo_11"
|
||||
}
|
||||
@@ -133,16 +146,26 @@ test_repo_list() {
|
||||
# Test matching rules for changing directory
|
||||
test_git_index_changing_directory() {
|
||||
ensureIndex
|
||||
git_index "github"; assertEquals "$GIT_REPO_DIR/github" "$PWD"
|
||||
git_index "github/"; assertEquals "$GIT_REPO_DIR/github" "$PWD"
|
||||
git_index "bucket"; assertEquals "$GIT_REPO_DIR/bitbucket" "$PWD"
|
||||
git_index "testcaps"; assertEquals "$GIT_REPO_DIR/TestCaps" "$PWD"
|
||||
git_index "green_sub"; assertEquals "$GIT_REPO_DIR/submodules_everywhere/very/nested/directory/green_submodule" "$PWD"
|
||||
git_index "_submod"; assertEquals "$GIT_REPO_DIR/submodules_everywhere/very/nested/directory/blue_submodule" "$PWD"
|
||||
git_index "test_repo_1"; assertEquals "/tmp/test_repo_1" "$PWD"
|
||||
git_index "test_repo_11"; assertEquals "/tmp/test_repo_11" "$PWD"
|
||||
git_index "test_repo_"; assertEquals "/tmp/test_repo_11" "$PWD"
|
||||
git_index "github/videos/octocat/live_action"; assertEquals "$GIT_REPO_DIR/github/videos/octocat/live_action" "$PWD"
|
||||
git_index "github"
|
||||
assertEquals "$GIT_REPO_DIR/github" "$PWD"
|
||||
git_index "github/"
|
||||
assertEquals "$GIT_REPO_DIR/github" "$PWD"
|
||||
git_index "bucket"
|
||||
assertEquals "$GIT_REPO_DIR/bitbucket" "$PWD"
|
||||
git_index "testcaps"
|
||||
assertEquals "$GIT_REPO_DIR/TestCaps" "$PWD"
|
||||
git_index "green_sub"
|
||||
assertEquals "$GIT_REPO_DIR/submodules_everywhere/very/nested/directory/green_submodule" "$PWD"
|
||||
git_index "_submod"
|
||||
assertEquals "$GIT_REPO_DIR/submodules_everywhere/very/nested/directory/blue_submodule" "$PWD"
|
||||
git_index "test_repo_1"
|
||||
assertEquals "/tmp/test_repo_1" "$PWD"
|
||||
git_index "test_repo_11"
|
||||
assertEquals "/tmp/test_repo_11" "$PWD"
|
||||
git_index "test_repo_"
|
||||
assertEquals "/tmp/test_repo_1" "$PWD"
|
||||
git_index "github/videos/octocat/live_action"
|
||||
assertEquals "$GIT_REPO_DIR/github/videos/octocat/live_action" "$PWD"
|
||||
}
|
||||
|
||||
test_git_index_tab_completion() {
|
||||
@@ -163,16 +186,15 @@ test_git_index_tab_completion() {
|
||||
# Test completion for project sub-directories when project ends with '/'
|
||||
COMP_WORDS="github/"
|
||||
_git_index_tab_completion
|
||||
assertIncludes "$(tab_completions)" "github/videos/"
|
||||
assertIncludes "$(tab_completions)" "github/videos/"
|
||||
# Check that '.git/' is filtered from completion, but other hidden dirs are available
|
||||
assertNotIncludes "$(tab_completions)" "github/.git/"
|
||||
assertIncludes "$(tab_completions)" "github/.im_hidden/"
|
||||
assertIncludes "$(tab_completions)" "github/.im_hidden/"
|
||||
|
||||
COMP_WORDS="github/videos/"
|
||||
_git_index_tab_completion
|
||||
assertIncludes "$(tab_completions)" "github/videos/octocat/"
|
||||
|
||||
|
||||
# Test that completion checks for other matching projects even if one matches perfectly
|
||||
COMP_WORDS="test_repo_1"
|
||||
_git_index_tab_completion
|
||||
@@ -180,7 +202,6 @@ test_git_index_tab_completion() {
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
# Test changing to top-level directory (when arg begins with '/')
|
||||
test_changing_to_top_level_directory() {
|
||||
mkdir "$GIT_REPO_DIR/gems"
|
||||
@@ -188,8 +209,6 @@ test_changing_to_top_level_directory() {
|
||||
assertEquals "$GIT_REPO_DIR/gems" "$PWD"
|
||||
}
|
||||
|
||||
|
||||
# load and run shUnit2
|
||||
# Call this function to run tests
|
||||
source "$scmbDir/test/support/shunit2"
|
||||
|
||||
|
||||
@@ -21,22 +21,38 @@ fi
|
||||
source "$scmbDir/test/support/test_helper.sh"
|
||||
source "$scmbDir/lib/scm_breeze.sh"
|
||||
|
||||
bin_path() {
|
||||
if [ -n "${ZSH_VERSION:-}" ];
|
||||
then where "$@" | tail -1
|
||||
else which "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
# Setup
|
||||
#-----------------------------------------------------------------------------
|
||||
oneTimeSetUp() {
|
||||
export shell_command_wrapping_enabled="true"
|
||||
export scmb_wrapped_shell_commands="not_found cat rm cp mv ln cd sed"
|
||||
export shell_ls_aliases_enabled="true"
|
||||
|
||||
alias rvm="test" # Ensure tests run if RVM isn't loaded but $HOME/.rvm is present
|
||||
|
||||
# Test functions
|
||||
function ln() { ln $@; }
|
||||
|
||||
# Before aliasing, get original locations so we can compare them in the test
|
||||
unalias mv rm sed cat 2>/dev/null
|
||||
export mv_path="$(bin_path mv)"
|
||||
export rm_path="$(bin_path rm)"
|
||||
export sed_path="$(bin_path sed)"
|
||||
export cat_path="$(bin_path cat)"
|
||||
|
||||
# Test aliases
|
||||
alias mv="nocorrect mv"
|
||||
alias rm="rm --option"
|
||||
alias sed="sed"
|
||||
alias mv="nocorrect $mv_path"
|
||||
alias rm="$rm_path --option"
|
||||
alias sed="$sed_path"
|
||||
# Test already wrapped commands
|
||||
alias cat="exec_scmb_expand_args /bin/cat"
|
||||
alias cat="exec_scmb_expand_args $cat_path"
|
||||
|
||||
# Run shortcut wrapping
|
||||
source "$scmbDir/lib/git/shell_shortcuts.sh"
|
||||
@@ -58,11 +74,11 @@ assertAliasEquals(){
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
test_shell_command_wrapping() {
|
||||
assertAliasEquals "exec_scmb_expand_args /bin/rm --option" "rm"
|
||||
assertAliasEquals "exec_scmb_expand_args nocorrect /bin/mv" "mv"
|
||||
assertAliasEquals "exec_scmb_expand_args /bin/sed" "sed"
|
||||
assertAliasEquals "exec_scmb_expand_args /bin/cat" "cat"
|
||||
assertAliasEquals "exec_scmb_expand_args builtin cd" "cd"
|
||||
assertAliasEquals "exec_scmb_expand_args nocorrect $mv_path" "mv"
|
||||
assertAliasEquals "exec_scmb_expand_args $rm_path --option" "rm"
|
||||
assertAliasEquals "exec_scmb_expand_args $sed_path" "sed"
|
||||
assertAliasEquals "exec_scmb_expand_args $cat_path" "cat"
|
||||
assertAliasEquals "exec_scmb_expand_args builtin cd" "cd"
|
||||
assertIncludes "$(declare -f ln)" "ln ()"
|
||||
assertIncludes "$(declare -f ln)" "exec_scmb_expand_args __original_ln"
|
||||
}
|
||||
@@ -71,7 +87,15 @@ test_ls_with_file_shortcuts() {
|
||||
export git_env_char="e"
|
||||
|
||||
TEST_DIR=$(mktemp -d -t scm_breeze.XXXXXXXXXX)
|
||||
|
||||
# Darwin actually symlinks /var inside /private, but mktemp reports back the
|
||||
# logical pathat time of file creation. So make sure we always get the
|
||||
# full physical path to be absolutely certain when doing comparisons later,
|
||||
# because thats how the Ruby status_shortcuts.rb script is going to obtain
|
||||
# them.
|
||||
cd $TEST_DIR
|
||||
TEST_DIR=$(pwd -P)
|
||||
|
||||
touch 'test file' 'test_file'
|
||||
mkdir -p "a [b]" 'a "b"' "a 'b'"
|
||||
touch "a \"b\"/c"
|
||||
@@ -82,7 +106,7 @@ test_ls_with_file_shortcuts() {
|
||||
ls_with_file_shortcuts > $temp_file
|
||||
ls_output=$(<$temp_file strip_colors)
|
||||
|
||||
# Compare as fixed strings (F), instead of regex (P)
|
||||
# Compare as fixed strings (F), instead of normal grep behavior
|
||||
assertIncludes "$ls_output" '[1] a "b"' F
|
||||
assertIncludes "$ls_output" "[2] a 'b'" F
|
||||
assertIncludes "$ls_output" '[3] a [b]' F
|
||||
|
||||
@@ -29,6 +29,7 @@ oneTimeSetUp() {
|
||||
export ga_auto_remove="yes"
|
||||
|
||||
testRepo=$(mktemp -d -t scm_breeze.XXXXXXXXXX)
|
||||
testRepo=$(cd $testRepo && pwd -P)
|
||||
}
|
||||
|
||||
oneTimeTearDown() {
|
||||
@@ -60,6 +61,10 @@ test_scmb_expand_args() {
|
||||
"$(scmb_expand_args -ma "Test Commit Message" "Unquoted")"
|
||||
}
|
||||
|
||||
test_command_wrapping_escapes_special_characters() {
|
||||
assertEquals 'should escape | the pipe' "$(exec_scmb_expand_args echo "should escape | the pipe")"
|
||||
assertEquals 'should escape ; the semicolon' "$(exec_scmb_expand_args echo "should escape ; the semicolon")"
|
||||
}
|
||||
|
||||
test_git_status_shortcuts() {
|
||||
setupTestRepo
|
||||
@@ -252,10 +257,10 @@ test_git_commit_prompt() {
|
||||
assertIncludes "$git_show_output" "$commit_msg"
|
||||
|
||||
# Test that history was appended correctly.
|
||||
if [[ $shell == "zsh" ]]; then
|
||||
test_history="$(history)"
|
||||
if [[ $shell == "zsh" ]]; then
|
||||
test_history="$(history)"
|
||||
else
|
||||
test_history="$(cat $HISTFILE)"
|
||||
test_history="$(cat $HISTFILE)"
|
||||
fi
|
||||
assertIncludes "$test_history" "$commit_msg"
|
||||
assertIncludes "$test_history" "git commit -m \"$dbl_escaped_msg\""
|
||||
@@ -285,10 +290,10 @@ test_git_commit_prompt_with_append() {
|
||||
assertIncludes "$git_show_output" "$commit_msg \[ci skip\]"
|
||||
|
||||
# Test that history was appended correctly.
|
||||
if [[ $shell == "zsh" ]]; then
|
||||
test_history="$(history)"
|
||||
if [[ $shell == "zsh" ]]; then
|
||||
test_history="$(history)"
|
||||
else
|
||||
test_history="$(cat $HISTFILE)"
|
||||
test_history="$(cat $HISTFILE)"
|
||||
fi
|
||||
assertIncludes "$test_history" "$commit_msg \[ci skip\]"
|
||||
assertIncludes "$test_history" "git commit -m \"$commit_msg \[ci skip\]\""
|
||||
@@ -312,4 +317,3 @@ test_adding_files_with_spaces() {
|
||||
|
||||
# load and run shUnit2
|
||||
source "$scmbDir/test/support/shunit2"
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ fi
|
||||
|
||||
# Strip color codes from a string
|
||||
strip_colors() {
|
||||
sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g"
|
||||
perl -pe 's/\e\[[\d;]*m//g'
|
||||
}
|
||||
|
||||
# Print space separated tab completion options
|
||||
@@ -34,7 +34,7 @@ verboseGitCommands() {
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
_includes() {
|
||||
if [ -n "$3" ]; then regex="$3"; else regex=P; fi
|
||||
if [ -n "$3" ]; then regex="$3"; else regex=''; fi
|
||||
if echo "$1" | grep -q$regex "$2"; then echo 0; else echo 1; fi
|
||||
}
|
||||
|
||||
@@ -46,4 +46,3 @@ assertIncludes() {
|
||||
assertNotIncludes() {
|
||||
assertFalse "'$1' should not have contained '$2'" $(_includes "$@")
|
||||
}
|
||||
|
||||
|
||||
32
test/support/travisci_deps.sh
Executable file
32
test/support/travisci_deps.sh
Executable file
@@ -0,0 +1,32 @@
|
||||
#!/usr/bin/env bash
|
||||
# Installs dependencies for travis-ci environments.
|
||||
|
||||
# Install dependencies, which looks to be just bash & zsh.
|
||||
#
|
||||
# Darwin has zsh preinstalled already, so only need to install on Ubuntu.
|
||||
#
|
||||
# Note: $TRAVIS_OS_NAME will only be set on text boxes with multi-os enabled,
|
||||
# so use negation test so it will fail gracefully on normal Travis linux setup.
|
||||
if [[ "$TRAVIS_OS_NAME" != "osx" ]]; then
|
||||
|
||||
# okay, so we know we're probably on a linux box (or at least not an osx box)
|
||||
# at this point. do we need to install zsh? let's say the default case is no:
|
||||
needs_zsh=false
|
||||
|
||||
# check if zsh is listed in the TEST_SHELLS environment variable, set by
|
||||
# our travis-ci build matrix.
|
||||
if [[ $TEST_SHELLS =~ zsh ]]; then needs_zsh=true; fi
|
||||
|
||||
# if there is NO $TEST_SHELLS env variable persent (which should never happen,
|
||||
# but maybe someone has been monkeying with the .travis.yml), run_tests.sh is
|
||||
# going to fall back onto the default of testing everything, so we need zsh.
|
||||
if [[ -z "$TEST_SHELLS" ]]; then needs_zsh=true; fi
|
||||
|
||||
# finally, we install zsh if needed!
|
||||
if $needs_zsh ; then
|
||||
sudo apt-get install zsh
|
||||
else
|
||||
echo "No deps required."
|
||||
fi
|
||||
|
||||
fi
|
||||
12
uninstall.sh
12
uninstall.sh
@@ -1,7 +1,15 @@
|
||||
#!/bin/sh
|
||||
# uninstall by (github: bernardofire)
|
||||
# Remove line from bashrc and zshrc if present.
|
||||
|
||||
sed="sed -i"
|
||||
if [[ $OSTYPE == "Darwin" ]]; then
|
||||
sed="sed -i ''"
|
||||
fi
|
||||
|
||||
for rc in bashrc zshrc; do
|
||||
sed -i '/scm_breeze/d' "$HOME/.$rc"
|
||||
printf "== Removed SCM Breeze from '$HOME/.$rc'\n"
|
||||
if [ -f "$HOME/.$rc" ]; then
|
||||
$sed '/scm_breeze/d' "$HOME/.$rc" &&
|
||||
printf "Removed SCM Breeze from %s\n" "$HOME/.$rc"
|
||||
fi
|
||||
done
|
||||
|
||||
Reference in New Issue
Block a user