)]}'
{
  "commit": "e125f0c08f13f271bfabcc26e97b2238f9b2fa1a",
  "tree": "de1e37f87b863efa1ac4d6ab5bbedc32fc2d3825",
  "parents": [
    "c27baf26292bdd1f81a8ad3b3ae66af5ff3dadb6"
  ],
  "author": {
    "name": "Daniele Sassoli",
    "email": "danielesassoli@gmail.com",
    "time": "Mon May 11 15:41:16 2026 +0100"
  },
  "committer": {
    "name": "Luca Milanesio",
    "email": "luca.milanesio@gmail.com",
    "time": "Sat May 30 10:37:27 2026 +0200"
  },
  "message": "Ensure no ambiguous change IDs when deleting in the index.changes api\n\nWhen deleteMissing is true, changes are potentially deleted from the\nindex, it\u0027s therefore crucial that we do not use an ambiguous change-id\nformats that could lead to Gerrit deleting the wrong change from the\nindex.\n\nThis api essentially used a side-effect of ChangeFinder to identify if a\nchange was present or not:\n- ChangeFinder uses the index to find the document if the identifier\n  isn\u0027t a `project~changeNumber`\n- If the entry is found on the index, it then tries to load the\n  associated NoteDb data from the Git repository\n- If the data is present in the index but NOT in NoteDb, then it\n  returns an empty result\n\nThe above doesn\u0027t happen if the change is in `project~changeNumber`\nformat.\n\nThe code was relying on the above logic to infer that a change was in\nthe index, but not in NoteDb, by checking if the result was empty, which\nis a side-effect rather than a direct contract behaviour.\n\nUse the queryProvider to identify if a change is present in the index or\nnot, and, if it is, check on disk if it\u0027s actually present. To ensure we\ndon\u0027t use ambiguous changeIDs, force using project~changeNum as its the\ntrue unique identifier of a change. Finally, fail the request with a 400\nstatus code if not all change ids are in said format.\n\nRelease-Notes: Breaking change: require tilde changeIds in config/server/index.changes when requesting deletions and reject legacy numeric-only ids.\nBug: Issue 515272357\nChange-Id: I8350971af868ee34b17fc8703aa9ef40c03f5ec5\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "8c3c972711ad0bdf92fe7a4b638bf754c0c2145f",
      "old_mode": 33188,
      "old_path": "Documentation/rest-api-config.txt",
      "new_id": "b86d732b0b933f919d7388e253f0bff6597c23b0",
      "new_mode": 33188,
      "new_path": "Documentation/rest-api-config.txt"
    },
    {
      "type": "modify",
      "old_id": "ea970d02268218b4e773844d26275c9e1a73e6e6",
      "old_mode": 33188,
      "old_path": "java/com/google/gerrit/server/restapi/config/IndexChanges.java",
      "new_id": "94f52a95d18ee00d84574cab0271c083dd830397",
      "new_mode": 33188,
      "new_path": "java/com/google/gerrit/server/restapi/config/IndexChanges.java"
    },
    {
      "type": "modify",
      "old_id": "12fd227ec6a24a263d1528d27ed03d27cceb33d0",
      "old_mode": 33188,
      "old_path": "javatests/com/google/gerrit/acceptance/rest/config/IndexChangesIT.java",
      "new_id": "a75b9982ea349baf20ca6a36a4d7feabaafa5b36",
      "new_mode": 33188,
      "new_path": "javatests/com/google/gerrit/acceptance/rest/config/IndexChangesIT.java"
    }
  ]
}
