Compare commits
10 commits
31c04c09c4
...
918bf6cc49
| Author | SHA1 | Date | |
|---|---|---|---|
| 918bf6cc49 | |||
| 74b5ff6282 | |||
| a72f8d5862 | |||
| 6a28b0e61f | |||
| 9aef83d133 | |||
| a76ca97377 | |||
| 306c72e58a | |||
| ba06a0c356 | |||
| 7e7f323184 | |||
| a81d75fe53 |
2 changed files with 166 additions and 67 deletions
99
README.md
99
README.md
|
|
@ -1,34 +1,69 @@
|
|||
# dotGit - 🐚 shell aliases + 🪄 dotfiles + 🧸 bare git repo
|
||||
# dotGit ::: 🪄 dotfiles + 🧸 bare git repo + 🐚 shell aliases
|
||||
|
||||
There are a lot of ways to manage your dotfiles. dotGit implements an idea that has been floating around on the internet for a while: a bare git repo for storing your dotfiles. A quick search finds [this post](https://news.ycombinator.com/item?id=11070797), but there may be older sources.
|
||||
There are a lot of ways to manage your dotfiles. dotGit implements an idea that has been floating around on the internet for a while: a bare git repo for storing your dotfiles. A quick search finds [this post](https://news.ycombinator.com/item?id=11070797), but there may be older sources. dotGit combines this with some convenient shell aliases, a couple of functions, and FZF's matching magic to track your dotfiles files with ease.
|
||||
|
||||
dotGit has modest aims:
|
||||
- 🏡 keep config files where tools expect them in `$HOME`
|
||||
- 🏡 keep configuration files where tools expect them in `$HOME`
|
||||
- 🐚 stay as light and close to git and the shell as possible
|
||||
- 🚀 reduce friction and make config changes quick and convenient
|
||||
- 🚀 reduce friction and make configuration changes quick and convenient
|
||||
|
||||
dotGit gives you a handful of shell aliases (tested with `zsh`🐚 and `bash`) to make dotfile management quick and easy. The shortcuts mimic a subset of those found in the [oh-my-zsh](https://github.com/ohmyzsh/ohmyzsh) [git](https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins/git) plugin.
|
||||
|
||||
- `.g` is the alias for running `git` with correct `--git-dir` and `--work-tree`
|
||||
- `.ga` runs `git add`
|
||||
- `.gc` runs `git commmit`
|
||||
- `.gco` runs `git checkout`
|
||||
- `.gd` runs `git diff`
|
||||
- `.gss` shows the `git status --short`
|
||||
- `.gp` will `git push` the changes to the origin
|
||||
- `.gl` will `git pull` changes from the origin
|
||||
- `.glo` runs `git log --oneline --decorate `
|
||||
- `.glg` runs `git log --stat`
|
||||
- `.glgp` runs `git log --stat --patch`
|
||||
- `.gg` runs `git grep` on your dotfiles. If [FZF](https://github.com/junegunn/fzf) is installed it will be used to present the matches, and make it easy open your `$EDITOR` on the right line (works with vi, emacs, nano, micro, and any editor that accepts the `+<number>` syntax to indicate the line number).
|
||||
- `.ge` (requires [FZF](https://github.com/junegunn/fzf)) lists all files using FZF and opens the selected file in your `$EDITOR`
|
||||
- `.lazygit` (requires [lazygit](https://github.com/jesseduffield/lazygit)) will run `lazygit` with the correct `-g` and `-w`
|
||||
- `.gitui` (requires [gitui](https://github.com/extrawurst/gitui)) will run `gitui` with the correct `-d` and `-w`
|
||||
## usage
|
||||
|
||||
There are two additional aliases used to (re)set up the bare git setup.
|
||||
- `.ginit` creates the bare git repository in `$DOT_FILES` directory.
|
||||
- `.gclone` will clone the repository set in `$DOT_ORIGIN` into the `$DOT_FILES` directory
|
||||
Both of these aliases also set git's `status.showUntrackedFiles` to `no`. This prevents every file in `$DOT_HOME` from showing as "untracked" by git.
|
||||
Most of dotGit is just some aliases that point to the `--git-dir` and `--work-tree`.
|
||||
|
||||
The real daily winners for me are the "edit" (`.ge`) and "grep" (`.gg`) aliases. They get me to where I need to be fast.
|
||||
|
||||
### a normal workflow for making configuration changes
|
||||
|
||||
1. `.gl` - pull changes from origin
|
||||
2. make some changes. Try:
|
||||
- `.ge zshrc` - presents all files with `zshrc` in the name
|
||||
- `.gg PATH` - runs `git grep` across your dotfiles and presents the results
|
||||
4. `.gc -m 'commit comment' .zshrc` - will commit the changes
|
||||
5. `.gp` - pushes the changes to the origin
|
||||
|
||||
### a list of all aliases defined
|
||||
|
||||
|
||||
| alias | action | note |
|
||||
| --- | --- | --- |
|
||||
| .git | `git --git-dir=${DOT_REPO} --work-tree=${DOT_HOME}` | |
|
||||
| .g | `.git` | |
|
||||
| .ga | `.git add` | |
|
||||
| .gc | `.git commit` | |
|
||||
| .gco | `.git checkout` | |
|
||||
| .gd | `.git diff` | |
|
||||
| .ge | calls the `_dotgit_ge` helper function | the dotGit edit feature [^fzf] |
|
||||
| .gg | calls the `_dotgit_gg` helper function | grep your dotfiles, and jump to correct line [^line] |
|
||||
| .gss | `.git status --short` | |
|
||||
| .glo | `.git log --oneline --decorate` | |
|
||||
| .glg | `.git log --stat` | |
|
||||
| .glgp | `.git log --stat --patch` | |
|
||||
| .gbl | `.git blame -w` | |
|
||||
| .gb | `.git branch` | |
|
||||
| .gba | `.git branch --all` | |
|
||||
| .gbd | `.git branch --delete` | |
|
||||
| .gbD | `.git branch --delete --force` | |
|
||||
| .gm | `.git merge` | |
|
||||
| .gma | `.git merge --abort` | |
|
||||
| .gmc | `.git merge --continue` | |
|
||||
| .gc! | `.git commit --verbose --amend` |
|
||||
| .gcm | `.git commit --message` | |
|
||||
| .gcp | `.git cherry-pick` | |
|
||||
| .gcpa | `.git cherry-pick --abort` | |
|
||||
| .gcpc | `.git cherry-pick --continue` | |
|
||||
| .gclean | `.git clean --interactive -d` | |
|
||||
| .ginit | `git init --bare "${DOT_REPO}"; .git config --local status.showUntrackedFiles no` | [^untracked] |
|
||||
| .gp | `.git push` | requires `DOT_ORIGIN` be set |
|
||||
| .gl | `.git pull` | requires `DOT_ORIGIN` be set
|
||||
| .gclone | `git clone --bare "${DOT_ORIGIN}" "${DOT_REPO}"; .git config --local status.showUntrackedFiles no` | |
|
||||
| .lazygit | `lazygit -g ${DOT_REPO}/ -w ${DOT_HOME}` | requires `lazygit` be installed |
|
||||
| .gitui | `gitui -d ${DOT_REPO}/ -w ${DOT_HOME}` | requires gitui to be installed |
|
||||
|
||||
[^line]: This works with vi, emacs, nano, micro, and any editor that accepts the line number to open the file to.
|
||||
[^untracked]: Also set git's `status.showUntrackedFiles` to `no`. This prevents every file in `$DOT_HOME` from showing as "untracked" by git.
|
||||
[^fzf]: requires [FZF](https://github.com/junegunn/fzf)
|
||||
|
||||
## requirements
|
||||
|
||||
|
|
@ -41,12 +76,12 @@ Both of these aliases also set git's `status.showUntrackedFiles` to `no`. This p
|
|||
|
||||
## installation
|
||||
|
||||
1. clone this repository or simply copy the [dotGit.sh](./dotGit.sh)
|
||||
2. add some config sauce to your shell initialization (.i.e. `.zshrc` or `.bashrc`). The `DOT_FILES` and `DOT_HOME` variables **must be set** for the dotGit.sh to load!
|
||||
1. clone this repository or simply copy the [dotgit.sh](./dotgit.sh)
|
||||
2. add some configuration sauce to your shell initialization (.i.e. `.zshrc` or `.bashrc`). The `DOT_REPO` and `DOT_HOME` variables **must be set** for the dotgit.sh to load!
|
||||
```bash
|
||||
export DOT_FILES="${HOME}/.dotfiles"
|
||||
export DOT_HOME="${HOME}"
|
||||
export DOT_ORIGIN="git@github.com:user/your-dotfiles-repo.git" # optional
|
||||
export DOT_REPO="${HOME}/.dotfiles" # this is where the repo will live
|
||||
export DOT_HOME="${HOME}" # this is generally the same as `$HOME`
|
||||
export DOT_ORIGIN="git@github.com:user/your-dotfiles-repo.git" # optional
|
||||
source <path to dotGit.sh>`
|
||||
```
|
||||
3. restart your shell or `source ~/.zshrc` or `source ~/.bashrc`
|
||||
|
|
@ -56,7 +91,7 @@ Both of these aliases also set git's `status.showUntrackedFiles` to `no`. This p
|
|||
|
||||
## initial clone cleanup
|
||||
|
||||
Existing config files will prevent checking out the files. To list the files causing the checkout to fail, run the following.
|
||||
Existing configuration files will prevent checking out the files. To list the files causing the checkout to fail, run the following.
|
||||
|
||||
```bash
|
||||
.g checkout 2>&1|grep -E '^\s'|cut -f2-|xargs -I {} echo "{}"
|
||||
|
|
@ -64,6 +99,10 @@ Existing config files will prevent checking out the files. To list the files cau
|
|||
|
||||
To remove all the conflicting files, simply change the `echo` in the above command to `rm`. **This will delete files, so be sure you want to remove them.** Once the files are removed the checkout will succeed.
|
||||
|
||||
## future features
|
||||
|
||||
- command line completion
|
||||
- manage system configuration files
|
||||
|
||||
## alternatives
|
||||
|
||||
|
|
|
|||
134
dotgit.sh
134
dotgit.sh
|
|
@ -1,48 +1,108 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
[[ ! "${DOT_FILES}" ]] && echo "NOT setting dotGit aliases, since DOT_FILES not set." && return
|
||||
[[ ! "${DOT_HOME}" ]] && echo "NOT setting dotGit aliases, since DOT_HOME not set." && return
|
||||
[[ ! "$DOT_REPO" ]] && echo "NOT setting dotgit aliases, since DOT_REPO not set." && return
|
||||
[[ ! "$DOT_HOME" ]] && echo "NOT setting dotgit aliases, since DOT_HOME not set." && return
|
||||
|
||||
alias .g='git --git-dir=${DOT_FILES} --work-tree=${DOT_HOME}'
|
||||
alias .ga='.g add'
|
||||
alias .gc='.g commit'
|
||||
alias .gco='.g checkout'
|
||||
alias .gd='.g diff'
|
||||
alias .gss='.g status --short'
|
||||
alias .gp='.g push'
|
||||
alias .gl='.g pull'
|
||||
alias .glo='.g log --oneline --decorate'
|
||||
alias .glg='.g log --stat'
|
||||
alias .glgp='.g log --stat --patch'
|
||||
[[ -n "$DEBUG" ]] && echo loading dotgit aliases
|
||||
|
||||
# shellcheck disable=SC2142,SC215
|
||||
alias .ge='_dotgit_ge(){
|
||||
cd ${DOT_HOME}
|
||||
FILE=$( Q="$@"; .g ls-files --full-name |
|
||||
fzf --preview "bat -n --color=always {}" -q "${Q}")
|
||||
[[ "$FILE" ]] && $EDITOR "${FILE}"
|
||||
cd ${OLDPWD}
|
||||
}; _dotgit_ge'
|
||||
[[ -z "$DOTGIT_MULTI_LIMIT" ]] && DOTGIT_MULTI_LIMIT=2
|
||||
[[ -z "$DOTGIT_MULTI_ACCEPT" ]] && DOTGIT_MULTI_ACCEPT='{1}'
|
||||
[[ -z "$DOTGIT_PREVIEW" ]] && DOTGIT_PREVIEW='bat -p --color=always'
|
||||
|
||||
# the master alias
|
||||
alias .git='git --git-dir=${DOT_REPO} --work-tree=${DOT_HOME}'
|
||||
# the short one
|
||||
alias .g='.git'
|
||||
|
||||
# and all the shortcuts
|
||||
alias .ga='.git add'
|
||||
alias .gc='.git commit'
|
||||
alias .gco='.git checkout'
|
||||
alias .gd='.git diff'
|
||||
alias .gss='.git status --short'
|
||||
alias .glo='.git log --oneline --decorate'
|
||||
alias .glg='.git log --stat'
|
||||
alias .glgp='.git log --stat --patch'
|
||||
alias .gbl='.git blame -w'
|
||||
alias .gb='.git branch'
|
||||
alias .gba='.git branch --all'
|
||||
alias .gbd='.git branch --delete'
|
||||
alias .gbD='.git branch --delete --force'
|
||||
alias .gm='.git merge'
|
||||
alias .gma='.git merge --abort'
|
||||
alias .gmc='.git merge --continue'
|
||||
alias .gc!='.git commit --verbose --amend'
|
||||
alias .gcm='.git commit --message'
|
||||
alias .gcp='.git cherry-pick'
|
||||
alias .gcpa='.git cherry-pick --abort'
|
||||
alias .gcpc='.git cherry-pick --continue'
|
||||
alias .gclean='.git clean --interactive -d'
|
||||
alias .ginit='git init --bare "${DOT_REPO}"; .git config --local status.showUntrackedFiles no'
|
||||
# only set up push and pull if DOT_ORIGIN is set
|
||||
if [[ -n "$DOT_ORIGIN" ]]; then
|
||||
alias .gp='.git push'
|
||||
alias .gl='.git pull'
|
||||
alias .gclone='git clone --bare "${DOT_ORIGIN}" "${DOT_REPO}"; .git config --local status.showUntrackedFiles no'
|
||||
else
|
||||
alias .gp='echo "error: must first configure DOT_ORIGIN"'
|
||||
alias .gl='echo "error: must first configure DOT_ORIGIN"'
|
||||
alias .gclone='echo "error: must first configure DOT_ORIGIN"'
|
||||
fi
|
||||
# if lazygit or gitui are available, we set up a .lazygit and .gitui
|
||||
[[ $(command -v lazygit) ]] &&
|
||||
alias .lazygit='lazygit -g ${DOT_REPO}/ -w ${DOT_HOME}'
|
||||
[[ $(command -v gitui) ]] &&
|
||||
alias .gitui='gitui -d ${DOT_REPO}/ -w ${DOT_HOME}'
|
||||
|
||||
# if fzf is installed we can have nice things
|
||||
# https://github.com/junegunn/fzf
|
||||
read -r -d '' FZF_HEADER<<EOF
|
||||
[enter] open/edit [ctrl-/] toggle preview [ctrl-w] toggle wrap
|
||||
EOF
|
||||
|
||||
if [[ $(command -v fzf) ]]; then
|
||||
# shellcheck disable=SC2142
|
||||
alias .gg='_dotgit_gg(){
|
||||
cd ${DOT_HOME}
|
||||
.g grep --full-name --color=always -n "$@" |
|
||||
fzf -0 --ansi -d ":" --bind "enter:execute($EDITOR +{2} {1})" \
|
||||
--preview "bat -n -H {2} --color=always {1}" \
|
||||
fzf_opts=(--multi="$DOTGIT_MULTI_LIMIT" --ansi -0
|
||||
--preview-window "right,60%,<60(down,75%),+{2}/2"
|
||||
cd ${OLDPWD}
|
||||
}; _dotgit_gg'
|
||||
--header "$FZF_HEADER"
|
||||
--bind 'ctrl-z:ignore'
|
||||
--bind 'ctrl-/:toggle-preview'
|
||||
--bind 'ctrl-w:toggle-preview-wrap'
|
||||
)
|
||||
_dotgit_ge() {
|
||||
local gitdir
|
||||
local files
|
||||
gitdir=$(.git rev-parse --show-toplevel)
|
||||
files=$(cd "$gitdir" && .git ls-files --full-name |
|
||||
fzf "${fzf_opts[@]}" \
|
||||
--preview "$DOTGIT_PREVIEW {1}" \
|
||||
--bind "enter:accept-non-empty" \
|
||||
-q "${@:-}" | paste -sd' ')
|
||||
[[ -n "$files" ]] && sh -c "cd \"$gitdir\" && \"$EDITOR\" $files"
|
||||
}
|
||||
alias .ge='_dotgit_ge'
|
||||
|
||||
_dotgit_gg() {
|
||||
local gitdir
|
||||
local files
|
||||
gitdir=$(.git rev-parse --show-toplevel)
|
||||
files=$(cd "$gitdir" && .git grep --full-name --color=always -n "$@" |
|
||||
fzf "${fzf_opts[@]}" -d ":" \
|
||||
--preview "$DOTGIT_PREVIEW -H{2} {1}" \
|
||||
--accept-nth "$DOTGIT_MULTI_ACCEPT" | paste -sd' ')
|
||||
[[ -n "$files" ]] && sh -c "cd \"$gitdir\" && \"$EDITOR\" $files"
|
||||
}
|
||||
alias .gg='_dotgit_gg'
|
||||
else
|
||||
alias .gg='.g grep'
|
||||
# simplified grep but no "interactive file select"
|
||||
alias .gg='.git grep'
|
||||
fi
|
||||
|
||||
alias .ginit='git init --bare "${DOT_FILES}"; .g config --local status.showUntrackedFiles no'
|
||||
[[ -n "$DOT_ORIGIN" ]] && alias .gclone='git clone --bare "${DOT_ORIGIN}" "${DOT_FILES}"; .g config --local status.showUntrackedFiles no'
|
||||
[[ -n "$DEBUG" ]] && echo dotgit aliases loaded
|
||||
|
||||
# if lazygit or gitui are avaiable, we set up a .lazygit and .gitui
|
||||
[[ $(command -v lazygit) ]] &&
|
||||
alias .lazygit='lazygit -g ${DOT_FILES}/.dotfiles/ -w ${DOT_HOME}'
|
||||
[[ $(command -v gitui) ]] &&
|
||||
alias .gitui='gitui -d ${DOT_FILES}/.dotfiles/ -w ${DOT_HOME}'
|
||||
# and to make general aliases available, we source this file again, but set
|
||||
# the aliases by removing the leading `.` and changing all instances of the
|
||||
# string 'dotgit' to 'anygit'
|
||||
# shellcheck source=/dev/null
|
||||
# the line above makes the source below not complain
|
||||
[[ "$DOTGIT_ANYGIT" == 'yes' ]] && \
|
||||
sed '/alias \.g.*DOT_REPO/d; s/\.g/g/g; s/dotgit/anygit/g' < "$0" | source /dev/stdin
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue