1

I'm working with JSON files and I need to find changes to certain attributes over the commits I've done.

For example with this fake file I'd want to see the changes done to attr1, 2, 3, and 4, but not 5 (or any other not listed.)

File 1 commit A

{
    "group": {
        "attr1": "apples",
        "attr2": "oranges"
    },
    "attr3": "",
    "attr4": "grapes",
    "attr5": "kiwi",
}

File 1 commit B

{  
    "attr3": "bananas",
    "attr4": "",
    "attr5": "strawberry",
    "attr-new": "watermelon",
    "group": {
        "attr1": "pineapples",
        "attr2": "oranges"
    }
}

Wanted output for each file:

File 1 Changes:
    attr1: "apples" to "pineapples"
    attr3: "" to "bananas"
    attr4: "grapes" to ""

I saw that git log has an -L option to search by line, but as you can see, the line numbers aren't consistent between the two commits. Also I know git log as a regex option to use, but I'm not familiar enough with regex to know if it would work here.

I'd need to do this for each file listed in the git log. How do I do this?

mkrieger1
  • 19,194
  • 5
  • 54
  • 65
  • 1
    Not quite what you are looking for, exactly, but `git blame` can tell you the latest change that edited any particular line - use line numbers or grep the output for the current line content. You can work backwards by setting that as the highest point for the next blame search. – Gem Taylor Jul 26 '21 at 19:14
  • Not a complete answer : a tool such as [gron](https://github.com/tomnomnom/gron) can turn json into something you can `grep`. You can write a script which inspects the modified files in a commit, and for each json file, use `gron + grep` on both "before" and "after" versions of the file, and diff those parts. – LeGEC Jul 28 '21 at 07:49

2 Answers2

0

Because all your attributes have unique names, you can probably just go like this

git log -S attr1 --source --all

and it'll give you all the commits that add or remove a line with that on it, which includes change the value.


I actually got the command from here:

https://stackoverflow.com/a/5816177

because I usually do it with gitk like this:

enter image description here


If your json looked like this it would be a little harder:

{
    "group": {
        "attr1": "apples",
        "attr2": "oranges"
    },
    "group2": {
       "attr1": "",
       "attr2": "grapes",
       "attr3": "kiwi"
    }
}
Alex028502
  • 3,486
  • 2
  • 23
  • 50
0

Given that you want a structural diff (rather than a simple text diff), I'd encourage you to find or write an appropriate tool. Git merely reads lines and runs them through a difference engine—code that solves a string-to-string correction problem.

Some languages come with toolsets that let you solve this problem on structured data, rather than just on lines. For instance, Python has difflib (still "string" and "line" oriented in parts but you get to define what a "string" or "line" or "character" is, and controlling the input symbols is the key). Python also has JSON readers. Read the JSON, convert it into (perhaps sorted) attributes, and use the difference engine to compare them (sorted attribute keys will let you use the string-oriented code conveniently).

torek
  • 448,244
  • 59
  • 642
  • 775