diff options
-rw-r--r-- | .gitattributes | 5 | ||||
-rw-r--r-- | .gitignore | 15 | ||||
-rw-r--r-- | Makefile | 72 | ||||
-rw-r--r-- | flashrom.c | 2 | ||||
-rwxr-xr-x | util/getrevision.sh | 260 | ||||
-rwxr-xr-x | util/git-hooks/applypatch-msg | 15 | ||||
-rwxr-xr-x | util/git-hooks/commit-msg | 15 | ||||
-rwxr-xr-x | util/git-hooks/install.sh | 19 | ||||
-rwxr-xr-x | util/git-hooks/pre-applypatch | 12 | ||||
-rwxr-xr-x | util/git-hooks/pre-commit | 9 | ||||
-rwxr-xr-x | util/git-hooks/pre-push | 74 | ||||
-rwxr-xr-x | util/git-hooks/wrapper.sh | 10 |
12 files changed, 385 insertions, 123 deletions
diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..10f8962 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,5 @@ +.gitattributes export-ignore +.gitignore export-ignore +/util/getrevision.sh export-ignore +/util/git-hooks export-ignore +/util/git-hooks/** export-ignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..19a4365 --- /dev/null +++ b/.gitignore @@ -0,0 +1,15 @@ +*.d +*.o +/.features +/.dependencies +/.libdeps +/build_details.txt +/flashrom +/flashrom-* +/flashrom.exe +/flashrom.8 + +/util/ich_descriptors_tool/ich_descriptors_tool +/util/ich_descriptors_tool/ich_descriptors_tool.exe +/util/ich_descriptors_tool/.dep +/util/ich_descriptors_tool/.obj @@ -526,23 +526,27 @@ LIB_OBJS = layout.o flashrom.o udelay.o programmer.o helpers.o CLI_OBJS = cli_classic.o cli_output.o cli_common.o print.o -# Set the flashrom version string from the highest revision number of the checked out flashrom files. +# Set the flashrom version string from the repository metadata (cf. util/getrevision.sh). # Note to packagers: Any tree exported with "make export" or "make tarball" -# will not require subversion. The downloadable snapshots are already exported. -SVNVERSION := $(shell ./util/getrevision.sh -u 2>/dev/null ) - -RELEASE := 0.9.9 -VERSION := $(RELEASE)-$(SVNVERSION) -RELEASENAME ?= $(VERSION) +# will not require git. The downloadable snapshots are already exported. +VERSION := $(shell ./util/getrevision.sh --revision) +# VERSION equals "offline" if online access is required but the respective git config variable is not set yet. +ifeq ($(VERSION),offline) + $(error Aborting) +endif +SCMDEF := -D'FLASHROM_VERSION="$(VERSION)"' -SVNDEF := -D'FLASHROM_VERSION="$(VERSION)"' +# No spaces in release names unless set explicitly +RELEASENAME ?= $(shell echo "$(VERSION)" | sed -e 's/ /_/') -# Inform user if there is no meaningful version string. If there is version information from a VCS print +# Inform user about the version string used. If there is no version information from a VCS then print # something anyway because $(info...) will print a line break in any case which would look suspicious. # The && between the echos is a workaround for old versions of GNU make that issue the error "unterminated # variable reference" if a semicolon is used instead. -$(info $(shell ./util/getrevision.sh -c 2>/dev/null || echo "Files don't seem to be under version control." && \ - echo "Replacing all version templates with $(VERSION)." )) +# Also, if a VCS is found then try to install hooks. +$(info $(shell ./util/getrevision.sh -c 2>/dev/null && ./util/git-hooks/install.sh || \ + echo "Files don't seem to be under version control." && \ + echo "Replacing all version templates with $(VERSION).")) ############################################################################### # Default settings of CONFIG_* variables. @@ -1024,7 +1028,7 @@ libflashrom.a: $(LIBFLASHROM_OBJS) TAROPTIONS = $(shell LC_ALL=C tar --version|grep -q GNU && echo "--owner=root --group=root") %.o: %.c .features - $(CC) -MMD $(CFLAGS) $(CPPFLAGS) $(FLASHROM_CFLAGS) $(FEATURE_CFLAGS) $(SVNDEF) -o $@ -c $< + $(CC) -MMD $(CFLAGS) $(CPPFLAGS) $(FLASHROM_CFLAGS) $(FEATURE_CFLAGS) $(SCMDEF) -o $@ -c $< # Make sure to add all names of generated binaries here. # This includes all frontends and libflashrom. @@ -1347,9 +1351,10 @@ endif $(PROGRAM).8.html: $(PROGRAM).8 @groff -mandoc -Thtml $< >$@ +MAN_DATE := $(shell ./util/getrevision.sh -d $(PROGRAM).8.tmpl 2>/dev/null) $(PROGRAM).8: $(PROGRAM).8.tmpl @# Add the man page change date and version to the man page - @sed -e 's#.TH FLASHROM 8 ".*".*#.TH FLASHROM 8 "$(shell ./util/getrevision.sh -d $(PROGRAM).8.tmpl 2>/dev/null)" "$(VERSION)"#' <$< >$@ + @sed -e 's#.TH FLASHROM 8 .*#.TH FLASHROM 8 "$(MAN_DATE)" "$(VERSION)" "$(MAN_DATE)"#' <$< >$@ install: $(PROGRAM)$(EXEC_SUFFIX) $(PROGRAM).8 mkdir -p $(DESTDIR)$(PREFIX)/sbin @@ -1357,25 +1362,38 @@ install: $(PROGRAM)$(EXEC_SUFFIX) $(PROGRAM).8 $(INSTALL) -m 0755 $(PROGRAM)$(EXEC_SUFFIX) $(DESTDIR)$(PREFIX)/sbin $(INSTALL) -m 0644 $(PROGRAM).8 $(DESTDIR)$(MANDIR)/man8 -export: $(PROGRAM).8 - @rm -rf $(EXPORTDIR)/flashrom-$(RELEASENAME) - @svn export -r BASE . $(EXPORTDIR)/flashrom-$(RELEASENAME) - @sed "s/^SVNVERSION.*/SVNVERSION := $(SVNVERSION)/" Makefile >$(EXPORTDIR)/flashrom-$(RELEASENAME)/Makefile - @cp $(PROGRAM).8 "$(EXPORTDIR)/flashrom-$(RELEASENAME)/$(PROGRAM).8" - @svn log >$(EXPORTDIR)/flashrom-$(RELEASENAME)/ChangeLog - @echo Exported $(EXPORTDIR)/flashrom-$(RELEASENAME)/ - -tarball: export - @tar cjf $(EXPORTDIR)/flashrom-$(RELEASENAME).tar.bz2 -C $(EXPORTDIR)/ $(TAROPTIONS) flashrom-$(RELEASENAME)/ +_export: $(PROGRAM).8 + @rm -rf "$(EXPORTDIR)/flashrom-$(RELEASENAME)" + @mkdir -p "$(EXPORTDIR)/flashrom-$(RELEASENAME)" + @git archive HEAD | tar -x -C "$(EXPORTDIR)/flashrom-$(RELEASENAME)" + @sed -e 's/^VERSION :=.*/VERSION := $(VERSION)/' \ + -e 's/^MAN_DATE :=.*/MAN_DATE := $(MAN_DATE)/' \ + -e 's#./util/getrevision.sh -c#false#' \ + Makefile >"$(EXPORTDIR)/flashrom-$(RELEASENAME)/Makefile" +# Restore modification date of all tracked files not marked 'export-ignore' in .gitattributes. +# sed is required to filter out file names having the attribute set. + @git ls-tree -r -z -t --full-name --name-only HEAD | \ + git check-attr -z --stdin export-ignore | \ + sed -zne 'x;n;n;s/^set$$//;t;x;p' | \ + xargs -0 sh -c 'for f; do \ + touch -d $$(git log --pretty=format:%cI -1 HEAD -- "$$f") \ + "$(EXPORTDIR)/flashrom-$(RELEASENAME)/$$f"; \ + done' + +export: _export + @echo "Exported $(EXPORTDIR)/flashrom-$(RELEASENAME)/" + +tarball: _export + @tar -cz --format=ustar -f $(EXPORTDIR)/flashrom-$(RELEASENAME).tar.gz -C $(EXPORTDIR)/ \ + $(TAROPTIONS) flashrom-$(RELEASENAME)/ +# Delete the exported directory again because it is most likely what's expected by the user. @rm -rf $(EXPORTDIR)/flashrom-$(RELEASENAME) - @echo Created $(EXPORTDIR)/flashrom-$(RELEASENAME).tar.bz2 + @echo Created $(EXPORTDIR)/flashrom-$(RELEASENAME).tar.gz -djgpp-dos: clean - make CC=i586-pc-msdosdjgpp-gcc STRIP=i586-pc-msdosdjgpp-strip libpayload: clean make CC="CC=i386-elf-gcc lpgcc" AR=i386-elf-ar RANLIB=i386-elf-ranlib -.PHONY: all install clean distclean compiler hwlibs features export tarball djgpp-dos featuresavailable libpayload +.PHONY: all install clean distclean compiler hwlibs features _export export tarball featuresavailable libpayload # Disable implicit suffixes and built-in rules (for performance and profit) .SUFFIXES: @@ -1801,7 +1801,7 @@ void print_buildinfo(void) void print_version(void) { - msg_ginfo("flashrom v%s", flashrom_version); + msg_ginfo("flashrom %s", flashrom_version); print_sysinfo(); msg_ginfo("\n"); } diff --git a/util/getrevision.sh b/util/getrevision.sh index 1012058..03d0b1e 100755 --- a/util/getrevision.sh +++ b/util/getrevision.sh @@ -5,7 +5,7 @@ # Copyright (C) 2005 coresystems GmbH <stepan@coresystems.de> # Copyright (C) 2009,2010 Carl-Daniel Hailfinger # Copyright (C) 2010 Chromium OS Authors -# Copyright (C) 2013 Stefan Tauner +# Copyright (C) 2013-2016 Stefan Tauner # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -30,31 +30,73 @@ export LC_ALL=C # nor local times or dates export TZ=UTC0 -# Helper functions -# First argument is the path to inspect (usually optional; w/o it the whole repository will be considered) -svn_has_local_changes() { - svn status "$1" | egrep '^ *[ADMR] *' >/dev/null +# List of important upstream branches... +upstream_branches="stable staging" +upstream_url="https://flashrom.org/git/flashrom.git" +upstream_patterns="github\.com.flashrom/flashrom(\.git)?|flashrom\.org.git/flashrom(\.git)?" + +upcache_prefix="refs/flashrom_org/" +# Generate upcache_refs +for b in $upstream_branches ; do + upcache_refs="$upcache_refs ${upcache_prefix}$b" +done + +# We need to update our upstream information sometimes so that we can create detailed version information. +# To that end the code below fetches parts of the upstream repository via https. +# This takes about one second or less under normal circumstances. +# +# It can be called manually, but is usually called via +# - the Makefile (implicitly via revision()) when there is no upstream information in any existing remote +forced_update() { + local rev_remote_refs + for ref in $upcache_refs ; do + rev_remote_refs="$rev_remote_refs +${ref##*/}:$ref" + done + git fetch -q "$upstream_url" --tags $rev_remote_refs && echo "Success." } +update() { + offline=$(git config flashrom.offline-builds 2>/dev/null) + if [ -z "$offline" ]; then + echo "To produce useful version information the build process needs access to the commit +history from an upstream repository. If no git remote is pointing to one we +can store the necessary information out of sight and update it on every build. +To enable this functionality and fetch the upstream commits from $upstream_url +please execute 'git config flashrom.offline-builds false' or add one of the +upstream repositories as git remote to rely on that information. +However, if you want to work completely offline and generate possibly meaningless +version strings then disable it with 'git config flashrom.offline-builds true' +You can force updating the local commit cache with '$0 --forced-update'">&2 + return 1 + elif [ "x$offline" = "xfalse" ]; then + echo "Fetching commit history from upstream repository $upstream_url +To disable any network activity execute 'git config flashrom.offline-builds true'.">&2 + forced_update >/dev/null + else + echo "Fetching commit history from upstream is disabled - version strings might be misleading. +To ensure proper version strings and allow network access run 'git config flashrom.offline-builds false'.">&2 + fi + return 0 +} + +# Helper functions +# First argument is the path to inspect (usually optional; w/o it the whole repository will be considered) git_has_local_changes() { git update-index -q --refresh >/dev/null ! git diff-index --quiet HEAD -- "$1" } git_last_commit() { + # git rev-parse --short HEAD would suffice if repository as a whole is of interest (no $1) git log --pretty=format:"%h" -1 -- "$1" } -svn_is_file_tracked() { - svn info "$1" >/dev/null 2>&1 -} - git_is_file_tracked() { git ls-files --error-unmatch -- "$1" >/dev/null 2>&1 } is_file_tracked() { - svn_is_file_tracked "$1" || git_is_file_tracked "$1" + git_is_file_tracked "$1" } # Tries to find a remote source for the changes committed locally. @@ -89,13 +131,7 @@ git_url() { scm_url() { local url= - # for a primitive VCS like subversion finding the URL is easy: there is only one upstream host - if svn_is_file_tracked "$1" ; then - url="$(svn info "$1" 2>/dev/null | - grep URL: | - sed 's/.*URL:[[:blank:]]*//;s/:\/\/.*@/:\/\//' | - grep ^.)" - elif git_is_file_tracked "$1" ; then + if git_is_file_tracked "$1" ; then url="$(git_url "$1")" else return ${EXIT_FAILURE} @@ -116,29 +152,7 @@ timestamp() { # freebsd date [-jnu] [-d dst] [-r seconds] [-f fmt date | [[[[[cc]yy]mm]dd]HH]MM[.ss]] [+format] [...] # dragonflybsd date [-jnu] [-d dst] [-r seconds] [-f fmt date | [[[[[cc]yy]mm]dd]HH]MM[.ss]] [+format] [...] # openbsd date [-aju] [-d dst] [-r seconds] [+format] [[[[[[cc]yy]mm]dd]HH]MM[.SS]] [...] - if svn_is_file_tracked "$2" ; then - if svn_has_local_changes "$2"; then - t=$(date -u "$1") - else - # No local changes, get date of the last log record. Subversion provides that in - # ISO 8601 format when using the --xml switch. The sed call extracts that ignoring any - # fractional parts started by a comma or a dot. - local last_commit_date="$(svn info --xml "$2"| \ - sed -n -e 's/<date>\([^,\.]*\)\([\.,].*\)*Z<\/date>/\1Z/p')" - - case $(uname) in - # Most BSD dates do not support parsing date values from user input with -d but all of - # them support parsing the syntax with [[[[[[cc]yy]mm]dd]HH]MM[.ss]]. We have to - # transform the ISO8601 date first though. - NetBSD|OpenBSD|DragonFly|FreeBSD) - last_commit_date="$(echo ${last_commit_date} | \ - sed -n -e 's/\(....\)-\(..\)-\(..\)T\(..\):\(..\):\(..\)Z/\1\2\3\4\5\.\6/p')" - t=$(date -u -j "${last_commit_date}" "$1" 2>/dev/null);; - *) - t=$(date -u -d "${last_commit_date}" "$1" 2>/dev/null);; - esac - fi - elif git_is_file_tracked "$2" ; then + if git_is_file_tracked "$2" ; then # are there local changes? if git_has_local_changes "$2" ; then t=$(date -u "${1}") @@ -163,55 +177,102 @@ timestamp() { echo "${t}" } -# Retrieve local SCM revision info. This is useful if we're working in a different SCM than upstream and/or -# have local changes. -local_revision() { - local r= - - if svn_is_file_tracked "$1" ; then - r=$(svn_has_local_changes "$1" && echo "dirty") - elif git_is_file_tracked "$1" ; then - r=$(git_last_commit "$1") - - local svn_base=$(git log --grep=git-svn-id -1 --format='%h') - if [ "$svn_base" != "" ] ; then - local diff_to_svn=$(git rev-list --count ${svn_base}..${r}) - if [ "$diff_to_svn" -gt 0 ] ; then - r="$r-$diff_to_svn" - fi - fi +tag() { + local t= + + if git_is_file_tracked "$1" ; then + local sha=$(git_last_commit "$1") + t=$(git describe --abbrev=0 "$sha") + fi + if [ -z "$t" ]; then + t="unknown" # default to unknown + fi + echo "${t}" +} - if git_has_local_changes "$1" ; then - r="$r-dirty" +find_upremote() { + # Try to find upstream's remote name + for remote in $(git remote) ; do + local url=$(git ls-remote --get-url $remote) + if echo "$url" | grep -q -E "$upstream_patterns" ; then + echo "$remote" + return fi + done +} + +revision() { + local sha=$(git_last_commit "$1" 2>/dev/null) + # No git no fun + if [ -z "$sha" ]; then + echo "unknown" + return + fi + + local r="$sha" + if git_has_local_changes "$1" ; then + r="$r-dirty" + fi + + # sha + possibly dirty info is not exactly verbose, therefore the code below tries to use tags and + # branches from the upstream repos to derive a more previse version string. + # To that end we try to use the existing remotes first. + # If the upstream repos (and its mirrors) are not available as remotes, use a shadow copy instead. + + local up_refs + local up_remote=$(find_upremote) + if [ -n "$up_remote" ]; then + for b in $upstream_branches ; do + up_refs="$up_refs ${up_remote}/${b}" + done else - return ${EXIT_FAILURE} + update || { echo "offline" ; return ; } + up_refs=$upcache_refs fi - echo "${r}" -} + # Find nearest commit contained in this branch that is also in any of the up_refs, i.e. the branch point + # of the current branch. This might be the latest commit if it's in any of the upstream branches. + local merge_point=$(git merge-base ${sha} ${up_refs}) + local upstream_branch + if [ -z "$merge_point" ]; then + echo "$sha" + return + fi + + # If the current commit is reachable from any remote branch, append the branch name and its + # distance to the nearest earlier tag to that tag name itself (tag-distance-branch). + # If multiple branches are reachable then we use the newest one (by commit date). + # If none is reachable we use the nearest tag and ? for distances and remote branch name. -# Get the upstream flashrom revision stored in SVN metadata. -upstream_revision() { - local r= - - if svn_is_file_tracked "$1" ; then - r=$(svn info "$1" 2>/dev/null | \ - grep "Last Changed Rev:" | \ - sed -e "s/^Last Changed Rev: *//" -e "s/\([0-9]*\).*/r\1/" | \ - grep "r[0-9]") - elif git_is_file_tracked "$1" ; then - # If this is a "native" git-svn clone we could use git svn log: - # git svn log --oneline -1 | sed 's/^r//;s/[[:blank:]].*//' or even git svn find-rev - # but it is easier to just grep for the git-svn-id unconditionally - r=$(git log --grep=git-svn-id -1 -- "$1" | \ - grep git-svn-id | \ - sed 's/.*@/r/;s/[[:blank:]].*//') + local cnt_upstream_branch2sha=$(git rev-list --count "${merge_point}..${sha}" 2>/dev/null) + + local lasttag=$(git describe --abbrev=0 "$merge_point" 2>/dev/null) + if [ -z "$lasttag" ]; then + echo "Could not find tag reachable from merge point!">&2 + echo "$sha" + return fi - if [ -z "$r" ]; then - r="unknown" # default to unknown + local cnt_tag2upstream_branch + for ref in $up_refs ; do + if git merge-base --is-ancestor ${merge_point} ${ref}; then + upstream_branch=${ref##*/} # remove everything till last / + cnt_tag2upstream_branch=$(git rev-list --count "${lasttag}..${merge_point}" 2>/dev/null) + break + fi + done + + if [ "$cnt_upstream_branch2sha" -gt 0 ]; then + r="$cnt_upstream_branch2sha-$r" + fi + if [ "$cnt_tag2upstream_branch" -gt 0 ]; then + if [ -n "$upstream_branch" ]; then + r="$upstream_branch-$r" + fi + r="$cnt_tag2upstream_branch-$r" fi + r="$lasttag-$r" + echo "${r}" } @@ -228,16 +289,20 @@ Commands this message -c or --check test if path is under version control at all - -l or --local - local revision information including an indicator for uncommitted changes - -u or --upstream - upstream revision - -U or --url + -T or --tag + returns the name of the last release/tag + -r or --revision + return unique revision information including the last tag and an indicator for uncommitted changes + -u or --url URL associated with the latest commit -d or --date date of most recent modification -t or --timestamp timestamp of most recent modification + -U or --update + update local shadow copy of upstream commits if need be and offline builds are not enforced + --forced-update + force updating the local shadow copy of upstream commits " return } @@ -260,15 +325,15 @@ main() { -h|--help) action=show_help; shift;; - -l|--local) + -T|--tag) check_action $1 - action=local_revision + action=tag shift;; - -u|--upstream) + -r|--revision) check_action $1 - action=upstream_revision + action=revision shift;; - -U|--url) + -u|--url) check_action $1 action=scm_url shift;; @@ -280,9 +345,17 @@ main() { check_action $1 action="timestamp +%Y-%m-%dT%H:%M:%SZ" # There is only one valid time format! ISO 8601 shift;; + -U|--update) + check_action $1 + action=update + shift;; + --forced-update) + check_action $1 + action=forced_update + shift;; -c|--check) - check_action=$1 - action="is_tracked" + check_action $1 + action=is_tracked shift;; -*) show_help; @@ -306,9 +379,6 @@ main() { if [ -z "$query_path" ] ; then query_path=. fi - if ! is_file_tracked "$query_path" ; then - echo "Warning: Path \"${query_path}\" is not under version control.">&2 - fi if [ -z "$action" ] ; then show_help echo "Error: No actions specified" diff --git a/util/git-hooks/applypatch-msg b/util/git-hooks/applypatch-msg new file mode 100755 index 0000000..32ff6c7 --- /dev/null +++ b/util/git-hooks/applypatch-msg @@ -0,0 +1,15 @@ +#!/bin/sh +# +# A hook script to check the commit log message taken by +# applypatch from an e-mail message (via git-am). +# We simply do the same as for other commit messages +# +# The hook should exit with non-zero status after issuing an +# appropriate message if it wants to stop the commit. The hook is +# allowed to edit the commit message file. +# + +. git-sh-setup +test -x "$GIT_DIR/hooks/commit-msg" && + exec "$GIT_DIR/hooks/commit-msg" ${1+"$@"} +: diff --git a/util/git-hooks/commit-msg b/util/git-hooks/commit-msg new file mode 100755 index 0000000..710fe78 --- /dev/null +++ b/util/git-hooks/commit-msg @@ -0,0 +1,15 @@ +#!/bin/sh +# +# A hook script to check the commit log message. +# Called by "git commit" with one argument, the name of the file +# that has the commit message. The hook should exit with non-zero +# status after issuing an appropriate message if it wants to stop the +# commit. The hook is allowed to edit the commit message file. +# + +# Catches duplicate Signed-off-by lines. +test "" = "$(grep '^Signed-off-by: ' "$1" | + sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { + echo "Duplicate Signed-off-by lines." >&2 + exit 1 +} diff --git a/util/git-hooks/install.sh b/util/git-hooks/install.sh new file mode 100755 index 0000000..e216af4 --- /dev/null +++ b/util/git-hooks/install.sh @@ -0,0 +1,19 @@ +#!/bin/sh -e + +root=$(git rev-parse --show-cdup 2>/dev/null) || \ + { echo "Not under git control. Cannot install git hooks." >&2 ; exit 0 ; } + +dst="${root}"$(git rev-parse --git-path hooks/) +src=util/git-hooks/ # relative to root +hooks=$(cd "${root}${src}" && git ls-files -c | grep -Ev 'install.sh|wrapper.sh') + +for h in $hooks; do + # Test if hook is not already installed, i.e. doesn't point at the wrapper + if [ ! "${dst}$h" -ef "${root}${src}wrapper.sh" ]; then + # preserve custom hooks if any + if [ -e "${dst}$h" ]; then + mv "${dst}$h" "${dst}$h.local" + fi + ln -s "../../${src}wrapper.sh" "${dst}$h" + fi +done diff --git a/util/git-hooks/pre-applypatch b/util/git-hooks/pre-applypatch new file mode 100755 index 0000000..2ed28f7 --- /dev/null +++ b/util/git-hooks/pre-applypatch @@ -0,0 +1,12 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed +# by applypatch from an e-mail message. +# +# The hook should exit with non-zero status after issuing an +# appropriate message if it wants to stop the commit. + +. git-sh-setup +test -x "$GIT_DIR/hooks/pre-commit" && + exec "$GIT_DIR/hooks/pre-commit" ${1+"$@"} +: diff --git a/util/git-hooks/pre-commit b/util/git-hooks/pre-commit new file mode 100755 index 0000000..dbccb9e --- /dev/null +++ b/util/git-hooks/pre-commit @@ -0,0 +1,9 @@ +#!/bin/sh +# +# A hook script to verify what is about to be committed. +# Called by "git commit" with no arguments. The hook should +# exit with non-zero status after issuing an appropriate message if +# it wants to stop the commit. + +# Check for whitespace errors +git diff-index --check --cached HEAD -- || exit 1 diff --git a/util/git-hooks/pre-push b/util/git-hooks/pre-push new file mode 100755 index 0000000..b7e34ee --- /dev/null +++ b/util/git-hooks/pre-push @@ -0,0 +1,74 @@ +#!/bin/sh + +# A hook script to verify what is about to be pushed. Called by "git +# push" after it has checked the remote status, but before anything has been +# pushed. If this script exits with a non-zero status nothing will be pushed. +# +# This hook is called with the following parameters: +# +# $1 -- Name of the remote to which the push is being done +# $2 -- URL to which the push is being done +# +# If pushing without using a named remote those arguments will be equal. +# +# Information about the commits which are being pushed is supplied as lines to +# the standard input in the form: +# +# <local ref> <local sha1> <remote ref> <remote sha1> + +remote="$1" +url="$2" + +zero=0000000000000000000000000000000000000000 + +upstream_pattern="github\.com.flashrom/flashrom(\.git)?|flashrom\.org.git/flashrom(\.git)?" +precious_branches=( stable staging ) + +# Only care about the upstream repository +if echo "$url" | grep -q -v -E "$upstream_pattern" ; then + exit 0 +fi + +while read local_ref local_sha remote_ref remote_sha ; do + if [ "$remote_ref" != "refs/heads/staging" -a "$remote_ref" != "refs/heads/stable" ]; then + echo "Feature branches not allowed ($remote_ref)." >&2 + exit 1 + fi + + if [ "$local_sha" = $zero ]; then + echo "Deletion of branches is prohibited." >&2 + exit 1 + else + if [ "$remote_sha" = "$zero" ]; then + echo "No new branches allowed." >&2 + exit 1 + else + range="$remote_sha..$local_sha" + fi + + # Check for Signed-off-by and Acked-by + commit=$(git rev-list -n 1 --all-match --invert-grep -E \ + --grep '^Signed-off-by: .+ <.+@.+\..+>$' --grep '^Acked-by: .+ <.+@.+\..+>$' "$range") + if [ -n "$commit" ]; then + echo "No Signoff or Ack found in commit $local_sha in $local_ref, not pushing." >&2 + exit 1 + fi + + # Make _really_ sure we do not rewrite precious history + for lbranch in "${precious_branches[@]}"; do + if [ "$remote_ref" = "refs/heads/$lbranch" ]; then + nonreachable=$(git rev-list $remote_sha ^$local_sha) + if [ -n "$nonreachable" ]; then + echo "Only fast-forward pushes are allowed on $lbranch." >&2 + echo "$nonreachable is not included in $remote_sha while pusing to $remote_ref" >&2 + exit 1 + fi + fi + done + + # FIXME: check commit log format (subject without full stop at the end etc). + # FIXME: do buildbot checks if authorized? + fi +done + +exit 0 diff --git a/util/git-hooks/wrapper.sh b/util/git-hooks/wrapper.sh new file mode 100755 index 0000000..3fc3e05 --- /dev/null +++ b/util/git-hooks/wrapper.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +if [ -x $0.local ]; then + $0.local "$@" || exit $? +fi + +hook=$(git rev-parse --show-toplevel)"/util/git-hooks/"$(basename $0) +if [ -x $hook ]; then + $hook "$@" || exit $? +fi |