skip to Main Content

In a project, we use 2 IDEs. The project contains hundreds files of code, and hundreds special files of JSON format which constantly get reread and rewritten by these IDEs. While we used single IDE, it’s not a problem, files always get written the same way. Unfortunately, different IDEs save JSON with different ordering which leads to dozens of changes for GIT and uselessly overwhelmed diff. These files are important and must not be excluded by GitIgnore, but they rarely get changed, and this probably can be handled manually.

So, is there a terminal command to quickly undo/unselect changes for specific file extension? Or, maybe it is possible for GIT to track changes of JSONs without considering the order?

I also had an idea to use custom script for reordering the JSONs, but it would consume too much CPU, and also lead to rereading by an IDE which is also bad.

Update

I found the following command from another SO question:

git checkout main -- $(git ls-files -- "*.yy")

This workaround isn’t handy but basically solves the problem. If anybody knows how to make GIT ignore JSON ordering, it would be great!

2

Answers


  1. One way to temporarily ignore changes to the json files is to tell git to assume they haven’t changed:

    git update-index --assume-unchanged file-to-ignore.json
    

    And only when you want to commit, tell git to really look at the file again:

    git update-index --no-assume-unchanged file-to-ignore.json
    

    Another option would be to use a pre-commit-hook to sort the json only when committing.

    Login or Signup to reply.
  2. i’d make a git pre-commit hook to make sure all JSONs are always formatted the same way, for example in .git/hooks/pre-commit put

    #!/bin/sh
    php git/precommit_hook.php
    exit $?
    

    and if you’re on a unix-system, make sure pre-commit is chmod +x .git/hooks/pre-commit
    and in git/precommit_hook.php put

    <?php
    declare (strict_types = 1);
    if(PHP_VERSION_ID < 70300) {
        fwrite(STDERR, "PHP 7.3 or higher is required to run this script");
        exit(1);
    }
    $changed_files = explode("x00", rtrim(shell_exec("git diff --name-only --cached -z"), "x00"));
    foreach ($changed_files as $file) {
        if(!file_exists($file)) {
            // File was deleted, skip it
            continue;
        }
        $ext = pathinfo($file, PATHINFO_EXTENSION);
        if ($ext === "json") {
            $json = json_decode(file_get_contents($file), true);
            if (json_last_error() !== JSON_ERROR_NONE) {
                fwrite(STDERR, "JSON Error: " . json_last_error_msg() . " in $file, will not format itn");
                continue;
            }
            $json = json_encode($json, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR);
            file_put_contents($file, $json, LOCK_EX);
        }
    }
    

    now all *.json files will be committed with the PHP json formatters JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR
    no matter what IDE you use 🙂

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search