diff --git a/.travis.yml b/.travis.yml
index 3d40388..d038f60 100644
--- a/.travis.yml
+++ b/.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
diff --git a/README.markdown b/README.markdown
index ec4181c..07abd94 100644
--- a/README.markdown
+++ b/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.
-
-
-
-## Demo video
-
-
-
-
-
-## 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:
+
+# 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
+
+
+
+### 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:
-### 'ls' shortcuts:
+
+#### 'ls' shortcuts:
-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:
-
-

-
-
-(When using bash, this commit prompt gives you access to your bash history via the arrow keys.)
-
+
(When using bash, this commit prompt gives
+you access to your bash history via the arrow keys.)
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`:
-## 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 ` 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 ` 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
diff --git a/git.scmbrc.example b/git.scmbrc.example
index f7867a6..a1ccca3 100644
--- a/git.scmbrc.example
+++ b/git.scmbrc.example
@@ -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"
diff --git a/install.sh b/install.sh
index 31f4631..dd025ef 100755
--- a/install.sh
+++ b/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
diff --git a/lib/bzr/BUILDME b/lib/bzr/BUILDME
deleted file mode 100644
index e69de29..0000000
diff --git a/lib/design.sh b/lib/design.sh
index 5106247..125175e 100644
--- a/lib/design.sh
+++ b/lib/design.sh
@@ -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
}
diff --git a/lib/git/aliases.sh b/lib/git/aliases.sh
index 91d95de..28b0e31 100644
--- a/lib/git/aliases.sh
+++ b/lib/git/aliases.sh
@@ -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
__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
-
diff --git a/lib/git/branch_shortcuts.sh b/lib/git/branch_shortcuts.sh
index 1e933b9..61012e2 100644
--- a/lib/git/branch_shortcuts.sh
+++ b/lib/git/branch_shortcuts.sh
@@ -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"
diff --git a/lib/git/fallback/status_shortcuts_shell.sh b/lib/git/fallback/status_shortcuts_shell.sh
old mode 100644
new mode 100755
index 86c6694..9368588
--- a/lib/git/fallback/status_shortcuts_shell.sh
+++ b/lib/git/fallback/status_shortcuts_shell.sh
@@ -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
diff --git a/lib/git/grep_shortcuts.rb b/lib/git/grep_shortcuts.rb
new file mode 100644
index 0000000..9f5ecc4
--- /dev/null
+++ b/lib/git/grep_shortcuts.rb
@@ -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
diff --git a/lib/git/grep_shortcuts.sh b/lib/git/grep_shortcuts.sh
new file mode 100644
index 0000000..d7024ea
--- /dev/null
+++ b/lib/git/grep_shortcuts.sh
@@ -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"
+}
diff --git a/lib/git/keybindings.sh b/lib/git/keybindings.sh
index 4ea46c3..11bb698 100644
--- a/lib/git/keybindings.sh
+++ b/lib/git/keybindings.sh
@@ -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
diff --git a/lib/git/repo_index.sh b/lib/git/repo_index.sh
index 44964f9..3d2e9c7 100644
--- a/lib/git/repo_index.sh
+++ b/lib/git/repo_index.sh
@@ -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
diff --git a/lib/git/shell_shortcuts.sh b/lib/git/shell_shortcuts.sh
index 9bdbe14..4c427d8 100644
--- a/lib/git/shell_shortcuts.sh
+++ b/lib/git/shell_shortcuts.sh
@@ -5,9 +5,9 @@
# ------------------------------------------------------------------------------
-if test | sed -E 's///g' 2>/dev/null; then
+if sed -E 's///g' /dev/null; then
SED_REGEX_ARG="E"
-elif test | sed -r 's///g' 2>/dev/null; then
+elif sed -r 's///g' /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 < $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"
\ No newline at end of file
+ # Setup aliases
+ alias ll="exec_scmb_expand_args ls_with_file_shortcuts"
+ alias la="ll -A"
+fi
diff --git a/lib/git/status_shortcuts.sh b/lib/git/status_shortcuts.sh
index fb823b4..d63bb0c 100644
--- a/lib/git/status_shortcuts.sh
+++ b/lib/git/status_shortcuts.sh
@@ -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
diff --git a/lib/hg/BUILDME b/lib/hg/BUILDME
deleted file mode 100644
index e69de29..0000000
diff --git a/lib/scm_breeze.sh b/lib/scm_breeze.sh
index 7d84148..2c692bb 100644
--- a/lib/scm_breeze.sh
+++ b/lib/scm_breeze.sh
@@ -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.
diff --git a/lib/svn/BUILDME b/lib/svn/BUILDME
deleted file mode 100644
index e69de29..0000000
diff --git a/run_tests.sh b/run_tests.sh
index fff4438..e25c5eb 100755
--- a/run_tests.sh
+++ b/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
\ No newline at end of file
+ true
+fi
diff --git a/scm_breeze.plugin.zsh b/scm_breeze.plugin.zsh
new file mode 100644
index 0000000..dbd6a0a
--- /dev/null
+++ b/scm_breeze.plugin.zsh
@@ -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"
+
+
diff --git a/scm_breeze.sh b/scm_breeze.sh
index 98957d5..4d83349 100644
--- a/scm_breeze.sh
+++ b/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"
diff --git a/test/lib/git/repo_index_test.sh b/test/lib/git/repo_index_test.sh
index d2afa8e..c866ec4 100755
--- a/test/lib/git/repo_index_test.sh
+++ b/test/lib/git/repo_index_test.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 <.gitmodules < /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 <> $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"
-
diff --git a/test/lib/git/shell_shortcuts_test.sh b/test/lib/git/shell_shortcuts_test.sh
index 3a6843a..f699085 100755
--- a/test/lib/git/shell_shortcuts_test.sh
+++ b/test/lib/git/shell_shortcuts_test.sh
@@ -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
diff --git a/test/lib/git/status_shortcuts_test.sh b/test/lib/git/status_shortcuts_test.sh
index aa86d2e..d83d9ca 100755
--- a/test/lib/git/status_shortcuts_test.sh
+++ b/test/lib/git/status_shortcuts_test.sh
@@ -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"
-
diff --git a/test/support/test_helper.sh b/test/support/test_helper.sh
index 7407b59..ba9e472 100644
--- a/test/support/test_helper.sh
+++ b/test/support/test_helper.sh
@@ -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 "$@")
}
-
diff --git a/test/support/travisci_deps.sh b/test/support/travisci_deps.sh
new file mode 100755
index 0000000..83cc32e
--- /dev/null
+++ b/test/support/travisci_deps.sh
@@ -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
diff --git a/uninstall.sh b/uninstall.sh
index ca7b83a..f91235a 100755
--- a/uninstall.sh
+++ b/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