Home > Software engineering >  Ignore JSON ordering
Ignore JSON ordering

Time:01-09

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!

CodePudding user response:

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 it\n");
            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 :)

CodePudding user response:

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.

  • Related