GithubHelp home page GithubHelp logo

barisione / clang-format-hooks Goto Github PK

View Code? Open in Web Editor NEW
195.0 5.0 53.0 271 KB

Apply a coding style with clang-format only to new code added to an existing code base.

License: MIT License

Shell 36.85% Python 63.15%
git clang-format clang syntax gitbook c cpp objective-c

clang-format-hooks's Introduction

Build status

clang-format git hooks

Apply a coding style with clang-format only to new code added to an existing code base.

At Undo, we decided to use the clang-format tool to enforce a consistent coding style for new and refactored code, but without changing the existing one.

This is done through a script (apply-format) which can be run manually or through a pre-commit git hook which is run every time just before code is committed.

What is clang-format?

clang-format is a tool, part of the LLVM project, which can reformat code to adhere to a configured style.

By default, clang-format supports a few pre-defined styles matching the style used by a few important projects, but it's possible to customise specific styles.

Setup

Dependencies

  • Ubuntu and Debian: install the clang-format package. You can install a newer version with these instructions.
  • Fedora, CentOS and Red Hat: install the clang package.
  • macOS: install clang-format using HomeBrew: brew install clang-format.

You can optionally install colordiff to get nicer output.

Configuring clang-format

clang-format needs to be configured to reformat code according to your project's preferred style.
All the options are described in the official style options documentation, but a great way to start is to use an interactive configurator.

Once you found the correct style options, just save them in a file called .clang-format in the top level directory of your project. From here, the scripts, will load the style automatically.

Scripts

Add the apply-format and git-pre-commit-format scripts to your repositories.

You can either copy them (maybe in a scripts/ sub-directory) or add this whole repository as a git submodule.

Registering the git hook

Run at a terminal:

$ ./git-pre-commit-format install

This will add a hook (in .git/hooks/) which is run every time you commit.

Using the pre-commit hook

After registering the git hook, you don't need to do anything except for committing your changes.

Every time you commit, the hook will check if your code matches the coding standard. If it doesn't, you get asked what to do and you can decide to:

  • Apply the fixes automatically (only to the code you are actually committing, not to unstaged code).
  • Commit anyway.
  • Abort the commit so you can fix the problem manually.

Note that, if you use git through a GUI or some other tool (i.e. not directly on the command line), the script will fail to get your input. In this case disable the interactive behaviour with:

$ git config hooks.clangFormatDiffInteractive false

For more information on the script use the --help option.

Manual script

You can also reformat changed code without committing it using the apply-format script directly.

By default, apply-format reformats only the code which was modified, i.e. the code that git diff would show, and prints the diff to the terminal.

If you want to automatically apply the suggested changes, run the script with -i.

If you only want to reformat your staged changes, but not the unstanged ones, use --staged.

For instance, a possible workflow would be similar to:

$ # Make some changes.
$ vi foo.c
$ # Stage changes you want to commit.
$ git add -p
$ # Reformat the staged changes you made.
$ ./scripts/apply-format -i --staged
$ # Commit the result.
$ git commit

It’s also possible to reformat a whole file (using --whole-file or its shorter form -f).

For more information on the script use the --help option.

clang-format-hooks's People

Contributors

barisione avatar du114rd avatar emilienmottet avatar jmdaly avatar koalo avatar perror avatar ptomato avatar wjt avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

clang-format-hooks's Issues

"start line should be at least 1" removing first line from file

Issue:

When removing the first line from a file, the pre-commit hook fails with the following error, preventing commit.

[test-clang-format-repo]$ git commit -m "Test file remove first line"
error: start line should be at least 1

The apply-format script failed.
[test-clang-format-repo]$

Steps to reproduce:

  1. mkdir test-clang-format-repo && cd test-clang-format-repo && git init .
  2. /path/to/this/repo/git-pre-commit-format install
  3. Create TestFile.cc with:

#include <iostream>

int main() {
  std::cout << "Hello, clang" << std::endl;
  return 0;
    }

(note first line is empty)

  1. git add 'TestFile.cc' && git commit -m "test file"
  2. accept the suggested correction (to the indentation)
  3. edit TestFile.cc and remove the first (empty) line
  4. git add 'TestFile.cc' && git commit -m "remove first line"

Expected behaviour:

  • commit is successful

Actual behaviour:

error: start line should be at least 1

The apply-format script failed.

[test-clang-format-repo]$ git status
On branch main
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   Testfile.cc

Change is still stashed.

clang-format-hooks is not formatting hpp files

In some C++ projects, the file extension .hpp is used when writing template code. Often, the implementations of function templates are placed in hpp files. Presently, the apply-format script does not process hpp files. I have addressed this on a branch in my fork of clang-format-hooks and can put a PR in shortly.

Error when committing

I get the following error when making a commit, using clang-format-diff from clang 9.

Traceback (most recent call last):
File "/usr/local/bin/clang-format-diff", line 127, in
main()
File "/usr/local/bin/clang-format-diff", line 110, in main
universal_newlines=True)
File "/usr/lib64/python2.7/subprocess.py", line 711, in init
errread, errwrite)
File "/usr/lib64/python2.7/subprocess.py", line 1327, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory

Apply format fails when environment uses python 3 instead of python 2

I usually have my environment set up so that python 3 is the default executable of python. However, the git-hook fails to recognize this and launch the format diff with the python 3 (although the script seems to be python 2).

Of course, I can set my local environment back to python 2 and it just works fine, but I just wonder if it's possible to find a correct python2 executable from the batch script? If so, it would be a nice small feature to add to the apply-format script.

New `clang-format-diff` returns a non-zero status code when diffs exist leading `apply-format` to fail

Starting from llvm/llvm-project#70883 (around LLVM version 18.1.0), the clang-format-diff script now will exit with a non-zero status code if it detects there has formatting changes.

And this change from LLVM clang-format will break the assuming in apply-format script, here at L329,

"${git_args[@]}" "$@" \
| "${format_diff_args[@]}" \
-p1 \
-style="$style" \
-iregex="$exclusions_regex"'.*\.(c|cpp|cxx|cc|h|hpp|m|mm|js|java)' \
> "$patch_dest" \
|| exit 1

which stops apply-format to apply the diff as format fix to the local or git-staged files.

Don't try to apply format on merge commits

Most our code is not formatted. We want to "get there" by steps, so we use this hook to format modified code and even then it is not always used.

When merge happens (I pull upstream changes to my topic branch), hook tries to format everything I pulled in the merge. If there is a lot of changes, format takes a lot of time. I would like it to just ignore merging commits. Even though formatting is right thing to do, merge commit is not a good time for it.

Ideas for detecting merge commits are here: https://stackoverflow.com/questions/27800512/bypass-pre-commit-hook-for-merge-commits

[Pedantic] README.md encourages violation of the project's own copyright notice

README.md instructs people that:

Add the apply_format and git-pre-commit-format scripts to your repositories.
You can either copy them (maybe in a scripts/ sub-directory) or add this whole repository as a git submodule.

But copying those scripts alone would technically be in violation of the project's own copyright permission notice:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software

Including the copyright notice inside both apply-format and git-pre-commit-format would resolve this.

Cannot find clang-format-diff

OS: macOS 11.5.2
clang-format version 12.0.1, installed by Homebrew
But, error while using it:

$ ./scripts/apply-format -i --staged
Cannot find clang-format-diff which should be shipped as part of the same
package where clang-format is.

Please find out where clang-format-diff is in your distro and report an issue
at https://github.com/barisione/clang-format-hooks/issues with details about
your operating system and setup.

You can also specify your own path for clang-format-diff by setting the
$CLANG_FORMAT_DIFF environment variable, for instance:

    CLANG_FORMAT_DIFF="python /.../clang-format-diff.py" \
        ./scripts/apply-format

Support for pre-commit framework

Thanks for these git hooks.

Is there support for using the scripts in this repo with the pre-commit framework?

The pre-commit framework is useful for incorporating multiple hooks that are useful for multiple languages. However, the supported clang-format hooks are not interactive like the ones in this repo.

Hook fails with git's diff.noPrefix config

The apply-format script fails when this git config is set:

$ git commit -m bla
No such file or directory
The apply-format script failed.

This config removes the "a/" and "b/" prefixes from diffs. I think apply-format expects them to be there unconditionally, so the file is not found.

Invalid value for -style

pre-commit cannot set style with format file from "git config hooks.clangFormatDiffStyle".
I tried with use absolute path and relative path, both failed.
Could you help to find fix?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.