3

I converted a few mercurial repos to git using the hg-fast-export tool and while all of them were converted fine, one produced the following error when I pushed the repo.

$ git remote add origin git@github.com:asdf/zxcv.git
$ git push -u origin master
Counting objects: 7840, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (2817/2817), done.
error: object 324f9ca2aaae7b1d716db3fc31c02d391c1c2c16:contains '.git'
fatal: Error in object
error: pack-objects died of signal 13
error: failed to push some refs to 'git@github.com:asdf/zxcv.git'

"contains '.git'" error has very broad terms and couldn't find any documentation so I tried to search for an existing '.git' folder in the original repo and I did. There was a subsubsub-folder that contains an instance of an old git repository which I removed with git rm, however, the problem remained.

Is there anyway I can push this to github or a new clean repo is the only option?

Any help in this appreciated. Thanks!

jimkont
  • 913
  • 1
  • 11
  • 18

2 Answers2

5

You can use the convert command with a filemap to strip the git repo from the repository. After that it will be gone from the history, and the repository will be safe for importing to git.

Example:

$ echo "exclude path/to/.git" > my-filemap
$ hg convert --filemap my-filemap originalrepo newrepo

Note that convert is a bundled extension which you first need to enable in your .hgrc like so:

[extensions]
convert =

For more information see hg help convert.

Laurens Holst
  • 20,156
  • 2
  • 29
  • 33
0

The changesets that you're trying to push contain .git in their history, even if not in the latest changeset, so I would think that you'd need to create a clean repo.

However, an alternative could be to rebase some changesets. Providing what you want to push has changesets from before the extraneous .git was added, and you don't mind losing a little history detail, you could rebase them into one changeset and try pushing that. In theory (!!) the .git directory would be effectively "edited-out" of the history.

Here's an example (note, I don't use git as much as Mercurial, so have no idea if this will work, or if my commands are valid, but it could give you a starting point):

$ git log --oneline  
1234567 More changes
abcdefa made changes
a5b6482 Added .git sub-sub-sub-directory to repo!
dead123 More things

$ git rm sub-sub-sub/.git
$ git commit -m "Removed .git sub-sub-sub-directory"
$ git log --oneline  
beef456 Removed .git sub-sub-sub-directory
1234567 More changes
abcdefa made changes
a5b6482 Added .git sub-sub-sub-directory to repo!
dead123 More things

$ git rebase -i HEAD~4
... at this point you need to interactively specify what to do*
$ git log --oneline  
eeee987 Some new commit message that sums up the changes
dead123 More things

When I tried this, the list of changesets to be "squashed" came up in an editor, which is different to all of the tutorials I have seen - I guess due to the conflict of the added-and-removed files. I modified the commands for three of the four changesets to be "squash" rather than "pick", which instructs the rebase-merge to squash that changeset into its parent. I basically squashed all of the changesets into one. It seems to have worked for me, none of the remaining changesets have the removed files. Whether that will allow you to push or not, I don't know.

Of course, try this on a clone or something first.

icabod
  • 6,992
  • 25
  • 41