)]}'
{
  "commit": "5bd39784cda151203aa6d97e24c21bf7fddc11de",
  "tree": "d97c78c4964a07b0aae715a83d78b45c1f5a5aea",
  "parents": [
    "600fe743028cbfb640855f659e9851522214bc0b"
  ],
  "author": {
    "name": "Tamir Duberstein",
    "email": "tamird@gmail.com",
    "time": "Fri Jun 12 17:49:12 2026 -0400"
  },
  "committer": {
    "name": "Junio C Hamano",
    "email": "gitster@pobox.com",
    "time": "Fri Jun 12 15:56:44 2026 -0700"
  },
  "message": "commit-reach: reject cycles in contains walk\n\nThe memoized contains traversal used by git tag assumes that commit\nancestry is acyclic. Replacement refs can violate that assumption,\ncausing it to keep pushing an already active commit until memory is\nexhausted.\n\nMark commits while they are active and die if the traversal encounters\nan active commit. Other failures in this walk already die through\nparse_commit_or_die(); using a second reachability walk would only add\na separate policy for malformed history.\n\nSuggested-by: Kristofer Karlsson \u003ckrka@spotify.com\u003e\nSigned-off-by: Tamir Duberstein \u003ctamird@gmail.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "5df471a313cf6be855b61fd9c06d2499e97bc7af",
      "old_mode": 33188,
      "old_path": "commit-reach.c",
      "new_id": "58553dff05692eaa09e219186e5d4995426aed0d",
      "new_mode": 33188,
      "new_path": "commit-reach.c"
    },
    {
      "type": "modify",
      "old_id": "3f3a563d8a5dd11cc928beee481e914f20cd3aea",
      "old_mode": 33188,
      "old_path": "commit-reach.h",
      "new_id": "f908d305b169029a25fca81670f6f12d026284cd",
      "new_mode": 33188,
      "new_path": "commit-reach.h"
    },
    {
      "type": "modify",
      "old_id": "d918005dd9859a3892bcccb278c8c16365c269da",
      "old_mode": 33261,
      "old_path": "t/t7004-tag.sh",
      "new_id": "67309494d283c76b0cb3fc8c3e2b2c12672bac42",
      "new_mode": 33261,
      "new_path": "t/t7004-tag.sh"
    }
  ]
}
