)]}'
{
  "commit": "bfff605c826532690442abbe2d81125c65eb52ec",
  "tree": "8444e17479672dac61e47f1b7274ea7db47f723a",
  "parents": [
    "519b720aa0e0b620ba4111ab48e60c2e37f1d6d6"
  ],
  "author": {
    "name": "Bryan Henry",
    "email": "bryanhenry@google.com",
    "time": "Fri Jun 24 23:25:44 2022 -0700"
  },
  "committer": {
    "name": "Brett Wilson",
    "email": "brettw@chromium.org",
    "time": "Fri Aug 05 23:00:24 2022 +0000"
  },
  "message": "[gn] Prevent build.ninja deletion when regeneration is interrupted\n\nPrior to this change, the top-level build.ninja file generated by GN\nwas configured in such a way that interrupting ninja file regeneration\n(e.g. with Ctrl-C) would cause ninja to delete build.ninja. This was\ndone by ninja\u0027s Builder::Cleanup() function because the \"build\nbuild.ninja\" statement that GN produces uses a depfile argument. GN uses\nthis depfile to capture implicit dependencies and automatically trigger\nninja regeneration if, for example, any BUILD.gn source file is\nmodified.\n\nIf build.ninja is deleted for this reason, the user must manually run\n`gn gen` to recreate it; a poor user experience. Worse, command-line\narguments that the user previously passed to `gn gen` are also lost,\nmeaning that the user must be sure to pass the same arguments again.\nBecause of this bug, developer tools layered on top of GN (like\nPigweed\u0027s `pw watch` file watcher) have added handling to automatically\nrun `gn gen` for the user in an attempt to provide a smoother user\nexperience, but these attempts are still frustrated by the command-line\nargument loss.\n\nThis change modifies the flow of ninja file generation slightly such\nthat build.ninja should never be deleted, even if regeneration is\ninterrupted, and thus ninja should always be able to restart it. The\nbuild rule for build.ninja has been split in two so that ninja will\nonly delete the .tmp file if interrupted:\n\n  build build.ninja.stamp: gn\n    depfile \u003d build.ninja.d\n\n  build build.ninja: phony build.ninja.stamp\n    generator \u003d 1\n\n`gn gen` now does the following:\n\n  1. If the \u0027--regeneration\u0027 flag is present (i.e. if the caller is\n     ninja rather than a user), the \u0027build.ninja\u0027 file is truncated to\n     only the commands needed to initiate regeneration again. (This is\n     the same operation `gn clean` applies to \u0027build.ninja\u0027.)\n\n  2. Ninja file generation proceeds as before, writing \u0027build.ninja\u0027 and\n     \u0027build.ninja.d\u0027, plus a new \u0027build.ninja.stamp\u0027 file.\n\nEssentially, this works by misleading ninja about when \u0027build.ninja\u0027 is\nactually written. Importantly, because of this gn takes on the\nresponsibility for ensuring that \u0027build.ninja\u0027 is always valid, which it\nachieves through atomic writes.\n\nFixed: https://bugs.chromium.org/p/gn/issues/detail?id\u003d25\nChange-Id: I4aef0317466b5e3430a9ef44eaa63c9515afefab\nReviewed-on: https://gn-review.googlesource.com/c/gn/+/14200\nReviewed-by: Brett Wilson \u003cbrettw@chromium.org\u003e\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "f877cc24d04b1948e01340fffadc1f72f226a963",
      "old_mode": 33261,
      "old_path": "build/gen.py",
      "new_id": "ce9d76843a6a7fdedf8bd063b0b9387aa7185617",
      "new_mode": 33261,
      "new_path": "build/gen.py"
    },
    {
      "type": "modify",
      "old_id": "5290dd652535a752897496da537f286aa1f5044f",
      "old_mode": 33188,
      "old_path": "src/gn/command_clean.cc",
      "new_id": "82618452ba5a86bd794c9c36e61f29c51b1bc5cc",
      "new_mode": 33188,
      "new_path": "src/gn/command_clean.cc"
    },
    {
      "type": "modify",
      "old_id": "5c6cc14efb82411f7e7f2f89e1164ce06f261562",
      "old_mode": 33188,
      "old_path": "src/gn/command_gen.cc",
      "new_id": "e212fe9a81f412e448ff9a2d57be11ce0b0ba1b4",
      "new_mode": 33188,
      "new_path": "src/gn/command_gen.cc"
    },
    {
      "type": "modify",
      "old_id": "cb447955e46bc0438af7fe6523449228e09f5743",
      "old_mode": 33188,
      "old_path": "src/gn/commands.cc",
      "new_id": "5ff7ca8eb8637e1ffee23a89f0a79cb250578ffb",
      "new_mode": 33188,
      "new_path": "src/gn/commands.cc"
    },
    {
      "type": "modify",
      "old_id": "acff044515f5861aad83366a7ddb17fbb5b351d1",
      "old_mode": 33188,
      "old_path": "src/gn/commands.h",
      "new_id": "702bf0cd37848971c44758621a9c828fc24b756b",
      "new_mode": 33188,
      "new_path": "src/gn/commands.h"
    },
    {
      "type": "modify",
      "old_id": "908c5df15e9875b190f33b6bc9389161f940a77b",
      "old_mode": 33188,
      "old_path": "src/gn/ninja_build_writer.cc",
      "new_id": "90a296b44909f95959eb3c2f220a10ab71c1a640",
      "new_mode": 33188,
      "new_path": "src/gn/ninja_build_writer.cc"
    },
    {
      "type": "modify",
      "old_id": "e77f7401c98df495ef5407a0b00fb58410f2880b",
      "old_mode": 33188,
      "old_path": "src/gn/ninja_build_writer.h",
      "new_id": "54a80aa022acb266afd0d59f3bd1bf08cdecf9d3",
      "new_mode": 33188,
      "new_path": "src/gn/ninja_build_writer.h"
    },
    {
      "type": "modify",
      "old_id": "fab082f2af905e3c4cad6a923634bb724fc6cd88",
      "old_mode": 33188,
      "old_path": "src/gn/ninja_build_writer_unittest.cc",
      "new_id": "453ff039b573846f73ed1037050d52e8181ae9ae",
      "new_mode": 33188,
      "new_path": "src/gn/ninja_build_writer_unittest.cc"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "51130d33273589d486bd855afbc7ace7d06b8fb6",
      "new_mode": 33188,
      "new_path": "src/util/atomic_write.cc"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "232917ac48efc678f40258d3f4e303e43a88fda1",
      "new_mode": 33188,
      "new_path": "src/util/atomic_write.h"
    }
  ]
}
