git-commit-vandalism/contrib
Jeff King 4d168e742a coccinelle: use <...> for function exclusion
Sometimes we want to suppress a coccinelle transformation
inside a particular function. For example, in finding
conversions of hashcmp() to oidcmp(), we should not convert
the call in oidcmp() itself, since that would cause infinite
recursion. We write that like this:

  @@
  identifier f != oidcmp;
  expression E1, E2;
  @@
    f(...) {...
  - hashcmp(E1->hash, E2->hash)
  + oidcmp(E1, E2)
    ...}

to match the interior of any function _except_ oidcmp().

Unfortunately, this doesn't catch all cases (e.g., the one
in sequencer.c that this patch fixes). The problem, as
explained by one of the Coccinelle developers in [1], is:

  For transformation, A ... B requires that B occur on every
  execution path starting with A, unless that execution path
  ends up in error handling code.  (eg, if (...) { ...
  return; }).  Here your A is the start of the function.  So
  you need a call to hashcmp on every path through the
  function, which fails when you add ifs.

  [...]

  Another issue with A ... B is that by default A and B
  should not appear in the matched region.  So your original
  rule matches only the case where every execution path
  contains exactly one call to hashcmp, not more than one.

One way to solve this is to put the pattern inside an
angle-bracket pattern like "<... P ...>", which allows zero
or more matches of P. That works (and is what this patch
does), but it has one drawback: it matches more than we care
about, and Coccinelle uses extra CPU. Here are timings for
"make coccicheck" before and after this patch:

  [before]
  real	1m27.122s
  user	7m34.451s
  sys	0m37.330s

  [after]
  real	2m18.040s
  user	10m58.310s
  sys	0m41.549s

That's not ideal, but it's more important for this to be
correct than to be fast. And coccicheck is already fairly
slow (and people don't run it for every single patch). So
it's an acceptable tradeoff.

There _is_ a better way to do it, which is to record the
position at which we find hashcmp(), and then check it
against the forbidden function list. Like:

  @@
  position p : script:python() { p[0].current_element != "oidcmp" };
  expression E1,E2;
  @@
  - hashcmp@p(E1->hash, E2->hash)
  + oidcmp(E1, E2)

This is only a little slower than the current code, and does
the right thing in all cases. Unfortunately, not all builds
of Coccinelle include python support (including the ones in
Debian). Requiring it may mean that fewer people can easily
run the tool, which is worse than it simply being a little
slower.

We may want to revisit this decision in the future if:

  - builds with python become more common

  - we find more uses for python support that tip the
    cost-benefit analysis

But for now this patch sticks with the angle-bracket
solution, and converts all existing cocci patches. This
fixes only one missed case in the current code, though it
makes a much better difference for some new rules I'm adding
(converting "!hashcmp()" to "hasheq()" misses over half the
possible conversions using the old form).

[1] https://public-inbox.org/git/alpine.DEB.2.21.1808240652370.2344@hadrien/

Helped-by: Julia Lawall <julia.lawall@lip6.fr>
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-08-29 11:32:49 -07:00
..
buildsystems
coccinelle coccinelle: use <...> for function exclusion 2018-08-29 11:32:49 -07:00
completion range-diff: make --dual-color the default mode 2018-08-13 10:44:52 -07:00
contacts
credential git-credential-netrc: make "all" default target of Makefile 2018-06-18 14:58:59 -07:00
diff-highlight diff-highlight: detect --graph by indent 2018-03-21 10:24:19 -07:00
emacs git{,-blame}.el: remove old bitrotting Emacs code 2018-04-16 17:25:49 +09:00
examples Merge branch 'bw/c-plus-plus' into ds/lazy-load-trees 2018-04-11 10:46:32 +09:00
fast-import import-tars: read overlong names from pax extended header 2018-05-24 08:35:51 +09:00
git-jump contrib/git-jump/git-jump: jump to exact location 2018-06-22 12:59:02 -07:00
git-shell-commands
hg-to-git Replace Free Software Foundation address in license notices 2017-11-09 13:21:21 +09:00
hooks hooks/pre-auto-gc-battery: allow gc to run on non-laptops 2018-02-28 14:24:46 -08:00
long-running-filter
mw-to-git mw-to-git/t9360: fix broken &&-chain 2018-07-31 11:23:23 -07:00
persistent-https
remote-helpers
stats
subtree subtree test: simplify preparation of expected results 2018-07-30 13:58:16 -07:00
svn-fe
thunderbird-patch-inline
update-unicode unicode_width.h: rename to use dash in file name 2018-04-11 18:11:00 +09:00
vscode vscode: let cSpell work on commit messages, too 2018-07-30 13:14:39 -07:00
workdir
git-resurrect.sh
README
remotes2config.sh
rerere-train.sh

Contributed Software

Although these pieces are available as part of the official git
source tree, they are in somewhat different status.  The
intention is to keep interesting tools around git here, maybe
even experimental ones, to give users an easier access to them,
and to give tools wider exposure, so that they can be improved
faster.

I am not expecting to touch these myself that much.  As far as
my day-to-day operation is concerned, these subdirectories are
owned by their respective primary authors.  I am willing to help
if users of these components and the contrib/ subtree "owners"
have technical/design issues to resolve, but the initiative to
fix and/or enhance things _must_ be on the side of the subtree
owners.  IOW, I won't be actively looking for bugs and rooms for
enhancements in them as the git maintainer -- I may only do so
just as one of the users when I want to scratch my own itch.  If
you have patches to things in contrib/ area, the patch should be
first sent to the primary author, and then the primary author
should ack and forward it to me (git pull request is nicer).
This is the same way as how I have been treating gitk, and to a
lesser degree various foreign SCM interfaces, so you know the
drill.

I expect that things that start their life in the contrib/ area
to graduate out of contrib/ once they mature, either by becoming
projects on their own, or moving to the toplevel directory.  On
the other hand, I expect I'll be proposing removal of disused
and inactive ones from time to time.

If you have new things to add to this area, please first propose
it on the git mailing list, and after a list discussion proves
there are some general interests (it does not have to be a
list-wide consensus for a tool targeted to a relatively narrow
audience -- for example I do not work with projects whose
upstream is svn, so I have no use for git-svn myself, but it is
of general interest for people who need to interoperate with SVN
repositories in a way git-svn works better than git-svnimport),
submit a patch to create a subdirectory of contrib/ and put your
stuff there.

-jc