简体   繁体   中英

Files deleted after push in GitHub remote repository

I have my first Git repository that I have created online named myName/python-algorithms .

It was containing many Python scripts. I tried to add a file test.py from my local Ubuntu terminal with the commands:

git init
git config user.name "myName"
git config user.e-mail "myEmail@myEmail.se"
git add test.py
git commit -m "some init msg"
git remote add origin https://github.com/myname/Python_Algorithms.git
git remote -v
git push -f origin master

which deleted all my Python scripts and replaced them with the file test.py on GitHub.

Any idea how I can get back my scripts that were deleted?

So there are a few ways to fix an undesired commit. It looks like maybe your local git repo didn't have all the info in your remote repo, which caused your push to overwrite it. In your terminal, use git log to look at the commit history for your local git. If it only lists your test commit, we'll need to find the last good commit (where all the files still existed) a different way.

Go to your github and navigate to your commit history. You should see a commit prior to the last push "some init msg" that overwrote your other files. It will have a hex identifier (in blue) on the right. Copy it!

From your git terminal, you want to use the command: git checkout copiedhex#

This will copy to your local repo the version with all the files. However, you'll be in a detached HEAD state, and should get a message to that effect. You'll want to make this into a new branch by using: git checkout -b some_new_branch_name Then you can proceed as normal (merge it with master or keep working separately, push etc)

More helpful info here: https://www.atlassian.com/git/tutorials/undoing-changes

Hope that helps!

Any idea how I can get back my scripts that were deleted?

The main way: Find a backup copy/clone of the original repository (or beg GitHub administrators to find one).

A temporary way: If you have a hash ID showing somewhere in a window or written down somewhere on paper or a whiteboard, and can navigate to the GitHub URL for that commit (eg, https://github.com/git/git/commit/b9e62f60115c75c5be5de593862925c8b8d7e683 is the URL for one particular commit on GitHub in this particular Git repository for Git), use that to get to the tree object by clicking on "Browse Files", and use that to get to your files. There is a limited time window during which you can do this; after that, GitHub's maintenance scrubbers will have deleted the commits and they will not be recoverable except via backup copies or other clones.


Remember, what Git stores are commits . Every commit holds a full and complete snapshot of all of your files, along with some metadata: information about the commit, such as who made it and when. Every commit has a unique hash ID, so that any Git repository can immediately tell whether it has that commit just by inspecting the hash ID. If the repository has a commit with that hash ID, it has that commit .

Meanwhile, of course, every repository holds some set of commits. Your GitHub repository had some set of commits, with your files in them.

When you create a new, empty repository:

 git init git config user.name "myName" git config user.e-mail "myEmail@myEmail.se"

this new empty repository has no commits at all . That's not that big a deal since you can then make new commits:

 git add test.py git commit -m "some init msg"

This new repository now has one commit. Let's draw it. It has some big ugly hash ID, but let's call it H for "hash":

H   <-- master

Meanwhile, the GitHub repository at https://github.com/myname/Python_Algorithms.git has other commit(s). Let's assume it has four commits, and call them A , B , C , and D . Its master holds the hash ID of commit D , which points back to commit C , which points back to B , which points to A , which is the first commit in that repository and hence doesn't point anywhere:

A <-B <-C <-D   <-- master   (in the Git on GitHub)

When you run git push without -f :

 git remote add origin https://github.com/myname/Python_Algorithms.git git remote -v

[and what you didn't do:]

git push origin master

your Git will call up that other Git and offer it your one commit, which you have and they don't. So far, all is well: they take that one commit and put it in a quarantine area. Then, your Git says to their Git: Please, if it's OK, use this commit's hash ID to set your branch name master .

Their Git looks in their repository, which has a chain of commits ending at D . It tries following commit H backwards, to see if that will get it to commit D . But commit H has no parent: it's a new root commit, like A . So H doesn't lead back to D , and GitHub responds to your Git: No! If I overwrite my name master with commit hash H , I'll lose commit D and thereby all earlier commits too!

Alas, you told your Git to git push -f origin master , adding the force flag. The force flag changes your Git's polite Please, if it is OK request into a command: Set your master !

The Git over on GitHub obeyed. He set his master to point to H :

A--B--C--D   [abandoned]

H   <-- master

The old commits in the GitHub repository are not accessible by normal Git mechanisms, at this point. Eventually, their Git maintenance / janitor processing will come around and sweep away the original chain of commits forever. Until then, access by direct URL through the .../commit/<hash> URL bypasses the normal Git mechanisms, so it can still work. But all regular Git operations are foiled by the fact that their master now points to commit H and there is no way for their Git to find commit D .

There may be some other clone you, or someone else, made, that contains commit D (and if so it likely has A through C as well, or perhaps it has only A through C as it never got updated after D got added, or whatever). If you can find such a repository, and can access its commits—by hash ID or by names like master —you can get your files that way, from those commits. If not ... well, that's why git push --force is dangerous!

FIXED: Thanks to torek comment, I fixed it as follows. From:

https://api.github.com/repos/myName/Python_Algorithms/events

I found the old HASH_ID, before the force push happened. Then I went to the link:

https://github.com/myNAme/Python_Algorithms/commit/HASH_ID

and I managed with Browse files and went back to my files.

Thanks toreks

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM