├── README.md └── gitjump.sh /README.md: -------------------------------------------------------------------------------- 1 | [![Gitter](https://img.shields.io/gitter/room/nwjs/nw.js.svg?maxAge=2592000)](https://gitter.im/gitjump/Lobby) 2 | 3 | #### GitJump 4 | 5 | A tiny git command wrapper for view git commits. 6 | 7 | commands: 8 | 9 | - ```git jump 100```: jump to 100th commit (```git j``` for short) 10 | - ```git jump +10```: jump 10 commits newer 11 | - ```git jump -10```: jump 10 commits older 12 | - ```git jump 03308b1a```: jump to commitid starts with 03308b1a 13 | - ```git next``` (```git n``` for short): jump to next commit (equivalent to ```git jump +1```) 14 | - ```git prev``` (```git p``` for short): jump to previous commit (equivalent to ```git jump -1```) 15 | - ```git first``` : jump to oldest commit (equivalent to ```git jump 1```) 16 | - ```git last``` : jump to most recent commit (equivalent to ```git jump 0```) 17 | 18 | Usage: 19 | 20 | 1. load 21 | ``` 22 | $ wget --no-check-certificate https://raw.githubusercontent.com/wuxc/gitjump/master/gitjump.sh 23 | $ source ./gitjump.sh 24 | ``` 25 | or add it to your ~/.bashrc: 26 | 27 | ``` 28 | # for Mac 29 | $ echo "source `pwd`/gitjump.sh" >> ~/.bash_profile 30 | # for Linux 31 | $ echo "source `pwd`/gitjump.sh" >> ~/.bashrc 32 | ``` 33 | 34 | 2. fire 35 | ``` 36 | $ cd some/awesome/repos.git 37 | $ git first 38 | $ git n; git status 39 | $ git diff 40 | ...... 41 | ``` 42 | 43 | Have fun! 44 | 45 | Tested on bash/zsh on mac OS. 46 | 47 | Please create an issue if you find anything wrong or have a suggestion. 48 | -------------------------------------------------------------------------------- /gitjump.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | # 3 | # Author: wuxc (https://github.com/wuxc) 4 | # License: MIT 5 | # Usage: 6 | # $ source path/to/gitjump.sh 7 | # $ cd your/repos.git 8 | # $ git first 9 | # $ git next 10 | 11 | orig_git=`/usr/bin/which git` 12 | logfile=".git/jump_logfile" 13 | branch_prefix="jump-branch-" 14 | 15 | function _git_jump_help { 16 | cat <<-EOF 17 | Hello, this is git jump. 18 | A tiny git command wrapper for view git commits. 19 | commands: 20 | 'git jump 100': jump to 100th commit ('git j' for short) 21 | 'git jump +10': jump 10 commits newer 22 | 'git jump -10': jump 10 commits older 23 | 'git jump 03308b1a': jump to commitid starts with 03308b1a 24 | 'git next' ('git n' for short): jump to next commit (equivalent to 'git jump +1') 25 | 'git prev' ('git p' for short): jump to previous commit (equivalent to 'git jump -1') 26 | 'git first' : jump to oldest commit (equivalent to 'git jump 1') 27 | 'git last' : jump to most recent commit (equivalent to 'git jump 0') 28 | EOF 29 | } 30 | 31 | function _git_is_merge { 32 | sha=$1 33 | msha=`$orig_git rev-list --merges ${sha}~1..$sha` 34 | [ -z "$msha" ] && return 1 35 | return 0 36 | } 37 | 38 | function _git_check_logfile { 39 | ## check & create logfile 40 | if [ ! -f $logfile ]; then 41 | _git_jump_help 42 | current=`$orig_git branch | grep "*" | cut -c 3-` 43 | if [ $current != "master" ]; then 44 | echo "You are currently on branch: $current" 45 | echo "Continue? (Y/N)" 46 | read ans 47 | if [ "$ans" != 'y' -a $ans != 'Y' ]; then 48 | echo "Abort." 49 | return -1 50 | fi 51 | fi 52 | $orig_git log --pretty=oneline > $logfile 53 | fi 54 | } 55 | 56 | function _git_checkout_commit { 57 | ## check if the branch exists & remove old branches 58 | ## args: commitid, next_commitid 59 | commitid=$1 60 | next_commitid=$2 61 | branch_name="${branch_prefix}${commitid:0:8}" 62 | current=`$orig_git branch | grep "*" | cut -c 3-` 63 | if [ $branch_name = $current ]; then 64 | echo "Already on commit $commitid" 65 | return 66 | fi 67 | ## clear old branches 68 | already_exist=false 69 | for line in `$orig_git branch | grep -v "*" | grep $branch_prefix` 70 | do 71 | if [ $line = $branch_name ]; then 72 | already_exist=true 73 | continue 74 | fi 75 | $orig_git branch -D -q $line 76 | done 77 | ## discard modifications before switch branch 78 | $orig_git clean -fdq 79 | $orig_git checkout -- . 80 | ## switch branch 81 | echo "checking out to: $branch_name ($commitid)" 82 | if $already_exist; then 83 | $orig_git checkout $branch_name > /dev/null 84 | else 85 | $orig_git checkout $commitid -b $branch_name > /dev/null 86 | fi 87 | branch=`$orig_git branch | grep "*" | cut -c 3-` 88 | echo "on branch: $branch" 89 | ## stop on newest 90 | if [ -z $next_commitid ]; then 91 | echo "Newest reached. No next commit." 92 | return 93 | fi 94 | ## cherry-pick commit and unstash changes 95 | _git_is_merge $next_commitid 96 | ismerge="$?" 97 | if [ $ismerge = "0" ]; then 98 | $orig_git cherry-pick -m 1 --no-commit --allow-empty --allow-empty-message $next_commitid 99 | else 100 | $orig_git cherry-pick --no-commit --allow-empty --allow-empty-message $next_commitid 101 | fi 102 | $orig_git reset HEAD -- . >> /dev/null 103 | echo "applied modifications from $next_commitid" 104 | $orig_git log $next_commitid -1 --pretty=format:"%n %Cgreen%an (%ae)%Creset %cd%n %Cblue%s%Creset%n" 105 | $orig_git diff --stat 106 | } 107 | 108 | function _git_jump { 109 | _git_check_logfile || return 110 | 111 | if [ -z $1 ]; then 112 | _git_jump_help 113 | return 114 | fi 115 | 116 | commit=$1 117 | sign=${commit:0:1} 118 | if [ $sign = "+" -o $sign = "-" ]; then 119 | commit=${commit:1} 120 | else 121 | sign= 122 | fi 123 | 124 | ## 0 for newest 125 | totallines=`cat $logfile | awk 'END{print NR}'` 126 | if [ $commit -eq 0 ] &> /dev/null; then 127 | commit=$totallines 128 | fi 129 | 130 | ## check for number 131 | expr $commit + 0 &> /dev/null 132 | if [ $? = 0 -o $? = 1 ]; then 133 | if [ -z $sign ]; then 134 | n=$commit 135 | else 136 | current=`$orig_git show | head -n1 | cut -d' ' -f2` 137 | n=`cat $logfile|grep -n "^$current" | cut -d':' -f1` 138 | n=$(($totallines+1-$n)) 139 | if [ $sign = "+" ]; then 140 | n=$(($n+$commit)) 141 | else 142 | n=$(($n-$commit)) 143 | fi 144 | fi 145 | else 146 | n=`cat $logfile | grep -n "^$1" | cut -d':' -f1` 147 | if [ "$n" = "" ]; then 148 | echo "No match commitid found for '$1'" 149 | return 150 | elif [ `echo $n | tr '\n' ' ' | awk -F' ' '{print NF}'` -gt 1 ]; then 151 | echo "Multiple matches found for '$1', please use more specific commit id." 152 | return 153 | fi 154 | n=$(($totallines+1-$n)) 155 | fi 156 | if [ $n -gt $totallines -o $n -le 0 ]; then 157 | echo "No more commit! (range: 1 - $totallines)" 158 | return 159 | fi 160 | 161 | progress="$n/$totallines" 162 | ## find out nth & n+1th commits 163 | ## special case for newest 164 | if [ $n -eq $totallines ]; then 165 | old=`head -n1 $logfile | awk '{print $1}'` 166 | new= 167 | else 168 | let n++ 169 | commits=`cat $logfile | tail -n $n | head -n2 | cut -d' ' -f1` 170 | new=`echo $commits | tr '\n' ' ' | awk '{print $1}'` 171 | old=`echo $commits | tr '\n' ' ' | awk '{print $2}'` 172 | fi 173 | ## special case for oldest -1 174 | if [ -z $old ]; then 175 | echo "Oldest reached. No prev commits." 176 | return 177 | fi 178 | _git_checkout_commit $old $new 179 | echo "Progress: $progress" 180 | } 181 | 182 | function git { 183 | ## no git installed 184 | if [ "$orig_git" = "" ]; then 185 | echo "git: command not found" 186 | return 127 187 | fi 188 | ## not a git repos 189 | $orig_git show > /dev/null 2>&1 190 | if [ $? != 0 ]; then 191 | $orig_git "$@" 192 | return $? 193 | fi 194 | ## find .git directory 195 | n=1 196 | gitdir=".git" 197 | while [ $n -le 100 ]; 198 | do 199 | if [ -d $gitdir ]; then 200 | break; 201 | fi 202 | gitdir="../$gitdir" 203 | let n++ 204 | done 205 | if [ ! -d $gitdir ]; then 206 | echo "Cannot find .git directory." 207 | return -1 208 | fi 209 | ## handle next | prev 210 | workdir=`pwd` 211 | if [ $# -ge 1 ]; then 212 | case $1 in 213 | n|next) builtin cd $gitdir/..; _git_jump +1; builtin cd $workdir; return ;; 214 | p|prev) builtin cd $gitdir/..; _git_jump -1; builtin cd $workdir; return ;; 215 | first) builtin cd $gitdir/..; _git_jump 1; builtin cd $workdir; return ;; 216 | last) builtin cd $gitdir/..; _git_jump 0; builtin cd $workdir; return ;; 217 | j|jump) builtin cd $gitdir/..; _git_jump $2; builtin cd $workdir; return ;; 218 | esac 219 | fi 220 | 221 | $orig_git "$@" 222 | } 223 | --------------------------------------------------------------------------------