1

I have been playing with Git for a while but I haven't found a good explanation of the technical details of renames.

I have always thought renames are somehow marked in the commit, so that space is saved and you can keep track of the history of the file before that rename. I was surprised to find out that the option --find-renames is included in git log and git show, but not in git add or similar, so I wonder, whether it is really only a way of presenting changes from commits or whether there is something special about renaming a file in Git.

I was facing a related problem. I wanted to convert a YAML file to a JSON one, which includes changing the content (more specifically changing every line of the original file) as well as renaming it (changing the extension). On the other hand, I think it really is a rename; when searching for the history of the JSON, you should also find the YAML one.

Depending on the answer to the first question: Is it possible to to find the YAML when searching for history of the JSON either by forcibly marking the conversion as a rename or by somehow instructing git log to display it (I was not successful with git log --follow -M0)?

user229044
  • 232,980
  • 40
  • 330
  • 338
Vojtech Kane
  • 559
  • 6
  • 21
  • I *think* renames are based on a heuristic where a "new" file appears at the same time that a similar file is "deleted". You might work around this by simply making the conversion from YAML to JSON (without renaming) in one commit, then renaming the file in another commit. – chepner Sep 25 '18 at 15:34
  • @chepner That would keep the history but would also create a *broken* commit; it makes no sense to store JSON content in `.yaml` file and it will definitely confuse other developers as well as naive parsers, so this is not a solution for me. – Vojtech Kane Sep 25 '18 at 15:40
  • Sure it does; YAML is a superset of JSON, so any valid JSON is also valid YAML. – chepner Sep 25 '18 at 15:45
  • YAML is definitely not a superset of JSON. I stand very corrected, that's pretty surprising. – user229044 Sep 25 '18 at 15:45
  • YAML is a *semantic* superset of JSON, but the *syntax* is totally different. So it indeed does not make sense to store YAML in a `.json` file or vice versa. – sschuberth Sep 25 '18 at 15:47
  • @sschuberth No, it's a *literal* superset of JSON. A valid JSON document is by definition also a valid YAML file. You can feed any JSON file into http://yaml-online-parser.appspot.com/ and it will parse as valid YAML. You can also use arbitrary JSON as any leaf-level element of a YAML document. – user229044 Sep 25 '18 at 15:48
  • Ok, somewhat: https://en.wikipedia.org/wiki/YAML#Comparison_with_JSON – sschuberth Sep 25 '18 at 15:50
  • 1
    YAML syntax contains a JSON-compatible subset; `["a", "b", "c"]` is valid YAML and JSON, though you would usually write that as a vertical list in a YAML file. Once the conversion of the YAML to JSON is complete, it would still be correct to call it YAML (just in a restricted form). – chepner Sep 25 '18 at 15:53
  • @chepner Thank you for mentioning this, I didn't know the relation between JSON and YAML. You are technically right, as far as I have found out. On the other hand, as @sschuberth mentions, it is kind a counter intuitive to store JSON in `.yaml`. Anyway according to @sschuberth's answer my original intentions cannot be realized, so I have to either make 2 commits or loose the history relations. – Vojtech Kane Sep 25 '18 at 16:22

1 Answers1

1

Git tracks contents, not files, and automatically determines similarities based on contents. If files are reasonable similar, they are tracked as renamed (if the original file was removed) or copies otherwise. That said, you cannot force Git to treat arbitrary unsimilar / different files to be a rename.

sschuberth
  • 28,386
  • 6
  • 101
  • 146
  • Thanks, this answers the question from the practical point of view, but could you please clarify what exactly does `tracked as renamed` mean? Is it `marked in a commit as renamed` or `presented as renamed when later reading the history`? – Vojtech Kane Sep 25 '18 at 15:43
  • The latter. You could e.g. lower your similarity threshold, and suddenly `gitk` would display files as renamed in the history that were not marked as renames before. – sschuberth Sep 25 '18 at 15:45