Add script to test a git sequence of commits.
Signed-off-by: Jacob Kiers <jacob@jacobkiers.net>
This commit is contained in:
		
							
								
								
									
										99
									
								
								bin/git-test-sequence
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										99
									
								
								bin/git-test-sequence
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,99 @@ | ||||
| #!/bin/sh | ||||
| # Run a command over a sequence of commits. | ||||
| # Example: | ||||
| #  git test-sequence origin/master.. 'make clean && make test' | ||||
|  | ||||
| . "$(git --exec-path)/git-sh-setup" | ||||
| require_work_tree | ||||
|  | ||||
| t= | ||||
| force= | ||||
| run_once= | ||||
| ref_name=pass | ||||
|  | ||||
| # The tree must be really really clean. | ||||
| if ! git update-index --ignore-submodules --refresh > /dev/null; then | ||||
|     echo >&2 "cannot rebase: you have unstaged changes" | ||||
|     git diff-files --name-status -r --ignore-submodules -- >&2 | ||||
|     exit 1 | ||||
| fi | ||||
| diff=$(git diff-index --cached --name-status -r --ignore-submodules HEAD --) | ||||
| case "$diff" in | ||||
|     ?*) echo >&2 "cannot rebase: your index contains uncommitted changes" | ||||
|         echo >&2 "$diff" | ||||
|         exit 1 | ||||
|         ;; | ||||
| esac | ||||
|  | ||||
| start_branch=`git rev-parse --symbolic-full-name HEAD | sed s,refs/heads/,,` | ||||
| git checkout `git rev-parse HEAD` > /dev/null 2>/dev/null | ||||
|  | ||||
| cleanup() { | ||||
|     git checkout $start_branch > /dev/null 2>/dev/null | ||||
| } | ||||
|  | ||||
| already_passed() { | ||||
|     obdata=${ref_name}-$t-$1 | ||||
|     obhash=`echo $obdata | git hash-object --stdin` | ||||
|     git cat-file blob $obhash > /dev/null 2>/dev/null \ | ||||
|         && echo "Already ${ref_name} $1" | ||||
| } | ||||
|  | ||||
| passed_on() { | ||||
|     obdata=${ref_name}-$t-$1 | ||||
|     echo $obdata | git hash-object -w --stdin > /dev/null | ||||
|     echo "Passed: $1." | ||||
| } | ||||
|  | ||||
| broke_on() { | ||||
|     git log --pretty="format:Broke on %H (%s)%n" -n 1 $1 | ||||
|     cleanup | ||||
|     exit 1 | ||||
| } | ||||
|  | ||||
| new_test() { | ||||
|     echo "Testing $2" | ||||
|     git reset --hard $v && eval "$2" && passed_on $1 || broke_on $v | ||||
|     status=$? | ||||
|     if test -n "$run_once"; then | ||||
|         cleanup | ||||
|         exit $status | ||||
|     fi | ||||
| } | ||||
|  | ||||
|  | ||||
| while test $# != 0 | ||||
| do | ||||
|     case "$1" in | ||||
|         --force) | ||||
|             force=yes | ||||
|             ;; | ||||
|         --once) | ||||
|             run_once=yes | ||||
|             ;; | ||||
|         --ref-name) | ||||
|             ref_name=$2 | ||||
|             shift | ||||
|             ;; | ||||
|         *) | ||||
|             break; | ||||
|             ;; | ||||
|     esac | ||||
|     shift | ||||
| done | ||||
|  | ||||
| t=`echo "$2" | git hash-object --stdin` | ||||
|  | ||||
| for v in `git rev-list --reverse $1` | ||||
| do | ||||
|     tree_ver=`git rev-parse "$v^{tree}"` | ||||
|     test -z "$force" && already_passed $tree_ver || new_test $tree_ver "$2" | ||||
| done | ||||
| cleanup | ||||
|  | ||||
| if test -n "$run_once"; then | ||||
|     echo "All commits already passed for --once argument. Quiting." | ||||
|     exit 127 | ||||
| fi | ||||
|  | ||||
| echo "All's well." | ||||
		Reference in New Issue
	
	Block a user