{"thread":{"id":"60008","subject":"[QUESTION] how to diff one blob with nothing","startedAt":"2023-07-19T10:00:00Z","lastAt":"2023-08-05T08:27:20Z","messageCount":15,"participants":["ZheNing Hu","Junio C Hamano","Konstantin Khomoutov","Taylor Blau","Christian Couder"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"479630","messageId":"CAOLTT8TVGna+C9nYy9nj3h5bT7AdAT0SKtUM3YVz6h=KZhGHHg@mail.gmail.com","threadId":"60008","inReplyTo":null,"subject":"[QUESTION] how to diff one blob with nothing","fromName":"ZheNing Hu","fromEmail":"adlternative@gmail.com","sentAt":"2023-07-19T09:59:15Z","receivedAt":"2023-07-19T10:00:00Z","isPatch":false,"sender":{"key":"adlternative@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58138461?v=4"},"body":"Hi,\n\nI want to diff two blobs right now, and one of them\nmay be empty, so I tried using\n0000000000000000000000000000000000000000 or\ne69de29bb2d1d6434b8b29ae775ad8c2e48c5391 (empty blobID)\nto test its effect, and the result I found was:\n\ngit diff 00750edc07d6415dcc07ae0351e9397b0222b7ba\n0000000000000000000000000000000000000000\nfatal: bad object 0000000000000000000000000000000000000000\n\ngit diff 00750edc07d6415dcc07ae0351e9397b0222b7ba\ne69de29bb2d1d6434b8b29ae775ad8c2e48c5391\nfatal: bad object e69de29bb2d1d6434b8b29ae775ad8c2e48c5391\n\nSince the \"empty object\" has not been created, the\ngit diff operation fails.\n\nThere may be some other methods [1] available to diff\ntwo blobs by creating an empty blob, but I don't want to\ncreate this empty blob, are there any other ways to solve\nthis problem?\n\n[1]: https://stackoverflow.com/questions/14564034/creating-a-git-diff-from-nothing\n"},{"id":"479639","messageId":"xmqqo7k7c1yw.fsf@gitster.g","threadId":"60008","inReplyTo":"CAOLTT8TVGna+C9nYy9nj3h5bT7AdAT0SKtUM3YVz6h=KZhGHHg@mail.gmail.com","subject":"Re: [QUESTION] how to diff one blob with nothing","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2023-07-19T16:15:03Z","receivedAt":"2023-07-19T16:15:22Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"ZheNing Hu <adlternative@gmail.com> writes:\n\n> I want to diff two blobs right now, and one of them\n> may be empty, so I tried using\n> 0000000000000000000000000000000000000000 or\n> e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 (empty blobID)\n> to test its effect, and the result I found was:\n>\n> git diff 00750edc07d6415dcc07ae0351e9397b0222b7ba\n> 0000000000000000000000000000000000000000\n> fatal: bad object 0000000000000000000000000000000000000000\n\nAs the object name for an empty blob is not all-0, this is expected.\n\n> git diff 00750edc07d6415dcc07ae0351e9397b0222b7ba\n> e69de29bb2d1d6434b8b29ae775ad8c2e48c5391\n> fatal: bad object e69de29bb2d1d6434b8b29ae775ad8c2e48c5391\n>\n> Since the \"empty object\" has not been created, the\n> git diff operation fails.\n\nIf you haven't created one, of course it would fail.  It should help\nto do\n\n    $ git hash-object -w --stdin </dev/null\n\nbefore running\n\n    $ git diff 00750edc e69de29bb\n\nLong time ago, with 346245a1 (hard-code the empty tree object,\n2008-02-13) we taught git what an empty-tree looks like, but it\nseems that we never did the same for an empty blob, perhaps?\n\nInteresting.  I am not sure if it is a good idea to teach empty_blob\nto find_cached_object() and leaning negative but I haven't thought\nthings through on this.\n\n\n\n"},{"id":"479910","messageId":"CAOLTT8R84Zrtpd=j6o2V=Y_uD54XAS5EA7NWHsdfL+XCkD5cqA@mail.gmail.com","threadId":"60008","inReplyTo":"xmqqo7k7c1yw.fsf@gitster.g","subject":"Re: [QUESTION] how to diff one blob with nothing","fromName":"ZheNing Hu","fromEmail":"adlternative@gmail.com","sentAt":"2023-07-26T18:00:17Z","receivedAt":"2023-07-26T18:00:40Z","isPatch":false,"sender":{"key":"adlternative@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58138461?v=4"},"body":"Junio C Hamano <gitster@pobox.com> 于2023年7月20日周四 00:15写道：\n>\n> ZheNing Hu <adlternative@gmail.com> writes:\n>\n> > I want to diff two blobs right now, and one of them\n> > may be empty, so I tried using\n> > 0000000000000000000000000000000000000000 or\n> > e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 (empty blobID)\n> > to test its effect, and the result I found was:\n> >\n> > git diff 00750edc07d6415dcc07ae0351e9397b0222b7ba\n> > 0000000000000000000000000000000000000000\n> > fatal: bad object 0000000000000000000000000000000000000000\n>\n> As the object name for an empty blob is not all-0, this is expected.\n>\n> > git diff 00750edc07d6415dcc07ae0351e9397b0222b7ba\n> > e69de29bb2d1d6434b8b29ae775ad8c2e48c5391\n> > fatal: bad object e69de29bb2d1d6434b8b29ae775ad8c2e48c5391\n> >\n> > Since the \"empty object\" has not been created, the\n> > git diff operation fails.\n>\n> If you haven't created one, of course it would fail.  It should help\n> to do\n>\n>     $ git hash-object -w --stdin </dev/null\n>\n> before running\n>\n>     $ git diff 00750edc e69de29bb\n>\n\nThis is a viable solution, but it's a bit ugly since a read-only \"diff\"\nrequires ”write“ an empty blob.\n\n> Long time ago, with 346245a1 (hard-code the empty tree object,\n> 2008-02-13) we taught git what an empty-tree looks like, but it\n> seems that we never did the same for an empty blob, perhaps?\n>\n\nIt would be great to have that capability.\n\n> Interesting.  I am not sure if it is a good idea to teach empty_blob\n> to find_cached_object() and leaning negative but I haven't thought\n> things through on this.\n>\n\nI currently don't have time to delve into implementation details,\nso I went with the approach that requires writing an empty blob, but\nI'll take a closer look at it later.\n\n>\n>\n\nThanks,\nZheNing Hu\n"},{"id":"479913","messageId":"xmqqila6cz0n.fsf@gitster.g","threadId":"60008","inReplyTo":"CAOLTT8R84Zrtpd=j6o2V=Y_uD54XAS5EA7NWHsdfL+XCkD5cqA@mail.gmail.com","subject":"Re: [QUESTION] how to diff one blob with nothing","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2023-07-26T18:23:52Z","receivedAt":"2023-07-26T18:24:05Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"ZheNing Hu <adlternative@gmail.com> writes:\n\n>> If you haven't created one, of course it would fail.  It should help\n>> to do\n>>\n>>     $ git hash-object -w --stdin </dev/null\n>>\n>> before running\n>>\n>>     $ git diff 00750edc e69de29bb\n>>\n>\n> This is a viable solution, but it's a bit ugly since a read-only \"diff\"\n> requires ”write“ an empty blob.\n\nIf you do not even have an empty blob, you have no business\ncomparing some other blobs you have with it, do you?\n\nIf you do not have a file with a single line \"hello, world\\n\" (that\nhashes to 4b5fa63702dd96796042e92787f464e28f09f17d if written in a\nblob), then you cannot do \"git diff 4b5fa637\" with anything and\nexpect it to work.  It is the same thing.\n\nBesides, if you _know_ you want to compare a blob X to emptyness,\nyou are better of doing \"git cat-file blob X\" in the first place.\n"},{"id":"479930","messageId":"20230727171334.6qg2xtecvmplg3or@carbon","threadId":"60008","inReplyTo":"CAOLTT8R84Zrtpd=j6o2V=Y_uD54XAS5EA7NWHsdfL+XCkD5cqA@mail.gmail.com","subject":"Re: [QUESTION] how to diff one blob with nothing","fromName":"Konstantin Khomoutov","fromEmail":"kostix@bswap.ru","sentAt":"2023-07-27T17:13:34Z","receivedAt":"2023-07-27T17:14:24Z","isPatch":false,"sender":{"key":"kostix@bswap.ru","avatar":null},"body":">> If you haven't created one, of course it would fail.  It should help\n>> to do\n>>\n>>     $ git hash-object -w --stdin </dev/null\n>>\n>> before running\n>>\n>>     $ git diff 00750edc e69de29bb\n>>\n>\n> This is a viable solution, but it's a bit ugly since a read-only \"diff\"\n> requires ”write“ an empty blob.\n\nYou could probably just do\n\n  git cat-file -s e69de29bb\n\nto figure out whether a blob is empty.\n\nWhat is your end goal? Do you indeed want to produce a \"trivial patch\" which\nmerely \"adds\" all the lines of the blob you'd like to compare to an empty one\n(assuming the blob conains text)?\n\n"},{"id":"479932","messageId":"ZMKtcaN7xYaTtkcI@nand.local","threadId":"60008","inReplyTo":"xmqqila6cz0n.fsf@gitster.g","subject":"Re: [QUESTION] how to diff one blob with nothing","fromName":"Taylor Blau","fromEmail":"me@ttaylorr.com","sentAt":"2023-07-27T17:46:25Z","receivedAt":"2023-07-27T17:46:34Z","isPatch":false,"sender":{"key":"me@ttaylorr.com","avatar":"https://avatars.githubusercontent.com/u/301000140?v=4"},"body":"On Wed, Jul 26, 2023 at 11:23:52AM -0700, Junio C Hamano wrote:\n> ZheNing Hu <adlternative@gmail.com> writes:\n>\n> >> If you haven't created one, of course it would fail.  It should help\n> >> to do\n> >>\n> >>     $ git hash-object -w --stdin </dev/null\n> >>\n> >> before running\n> >>\n> >>     $ git diff 00750edc e69de29bb\n> >>\n> >\n> > This is a viable solution, but it's a bit ugly since a read-only \"diff\"\n> > requires ”write“ an empty blob.\n>\n> If you do not even have an empty blob, you have no business\n> comparing some other blobs you have with it, do you?\n>\n> If you do not have a file with a single line \"hello, world\\n\" (that\n> hashes to 4b5fa63702dd96796042e92787f464e28f09f17d if written in a\n> blob), then you cannot do \"git diff 4b5fa637\" with anything and\n> expect it to work.  It is the same thing.\n>\n> Besides, if you _know_ you want to compare a blob X to emptyness,\n> you are better of doing \"git cat-file blob X\" in the first place.\n\nYeah, exactly. In 346245a1bb6 (hard-code the empty tree object,\n2008-02-13), the rationale was partly that having the empty tree object\nis useful for showing some diffs, such as for the initial commit.\n\nBut I can't think of a similar argument for the empty blob. Like Junio\nsaid, if you're purposefully diff-ing against the empty blob, wouldn't\nyou simply want the entire contents anyway? If that's the case, cat-file\nseems like a much more appropriate tool.\n\nThanks,\nTaylor\n"},{"id":"479954","messageId":"CAOLTT8TOs2eTryXWTy5aZ8BGNAymgjrsg1BCLbigFunkFpc7JQ@mail.gmail.com","threadId":"60008","inReplyTo":"20230727171334.6qg2xtecvmplg3or@carbon","subject":"Re: [QUESTION] how to diff one blob with nothing","fromName":"ZheNing Hu","fromEmail":"adlternative@gmail.com","sentAt":"2023-07-28T03:35:28Z","receivedAt":"2023-07-28T03:35:59Z","isPatch":false,"sender":{"key":"adlternative@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58138461?v=4"},"body":"Konstantin Khomoutov <kostix@bswap.ru> 于2023年7月28日周五 01:13写道：\n>\n> >> If you haven't created one, of course it would fail.  It should help\n> >> to do\n> >>\n> >>     $ git hash-object -w --stdin </dev/null\n> >>\n> >> before running\n> >>\n> >>     $ git diff 00750edc e69de29bb\n> >>\n> >\n> > This is a viable solution, but it's a bit ugly since a read-only \"diff\"\n> > requires ”write“ an empty blob.\n>\n> You could probably just do\n>\n>   git cat-file -s e69de29bb\n>\n> to figure out whether a blob is empty.\n>\n> What is your end goal? Do you indeed want to produce a \"trivial patch\" which\n> merely \"adds\" all the lines of the blob you'd like to compare to an empty one\n> (assuming the blob conains text)?\n>\n\nYes, I need to compare the diff between multiple versions of blobs in real time\n(only given the blobID). Once a file is deleted or created, I have to\nperform this\ncomparison with the \"empty blob\".\n"},{"id":"479955","messageId":"CAOLTT8Ru+3efmUNMOwbhzwRu-FW-SVPYn88-xtrRQiRuweFG+Q@mail.gmail.com","threadId":"60008","inReplyTo":"ZMKtcaN7xYaTtkcI@nand.local","subject":"Re: [QUESTION] how to diff one blob with nothing","fromName":"ZheNing Hu","fromEmail":"adlternative@gmail.com","sentAt":"2023-07-28T03:40:58Z","receivedAt":"2023-07-28T03:41:22Z","isPatch":false,"sender":{"key":"adlternative@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58138461?v=4"},"body":"Taylor Blau <me@ttaylorr.com> 于2023年7月28日周五 01:46写道：\n>\n> On Wed, Jul 26, 2023 at 11:23:52AM -0700, Junio C Hamano wrote:\n> > ZheNing Hu <adlternative@gmail.com> writes:\n> >\n> > >> If you haven't created one, of course it would fail.  It should help\n> > >> to do\n> > >>\n> > >>     $ git hash-object -w --stdin </dev/null\n> > >>\n> > >> before running\n> > >>\n> > >>     $ git diff 00750edc e69de29bb\n> > >>\n> > >\n> > > This is a viable solution, but it's a bit ugly since a read-only \"diff\"\n> > > requires ”write“ an empty blob.\n> >\n> > If you do not even have an empty blob, you have no business\n> > comparing some other blobs you have with it, do you?\n> >\n> > If you do not have a file with a single line \"hello, world\\n\" (that\n> > hashes to 4b5fa63702dd96796042e92787f464e28f09f17d if written in a\n> > blob), then you cannot do \"git diff 4b5fa637\" with anything and\n> > expect it to work.  It is the same thing.\n> >\n> > Besides, if you _know_ you want to compare a blob X to emptyness,\n> > you are better of doing \"git cat-file blob X\" in the first place.\n>\n> Yeah, exactly. In 346245a1bb6 (hard-code the empty tree object,\n> 2008-02-13), the rationale was partly that having the empty tree object\n> is useful for showing some diffs, such as for the initial commit.\n>\n> But I can't think of a similar argument for the empty blob. Like Junio\n> said, if you're purposefully diff-ing against the empty blob, wouldn't\n> you simply want the entire contents anyway? If that's the case, cat-file\n> seems like a much more appropriate tool.\n>\n\nHere, it is necessary to compare multiple versions of blobs while also\nconsidering the situations of creation and deletion.\n\nWell, what I need is the \"diff\" content, with lines in the diff indicating\n'+' or '-' signs. This can be achieved by manually adding them, but it is\nnot very compatible with the original logic.\n\n> Thanks,\n> Taylor\n"},{"id":"480112","messageId":"CAOLTT8S=_1Vd2Y4rBqq03JsJ1megRBcx9v-HYAWXe88jDek98Q@mail.gmail.com","threadId":"60008","inReplyTo":"CAOLTT8Ru+3efmUNMOwbhzwRu-FW-SVPYn88-xtrRQiRuweFG+Q@mail.gmail.com","subject":"Re: [QUESTION] how to diff one blob with nothing","fromName":"ZheNing Hu","fromEmail":"adlternative@gmail.com","sentAt":"2023-08-03T05:16:02Z","receivedAt":"2023-08-03T05:17:52Z","isPatch":false,"sender":{"key":"adlternative@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58138461?v=4"},"body":"ZheNing Hu <adlternative@gmail.com> 于2023年7月28日周五 11:40写道：\n>\n> Taylor Blau <me@ttaylorr.com> 于2023年7月28日周五 01:46写道：\n> >\n> > On Wed, Jul 26, 2023 at 11:23:52AM -0700, Junio C Hamano wrote:\n> > > ZheNing Hu <adlternative@gmail.com> writes:\n> > >\n> > > >> If you haven't created one, of course it would fail.  It should help\n> > > >> to do\n> > > >>\n> > > >>     $ git hash-object -w --stdin </dev/null\n> > > >>\n> > > >> before running\n> > > >>\n> > > >>     $ git diff 00750edc e69de29bb\n> > > >>\n> > > >\n> > > > This is a viable solution, but it's a bit ugly since a read-only \"diff\"\n> > > > requires ”write“ an empty blob.\n> > >\n> > > If you do not even have an empty blob, you have no business\n> > > comparing some other blobs you have with it, do you?\n> > >\n> > > If you do not have a file with a single line \"hello, world\\n\" (that\n> > > hashes to 4b5fa63702dd96796042e92787f464e28f09f17d if written in a\n> > > blob), then you cannot do \"git diff 4b5fa637\" with anything and\n> > > expect it to work.  It is the same thing.\n> > >\n> > > Besides, if you _know_ you want to compare a blob X to emptyness,\n> > > you are better of doing \"git cat-file blob X\" in the first place.\n> >\n> > Yeah, exactly. In 346245a1bb6 (hard-code the empty tree object,\n> > 2008-02-13), the rationale was partly that having the empty tree object\n> > is useful for showing some diffs, such as for the initial commit.\n> >\n> > But I can't think of a similar argument for the empty blob. Like Junio\n> > said, if you're purposefully diff-ing against the empty blob, wouldn't\n> > you simply want the entire contents anyway? If that's the case, cat-file\n> > seems like a much more appropriate tool.\n> >\n>\n> Here, it is necessary to compare multiple versions of blobs while also\n> considering the situations of creation and deletion.\n>\n> Well, what I need is the \"diff\" content, with lines in the diff indicating\n> '+' or '-' signs. This can be achieved by manually adding them, but it is\n> not very compatible with the original logic.\n>\n\nThe native diff command itself supports comparison with an empty file.\n\n#diff -u  /dev/null a\n--- /dev/null 2023-07-25 16:47:50.270094301 +0800\n+++ a 2023-08-03 13:14:16.980262362 +0800\n@@ -0,0 +1 @@\n+a\n\nSo I believe this feature would also be useful in git.\n\n> > Thanks,\n> > Taylor\n"},{"id":"480123","messageId":"ZMvGsYSystLu6oBY@nand.local","threadId":"60008","inReplyTo":"CAOLTT8S=_1Vd2Y4rBqq03JsJ1megRBcx9v-HYAWXe88jDek98Q@mail.gmail.com","subject":"Re: [QUESTION] how to diff one blob with nothing","fromName":"Taylor Blau","fromEmail":"me@ttaylorr.com","sentAt":"2023-08-03T15:24:33Z","receivedAt":"2023-08-03T15:24:39Z","isPatch":false,"sender":{"key":"me@ttaylorr.com","avatar":"https://avatars.githubusercontent.com/u/301000140?v=4"},"body":"On Thu, Aug 03, 2023 at 01:16:02PM +0800, ZheNing Hu wrote:\n> > Here, it is necessary to compare multiple versions of blobs while also\n> > considering the situations of creation and deletion.\n> >\n> > Well, what I need is the \"diff\" content, with lines in the diff indicating\n> > '+' or '-' signs. This can be achieved by manually adding them, but it is\n> > not very compatible with the original logic.\n>\n> The native diff command itself supports comparison with an empty file.\n>\n> #diff -u  /dev/null a\n> --- /dev/null 2023-07-25 16:47:50.270094301 +0800\n> +++ a 2023-08-03 13:14:16.980262362 +0800\n> @@ -0,0 +1 @@\n> +a\n>\n> So I believe this feature would also be useful in git.\n\nSure, you can easily diff any file against any other, including if\neither one or both are empty. I think the main difference here is that\n/dev/null exists on your system without additional configuration and\nthe empty blob does not exist in a Git repository without additional\nconfiguration (in this case, `git hash-object -w -t blob --stdin\n</dev/null`).\n\nTBH, I don't know if /dev/null existing by default is necessarily a\nsolid argument in favor of having Git repositories come initialized with\nthe empty blob by default.\n\n(To be clear, when I say \"initialized\", I mean that a Git repository\nwould recognize the empty blob object's hash for any value of\n`the_hash_algo`, not that every repository would be prepared with a\nloose object by default.)\n\nThanks,\nTaylor\n"},{"id":"480140","messageId":"CAOLTT8Tc9NevyUfwiPscEH7BqShSscb=iZP4r+7mjsEwouLeXg@mail.gmail.com","threadId":"60008","inReplyTo":"ZMvGsYSystLu6oBY@nand.local","subject":"Re: [QUESTION] how to diff one blob with nothing","fromName":"ZheNing Hu","fromEmail":"adlternative@gmail.com","sentAt":"2023-08-04T02:28:25Z","receivedAt":"2023-08-04T02:28:43Z","isPatch":false,"sender":{"key":"adlternative@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58138461?v=4"},"body":"Taylor Blau <me@ttaylorr.com> 于2023年8月3日周四 23:24写道：\n>\n> On Thu, Aug 03, 2023 at 01:16:02PM +0800, ZheNing Hu wrote:\n> > > Here, it is necessary to compare multiple versions of blobs while also\n> > > considering the situations of creation and deletion.\n> > >\n> > > Well, what I need is the \"diff\" content, with lines in the diff indicating\n> > > '+' or '-' signs. This can be achieved by manually adding them, but it is\n> > > not very compatible with the original logic.\n> >\n> > The native diff command itself supports comparison with an empty file.\n> >\n> > #diff -u  /dev/null a\n> > --- /dev/null 2023-07-25 16:47:50.270094301 +0800\n> > +++ a 2023-08-03 13:14:16.980262362 +0800\n> > @@ -0,0 +1 @@\n> > +a\n> >\n> > So I believe this feature would also be useful in git.\n>\n> Sure, you can easily diff any file against any other, including if\n> either one or both are empty. I think the main difference here is that\n> /dev/null exists on your system without additional configuration and\n> the empty blob does not exist in a Git repository without additional\n> configuration (in this case, `git hash-object -w -t blob --stdin\n> </dev/null`).\n>\n> TBH, I don't know if /dev/null existing by default is necessarily a\n> solid argument in favor of having Git repositories come initialized with\n> the empty blob by default.\n>\n> (To be clear, when I say \"initialized\", I mean that a Git repository\n> would recognize the empty blob object's hash for any value of\n> `the_hash_algo`, not that every repository would be prepared with a\n> loose object by default.)\n>\n\nActually, there is no need to support a default empty blob.\nFor example, with the command \"git diff --no-index <file> /dev/null\",\nit can compare a file with /dev/null, but it can only compare <file>\nand not <oid>.\nTherefore, using commands like \"git diff <oid> /dev/null\",\n\"git diff --no-index <oid> /dev/null\", or even \"git diff <oid> --stdin\"\ncould potentially solve this issue.\n\nThanks,\nZheNing Hu\n"},{"id":"480151","messageId":"CAP8UFD2GV+1LhZDrSsgQ5=gRgYSTYsS36i2ugoBEHu-Oto-Sow@mail.gmail.com","threadId":"60008","inReplyTo":"CAOLTT8Tc9NevyUfwiPscEH7BqShSscb=iZP4r+7mjsEwouLeXg@mail.gmail.com","subject":"Re: [QUESTION] how to diff one blob with nothing","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2023-08-04T08:28:53Z","receivedAt":"2023-08-04T08:29:48Z","isPatch":false,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"On Fri, Aug 4, 2023 at 6:42 AM ZheNing Hu <adlternative@gmail.com> wrote:\n\n> Actually, there is no need to support a default empty blob.\n> For example, with the command \"git diff --no-index <file> /dev/null\",\n> it can compare a file with /dev/null, but it can only compare <file>\n> and not <oid>.\n> Therefore, using commands like \"git diff <oid> /dev/null\",\n> \"git diff --no-index <oid> /dev/null\", or even \"git diff <oid> --stdin\"\n> could potentially solve this issue.\n\nMaybe it would be clearer to have a new option, called for example\n\"--blob-vs-file\", for that then. It could support both:\n\n$ git diff --blob-vs-file <blob> <file>\n\nand:\n\n$ git diff --blob-vs-file <file> <blob>\n"},{"id":"480164","messageId":"ZM1EvGVGv2ZYrpuT@nand.local","threadId":"60008","inReplyTo":"CAP8UFD2GV+1LhZDrSsgQ5=gRgYSTYsS36i2ugoBEHu-Oto-Sow@mail.gmail.com","subject":"Re: [QUESTION] how to diff one blob with nothing","fromName":"Taylor Blau","fromEmail":"me@ttaylorr.com","sentAt":"2023-08-04T18:34:36Z","receivedAt":"2023-08-04T18:36:14Z","isPatch":false,"sender":{"key":"me@ttaylorr.com","avatar":"https://avatars.githubusercontent.com/u/301000140?v=4"},"body":"On Fri, Aug 04, 2023 at 10:28:53AM +0200, Christian Couder wrote:\n> On Fri, Aug 4, 2023 at 6:42 AM ZheNing Hu <adlternative@gmail.com> wrote:\n>\n> > Actually, there is no need to support a default empty blob.\n> > For example, with the command \"git diff --no-index <file> /dev/null\",\n> > it can compare a file with /dev/null, but it can only compare <file>\n> > and not <oid>.\n> > Therefore, using commands like \"git diff <oid> /dev/null\",\n> > \"git diff --no-index <oid> /dev/null\", or even \"git diff <oid> --stdin\"\n> > could potentially solve this issue.\n>\n> Maybe it would be clearer to have a new option, called for example\n> \"--blob-vs-file\", for that then. It could support both:\n>\n> $ git diff --blob-vs-file <blob> <file>\n>\n> and:\n>\n> $ git diff --blob-vs-file <file> <blob>\n\nHmm. This feels like a case of trying to teach 'git diff' to do too\nmuch.\n\nThanks,\nTaylor\n"},{"id":"480165","messageId":"xmqqmsz6ljk4.fsf@gitster.g","threadId":"60008","inReplyTo":"ZM1EvGVGv2ZYrpuT@nand.local","subject":"Re: [QUESTION] how to diff one blob with nothing","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2023-08-04T19:00:11Z","receivedAt":"2023-08-04T19:00:22Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Taylor Blau <me@ttaylorr.com> writes:\n\n> On Fri, Aug 04, 2023 at 10:28:53AM +0200, Christian Couder wrote:\n>> On Fri, Aug 4, 2023 at 6:42 AM ZheNing Hu <adlternative@gmail.com> wrote:\n>>\n>> > Actually, there is no need to support a default empty blob.\n>> > For example, with the command \"git diff --no-index <file> /dev/null\",\n>> > it can compare a file with /dev/null, but it can only compare <file>\n>> > and not <oid>.\n>> > Therefore, using commands like \"git diff <oid> /dev/null\",\n>> > \"git diff --no-index <oid> /dev/null\", or even \"git diff <oid> --stdin\"\n>> > could potentially solve this issue.\n>>\n>> Maybe it would be clearer to have a new option, called for example\n>> \"--blob-vs-file\", for that then. It could support both:\n>>\n>> $ git diff --blob-vs-file <blob> <file>\n>>\n>> and:\n>>\n>> $ git diff --blob-vs-file <file> <blob>\n>\n> Hmm. This feels like a case of trying to teach 'git diff' to do too\n> much.\n\nWorse yet, I do not quite get the original use case in the first\nplace.  What is the series of diff output that result in comparing a\nrandom pair of blob object names going to be used for?\n\nThe reply to <ZMKtcaN7xYaTtkcI@nand.local> says that the original\nuse case was to express the evolution of a single path since its\ncreation until its removal, but the thing is, a diff with an empty\nblob and a creation or a deletion event are expressed differently in\nthe patch output, exactly because the patch has to be able to\nexpress \"before this change, a file with zero byte content was\nthere\" and \"before this change, there was nothing at this path\"\n(vice versa for contents-removal vs deletion).\n\nFor that reason, I have a hard time to find any merit in the earlier\ncomplaint that said \"can be achieved by manually adding them, but it\nis not very compatible with the original logic\", whatever the\n\"original logic\" refers to.  If creation needs to be recorded as\ncreation and not as a change from an empty and existing blob, there\nhas to be something that needs to be manually done to turn the\nlatter (which is the only thing \"diff\" between two blobs or even a\nblob and a file can give) into the former *anyway*.  Whatever the\nthing that is looping over the history/evoluation of a single path\nneeds to have a three-arm switch for each iteration to deal with\ncreation, modification, and removal, and iterating over the contents\nof the files and prefixing \"+\" or \"-\" on each and every line would\nbe the _easiest_ part of such a necessary tweak to turn \"diff\nbetween an empty contents and something else\" into \"creation or\ndeletion of a file.\"\n\n"},{"id":"480184","messageId":"CAOLTT8SBAb8bAV3uCPJ-q2btNeatMjmtRzDkRASffN5xTS1M0g@mail.gmail.com","threadId":"60008","inReplyTo":"xmqqmsz6ljk4.fsf@gitster.g","subject":"Re: [QUESTION] how to diff one blob with nothing","fromName":"ZheNing Hu","fromEmail":"adlternative@gmail.com","sentAt":"2023-08-05T08:27:06Z","receivedAt":"2023-08-05T08:27:20Z","isPatch":false,"sender":{"key":"adlternative@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58138461?v=4"},"body":"Junio C Hamano <gitster@pobox.com> 于2023年8月5日周六 03:00写道：\n>\n> Taylor Blau <me@ttaylorr.com> writes:\n>\n> > On Fri, Aug 04, 2023 at 10:28:53AM +0200, Christian Couder wrote:\n> >> On Fri, Aug 4, 2023 at 6:42 AM ZheNing Hu <adlternative@gmail.com> wrote:\n> >>\n> >> > Actually, there is no need to support a default empty blob.\n> >> > For example, with the command \"git diff --no-index <file> /dev/null\",\n> >> > it can compare a file with /dev/null, but it can only compare <file>\n> >> > and not <oid>.\n> >> > Therefore, using commands like \"git diff <oid> /dev/null\",\n> >> > \"git diff --no-index <oid> /dev/null\", or even \"git diff <oid> --stdin\"\n> >> > could potentially solve this issue.\n> >>\n> >> Maybe it would be clearer to have a new option, called for example\n> >> \"--blob-vs-file\", for that then. It could support both:\n> >>\n> >> $ git diff --blob-vs-file <blob> <file>\n> >>\n> >> and:\n> >>\n> >> $ git diff --blob-vs-file <file> <blob>\n> >\n> > Hmm. This feels like a case of trying to teach 'git diff' to do too\n> > much.\n>\n> Worse yet, I do not quite get the original use case in the first\n> place.  What is the series of diff output that result in comparing a\n> random pair of blob object names going to be used for?\n>\n> The reply to <ZMKtcaN7xYaTtkcI@nand.local> says that the original\n> use case was to express the evolution of a single path since its\n> creation until its removal, but the thing is, a diff with an empty\n> blob and a creation or a deletion event are expressed differently in\n> the patch output, exactly because the patch has to be able to\n> express \"before this change, a file with zero byte content was\n> there\" and \"before this change, there was nothing at this path\"\n> (vice versa for contents-removal vs deletion).\n>\n> For that reason, I have a hard time to find any merit in the earlier\n> complaint that said \"can be achieved by manually adding them, but it\n> is not very compatible with the original logic\", whatever the\n> \"original logic\" refers to.  If creation needs to be recorded as\n> creation and not as a change from an empty and existing blob, there\n> has to be something that needs to be manually done to turn the\n> latter (which is the only thing \"diff\" between two blobs or even a\n> blob and a file can give) into the former *anyway*.  Whatever the\n> thing that is looping over the history/evoluation of a single path\n> needs to have a three-arm switch for each iteration to deal with\n> creation, modification, and removal, and iterating over the contents\n> of the files and prefixing \"+\" or \"-\" on each and every line would\n> be the _easiest_ part of such a necessary tweak to turn \"diff\n> between an empty contents and something else\" into \"creation or\n> deletion of a file.\"\n>\n\nOkay, let me clarify the background for using an empty blob diff.\nEssentially, it is a git web diff interface that requires real-time calculation\nof the diff between files across multiple versions and rendering them.\nDue to some reasons, the higher-level component did not provide multiple\nversions of commits but instead provided blob OIDs (Object IDs).\n\nTherefore, I expected to generate the diff results directly using the\n\"git diff <oid> <oid>\" command. (I only care about the patch part\nin the diff and don't really care about the related information of OIDs\nin the diff output.) Everything went smoothly except when a blob\nis created or deleted, as there is no direct way to obtain\nthe diff for a blob using the \"git diff <oid> <oid>\" interface. Initially,\nI intended to generate a patch by diffing an empty blob\n (e69de29bb2d1d6434b8b29ae775ad8c2e48c5391) with the blob ID.\nHowever, unlike the empty tree (4b825dc642cb6eb9a060e54bf8d69288fbee4904),\nthe empty blob does not exist in the git repository by default.\n\nI had to create an additional empty blob for the purpose of performing\nthe diff, but this goes against the design of the web-based diff interface,\nwhich is intended to be read-only.\n\nSo, I might explore methods like \"git diff <oid> /dev/null\" or\n \"git diff <oid> --stdin\", they are read only, but it does not\ncurrently exist...\n\nRegardless, I hope that the empty blob diff can simulate the effect of\nan empty tree diff:\n\ngit diff 4b825dc642cb6eb9a060e54bf8d69288fbee4904\n\ndiff --git a/.cirrus.yml b/.cirrus.yml\nnew file mode 100644\nindex 0000000000..4860bebd32\n--- /dev/null\n+++ b/.cirrus.yml\n@@ -0,0 +1,22 @@\n+env:\n+  CIRRUS_CLONE_DEPTH: 1\n+\n+freebsd_12_task:\n+  env:\n+    GIT_PROVE_OPTS: \"--timer --jobs 10\"\n+    GIT_TEST_OPTS: \"--no-chain-lint --no-bin-wrappers\"\n+    MAKEFLAGS: \"-j4\"\n+    DEFAULT_TEST_TARGET: prove\n+    DEVELOPER: 1\n+  freebsd_instance:\n+    image_family: freebsd-12-3\n+    memory: 2G\n+  install_script:\n+    pkg install -y gettext gmake perl5\n+  create_user_script:\n+    - pw useradd git\n+    - chown -R git:git .\n+  build_script:\n+    - su git -c gmake\n+  test_script:\n+    - su git -c 'gmake test'\n\nThanks,\nZheNing Hu\n"}]}