diff options
Diffstat (limited to 'contrib')
-rw-r--r-- | contrib/coccinelle/commit.cocci | 4 | ||||
-rw-r--r-- | contrib/coccinelle/object_id.cocci | 50 | ||||
-rw-r--r-- | contrib/completion/git-completion.bash | 4 | ||||
-rwxr-xr-x | contrib/coverage-diff.sh | 108 | ||||
-rwxr-xr-x | contrib/subtree/git-subtree.sh | 129 |
5 files changed, 237 insertions, 58 deletions
diff --git a/contrib/coccinelle/commit.cocci b/contrib/coccinelle/commit.cocci index aec3345adb..c49aa558f0 100644 --- a/contrib/coccinelle/commit.cocci +++ b/contrib/coccinelle/commit.cocci @@ -15,10 +15,10 @@ expression c; identifier f !~ "^(get_commit_tree|get_commit_tree_in_graph_one|load_tree_for_commit)$"; expression c; @@ - f(...) {... + f(...) {<... - c->maybe_tree + get_commit_tree(c) - ...} + ...>} @@ expression c; diff --git a/contrib/coccinelle/object_id.cocci b/contrib/coccinelle/object_id.cocci index 09afdbf994..d8bdb48712 100644 --- a/contrib/coccinelle/object_id.cocci +++ b/contrib/coccinelle/object_id.cocci @@ -20,10 +20,10 @@ expression E1; identifier f != oid_to_hex; expression E1; @@ - f(...) {... + f(...) {<... - sha1_to_hex(E1->hash) + oid_to_hex(E1) - ...} + ...>} @@ expression E1, E2; @@ -35,10 +35,10 @@ expression E1, E2; identifier f != oid_to_hex_r; expression E1, E2; @@ - f(...) {... + f(...) {<... - sha1_to_hex_r(E1, E2->hash) + oid_to_hex_r(E1, E2) - ...} + ...>} @@ expression E1; @@ -50,10 +50,10 @@ expression E1; identifier f != oidclr; expression E1; @@ - f(...) {... + f(...) {<... - hashclr(E1->hash) + oidclr(E1) - ...} + ...>} @@ expression E1, E2; @@ -65,10 +65,10 @@ expression E1, E2; identifier f != oidcmp; expression E1, E2; @@ - f(...) {... + f(...) {<... - hashcmp(E1->hash, E2->hash) + oidcmp(E1, E2) - ...} + ...>} @@ expression E1, E2; @@ -92,10 +92,10 @@ expression E1, E2; identifier f != oidcpy; expression E1, E2; @@ - f(...) {... + f(...) {<... - hashcpy(E1->hash, E2->hash) + oidcpy(E1, E2) - ...} + ...>} @@ expression E1, E2; @@ -108,3 +108,33 @@ expression E1, E2; @@ - hashcpy(E1.hash, E2->hash) + oidcpy(&E1, E2) + +@@ +expression E1, E2; +@@ +- oidcmp(E1, E2) == 0 ++ oideq(E1, E2) + +@@ +identifier f != hasheq; +expression E1, E2; +@@ + f(...) {<... +- hashcmp(E1, E2) == 0 ++ hasheq(E1, E2) + ...>} + +@@ +expression E1, E2; +@@ +- oidcmp(E1, E2) != 0 ++ !oideq(E1, E2) + +@@ +identifier f != hasheq; +expression E1, E2; +@@ + f(...) {<... +- hashcmp(E1, E2) != 0 ++ !hasheq(E1, E2) + ...>} diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index 12f7ce0c5c..5f556075d3 100644 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -943,6 +943,7 @@ __git_complete_remote_or_refspec () *) ;; esac ;; + --multiple) no_complete_refspec=1; break ;; -*) ;; *) remote="$i"; break ;; esac @@ -2556,6 +2557,9 @@ _git_stash () drop,--*) __gitcomp "--quiet" ;; + list,--*) + __gitcomp "--name-status --oneline --patch-with-stat" + ;; show,--*|branch,--*) ;; branch,*) diff --git a/contrib/coverage-diff.sh b/contrib/coverage-diff.sh new file mode 100755 index 0000000000..4ec419f900 --- /dev/null +++ b/contrib/coverage-diff.sh @@ -0,0 +1,108 @@ +#!/bin/sh + +# Usage: Run 'contrib/coverage-diff.sh <version1> <version2>' from source-root +# after running +# +# make coverage-test +# make coverage-report +# +# while checked out at <version2>. This script combines the *.gcov files +# generated by the 'make' commands above with 'git diff <version1> <version2>' +# to report new lines that are not covered by the test suite. + +V1=$1 +V2=$2 + +diff_lines () { + perl -e ' + my $line_num; + while (<>) { + # Hunk header? Grab the beginning in postimage. + if (/^@@ -\d+(?:,\d+)? \+(\d+)(?:,\d+)? @@/) { + $line_num = $1; + next; + } + + # Have we seen a hunk? Ignore "diff --git" etc. + next unless defined $line_num; + + # Deleted line? Ignore. + if (/^-/) { + next; + } + + # Show only the line number of added lines. + if (/^\+/) { + print "$line_num\n"; + } + # Either common context or added line appear in + # the postimage. Count it. + $line_num++; + } + ' +} + +files=$(git diff --name-only "$V1" "$V2" -- \*.c) + +# create empty file +>coverage-data.txt + +for file in $files +do + git diff "$V1" "$V2" -- "$file" | + diff_lines | + sort >new_lines.txt + + if ! test -s new_lines.txt + then + continue + fi + + hash_file=$(echo $file | sed "s/\//\#/") + + if ! test -s "$hash_file.gcov" + then + continue + fi + + sed -ne '/#####:/{ + s/ #####:// + s/:.*// + s/ //g + p + }' "$hash_file.gcov" | + sort >uncovered_lines.txt + + comm -12 uncovered_lines.txt new_lines.txt | + sed -e 's/$/\)/' | + sed -e 's/^/ /' >uncovered_new_lines.txt + + grep -q '[^[:space:]]' <uncovered_new_lines.txt && + echo $file >>coverage-data.txt && + git blame -s "$V2" -- "$file" | + sed 's/\t//g' | + grep -f uncovered_new_lines.txt >>coverage-data.txt && + echo >>coverage-data.txt + + rm -f new_lines.txt uncovered_lines.txt uncovered_new_lines.txt +done + +cat coverage-data.txt + +echo "Commits introducing uncovered code:" + +commit_list=$(cat coverage-data.txt | + grep -E '^[0-9a-f]{7,} ' | + awk '{print $1;}' | + sort | + uniq) + +( + for commit in $commit_list + do + git log --no-decorate --pretty=format:'%an %h: %s' -1 $commit + echo + done +) | sort + +rm coverage-data.txt diff --git a/contrib/subtree/git-subtree.sh b/contrib/subtree/git-subtree.sh index d3f39a862a..147201dc6c 100755 --- a/contrib/subtree/git-subtree.sh +++ b/contrib/subtree/git-subtree.sh @@ -231,12 +231,14 @@ cache_miss () { } check_parents () { - missed=$(cache_miss "$@") + missed=$(cache_miss "$1") + local indent=$(($2 + 1)) for miss in $missed do if ! test -r "$cachedir/notree/$miss" then debug " incorrect order: $miss" + process_split_commit "$miss" "" "$indent" fi done } @@ -340,7 +342,12 @@ find_existing_splits () { revs="$2" main= sub= - git log --grep="^git-subtree-dir: $dir/*\$" \ + local grep_format="^git-subtree-dir: $dir/*\$" + if test -n "$ignore_joins" + then + grep_format="^Add '$dir/' from commit '" + fi + git log --grep="$grep_format" \ --no-show-signature --pretty=format:'START %H%n%s%n%n%b%nEND%n' $revs | while read a b junk do @@ -534,6 +541,7 @@ copy_or_skip () { nonidentical= p= gotparents= + copycommit= for parent in $newparents do ptree=$(toptree_for_commit $parent) || exit $? @@ -541,7 +549,24 @@ copy_or_skip () { if test "$ptree" = "$tree" then # an identical parent could be used in place of this rev. - identical="$parent" + if test -n "$identical" + then + # if a previous identical parent was found, check whether + # one is already an ancestor of the other + mergebase=$(git merge-base $identical $parent) + if test "$identical" = "$mergebase" + then + # current identical commit is an ancestor of parent + identical="$parent" + elif test "$parent" != "$mergebase" + then + # no common history; commit must be copied + copycommit=1 + fi + else + # first identical parent detected + identical="$parent" + fi else nonidentical="$parent" fi @@ -564,7 +589,6 @@ copy_or_skip () { fi done - copycommit= if test -n "$identical" && test -n "$nonidentical" then extras=$(git rev-list --count $identical..$nonidentical) @@ -598,6 +622,58 @@ ensure_valid_ref_format () { die "'$1' does not look like a ref" } +process_split_commit () { + local rev="$1" + local parents="$2" + local indent=$3 + + if test $indent -eq 0 + then + revcount=$(($revcount + 1)) + else + # processing commit without normal parent information; + # fetch from repo + parents=$(git rev-parse "$rev^@") + extracount=$(($extracount + 1)) + fi + + progress "$revcount/$revmax ($createcount) [$extracount]" + + debug "Processing commit: $rev" + exists=$(cache_get "$rev") + if test -n "$exists" + then + debug " prior: $exists" + return + fi + createcount=$(($createcount + 1)) + debug " parents: $parents" + check_parents "$parents" "$indent" + newparents=$(cache_get $parents) + debug " newparents: $newparents" + + tree=$(subtree_for_commit "$rev" "$dir") + debug " tree is: $tree" + + # ugly. is there no better way to tell if this is a subtree + # vs. a mainline commit? Does it matter? + if test -z "$tree" + then + set_notree "$rev" + if test -n "$newparents" + then + cache_set "$rev" "$rev" + fi + return + fi + + newrev=$(copy_or_skip "$rev" "$tree" "$newparents") || exit $? + debug " newrev is: $newrev" + cache_set "$rev" "$newrev" + cache_set latest_new "$newrev" + cache_set latest_old "$rev" +} + cmd_add () { if test -e "$dir" then @@ -689,12 +765,7 @@ cmd_split () { done fi - if test -n "$ignore_joins" - then - unrevs= - else - unrevs="$(find_existing_splits "$dir" "$revs")" - fi + unrevs="$(find_existing_splits "$dir" "$revs")" # We can't restrict rev-list to only $dir here, because some of our # parents have the $dir contents the root, and those won't match. @@ -703,45 +774,11 @@ cmd_split () { revmax=$(eval "$grl" | wc -l) revcount=0 createcount=0 + extracount=0 eval "$grl" | while read rev parents do - revcount=$(($revcount + 1)) - progress "$revcount/$revmax ($createcount)" - debug "Processing commit: $rev" - exists=$(cache_get "$rev") - if test -n "$exists" - then - debug " prior: $exists" - continue - fi - createcount=$(($createcount + 1)) - debug " parents: $parents" - newparents=$(cache_get $parents) - debug " newparents: $newparents" - - tree=$(subtree_for_commit "$rev" "$dir") - debug " tree is: $tree" - - check_parents $parents - - # ugly. is there no better way to tell if this is a subtree - # vs. a mainline commit? Does it matter? - if test -z "$tree" - then - set_notree "$rev" - if test -n "$newparents" - then - cache_set "$rev" "$rev" - fi - continue - fi - - newrev=$(copy_or_skip "$rev" "$tree" "$newparents") || exit $? - debug " newrev is: $newrev" - cache_set "$rev" "$newrev" - cache_set latest_new "$newrev" - cache_set latest_old "$rev" + process_split_commit "$rev" "$parents" 0 done || exit $? latest_new=$(cache_get latest_new) |