{"thread":{"id":"61904","subject":"git clone --reference=<repository> (without --dissociate), forgets to copy/get_pack_of objects from <repository> when \"--no-local\"/\"file://\" is present","startedAt":"2024-08-05T21:37:46Z","lastAt":"2024-08-14T04:57:11Z","messageCount":3,"participants":["Han Jiang","Jeff King"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"500125","messageId":"CANrWfmR2sB8abN3tjuavu-sDwuENMh3DPdFKS9fXan_1kYURPA@mail.gmail.com","threadId":"61904","inReplyTo":null,"subject":"git clone --reference=<repository> (without --dissociate), forgets to copy/get_pack_of objects from <repository> when \"--no-local\"/\"file://\" is present","fromName":"Han Jiang","fromEmail":"jhcarl0814@gmail.com","sentAt":"2024-08-05T21:37:33Z","receivedAt":"2024-08-05T21:37:46Z","isPatch":false,"sender":{"key":"jhcarl0814@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5171262?v=4"},"body":"Thank you for filling out a Git bug report!\nPlease answer the following questions to help us understand your issue.\n\nWhat did you do before the bug happened? (Steps to reproduce your issue)\n\n(repo7 and repo8 should behave similar to repo5 and repo6, i.e. setup\n\".git/objects/info/alternates\" && copy/get_pack_of objects;)\n(repo7 and repo8 shouldn't: forget to copy/get_pack_of objects.)\n(The problem only surfaces after \"./client/mirror.git/\" is removed:\nrepo7 and repo8 should have the original objects (so git log shouldn't\ngive error) but they don't have.)\n\ncd '/'; cd '/'; rm --force --recursive -- './test_git'; mkdir \"$_\"; cd \"$_\";\nmkdir --parents -- './server' './client';\n\ngit -C './server' init --bare './repo.git'\ngit --git-dir='./server/repo.git' --work-tree='.' commit --allow-empty\n-m \"$((++number))\"\nfind './server/repo.git/objects' -printf '%p %n\\n'\n\ngit -C './client' clone --shared '../server/repo.git' './repo1'\nfind './server/repo.git/objects' -printf '%p %n\\n'\n\ngit -C './client' clone --shared --local '../server/repo.git' './repo2'\nfind './server/repo.git/objects' -printf '%p %n\\n'\n\ngit -C './client' clone --shared --no-local '../server/repo.git' './repo3'\nfind './server/repo.git/objects' -printf '%p %n\\n'\n\ngit -C './client' clone --shared 'file://'\"$(realpath\n'./server/repo.git')\" './repo4'\nfind './server/repo.git/objects' -printf '%p %n\\n'\n\ncp --recursive --no-target-directory -- './server/repo.git'\n'./client/mirror.git/'\n\ngit -C './client' clone --reference='./mirror.git'\n'../server/repo.git' './repo5'\nfind './server/repo.git/objects' -printf '%p %n\\n'\n\ngit -C './client' clone --reference='./mirror.git' --local\n'../server/repo.git' './repo6'\nfind './server/repo.git/objects' -printf '%p %n\\n'\n\ngit -C './client' clone --reference='./mirror.git' --no-local\n'../server/repo.git' './repo7'\nfind './server/repo.git/objects' -printf '%p %n\\n'\n\ngit -C './client' clone --reference='./mirror.git'\n'file://'\"$(realpath './server/repo.git')\" './repo8'\nfind './server/repo.git/objects' -printf '%p %n\\n'\n\ngit -C './client' clone --reference='./mirror.git' --dissociate\n'../server/repo.git' './repo9'\nfind './server/repo.git/objects' -printf '%p %n\\n'\n\ngit -C './client' clone --reference='./mirror.git' --dissociate\n--local '../server/repo.git' './repo10'\nfind './server/repo.git/objects' -printf '%p %n\\n'\n\ngit -C './client' clone --reference='./mirror.git' --dissociate\n--no-local '../server/repo.git' './repo11'\nfind './server/repo.git/objects' -printf '%p %n\\n'\n\ngit -C './client' clone --reference='./mirror.git' --dissociate\n'file://'\"$(realpath './server/repo.git')\" './repo12'\nfind './server/repo.git/objects' -printf '%p %n\\n'\n\ntree './client/repo1/.git/objects'\ntree './client/repo2/.git/objects'\ntree './client/repo3/.git/objects'\ntree './client/repo4/.git/objects'\ntree './client/repo5/.git/objects'\ntree './client/repo6/.git/objects'\ntree './client/repo7/.git/objects'\ntree './client/repo8/.git/objects'\ntree './client/repo9/.git/objects'\ntree './client/repo10/.git/objects'\ntree './client/repo11/.git/objects'\ntree './client/repo12/.git/objects'\n\ngit -C './client/repo1' log\ngit -C './client/repo2' log\ngit -C './client/repo3' log\ngit -C './client/repo4' log\ngit -C './client/repo5' log\ngit -C './client/repo6' log\ngit -C './client/repo7' log\ngit -C './client/repo8' log\ngit -C './client/repo9' log\ngit -C './client/repo10' log\ngit -C './client/repo11' log\ngit -C './client/repo12' log\n\ngit -C './server/repo.git' cat-file --batch-check --batch-all-objects\ngit --git-dir='./server/repo.git' --work-tree='.' commit --amend\n--allow-empty -m \"$((++number))\"\ngit -C './server/repo.git' cat-file --batch-check --batch-all-objects\ngit -C './server/repo.git' -c 'gc.pruneExpire=now' -c\n'gc.reflogExpireUnreachable=now' gc\ngit -C './server/repo.git' cat-file --batch-check --batch-all-objects\ngit -C './client/repo1' log\ngit -C './client/repo2' log\ngit -C './client/repo3' log\ngit -C './client/repo4' log\ngit -C './client/repo5' log\ngit -C './client/repo6' log\ngit -C './client/repo7' log\ngit -C './client/repo8' log\ngit -C './client/repo9' log\ngit -C './client/repo10' log\ngit -C './client/repo11' log\ngit -C './client/repo12' log\n\nrm --force --recursive -- './client/mirror.git/'\ncp --recursive --no-target-directory -- './server/repo.git'\n'./client/mirror.git/'\ngit -C './client/repo1' log\ngit -C './client/repo2' log\ngit -C './client/repo3' log\ngit -C './client/repo4' log\ngit -C './client/repo5' log\ngit -C './client/repo6' log\ngit -C './client/repo7' log\ngit -C './client/repo8' log\ngit -C './client/repo9' log\ngit -C './client/repo10' log\ngit -C './client/repo11' log\ngit -C './client/repo12' log\n\nrm --force --recursive -- './client/mirror.git/'\ngit -C './client/repo1' log\ngit -C './client/repo2' log\ngit -C './client/repo3' log\ngit -C './client/repo4' log\ngit -C './client/repo5' log\ngit -C './client/repo6' log\ngit -C './client/repo7' log\ngit -C './client/repo8' log\ngit -C './client/repo9' log\ngit -C './client/repo10' log\ngit -C './client/repo11' log\ngit -C './client/repo12' log\n\n\nWhat did you expect to happen? (Expected behavior)\n\nrepo7 and repo8 should behave similar to repo5 and repo6, i.e. setup\n\".git/objects/info/alternates\" && copy/get_pack_of objects;\nrepo7 and repo8 shouldn't: forget to copy/get_pack_of objects.\nThe problem only surfaces after \"./client/mirror.git/\" is removed:\nrepo7 and repo8 should have the original objects (so git log shouldn't\ngive error) but they don't have.\nBTW, --shared (setup \".git/objects/info/alternates\") / --local\n(hard_link) / --no-hardlinks (copy) / --no-local (use the regular Git\ntransport, gives a pack) should be mutually exclusive.\n\nWhat happened instead? (Actual behavior)\n\nWhat's different between what you expected and what actually happened?\n\nAnything else you want to add:\n\nPlease review the rest of the bug report below.\nYou can delete any lines you don't wish to share.\n\n\n[System Info]\ngit version:\ngit version 2.46.0.windows.1\ncpu: x86_64\nbuilt from commit: 2e6a859ffc0471f60f79c1256f766042b0d5d17d\nsizeof-long: 4\nsizeof-size_t: 8\nshell-path: D:/git-sdk-64-build-installers/usr/bin/sh\nfeature: fsmonitor--daemon\nlibcurl: 8.9.0\nOpenSSL: OpenSSL 3.2.2 4 Jun 2024\nzlib: 1.3.1\nuname: Windows 10.0 22631\ncompiler info: gnuc: 14.1\nlibc info: no libc information available\n$SHELL (typically, interactive shell): C:\\Program Files\\Git\\usr\\bin\\bash.exe\n\n\n[Enabled Hooks]\nnot run from a git repository - no hooks to show\n"},{"id":"500778","messageId":"20240813131614.GF968816@coredump.intra.peff.net","threadId":"61904","inReplyTo":"CANrWfmR2sB8abN3tjuavu-sDwuENMh3DPdFKS9fXan_1kYURPA@mail.gmail.com","subject":"Re: git clone --reference=<repository> (without --dissociate), forgets to copy/get_pack_of objects from <repository> when \"--no-local\"/\"file://\" is present","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2024-08-13T13:16:14Z","receivedAt":"2024-08-13T13:16:16Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Tue, Aug 06, 2024 at 09:37:33AM +1200, Han Jiang wrote:\n\n> What did you do before the bug happened? (Steps to reproduce your issue)\n> \n> (repo7 and repo8 should behave similar to repo5 and repo6, i.e. setup\n> \".git/objects/info/alternates\" && copy/get_pack_of objects;)\n> (repo7 and repo8 shouldn't: forget to copy/get_pack_of objects.)\n> (The problem only surfaces after \"./client/mirror.git/\" is removed:\n> repo7 and repo8 should have the original objects (so git log shouldn't\n> give error) but they don't have.)\n\nI don't think this expectation is correct. Using \"--reference\" without\n\"-dissociate\" creates a dependency on the mirror repository. It's not\nsafe to delete it. This is discussed in the \"--shared\" description of\ngit-clone(1), and the \"--reference\" description refers to it.\n\nSo in your example:\n\n> git -C './client' clone --reference='./mirror.git' --no-local '../server/repo.git' './repo7'\n\nI would not expect repo7 to have any objects. Its needs were satisfied\nby the mirror, and when it told the upload-pack process running in\nserver/repo.git what it had, that process knew that it did not need to\nsend any objects.\n\nIt's actually your repo5 and repo6 that are the oddballs:\n\n> git -C './client' clone --reference='./mirror.git' '../server/repo.git' './repo5'\n\nHere since we are cloning a local-file repo, we take a shortcut and do\nnot do any object negotiation at all! Instead, we just take all of the\nobjects from server/repo.git as hardlinks, since doing so is less work\nthan figuring out what we might need.\n\nIt makes us robust to mirror.git being removed (since we ended up with\nduplicates of all of its objects anyway). But it's still not safe in the\nlong run. If the mirror gets new objects, we'd rely on them for\nsubsequent fetches (rather than getting new copies), and the same\ndependency is created.\n\n-Peff\n"},{"id":"500839","messageId":"CANrWfmQw4pG6Dz3kCPqc-P4wLKm_VqyHmb+4MwKgfCUUaN5bzw@mail.gmail.com","threadId":"61904","inReplyTo":"20240813131614.GF968816@coredump.intra.peff.net","subject":"Re: git clone --reference=<repository> (without --dissociate), forgets to copy/get_pack_of objects from <repository> when \"--no-local\"/\"file://\" is present","fromName":"Han Jiang","fromEmail":"jhcarl0814@gmail.com","sentAt":"2024-08-14T04:56:58Z","receivedAt":"2024-08-14T04:57:11Z","isPatch":false,"sender":{"key":"jhcarl0814@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5171262?v=4"},"body":"Thank you for pointing out the error! My commands' use of git is\nincorrect, so the results don't make sense.\nI will post the corrected commands here in case anyone needs them.\n\n1. git clone --reference=<repository>, then the referenced repository\nis updated (e.g. amend/rebase), how to keep up to date:\n\ncd '/'; cd '/'; rm --force --recursive -- './test_git'; mkdir \"$_\"; cd \"$_\";\nmkdir --parents -- './server' './client';\n\ngit -C './server' init --bare './repo.git'\ngit --git-dir='./server/repo.git' --work-tree='.' commit --allow-empty\n-m \"$((++number))\"\nfind './server/repo.git/objects' -printf '%p %n\\n'\n\ngit -C './client' clone --shared '../server/repo.git' './repo1'\nfind './server/repo.git/objects' -printf '%p %n\\n'\n\ngit -C './client' clone --shared --local '../server/repo.git' './repo2'\nfind './server/repo.git/objects' -printf '%p %n\\n'\n\ngit -C './client' clone --shared --no-local '../server/repo.git' './repo3'\nfind './server/repo.git/objects' -printf '%p %n\\n'\n\ngit -C './client' clone --shared 'file://'\"$(realpath\n'./server/repo.git')\" './repo4'\nfind './server/repo.git/objects' -printf '%p %n\\n'\n\ncp --recursive --no-target-directory -- './server/repo.git'\n'./client/mirror.git/'\n\ngit -C './client' clone --reference='./mirror.git'\n'../server/repo.git' './repo5'\nfind './server/repo.git/objects' -printf '%p %n\\n'\n\ngit -C './client' clone --reference='./mirror.git' --local\n'../server/repo.git' './repo6'\nfind './server/repo.git/objects' -printf '%p %n\\n'\n\ngit -C './client' clone --reference='./mirror.git' --no-local\n'../server/repo.git' './repo7'\nfind './server/repo.git/objects' -printf '%p %n\\n'\n\ngit -C './client' clone --reference='./mirror.git'\n'file://'\"$(realpath './server/repo.git')\" './repo8'\nfind './server/repo.git/objects' -printf '%p %n\\n'\n\ngit -C './client' clone --reference='./mirror.git' --dissociate\n'../server/repo.git' './repo9'\nfind './server/repo.git/objects' -printf '%p %n\\n'\n\ngit -C './client' clone --reference='./mirror.git' --dissociate\n--local '../server/repo.git' './repo10'\nfind './server/repo.git/objects' -printf '%p %n\\n'\n\ngit -C './client' clone --reference='./mirror.git' --dissociate\n--no-local '../server/repo.git' './repo11'\nfind './server/repo.git/objects' -printf '%p %n\\n'\n\ngit -C './client' clone --reference='./mirror.git' --dissociate\n'file://'\"$(realpath './server/repo.git')\" './repo12'\nfind './server/repo.git/objects' -printf '%p %n\\n'\n\ntree './client/repo1/.git/objects'\ntree './client/repo2/.git/objects'\ntree './client/repo3/.git/objects'\ntree './client/repo4/.git/objects'\ntree './client/repo5/.git/objects'\ntree './client/repo6/.git/objects'\ntree './client/repo7/.git/objects'\ntree './client/repo8/.git/objects'\ntree './client/repo9/.git/objects'\ntree './client/repo10/.git/objects'\ntree './client/repo11/.git/objects'\ntree './client/repo12/.git/objects'\n\ngit -C './client/repo1' log\ngit -C './client/repo2' log\ngit -C './client/repo3' log\ngit -C './client/repo4' log\ngit -C './client/repo5' log\ngit -C './client/repo6' log\ngit -C './client/repo7' log\ngit -C './client/repo8' log\ngit -C './client/repo9' log\ngit -C './client/repo10' log\ngit -C './client/repo11' log\ngit -C './client/repo12' log\n\ngit -C './server/repo.git' cat-file --batch-check --batch-all-objects\ngit --git-dir='./server/repo.git' --work-tree='.' commit --amend\n--allow-empty -m \"$((++number))\"\ngit -C './server/repo.git' cat-file --batch-check --batch-all-objects\ngit -C './server/repo.git' -c 'gc.pruneExpire=now' -c\n'gc.reflogExpireUnreachable=now' gc\ngit -C './server/repo.git' cat-file --batch-check --batch-all-objects\ngit -C './client/repo1' log\ngit -C './client/repo2' log\ngit -C './client/repo3' log\ngit -C './client/repo4' log\ngit -C './client/repo5' log\ngit -C './client/repo6' log\ngit -C './client/repo7' log\ngit -C './client/repo8' log\ngit -C './client/repo9' log\ngit -C './client/repo10' log\ngit -C './client/repo11' log\ngit -C './client/repo12' log\n\nrm --force --recursive -- './client/mirror.git/'\ncp --recursive --no-target-directory -- './server/repo.git'\n'./client/mirror.git/'\ngit -C './client/repo1' log\ngit -C './client/repo2' log\ngit -C './client/repo3' log\ngit -C './client/repo4' log\ngit -C './client/repo5' log\ngit -C './client/repo6' log\ngit -C './client/repo7' log\ngit -C './client/repo8' log\ngit -C './client/repo9' log\ngit -C './client/repo10' log\ngit -C './client/repo11' log\ngit -C './client/repo12' log\n\ngit -C './client/repo7' branch --all --verbose --verbose\ngit -C './client/repo7' branch --all --verbose\ngit -C './client/repo7' branch --all\ngit -C './client/repo7' update-ref -d 'refs/heads/main'\ngit -C './client/repo7' update-ref -d 'refs/remotes/origin/main'\ngit -C './client/repo7' pull\ngit -C './client/repo7' branch --all --verbose --verbose\ntree './client/repo7/.git/objects'\n\ngit -C './client/repo8' branch --all --verbose --verbose\ngit -C './client/repo8' branch --all --verbose\ngit -C './client/repo8' branch --all\ngit -C './client/repo8' update-ref -d 'refs/heads/main'\ngit -C './client/repo8' update-ref -d 'refs/remotes/origin/main'\ngit -C './client/repo8' pull\ngit -C './client/repo8' branch --all --verbose --verbose\ntree './client/repo8/.git/objects'\n\n2. git clone --reference=<repository>, then the referenced repository\nis removed (e.g. rm), how to switch back to\nnot-referencing-the-repository mode:\n\ncd '/'; cd '/'; rm --force --recursive -- './test_git'; mkdir \"$_\"; cd \"$_\";\nmkdir --parents -- './server' './client';\n\ngit -C './server' init --bare './repo.git'\ngit --git-dir='./server/repo.git' --work-tree='.' commit --allow-empty\n-m \"$((++number))\"\nfind './server/repo.git/objects' -printf '%p %n\\n'\n\ngit -C './client' clone --shared '../server/repo.git' './repo1'\nfind './server/repo.git/objects' -printf '%p %n\\n'\n\ngit -C './client' clone --shared --local '../server/repo.git' './repo2'\nfind './server/repo.git/objects' -printf '%p %n\\n'\n\ngit -C './client' clone --shared --no-local '../server/repo.git' './repo3'\nfind './server/repo.git/objects' -printf '%p %n\\n'\n\ngit -C './client' clone --shared 'file://'\"$(realpath\n'./server/repo.git')\" './repo4'\nfind './server/repo.git/objects' -printf '%p %n\\n'\n\ncp --recursive --no-target-directory -- './server/repo.git'\n'./client/mirror.git/'\n\ngit -C './client' clone --reference='./mirror.git'\n'../server/repo.git' './repo5'\nfind './server/repo.git/objects' -printf '%p %n\\n'\n\ngit -C './client' clone --reference='./mirror.git' --local\n'../server/repo.git' './repo6'\nfind './server/repo.git/objects' -printf '%p %n\\n'\n\ngit -C './client' clone --reference='./mirror.git' --no-local\n'../server/repo.git' './repo7'\nfind './server/repo.git/objects' -printf '%p %n\\n'\n\ngit -C './client' clone --reference='./mirror.git'\n'file://'\"$(realpath './server/repo.git')\" './repo8'\nfind './server/repo.git/objects' -printf '%p %n\\n'\n\ngit -C './client' clone --reference='./mirror.git' --dissociate\n'../server/repo.git' './repo9'\nfind './server/repo.git/objects' -printf '%p %n\\n'\n\ngit -C './client' clone --reference='./mirror.git' --dissociate\n--local '../server/repo.git' './repo10'\nfind './server/repo.git/objects' -printf '%p %n\\n'\n\ngit -C './client' clone --reference='./mirror.git' --dissociate\n--no-local '../server/repo.git' './repo11'\nfind './server/repo.git/objects' -printf '%p %n\\n'\n\ngit -C './client' clone --reference='./mirror.git' --dissociate\n'file://'\"$(realpath './server/repo.git')\" './repo12'\nfind './server/repo.git/objects' -printf '%p %n\\n'\n\ntree './client/repo1/.git/objects'\ntree './client/repo2/.git/objects'\ntree './client/repo3/.git/objects'\ntree './client/repo4/.git/objects'\ntree './client/repo5/.git/objects'\ntree './client/repo6/.git/objects'\ntree './client/repo7/.git/objects'\ntree './client/repo8/.git/objects'\ntree './client/repo9/.git/objects'\ntree './client/repo10/.git/objects'\ntree './client/repo11/.git/objects'\ntree './client/repo12/.git/objects'\n\ngit -C './client/repo1' log\ngit -C './client/repo2' log\ngit -C './client/repo3' log\ngit -C './client/repo4' log\ngit -C './client/repo5' log\ngit -C './client/repo6' log\ngit -C './client/repo7' log\ngit -C './client/repo8' log\ngit -C './client/repo9' log\ngit -C './client/repo10' log\ngit -C './client/repo11' log\ngit -C './client/repo12' log\n\nrm --force --recursive -- './client/mirror.git/'\ngit -C './client/repo1' log\ngit -C './client/repo2' log\ngit -C './client/repo3' log\ngit -C './client/repo4' log\ngit -C './client/repo5' log\ngit -C './client/repo6' log\ngit -C './client/repo7' log\ngit -C './client/repo8' log\ngit -C './client/repo9' log\ngit -C './client/repo10' log\ngit -C './client/repo11' log\ngit -C './client/repo12' log\n\ngit -C './client/repo7' branch --all --verbose --verbose\ngit -C './client/repo7' branch --all --verbose\ngit -C './client/repo7' branch --all\nrm './client/repo7/.git/objects/info/alternates'\ngit -C './client/repo7' branch --all --verbose --verbose\ngit -C './client/repo7' branch --all --verbose\ngit -C './client/repo7' branch --all\ngit -C './client/repo7' update-ref -d 'refs/heads/main'\ngit -C './client/repo7' pull\ngit -C './client/repo7' branch --all --verbose --verbose\ntree './client/repo7/.git/objects'\n\ngit -C './client/repo8' branch --all --verbose --verbose\ngit -C './client/repo8' branch --all --verbose\ngit -C './client/repo8' branch --all\nrm './client/repo8/.git/objects/info/alternates'\ngit -C './client/repo8' branch --all --verbose --verbose\ngit -C './client/repo8' branch --all --verbose\ngit -C './client/repo8' branch --all\ngit -C './client/repo8' update-ref -d 'refs/heads/main'\ngit -C './client/repo8' pull\ngit -C './client/repo8' branch --all --verbose --verbose\ntree './client/repo8/.git/objects'\n\nOn Wed, Aug 14, 2024 at 1:16 AM Jeff King <peff@peff.net> wrote:\n>\n> On Tue, Aug 06, 2024 at 09:37:33AM +1200, Han Jiang wrote:\n>\n> > What did you do before the bug happened? (Steps to reproduce your issue)\n> >\n> > (repo7 and repo8 should behave similar to repo5 and repo6, i.e. setup\n> > \".git/objects/info/alternates\" && copy/get_pack_of objects;)\n> > (repo7 and repo8 shouldn't: forget to copy/get_pack_of objects.)\n> > (The problem only surfaces after \"./client/mirror.git/\" is removed:\n> > repo7 and repo8 should have the original objects (so git log shouldn't\n> > give error) but they don't have.)\n>\n> I don't think this expectation is correct. Using \"--reference\" without\n> \"-dissociate\" creates a dependency on the mirror repository. It's not\n> safe to delete it. This is discussed in the \"--shared\" description of\n> git-clone(1), and the \"--reference\" description refers to it.\n>\n> So in your example:\n>\n> > git -C './client' clone --reference='./mirror.git' --no-local '../server/repo.git' './repo7'\n>\n> I would not expect repo7 to have any objects. Its needs were satisfied\n> by the mirror, and when it told the upload-pack process running in\n> server/repo.git what it had, that process knew that it did not need to\n> send any objects.\n>\n> It's actually your repo5 and repo6 that are the oddballs:\n>\n> > git -C './client' clone --reference='./mirror.git' '../server/repo.git' './repo5'\n>\n> Here since we are cloning a local-file repo, we take a shortcut and do\n> not do any object negotiation at all! Instead, we just take all of the\n> objects from server/repo.git as hardlinks, since doing so is less work\n> than figuring out what we might need.\n>\n> It makes us robust to mirror.git being removed (since we ended up with\n> duplicates of all of its objects anyway). But it's still not safe in the\n> long run. If the mirror gets new objects, we'd rely on them for\n> subsequent fetches (rather than getting new copies), and the same\n> dependency is created.\n>\n> -Peff\n"}]}