mirror of
https://github.com/paulirish/git-recent.git
synced 2026-09-10 07:26:16 -04:00
commit
e8a0560e05
98
git-recent
98
git-recent
|
|
@ -1,62 +1,52 @@
|
|||
#!/bin/bash
|
||||
|
||||
##
|
||||
## git-recent
|
||||
##
|
||||
## list all local branches, sorted by last commit, formatted reall purdy
|
||||
##
|
||||
#
|
||||
# git recent 2.0 - switching branches, but so fancy
|
||||
#
|
||||
# - view recently edited local branches
|
||||
# - see unique commits to that branch, and optionally the branch diff (against the main/master/primary branch) with Ctrl-o
|
||||
# - hit Enter to checkout the selected branch.
|
||||
# - text filtering against branch names, too.
|
||||
#
|
||||
|
||||
# Windows needs more basic format (#8, git-for-windows/git#865)
|
||||
case $(uname -s) in
|
||||
CYGWIN*|MINGW*|MSYS*)
|
||||
branch='%(refname:short)'
|
||||
;;
|
||||
*)
|
||||
branch='%(color:yellow)%(refname:short)%(color:reset)'
|
||||
;;
|
||||
esac
|
||||
branches_format="%(color:yellow)%(refname:short)%(color:reset)"
|
||||
commits_format="%C(red bold)%h %C(bold blue)%an %C(bold green)%ad %Creset%s"
|
||||
|
||||
COUNT=0
|
||||
while getopts "n:" opt; do
|
||||
case ${opt} in
|
||||
n )
|
||||
if ! [[ $OPTARG =~ ^[0-9]{1,}$ ]]; then
|
||||
echo "-n should be an integer."
|
||||
exit 1
|
||||
fi
|
||||
COUNT=${OPTARG}
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
shift $((OPTIND-1))
|
||||
# The primary branch
|
||||
mainormaster() {
|
||||
(git branch --format '%(refname:short)' --sort=-committerdate --list master main; echo main) | head -n1 || echo main
|
||||
}
|
||||
|
||||
format="\
|
||||
%(HEAD) \
|
||||
$branch|\
|
||||
%(color:bold red)%(objectname:short)%(color:reset) \
|
||||
%(color:bold green)(%(committerdate:relative))%(color:reset) \
|
||||
%(color:bold blue)%(authorname)%(color:reset) \
|
||||
%(color:yellow)%(upstream:track)%(color:reset) \
|
||||
%(contents:subject)"
|
||||
uniqcommits_cmd="git log --date=human --color=always --format='$commits_format' --no-merges origin/$(mainormaster)..{1}"
|
||||
|
||||
lessopts="--tabs=4 --quit-if-one-screen --RAW-CONTROL-CHARS --no-init"
|
||||
diffbranch_cmd="git diff --color=always origin/$(mainormaster)...{}"
|
||||
# Progressive enhancement if you have delta or diff-so-fancy
|
||||
if command -v delta >/dev/null 2>&1; then
|
||||
diffbranch_cmd="$diffbranch_cmd | delta"
|
||||
elif command -v diff-so-fancy >/dev/null 2>&1; then
|
||||
diffbranch_cmd="$diffbranch_cmd | diff-so-fancy"
|
||||
fi
|
||||
|
||||
git for-each-ref \
|
||||
--color=always \
|
||||
--count=$COUNT \
|
||||
--sort=-committerdate \
|
||||
"refs/heads/" \
|
||||
--format="$format" \
|
||||
| column -ts '|' \
|
||||
| less "$lessopts"
|
||||
# fzf basic inspiration:
|
||||
# - https://github.com/junegunn/fzf/wiki/Examples#git, https://github.com/junegunn/fzf/wiki/Examples-(fish)#git
|
||||
# Hardcore inspiration:
|
||||
# - https://github.com/junegunn/fzf-git.sh
|
||||
|
||||
# The above command:
|
||||
# for all known branches,
|
||||
# (force coloring on this, especially since it's being piped)
|
||||
# optionally, specify the number of branches you want to display
|
||||
# sort descending by last commit
|
||||
# show local branches (change to "" to include both local + remote branches)
|
||||
# apply the formatting template above
|
||||
# break into columns
|
||||
# use the pager only if there's not enough space
|
||||
_browse_branches() {
|
||||
git for-each-ref --color=always --sort=-authordate "refs/heads/" --format="$branches_format" \
|
||||
| fzf-tmux --ansi -p80%,60% -- \
|
||||
--layout=reverse --multi --height=90% --min-height=20 \
|
||||
--border-label-pos=2 --border-label '🌲 Branches' --border \
|
||||
--no-hscroll --no-multi \
|
||||
--preview-window='right,70%,border-left,border-rounded' --preview="$uniqcommits_cmd" --preview-label="Commits unique to branch" \
|
||||
--header $'ENTER (checkout)\nCTRL-O (show branch diff)\n' \
|
||||
--bind 'preview-scroll-up:preview-up+preview-up+preview-up' \
|
||||
--bind 'preview-scroll-down:preview-down+preview-down+preview-down' \
|
||||
--bind "ctrl-o:preview:$diffbranch_cmd"
|
||||
}
|
||||
|
||||
chosen_branch="$(_browse_branches)"
|
||||
if [[ -n "$chosen_branch" ]]; then
|
||||
echo git checkout "$chosen_branch"
|
||||
git checkout "$chosen_branch"
|
||||
fi
|
||||
|
|
|
|||
62
git-recent-og
Executable file
62
git-recent-og
Executable file
|
|
@ -0,0 +1,62 @@
|
|||
#!/bin/bash
|
||||
|
||||
##
|
||||
## git-recent
|
||||
##
|
||||
## list all local branches, sorted by last commit, formatted reall purdy
|
||||
##
|
||||
|
||||
# Windows needs more basic format (#8, git-for-windows/git#865)
|
||||
case $(uname -s) in
|
||||
CYGWIN*|MINGW*|MSYS*)
|
||||
branch='%(refname:short)'
|
||||
;;
|
||||
*)
|
||||
branch='%(color:yellow)%(refname:short)%(color:reset)'
|
||||
;;
|
||||
esac
|
||||
|
||||
COUNT=0
|
||||
while getopts "n:" opt; do
|
||||
case ${opt} in
|
||||
n )
|
||||
if ! [[ $OPTARG =~ ^[0-9]{1,}$ ]]; then
|
||||
echo "-n should be an integer."
|
||||
exit 1
|
||||
fi
|
||||
COUNT=${OPTARG}
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
shift $((OPTIND-1))
|
||||
|
||||
format="\
|
||||
%(HEAD) \
|
||||
$branch|\
|
||||
%(color:bold red)%(objectname:short)%(color:reset) \
|
||||
%(color:bold green)(%(committerdate:relative))%(color:reset) \
|
||||
%(color:bold blue)%(authorname)%(color:reset) \
|
||||
%(color:yellow)%(upstream:track)%(color:reset) \
|
||||
%(contents:subject)"
|
||||
|
||||
lessopts="--tabs=4 --quit-if-one-screen --RAW-CONTROL-CHARS --no-init"
|
||||
|
||||
git for-each-ref \
|
||||
--color=always \
|
||||
--count=$COUNT \
|
||||
--sort=-committerdate \
|
||||
"refs/heads/" \
|
||||
--format="$format" \
|
||||
| column -ts '|' \
|
||||
| less "$lessopts"
|
||||
|
||||
# The above command:
|
||||
# for all known branches,
|
||||
# (force coloring on this, especially since it's being piped)
|
||||
# optionally, specify the number of branches you want to display
|
||||
# sort descending by last commit
|
||||
# show local branches (change to "" to include both local + remote branches)
|
||||
# apply the formatting template above
|
||||
# break into columns
|
||||
# use the pager only if there's not enough space
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
|
||||
#!/bin/bash
|
||||
|
||||
#
|
||||
# git recent upgraded. lists unique commits to that branch. and the branch diff.
|
||||
#
|
||||
# run it:
|
||||
# git recent-with-fzf-and-diff # or alias it
|
||||
# then within it
|
||||
# `ctrl-o` to show the diff of that branch against the origin/main (or origin/master)
|
||||
# `enter` to git checkout that branch
|
||||
#
|
||||
|
||||
|
||||
branches_format="%(color:yellow)%(refname:short)%(color:reset)"
|
||||
commits_format="%C(red bold)%h %C(bold blue)%an %C(bold green)%ad %Creset%s"
|
||||
|
||||
mainormaster() {
|
||||
(git branch --format '%(refname:short)' --sort=-committerdate --list master main; echo main) | head -n1 || echo main
|
||||
}
|
||||
|
||||
stat_cmd="git diff --color=always --stat origin/$(mainormaster)...{}"
|
||||
diffcommits_cmd="git log --date=human --color=always --format='$commits_format' --no-merges origin/$(mainormaster)..{1}"
|
||||
diffbranch_cmd="git diff origin/$(mainormaster)...{} | delta"
|
||||
|
||||
# fzf basic inspiration:
|
||||
# - https://github.com/junegunn/fzf/wiki/Examples#git, https://github.com/junegunn/fzf/wiki/Examples-(fish)#git
|
||||
# Hardcore inspiration:
|
||||
# - https://github.com/junegunn/fzf-git.sh
|
||||
|
||||
|
||||
_browse_branches() {
|
||||
local preview_cmd="$diffcommits_cmd" # Default preview: commit log
|
||||
|
||||
git for-each-ref --color=always --sort=-authordate "refs/heads/" --format="$branches_format" \
|
||||
| fzf-tmux --ansi -p80%,60% -- \
|
||||
--layout=reverse --multi --height=90% --min-height=20 \
|
||||
--border-label-pos=2 --border-label '🌲 Branches' --border \
|
||||
--no-hscroll --no-multi \
|
||||
--preview-window='right,70%,border-left,border-rounded' --preview="$diffcommits_cmd" --preview-label="Commits unique to branch" \
|
||||
--header $'CTRL-O (show branch diff)\nENTER (checkout)\n' \
|
||||
--bind 'preview-scroll-up:preview-up+preview-up+preview-up' \
|
||||
--bind 'preview-scroll-down:preview-down+preview-down+preview-down' \
|
||||
--bind "ctrl-o:preview:$diffbranch_cmd"
|
||||
}
|
||||
|
||||
|
||||
chosen_branch="$(_browse_branches)"
|
||||
if [[ -n "$chosen_branch" ]]; then
|
||||
echo git checkout "$chosen_branch"
|
||||
git checkout "$chosen_branch"
|
||||
fi
|
||||
56
readme.md
56
readme.md
|
|
@ -1,17 +1,53 @@
|
|||
# git-recent
|
||||
# git recent
|
||||
|
||||
Type `git recent` to see your latest local git branches
|
||||
Speedily browse your latest local git branches, `checkout` with Enter. Also view branches unique commits, and optionally the diff against main.
|
||||
|
||||
## Usage
|
||||
[Demo video of git recent 2.0](https://github.com/user-attachments/assets/441f0b9b-8469-41bd-a826-0bb0cd7c7de8)
|
||||
|
||||
`git recent` now offers an interactive UI (thx to [fzf](https://github.com/junegunn/fzf)) for browsing recent branches, seeing differences, and `checkout`'ing your selection.
|
||||
|
||||
See a diff of your branch vs main with `ctrl-o`. If you have [delta](https://dandavison.github.io/delta//) it'll use that for formatting, but will fallback, too.
|
||||
|
||||
If you're like me, mostly using classic git commands, then `git recent` provides a nice upgrade for browsing/selecting recent branches. But if you're a TUI fan using [git-fuzzy](https://github.com/bigH/git-fuzzy), [`lazygit`](https://github.com/jesseduffield/lazygit) or [`tig`](https://jonas.github.io/tig/) or [`fzf-git`](https://github.com/junegunn/fzf-git.sh), well… this probably isn't an upgrade. :p (But you can certainly [read the source](/git-recent) quickly!)
|
||||
|
||||
|
||||
### Installation
|
||||
|
||||
`fzf` is required for 2.0. TBH, it's a fantastic tool; those [shell key bindings](https://junegunn.github.io/fzf/shell-integration/) are _delightful_. That said, if you're dependency-averse, the older version below, [`git recent-og`](#git-recent-og), may be for you.
|
||||
|
||||
* Mac: `brew install fzf`
|
||||
* Linux: `sudo apt-get install fzf`
|
||||
* Windows: `choco install fzf`
|
||||
|
||||
Then, do one of these:
|
||||
|
||||
* Manual: Grab the `git-recent` script from this repo and put it anywhere in your `$PATH`. Run `chmod +x git-recent`.
|
||||
* Via NPM: `npm install --global git-recent`
|
||||
* ~Homebrew: `brew install git-recent`~ _(Coming soon! Updated for 2.0)_
|
||||
|
||||
### Usage
|
||||
|
||||
git recent
|
||||
|
||||
Hit `Enter` to checkout the selected branch.
|
||||
|
||||
Type or use arrow keys to navigate your list of branches.
|
||||
|
||||
Hit `ctrl-o` to see the branch diff.
|
||||
|
||||
--------------------------------
|
||||
|
||||
# `git recent-og`
|
||||
|
||||
`git recent-og` is the [OG](https://www.urbandictionary.com/define.php?term=OG) `git recent`, released back in 2016. Now it's been renamed to `git recent-og`.
|
||||
|
||||
git recent-og
|
||||
|
||||
Optionally, add `-n<int>` to see the most recent `<n>` branches
|
||||
|
||||
git recent -n5
|
||||
git recent-og -n5
|
||||
|
||||

|
||||

|
||||
|
||||
If you're a Windows user, you need to use [Git Bash](https://git-scm.com/downloads) or similar shell in order to effectively use this utility.
|
||||
|
||||
|
|
@ -28,6 +64,8 @@ On Mac, you can install with homebrew:
|
|||
|
||||
brew install git-recent
|
||||
|
||||
----------
|
||||
|
||||
## If you like this you may also be interested in...
|
||||
|
||||
- [`git open`](https://github.com/paulirish/git-open) - Open the repo website in your browser
|
||||
|
|
@ -37,8 +75,10 @@ On Mac, you can install with homebrew:
|
|||
|
||||
Copyright Paul Irish. Licensed under MIT.
|
||||
|
||||
|
||||
## Changelog
|
||||
|
||||
- **2016-05-16** - added to [paulirish/dotfiles](https://github.com/paulirish/dotfiles/commit/1ca1ff760832af558447145fa2a367046b1829d2)
|
||||
- **2016-08-05** - released in standalone repo and published to npm
|
||||
- **2025-02** - 2.0 upgrade with fzf integration. 1.0 binary is now available as `git recent-og`.
|
||||
- **2019-06** - Last bugfix for 1.0 landed. Been stable since then.
|
||||
- **2018-10** - Added count `-n` parameter
|
||||
- **2016-08** - released in standalone repo and published to npm
|
||||
- **2016-05** - added to [paulirish/dotfiles](https://github.com/paulirish/dotfiles/commit/1ca1ff760832af558447145fa2a367046b1829d2)
|
||||
|
|
|
|||
Loading…
Reference in a new issue