)]}'
{
  "commit": "c8b34ef8df51e3b6ad531664698939c03c5b22a4",
  "tree": "50a84ff9ae6eb09866338afc8829fcfce668fb52",
  "parents": [
    "21cca7613ea893f44f2431f8dc138b12304021b6"
  ],
  "author": {
    "name": "Joshua Haberman",
    "email": "haberman@google.com",
    "time": "Sun Oct 18 23:01:30 2026 -0700"
  },
  "committer": {
    "name": "Copybara-Service",
    "email": "copybara-worker@google.com",
    "time": "Mon Oct 19 11:30:24 2026 -0700"
  },
  "message": "Raise AssertionError on message self-merge in pyext and upb.\n\nmsg.MergeFrom(msg) was handled differently by every implementation:\n\n- pyext passed the message to itself as the source of Message::MergeFrom(),\n  which CHECK-fails and aborts the whole process.\n- upb merged from a serialized copy of the message, doubling repeated fields.\n- Pure Python raises AssertionError (it asserts that the source is not self).\n\nC++ does not support self-merge either, so make pyext and upb raise\nAssertionError like pure Python instead of defining a new, more permissive\nbehavior.\n\nIn pyext this needs no flag, since it replaces a process abort. In upb, existing\nusers may depend on the current behavior, so the change is guarded by a new\nbreaking-change flag, PROTOBUF_PY_FUTURE_SELF_MERGE_RAISES. With the flag\nenabled (as in google3), self-merge raises AssertionError. Without it (OSS until\nthe next breaking release), upb keeps its current behavior but emits a\nFutureWarning.\n\nPiperOrigin-RevId: 1002100123\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "ed7dc362533adf22b3ecaa5d0af7bc523c834e36",
      "old_mode": 33188,
      "old_path": "python/extension_dict.c",
      "new_id": "19dab0d41adf9edeb931bfa69b57bfb2c3a2b7b6",
      "new_mode": 33188,
      "new_path": "python/extension_dict.c"
    },
    {
      "type": "modify",
      "old_id": "87a651dcb0e43f6ffd9196c97c1273a03d3a05e2",
      "old_mode": 33188,
      "old_path": "python/google/protobuf/breaking_changes.h",
      "new_id": "10afd52aab7b951f602b907f0377fddb0de64346",
      "new_mode": 33188,
      "new_path": "python/google/protobuf/breaking_changes.h"
    },
    {
      "type": "modify",
      "old_id": "c38ad119b85b89fd0a658528a8a45de114ad55f2",
      "old_mode": 33188,
      "old_path": "python/google/protobuf/internal/message_set_extensions.proto",
      "new_id": "faae0c3242929f5fa4eae1ec5dbb65a2aa016684",
      "new_mode": 33188,
      "new_path": "python/google/protobuf/internal/message_set_extensions.proto"
    },
    {
      "type": "modify",
      "old_id": "b7157ef838f8f8e088033396fb6640e91155184a",
      "old_mode": 33261,
      "old_path": "python/google/protobuf/internal/message_test.py",
      "new_id": "676a6c52f4f2767f8d56d4ae871a1ce30ffe995b",
      "new_mode": 33261,
      "new_path": "python/google/protobuf/internal/message_test.py"
    },
    {
      "type": "modify",
      "old_id": "a482578ada75f0e1096dfe9e76ad128af4dd22ae",
      "old_mode": 33188,
      "old_path": "python/google/protobuf/pyext/extension_dict.cc",
      "new_id": "323becff3a3c2f5a5b64f17040dd0f1c9e71eeb4",
      "new_mode": 33188,
      "new_path": "python/google/protobuf/pyext/extension_dict.cc"
    },
    {
      "type": "modify",
      "old_id": "596540e04e47971b784731f1bfbae5539ca20ffb",
      "old_mode": 33188,
      "old_path": "python/google/protobuf/pyext/message.cc",
      "new_id": "5e842a55f0c71790d457138b37fdc958af3cc09f",
      "new_mode": 33188,
      "new_path": "python/google/protobuf/pyext/message.cc"
    },
    {
      "type": "modify",
      "old_id": "2642a5fff677061110d8217cf730e1bdfdb7b974",
      "old_mode": 33188,
      "old_path": "python/message.c",
      "new_id": "f2870348e4f76e9ddfd557b290b582471d3167b1",
      "new_mode": 33188,
      "new_path": "python/message.c"
    }
  ]
}
