git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: Corrupt repo with force push when using a reference repo

From
brian m. carlson <sandals@crustytoothpaste.net>
Date
Aug 16, 2023, 01:21 UTC
Message-ID
<ZNwkh47mBJxcSYkm@tapette.crustytoothpaste.net>
In-Reply-To
<MN2PR03MB5072F08C68E7F32C9F5AC866A614A@MN2PR03MB5072.namprd03.prod.outlook.com>
On 2023-08-15 at 04:05:34, Grant Singleton wrote:
Show 32 quoted lines
> Thank you for filling out a Git bug report!
> Please answer the following questions to help us understand your issue.
> 
> What did you do before the bug happened? (Steps to reproduce your issue)
> 
> With 3 clones of a repo, one on branch-a one a mirror,  another using the mirror as a reference repo on branch-b, do the following
> 
> # in the repo on branch-a, make a change, commit and push
> cd bad-object-test
> echo $(( RANDOM % 1000 + 1 )) > file.txt
> git ci -am "change a file"
> git push
> 
> # do a git fetch in the reference repo
> cd ../bad-object-test.git/
> git fetch
> 
> # do a git pull in the repo on branch-b
> cd ../bad-object-test-with-reference-repo/
> git pull
> 
> # All good so far
> 
> # in the repo on branch-a, discard HEAD and force push
> cd ../bad-object-test
> git reset --hard HEAD~1
> git push --force
> 
> # do a git fetch in the reference repo and then prune loose objects
> cd ../bad-object-test.git/
> git fetch
> git prune -v --expire=now

When you clone using --shared or --reference, you implicitly depend on the objects in the referenced repository existing without being pruned for the integrity of the repository.

The manual page for git clone says this:
  NOTE: this is a possibly dangerous operation; do not use it unless you
  understand what it does. If you clone your repository using this
  option and then delete branches (or use any other Git command that
  makes any existing commit unreferenced) in the source repository, some
  objects may become unreferenced (or dangling). These objects may be
  removed by normal Git operations (such as git commit) which
  automatically call git maintenance run --auto. (See
  git‐maintenance(1).) If these objects are removed and were referenced
  by the cloned repository, then the cloned repository will become
  corrupt.

If you want to change the references in any non-fast-forward way or do any sort of GC or pruning in the reference repository, you need to run `git repack -a` in the non-reference repository to repack all of the objects in that repository and dissociate it from the reference repository.

In general, unless you are _very_ sure you know what you're doing, you usually want to use `--dissociate` with `--reference` such that you detach immediately.

-- 
brian m. carlson (he/him or they/them)
Toronto, Ontario, CA
Previous: Grant SingletonNext: U-AP\GSingleton
Message 2 of 3 in “Corrupt repo with force push when using a reference repo”
  1. Grant SingletonAug 15, 2023
  2. brian m. carlsonAug 16, 2023
  3. U-AP\GSingletonAug 22, 2023

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.