Как я могу вычислить хеш дерева git? - PullRequest
0 голосов
/ 05 января 2019

Для проекта nodejs мне нужно определить хеш моей папки, чтобы проверить версию. На самом деле, я сделал скрипт для тестирования моего кода (без файловой системы, непосредственно из git api для моего теста). Но это работает в половине случаев.

  • А1 работает;
  • A2 не работает, потому что Я не получаю тот же хэш ;
  • A3 работает.
  • А4 работает.

Я использовал этот API для получения хеша: https://api.github.com/repos/zestedesavoir/zds-site/branches/dev

Я сделал версию сценария Perl , чтобы проверить мой код js code. Он возвращает те же вещи. Я думаю, что моя ошибка в Object.values(json.tree).forEach(function (blob) шаблон должен быть нехорошим с text += blob.mode + " " + blob.path + "\0" + sha;. Я не знаю почему.

Мой js-скрипт:

(Демонстрационная версия: https://repl.it/repls/FearfulWhiteShelfware)

const crypto = require("crypto"),
      fs = require("fs"),
      path = require("path"),
      getURL = require("./ajax.js").getURL;

const apiJSON = [];
//https://api.github.com/
const hashs = [
  "8d66139b3acf78fa50e16383693a161c33b5e048",
  "4ef57de8e81c8415d6da2b267872e602b1f28cfe",
  "13b54c0bab5e7f7a05398d6d92e65eee2b227136",
  "218a8f506fcd3076fad059ec42d4656c635a8171"
];

let loaded = 0;

const USEAPI = false; /*  becarful low limit on repl.it */

for (let i = 0; i < hashs.length; i++) {
  if (!USEAPI) {
    apiJSON[i] = JSON.parse(fs.readFileSync(`a${i+1}.json`));
    console.log(`A${i+1}:`);
    getTreeSHA(apiJSON[i], false);

    if (i+1 === hashs.length) {
      console.log("\n\nPerl ouput:");
      for (let j = 0; j < hashs.length; j++)
        getTreeSHA(apiJSON[j], true);
    }
  } else {
    getURL("/repos/zestedesavoir/zds-site/git/trees/" + hashs[i], function(json) {
      loaded++; apiJSON[i] = json;
      if (loaded === hashs.length) {
        for (let i = 0; i < hashs.length; i++) {
          console.log(`A${i+1}:`); getTreeSHA(apiJSON[i], false);
        }
        console.log("\n\nPerl ouput:");
        for (let i = 0; i < hashs.length; i++)
          getTreeSHA(apiJSON[i], true);
      }
    });
  }
}

function getTreeSHA(json, getPattern) {
  /*json.tree.sort((a, b) => { ---> not good see A3 & A4
    if (a.type !== b.type)
      if (a.type === "tree")
        return 1;
      else if (b.type === "tree")
        return -1;
    return a.path.charCodeAt(0) - b.path.charCodeAt(0)
  });*/

  let text = "";

  Object.values(json.tree).forEach(function (blob) {
      const sha = Buffer.from(blob.sha, "hex").toString(!getPattern ? "binary" : "hex");
      text += (+blob.mode) + " " + blob.path;
      //       ^ https://stackoverflow.com/a/54137728
      text += (!getPattern) ? ("\0" + sha) : (" " + sha + "\n");
  });

  if (getPattern) return console.log(text.replace(/\0/g, ""));

  console.log("Original " + json.sha);
  const pattern = "tree " + text.length + "\0" + text;
  console.log("Actual : " + sha1(pattern));

  function sha1(data) {
      return crypto.createHash("sha1").update(data, "binary").digest("hex");
  }
}

Выход:

A1:
Original 8d66139b3acf78fa50e16383693a161c33b5e048
Actual : 8d66139b3acf78fa50e16383693a161c33b5e048
A2:
Original 4ef57de8e81c8415d6da2b267872e602b1f28cfe
Actual : c5c701b8114582e3bb2e353aac157a7febfcd33b <-- not god
A3:
Original 13b54c0bab5e7f7a05398d6d92e65eee2b227136
Actual : 13b54c0bab5e7f7a05398d6d92e65eee2b227136
A4:
Original 218a8f506fcd3076fad059ec42d4656c635a8171
Actual : 218a8f506fcd3076fad059ec42d4656c635a8171

Требуется вывод:

//...
A2:
Original 4ef57de8e81c8415d6da2b267872e602b1f28cfe
Actual : 4ef57de8e81c8415d6da2b267872e602b1f28cfe
//...

A2:

{
  "sha": "4ef57de8e81c8415d6da2b267872e602b1f28cfe",
  "url": "https://api.github.com/repos/zestedesavoir/zds-site/git/trees/4ef57de8e81c8415d6da2b267872e602b1f28cfe",
  "tree": [
    {
      "path": ".coveragerc",
      "mode": "100644",
      "type": "blob",
      "sha": "449170d0faeb75182310345564fd1811c0b9fd73",
      "size": 163,
      "url": "https://api.github.com/repos/zestedesavoir/zds-site/git/blobs/449170d0faeb75182310345564fd1811c0b9fd73"
    },
    {
      "path": ".editorconfig",
      "mode": "100644",
      "type": "blob",
      "sha": "75884936ea2d35b531af886acad747d4fd9b2a9e",
      "size": 328,
      "url": "https://api.github.com/repos/zestedesavoir/zds-site/git/blobs/75884936ea2d35b531af886acad747d4fd9b2a9e"
    },
    {
      "path": ".flake8",
      "mode": "100644",
      "type": "blob",
      "sha": "69e872e30d30f5c7de3276d289d6aee81ccf4af7",
      "size": 232,
      "url": "https://api.github.com/repos/zestedesavoir/zds-site/git/blobs/69e872e30d30f5c7de3276d289d6aee81ccf4af7"
    },
    {
      "path": ".github",
      "mode": "040000",
      "type": "tree",
      "sha": "56b49acad224fdb70fca11809f3e5a4d396cb01c",
      "url": "https://api.github.com/repos/zestedesavoir/zds-site/git/trees/56b49acad224fdb70fca11809f3e5a4d396cb01c"
    },
    {
      "path": ".gitignore",
      "mode": "100644",
      "type": "blob",
      "sha": "4832b44b973574253cf1b59ba7a66cfc227cd699",
      "size": 1439,
      "url": "https://api.github.com/repos/zestedesavoir/zds-site/git/blobs/4832b44b973574253cf1b59ba7a66cfc227cd699"
    },
    {
      "path": ".jshintrc",
      "mode": "100644",
      "type": "blob",
      "sha": "939efa02939437adece1e3a076d597b2557e36b5",
      "size": 319,
      "url": "https://api.github.com/repos/zestedesavoir/zds-site/git/blobs/939efa02939437adece1e3a076d597b2557e36b5"
    },
    {
      "path": ".travis.yml",
      "mode": "100644",
      "type": "blob",
      "sha": "6b5e4f43790874e2cf9db23e964f72b99deeb0d1",
      "size": 6040,
      "url": "https://api.github.com/repos/zestedesavoir/zds-site/git/blobs/6b5e4f43790874e2cf9db23e964f72b99deeb0d1"
    },
    {
      "path": "AUTHORS",
      "mode": "100644",
      "type": "blob",
      "sha": "0b92b7759ce2dd0a7cacf79b273368bb71ac5397",
      "size": 197,
      "url": "https://api.github.com/repos/zestedesavoir/zds-site/git/blobs/0b92b7759ce2dd0a7cacf79b273368bb71ac5397"
    },
    {
      "path": "CODE_OF_CONDUCT.md",
      "mode": "100644",
      "type": "blob",
      "sha": "ae61c31efae6cea565e447467e4377da76125679",
      "size": 2754,
      "url": "https://api.github.com/repos/zestedesavoir/zds-site/git/blobs/ae61c31efae6cea565e447467e4377da76125679"
    },
    {
      "path": "CONTRIBUTING.md",
      "mode": "100644",
      "type": "blob",
      "sha": "ac71ad378faf7fb7ae927b20d4d28a57c6085bf9",
      "size": 155,
      "url": "https://api.github.com/repos/zestedesavoir/zds-site/git/blobs/ac71ad378faf7fb7ae927b20d4d28a57c6085bf9"
    },
    {
      "path": "COPYING",
      "mode": "100644",
      "type": "blob",
      "sha": "94a9ed024d3859793618152ea559a168bbcbb5e2",
      "size": 35147,
      "url": "https://api.github.com/repos/zestedesavoir/zds-site/git/blobs/94a9ed024d3859793618152ea559a168bbcbb5e2"
    },
    {
      "path": "Gulpfile.js",
      "mode": "100644",
      "type": "blob",
      "sha": "5dd951ae61f0913605197fafa018f7db49549a68",
      "size": 6137,
      "url": "https://api.github.com/repos/zestedesavoir/zds-site/git/blobs/5dd951ae61f0913605197fafa018f7db49549a68"
    },
    {
      "path": "LICENSE",
      "mode": "100644",
      "type": "blob",
      "sha": "8a171a155d85927b678068becd046194aea777a9",
      "size": 717,
      "url": "https://api.github.com/repos/zestedesavoir/zds-site/git/blobs/8a171a155d85927b678068becd046194aea777a9"
    },
    {
      "path": "Makefile",
      "mode": "100644",
      "type": "blob",
      "sha": "cc722c2bc71dfbaa1b025c8c56245ed0fcd61739",
      "size": 3829,
      "url": "https://api.github.com/repos/zestedesavoir/zds-site/git/blobs/cc722c2bc71dfbaa1b025c8c56245ed0fcd61739"
    },
    {
      "path": "README.md",
      "mode": "100644",
      "type": "blob",
      "sha": "a6a9013159a3766da62443c4be5e267435469fd9",
      "size": 3280,
      "url": "https://api.github.com/repos/zestedesavoir/zds-site/git/blobs/a6a9013159a3766da62443c4be5e267435469fd9"
    },
    {
      "path": "assets",
      "mode": "040000",
      "type": "tree",
      "sha": "1846a32450eb2a7605acb55cab8206028cfb656f",
      "url": "https://api.github.com/repos/zestedesavoir/zds-site/git/trees/1846a32450eb2a7605acb55cab8206028cfb656f"
    },
    {
      "path": "doc",
      "mode": "040000",
      "type": "tree",
      "sha": "f55b804a2b694db577b20c8e9851ad783fea8ee5",
      "url": "https://api.github.com/repos/zestedesavoir/zds-site/git/trees/f55b804a2b694db577b20c8e9851ad783fea8ee5"
    },
    {
      "path": "errors",
      "mode": "040000",
      "type": "tree",
      "sha": "b37a18162be2bdae7382fc194f1bf2d0ab89bba3",
      "url": "https://api.github.com/repos/zestedesavoir/zds-site/git/trees/b37a18162be2bdae7382fc194f1bf2d0ab89bba3"
    },
    {
      "path": "export-assets",
      "mode": "040000",
      "type": "tree",
      "sha": "3a8b85efa969c389ac3c5e7e6ad62206dbddcaca",
      "url": "https://api.github.com/repos/zestedesavoir/zds-site/git/trees/3a8b85efa969c389ac3c5e7e6ad62206dbddcaca"
    },
    {
      "path": "fixtures",
      "mode": "040000",
      "type": "tree",
      "sha": "89cacb4de6feb81a962b9a992b9434cb44d3b0aa",
      "url": "https://api.github.com/repos/zestedesavoir/zds-site/git/trees/89cacb4de6feb81a962b9a992b9434cb44d3b0aa"
    },
    {
      "path": "geodata",
      "mode": "040000",
      "type": "tree",
      "sha": "635d29035ae7528231edb9b74eb09887c22dda2a",
      "url": "https://api.github.com/repos/zestedesavoir/zds-site/git/trees/635d29035ae7528231edb9b74eb09887c22dda2a"
    },
    {
      "path": "manage.py",
      "mode": "100755",
      "type": "blob",
      "sha": "458f6e2df8b431b9fa819c89e82cebf2e0a91260",
      "size": 1536,
      "url": "https://api.github.com/repos/zestedesavoir/zds-site/git/blobs/458f6e2df8b431b9fa819c89e82cebf2e0a91260"
    },
    {
      "path": "package.json",
      "mode": "100644",
      "type": "blob",
      "sha": "02d231aa0c0fa299581be07bcece0393dc9a9e47",
      "size": 1402,
      "url": "https://api.github.com/repos/zestedesavoir/zds-site/git/blobs/02d231aa0c0fa299581be07bcece0393dc9a9e47"
    },
    {
      "path": "quotes.txt",
      "mode": "100644",
      "type": "blob",
      "sha": "e8e84a048d70bc57c1f725fc12f2101a40c5dcbb",
      "size": 1552,
      "url": "https://api.github.com/repos/zestedesavoir/zds-site/git/blobs/e8e84a048d70bc57c1f725fc12f2101a40c5dcbb"
    },
    {
      "path": "requirements-dev.txt",
      "mode": "100644",
      "type": "blob",
      "sha": "7297a894036fcf70a7209062bb51f45db1b71d39",
      "size": 227,
      "url": "https://api.github.com/repos/zestedesavoir/zds-site/git/blobs/7297a894036fcf70a7209062bb51f45db1b71d39"
    },
    {
      "path": "requirements-prod.txt",
      "mode": "100644",
      "type": "blob",
      "sha": "2f957115bcf3794fdecf3c4848f21ae8f428c31b",
      "size": 83,
      "url": "https://api.github.com/repos/zestedesavoir/zds-site/git/blobs/2f957115bcf3794fdecf3c4848f21ae8f428c31b"
    },
    {
      "path": "requirements.txt",
      "mode": "100644",
      "type": "blob",
      "sha": "805fefa566ef0d8f6a7c7e58d01fa4684078cf50",
      "size": 998,
      "url": "https://api.github.com/repos/zestedesavoir/zds-site/git/blobs/805fefa566ef0d8f6a7c7e58d01fa4684078cf50"
    },
    {
      "path": "robots.txt",
      "mode": "100644",
      "type": "blob",
      "sha": "8ca70253a4bb677cb797a7b409df4c4a9c0baa67",
      "size": 948,
      "url": "https://api.github.com/repos/zestedesavoir/zds-site/git/blobs/8ca70253a4bb677cb797a7b409df4c4a9c0baa67"
    },
    {
      "path": "scripts",
      "mode": "040000",
      "type": "tree",
      "sha": "f6a251faaaa14ba4fcf702cd0556675e70cc80f3",
      "url": "https://api.github.com/repos/zestedesavoir/zds-site/git/trees/f6a251faaaa14ba4fcf702cd0556675e70cc80f3"
    },
    {
      "path": "suggestions.txt",
      "mode": "100644",
      "type": "blob",
      "sha": "5e5d11a62a00d3f1aea8f3825c8ec89860d31ad0",
      "size": 285,
      "url": "https://api.github.com/repos/zestedesavoir/zds-site/git/blobs/5e5d11a62a00d3f1aea8f3825c8ec89860d31ad0"
    },
    {
      "path": "templates",
      "mode": "040000",
      "type": "tree",
      "sha": "5b6dde8b8b616ba078305584e23e55ad0c5b2299",
      "url": "https://api.github.com/repos/zestedesavoir/zds-site/git/trees/5b6dde8b8b616ba078305584e23e55ad0c5b2299"
    },
    {
      "path": "update.md",
      "mode": "100644",
      "type": "blob",
      "sha": "734cb67218ac7ad952ffe2f816e4820427efe809",
      "size": 45743,
      "url": "https://api.github.com/repos/zestedesavoir/zds-site/git/blobs/734cb67218ac7ad952ffe2f816e4820427efe809"
    },
    {
      "path": "yarn.lock",
      "mode": "100644",
      "type": "blob",
      "sha": "9fed208fbed286860cb606c9904eb3bab2b3d960",
      "size": 193867,
      "url": "https://api.github.com/repos/zestedesavoir/zds-site/git/blobs/9fed208fbed286860cb606c9904eb3bab2b3d960"
    },
    {
      "path": "zds",
      "mode": "040000",
      "type": "tree",
      "sha": "45b76aa70ad46e116c491a55def4b396b4ecba89",
      "url": "https://api.github.com/repos/zestedesavoir/zds-site/git/trees/45b76aa70ad46e116c491a55def4b396b4ecba89"
    },
    {
      "path": "zmd",
      "mode": "040000",
      "type": "tree",
      "sha": "89289051d5d1e37ecc12629737d4fc01dd0df06e",
      "url": "https://api.github.com/repos/zestedesavoir/zds-site/git/trees/89289051d5d1e37ecc12629737d4fc01dd0df06e"
    }
  ],
  "truncated": false
}

Я сделал версию сценария Perl, чтобы проверить мой код и понять эту проблему.

Perl:

(Демонстрационная версия: https://repl.it/repls/VainPrizeDebugmonitor)

Файлы:

output_a1

100644 arborescence-back.rst 05392dacd107b9e2bb931c85632e115ae69c22cb
100644 featured.rst 20084355452644d3a171b54e9331485e73a897ea
100644 forum.rst 82efe44d491fbc69fb99b0fc0829ad349a11aae7
100644 gallery.rst e075f6d1fe182e595b950cc50d1c5701c6c48bb1
100644 member.rst 157a97545f397f02293a95034989f293cda00ee8
100644 pages.rst 30d85eb8babc8608a87272eb02a73685a71623c3
100644 private-message.rst 6e4872283841ddb0edf03f7535003b4cb5e2f3ce
100644 searchv2.rst a31835f3f39b77408b75548c215d06dcd776d3c2
100644 tutorialv2.rst e646fef1203c7c9b8137c6420d990fd40c1255ae
100644 utils.rst 846765fc32bafc05bb58e6b70883acf5de8ae97b

output_a2

100644 .coveragerc 449170d0faeb75182310345564fd1811c0b9fd73
100644 .editorconfig 75884936ea2d35b531af886acad747d4fd9b2a9e
100644 .flake8 69e872e30d30f5c7de3276d289d6aee81ccf4af7
40000 .github 56b49acad224fdb70fca11809f3e5a4d396cb01c
100644 .gitignore 4832b44b973574253cf1b59ba7a66cfc227cd699
100644 .jshintrc 939efa02939437adece1e3a076d597b2557e36b5
100644 .travis.yml 6b5e4f43790874e2cf9db23e964f72b99deeb0d1
100644 AUTHORS 0b92b7759ce2dd0a7cacf79b273368bb71ac5397
100644 CODE_OF_CONDUCT.md ae61c31efae6cea565e447467e4377da76125679
100644 CONTRIBUTING.md ac71ad378faf7fb7ae927b20d4d28a57c6085bf9
100644 COPYING 94a9ed024d3859793618152ea559a168bbcbb5e2
100644 Gulpfile.js 5dd951ae61f0913605197fafa018f7db49549a68
100644 LICENSE 8a171a155d85927b678068becd046194aea777a9
100644 Makefile cc722c2bc71dfbaa1b025c8c56245ed0fcd61739
100644 README.md a6a9013159a3766da62443c4be5e267435469fd9
40000 assets 1846a32450eb2a7605acb55cab8206028cfb656f
40000 doc f55b804a2b694db577b20c8e9851ad783fea8ee5
40000 errors b37a18162be2bdae7382fc194f1bf2d0ab89bba3
40000 export-assets 3a8b85efa969c389ac3c5e7e6ad62206dbddcaca
40000 fixtures 89cacb4de6feb81a962b9a992b9434cb44d3b0aa
40000 geodata 635d29035ae7528231edb9b74eb09887c22dda2a
100755 manage.py 458f6e2df8b431b9fa819c89e82cebf2e0a91260
100644 package.json 02d231aa0c0fa299581be07bcece0393dc9a9e47
100644 quotes.txt e8e84a048d70bc57c1f725fc12f2101a40c5dcbb
100644 requirements-dev.txt 7297a894036fcf70a7209062bb51f45db1b71d39
100644 requirements-prod.txt 2f957115bcf3794fdecf3c4848f21ae8f428c31b
100644 requirements.txt 805fefa566ef0d8f6a7c7e58d01fa4684078cf50
100644 robots.txt 8ca70253a4bb677cb797a7b409df4c4a9c0baa67
40000 scripts f6a251faaaa14ba4fcf702cd0556675e70cc80f3
100644 suggestions.txt 5e5d11a62a00d3f1aea8f3825c8ec89860d31ad0
40000 templates 5b6dde8b8b616ba078305584e23e55ad0c5b2299
100644 update.md 734cb67218ac7ad952ffe2f816e4820427efe809
100644 yarn.lock 9fed208fbed286860cb606c9904eb3bab2b3d960
40000 zds 45b76aa70ad46e116c491a55def4b396b4ecba89
40000 zmd 89289051d5d1e37ecc12629737d4fc01dd0df06e

output_a3

100644 Makefile fd4542fcb89018c3f97901b26992577590db1fe1
100644 make.bat f17fd5b680fc6dafdba3d1adda49389de4ae0b25
40000 source 7425440b50da313c10be22342f8a0f575ca64196

output_a4

40000 includes 52fe1c1c43130c011e78fc7d488ee5cd2d39fc61
100644 opensearch.xml be2e32c0f7c32a22da4c428438ae6f79965ea4ca
100644 search.html 5618f244fee4945eb799022f7e109ec8cbb2c696

Perl-скрипт:

XX="$(perl -sane '$F[2] =~ s/(..)/\\x$1/g ; print $F[0]." ".$F[1]."\\"."x00".$F[2]' output_a1)"
SIZE=$(echo -en "$XX" | wc -c)

echo "A1:"
echo "original: 8d66139b3acf78fa50e16383693a161c33b5e048"
echo "output :" $(echo -en "tree $SIZE\x00$XX" | sha1sum)

# ...

Вывод:

A1:
original: 8d66139b3acf78fa50e16383693a161c33b5e048
output  : 8d66139b3acf78fa50e16383693a161c33b5e048
A2:
original: 4ef57de8e81c8415d6da2b267872e602b1f28cfe
output  : c5c701b8114582e3bb2e353aac157a7febfcd33b
A3:
original: 13b54c0bab5e7f7a05398d6d92e65eee2b227136
output  : 13b54c0bab5e7f7a05398d6d92e65eee2b227136
A4:
original: 218a8f506fcd3076fad059ec42d4656c635a8171
output  : 218a8f506fcd3076fad059ec42d4656c635a8171

Затем мы видим, что мои JS и Perl Script возвращают одно и то же. Это значит, что моя модель была искажена, я не знаю почему.

1 Ответ

0 голосов
/ 11 января 2019

Ваш код содержит проблему, однако исправление не устраняет расхождение в случае A2.

Проблема с вашим кодом

Официальный алгоритм git для вычисления хэшей на деревьях сбрасывает ведущие нули из поля режима. В ваших примерах это поле содержит значения 100644 и 040000, а последнее записывается в git как 40000.

Доказательство:

$ git cat-file tree 4ef57de8e81c8415d6da2b267872e602b1f28cfe|hexdump -C
00000000  31 30 30 36 34 34 20 2e  63 6f 76 65 72 61 67 65  |100644 .coverage|
00000010  72 63 00 44 91 70 d0 fa  eb 75 18 23 10 34 55 64  |rc.D.p...u.#.4Ud|
00000020  fd 18 11 c0 b9 fd 73 31  30 30 36 34 34 20 2e 65  |......s100644 .e|
00000030  64 69 74 6f 72 63 6f 6e  66 69 67 00 75 88 49 36  |ditorconfig.u.I6|
00000040  ea 2d 35 b5 31 af 88 6a  ca d7 47 d4 fd 9b 2a 9e  |.-5.1..j..G...*.|
00000050  31 30 30 36 34 34 20 2e  66 6c 61 6b 65 38 00 69  |100644 .flake8.i|
00000060  e8 72 e3 0d 30 f5 c7 de  32 76 d2 89 d6 ae e8 1c  |.r..0...2v......|
00000070  cf 4a f7 34 30 30 30 30  20 2e 67 69 74 68 75 62  |.J.40000 .github|
...                                                             ^^^^^
...                                                             !!!!!

Но добавление удаления начальных нулей 1 в сценарий perl по-прежнему не исправляет случай A2 (хотя вычисленный хеш-код меняется, он все равно отличается от ожидаемого):

$ cat main.sh
XX="$(perl -sane '$F[2] =~ s/(..)/\\x$1/g ; $F[0] =~ s/^0+//g ; print $F[0]." ".$F[1]."\\"."x00".$F[2]' output_a1)"
SIZE=$(echo -en "$XX" | wc -c)

echo "original: 8d66139b3acf78fa50e16383693a161c33b5e048 output:"
echo -en "tree $SIZE\x00$XX" | sha1sum

XX="$(perl -sane '$F[2] =~ s/(..)/\\x$1/g ; $F[0] =~ s/^0+//g ; print $F[0]." ".$F[1]."\\"."x00".$F[2]' output_a2)"
SIZE=$(echo -en "$XX" | wc -c)

echo "original: 4ef57de8e81c8415d6da2b267872e602b1f28cfe output:"
echo -en "tree $SIZE\x00$XX" | sha1sum

$ ./main.sh 
original: 8d66139b3acf78fa50e16383693a161c33b5e048 output:
8d66139b3acf78fa50e16383693a161c33b5e048  -
original: 4ef57de8e81c8415d6da2b267872e602b1f28cfe output:
c5c701b8114582e3bb2e353aac157a7febfcd33b  -

Проблема (?) С GitHub API

Объяснение состоит в том, что хэш A2 4ef57de8e81c8415d6da2b267872e602b1f28cfe указывает на объект фиксации, а не на дерево. Этот объект фиксации в свою очередь ссылается на дерево с хешем c5c701b8114582e3bb2e353aac157a7febfcd33b , которое в точности равно значению, вычисленному фиксированным кодом:

$ git cat-file -t 4ef57de8e81c8415d6da2b267872e602b1f28cfe
commit

$ git cat-file -p 4ef57de8e81c8415d6da2b267872e602b1f28cfe
tree c5c701b8114582e3bb2e353aac157a7febfcd33b
parent 502a88b41161ec7dbff0862e3d805db397caf366
...

Если бы вы использовали для запроса A2 дерево, а не хеш коммита ( попробуйте это ), у вас не было бы никаких проблем с самого начала.

Спорная проблема с GitHub API заключается в том, что он молча разрешает хеш коммита в базовое дерево, а не возвращает ошибку или включает в ответ указание того, что произошло (например, путем установки sha поле к хешу дерева, а не к значению запроса).


1 Быстрое и грязное исправление не будет работать правильно в одном случае, когда поле режима состоит только из нулей. В этом случае поле режима будет полностью удалено, а не заменено одним нулем. Однако на практике такой случай невозможен, так как объект с таким значением режима будет просто недоступен для git.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...