0

I have a plain copy backup of a .git directory. I don't have the actual files outside of the .git directory in the backup (git status shows that all files would be deleted on commit), only the actual .git directory.

When I do git checkout master, I get about half of the files that should be there. I was under the impression that this should recreate all the project files.

Does this mean that somewhere in the git history there is an error? Some files changes clearly couldn't resolve all the way to a complete file. If I get a backup from the complete project including the files, how can I 'fix' my history to make sure it contains everything?

I'm not a git-pro, but the backup, unpacked to an empty directory, is currently sitting in a feature branch. So according to git status, a million files would be deleted if I would do git commit. I reckoned doing git checkout master would give me all the files in the latest master commit in the empty directory.

Zoe
  • 27,060
  • 21
  • 118
  • 148
Redsandro
  • 11,060
  • 13
  • 76
  • 106
  • 1
    Are you certain that the half that are missing are actually in the repository? And what do you mean by your first sentence? – sma Sep 22 '14 at 13:44
  • What happens if you revert to a commit before `HEAD`? Is it currently sitting at `HEAD`? – Simon Whitehead Sep 22 '14 at 13:45
  • Question edited. __@sma__ they are not in `.gitignore`, and when I was working on it, I never had _unwatched files._ Apart from that, I don't really know what happened or how I can verify. __@Simon Whitehead__ yes I believe it is at HEAD of a different branch. I tried to revert commit to answer your question and I messed the merge conflicts up so I reset the backup. (I'm not very pro with git) – Redsandro Sep 22 '14 at 14:26

3 Answers3

1

Dont know why half the files are missing, but you could try:

git clone .git /path/to/new/repo

Then you would trick git into beliving it's a bare repository, and clone from it to /path/to/new/repo, where master would be checked out.

On your edit: The modification since last commit will not stay on one branch. So for example, in your case, git status shows that all files are deleted, changing branch then doesnt "keep" this changes on that branch, but the changes brought to the next brach you checkout, unless you stash it first.

Consider this example:

git init gittest
cd gittest
echo "First commit" > a
git status
   Untracked files:
      a

git add a
git commit -m "Initial commit"
git branch test
git checkout test
echo "Editing a" >> a
git status
   modified: a
git checkout master
M      a
Switched to branch 'master'
git status
   modified: a
cat a
First commit
Editing a

Here I work in master and commit the first commit, then change branch to test, edit a, then move back master, and see, the changes are kept! This is what happends to you, in your feature branch, all files are deleted, and when you checkout master, you bring these changes (the removed file chanes) to master as well.

You see? It's a bit messy explanation, but hope you get it.

If you want to undelede the files, you can use whats described in this answer How do I revert all local changes in Git managed project to previous state?, by doing:

git checkout .
git reset
# vìola
Community
  • 1
  • 1
netdigger
  • 3,659
  • 3
  • 26
  • 49
  • I know, but if it's cloned as bare the working directory will be ignored, (to avoid any potential problems with it). – netdigger Sep 22 '14 at 13:59
  • Also, he said he has a copy of .git. Which pretty much is a bare repo, so why not use it? – netdigger Sep 22 '14 at 14:00
  • I think I misread your command. I'll delete my earlier comment. – jub0bs Sep 22 '14 at 14:31
  • I think this works. I have a lot more files this way. I need to verify some more. I thought this was silently equal-ish to checking out the master branch in an empty dir. Upvoted for now, possibly accepted later. – Redsandro Sep 22 '14 at 14:51
1

A better and safe option would be:

  1. Copy the contents of a .git dierctory into a new directory

  2. cd into the new directory and run git config --bool core.bare true This will make the new directory as a bare repo

  3. Now run git clone <URL-To-Bare> <New-repo>

hope it solves the problem!

Mudassir Razvi
  • 1,783
  • 12
  • 33
  • If by `URL-To-Bare` you mean the copy of the repo I made, this seems to have the same effect as __everlof__'s answer. Can you elaborate a bit on what happens, and what is theoretically different from that answer? – Redsandro Sep 22 '14 at 15:04
  • Git treats a repo as a bare repository only if core.bare is set to true. Practically there is no difference, but cloning directly from `.git` is not a common practice. And by URL-To-bare I mean the new bare repo you created. (Its not just a copy). This way you do things in a structured way and you can use the new bare repo you created as remote for collaboration also. – Mudassir Razvi Sep 22 '14 at 15:21
  • 2
    IMO, if the sentence: "Git treats a repo as a bare repository only if core.bare is set to true" was true, my answer wouldnt work, because then git would look for a `.git` in the `.git`, so obviously it actually treats it as a bare repo. – netdigger Sep 23 '14 at 06:43
1

Git stash would undo all the changes on working copy (including 'deleted' files) restoring all your files to working copy

git stash

The same result like if you were using "git clone" again

After this, if you want to delete the recently created stash, you can do:

git stash drop stash@{0}

I don't recommend deleting stash, since you wouldn't know at first when you would need the stashed info, as also stashes are not really using too much space (stashes are internally represented in the same structure as commits objects)

dseminara
  • 11,665
  • 2
  • 20
  • 22
  • This is clever! Can you add how to delete the (useless) stash? I now have three answers that all seem to work. Not sure which to accept. Maybe some extra upvotes will help me decide. :) – Redsandro Sep 23 '14 at 11:18
  • If you only have one stash, you can delete it with `git stash drop stash@{0}`. Otherwise you have to identify it with `git list stash` and change `stash@{0}` to whatever. – netdigger Sep 23 '14 at 13:17