Skip to content

Instantly share code, notes, and snippets.

@genzj
Last active August 31, 2018 11:45
Show Gist options
  • Save genzj/f54883bd89ed4ac39298d6fb067a7b65 to your computer and use it in GitHub Desktop.
Save genzj/f54883bd89ed4ac39298d6fb067a7b65 to your computer and use it in GitHub Desktop.
A git remote hook example to iterate and check each commits in a push
* commit 9b5a1a68de5df1702f59c7d309e73d7152b5c582 (HEAD -> master, new)
| Author: ZHU Jie <[email protected]>
| Date: Fri Aug 31 10:52:57 2018 +0000
|
| update another file
|
* commit 6d94315602e0969e61d7f141cb3f27e567bd65f5
| Author: ZHU Jie <[email protected]>
| Date: Fri Aug 31 10:52:42 2018 +0000
|
| update file
|
* commit 3e778922679c0d1365ef1f4c63e18b0091a22163 (origin/master)
Author: ZHU Jie <[email protected]>
Date: Fri Aug 31 10:48:59 2018 +0000
add another file
* commit 0217f33494af140f303a8930a338bd1a0f6f54c2 (origin/new)
Author: ZHU Jie <[email protected]>
Date: Fri Aug 31 10:26:37 2018 +0000
add a file
Counting objects: 6, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (6/6), 573 bytes | 286.00 KiB/s, done.
Total 6 (delta 0), reused 0 (delta 0)
remote: check rev 1: 3e778922679c0d1365ef1f4c63e18b0091a22163 9b5a1a68de5df1702f59c7d309e73d7152b5c582 refs/heads/master
remote: iterate commits between 3e778922679c0d1365ef1f4c63e18b0091a22163..9b5a1a68de5df1702f59c7d309e73d7152b5c582
remote: check commit 1: 9b5a1a68de5df1702f59c7d309e73d7152b5c582
remote: commit message: update another file
remote: 6d94315602e0969e61d7f141cb3f27e567bd65f5
remote: file 1: 2.txt
remote: check commit 2: 6d94315602e0969e61d7f141cb3f27e567bd65f5
remote: commit message: update file
remote: 3e778922679c0d1365ef1f4c63e18b0091a22163
remote: file 1: 1.txt
remote: check rev 2: 0217f33494af140f303a8930a338bd1a0f6f54c2 9b5a1a68de5df1702f59c7d309e73d7152b5c582 refs/heads/new
remote: iterate commits between 0217f33494af140f303a8930a338bd1a0f6f54c2..9b5a1a68de5df1702f59c7d309e73d7152b5c582
remote: check commit 1: 9b5a1a68de5df1702f59c7d309e73d7152b5c582
remote: commit message: update another file
remote: 6d94315602e0969e61d7f141cb3f27e567bd65f5
remote: file 1: 2.txt
remote: check commit 2: 6d94315602e0969e61d7f141cb3f27e567bd65f5
remote: commit message: update file
remote: 3e778922679c0d1365ef1f4c63e18b0091a22163
remote: file 1: 1.txt
remote: check commit 3: 3e778922679c0d1365ef1f4c63e18b0091a22163
remote: commit message: add another file
remote: fatal: ambiguous argument '3e778922679c0d1365ef1f4c63e18b0091a22163^': unknown revision or path not in the working tree.
remote: Use '--' to separate paths from revisions, like this:
remote: 'git <command> [<revision>...] -- [<file>...]'
remote: 3e778922679c0d1365ef1f4c63e18b0091a22163^
remote: file 1: 1.txt
remote: file 2: 2.txt
To /tmp/test-hook/upstream/
! [remote rejected] master -> master (pre-receive hook declined)
! [remote rejected] new -> new (pre-receive hook declined)
error: failed to push some refs to '/tmp/test-hook/upstream/
#!/bin/bash
BIGBANG=4b825dc642cb6eb9a060e54bf8d69288fbee4904
function iterate_commits {
local base=$1
local new=$2
local callback=$3
echo "iterate commits between $base..$new"
if echo "${base}" | grep -q '^0\+$' ; then
# bigbang push
base=$BIGBANG
fi
local CMD="git rev-list $base..$new"
local i=0
while read commit_id ; do {
i=$((i + 1))
echo "check commit $i: $commit_id"
$callback $commit_id
} ; done <<<$($CMD)
}
function check_commit {
local commit_id=$1
local i=0
echo "commit message: $(git rev-list --format=%B --max-count=1 $commit_id | sed '1d')"
local strict_parent=""
if ! git rev-parse "$commit_id^" ; then
strict_parent=$BIGBANG
fi
while read filename ; do
i=$((i + 1))
echo "file $i: $filename"
done <<<$(git diff-tree --no-commit-id --name-only -r $commit_id $strict_parent)
}
function main {
i=0
while read old new ref ; do
i=$((i + 1))
echo "check rev $i: $old $new $ref"
iterate_commits $old $new check_commit
done
}
main
exit 1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment