Convert shallow repo to normal repo
Asked Answered
S

2

7

I have "shallowed" a repo:

FIRST_COMMIT="bf450342272a94117d78eae34a140a2a39359dad"
git rev-parse ${FIRST_COMMIT} > .git/shallow
git fsck --unreachable
git gc --prune=now

Now I try to push:

! [remote rejected] develop -> develop (shallow update not allowed)

I understand that this limitation is due to the repo being shallow.

How can I convert a shallow repo to a normal repo?

I do not care about losing old history. Actually, I want to lose old history

To clarify this:

  • I want the converted repo to keep the commit history, with metadata (date, author, commit message, ...) of the shallow repo
  • I want to completely lose the old history
  • I do not care about compatibility with the original repo: this is to be considered a new repo
  • I do not care if the commits are recreated, just that the metadata is kept.

EDIT

Simply removing the .git/shallow file does not work:

» git push -f --set-upstream myorigin develop
error: Could not read d18d4a247bebd32a3b57b2c0e5f9c28749083211
fatal: revision walk setup failed
error: remote unpack failed: eof before pack header was fully read
error: failed to push some refs to 'git@somehost:repos/somerepo.git'

EDIT2

Trying to unshallow with fetch:

git fetch --unshallow

Still leaves a grafted repo:

commit bf450342272a94117d78eae34a140a2a39359dad (grafted)
Author: The author
Date:   Thu Nov 29 16:55:05 2018 +0100

    Chages by pre-commit hook (!?)
Siegfried answered 16/1, 2019 at 8:58 Comment(7)
I believe you want git fetch --unshallowLargo
@OwenDelahoy fetch from where? there is no remote to fetch from. The repo is local for the time being. That is, I am trying to push to a new remote, which has no history, and from where I have not cloned. What does fetch mean in that context?Siegfried
Your error says [remote rejected], so presumably there is a remote repo? So where are you trying to push to?Largo
@OwenDelahoy that is the new remote, to which I want to push. Fetching from it makes no sense?Siegfried
@OwenDelahoy tried to fetch, no luckSiegfried
Probably not advised, but you could force your local history to match remote's history you could use git reset --soft develop/master be sure to immediately commit all your files and push all your files. If you need to recover your history you should be able to soft reset again with a commit hash from git reflogLargo
Does this answer your question? How to convert a Git shallow clone to a full clone?Predict
P
9

From "How to convert a Git shallow clone to a full clone":

The below command (git version 1.8.3) will convert the shallow clone to regular one:

git fetch --unshallow

Then, to get access to all the branches on origin (thanks @Peter in the comments)

git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
git fetch origin
Predict answered 7/2, 2020 at 8:23 Comment(0)
S
2

There is already a similar (identical?) question, with a very good answer which also solves my problem.

Basically I need to do the following:

git rev-parse --verify bf450342272a94117d78eae34a140a2a39359dad > .git/info/grafts
git filter-branch -f -- --all 

This will rewrite the history with the specified commit as the new root. Commit metadata will not be affected (date, owner, ...), just the commit hash, and the links between commits, so that the new graph starts from the specified root.

The repo will be then unshallowed / ungrafted, and can be normally pushed to new remotes, with reduced history.

Siegfried answered 16/1, 2019 at 9:18 Comment(4)
I read your question as one about how to "de-shallow-ize" a repo by obtaining the missing history. The method you're describing here "de-shallow-izes" a repo by making the remaining history the true (and only) history, which makes a new and incompatible (but not shallow) repository. These are drastically different since the new repository can never be used with the old clones (well, not without a lot of pain).Seedling
@Seedling it is there in my question, even in bold: "I do not care about losing old history. Actually, I want to lose old history"Siegfried
Yes, but it was not clear to me from the question itself that you understood that this requires copying every commit to a new and different commit with a new and different hash ID. But, given your own answer and this comment series, it's clear that you do want that. I think it's important to point it out for others who don't want that, and may make the same mistake I did in reading your question...Seedling
@Seedling understood. I will clarify the question in this respectSiegfried

© 2022 - 2024 — McMap. All rights reserved.