简体   繁体   English

在 GitHub 远程存储库中推送后删除的文件

[英]Files deleted after push in GitHub remote repository

I have my first Git repository that I have created online named myName/python-algorithms .我有我在网上创建的第一个 Git 存储库,名为myName/python-algorithms

It was containing many Python scripts.它包含许多 Python 脚本。 I tried to add a file test.py from my local Ubuntu terminal with the commands:我尝试使用以下命令从本地 Ubuntu 终端添加文件test.py

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.它删除了我所有的 Python 脚本并将它们替换为 GitHub 上的文件test.py

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.看起来您的本地 git 存储库可能没有远程存储库中的所有信息,这导致您的推送覆盖了它。 In your terminal, use git log to look at the commit history for your local git.在您的终端中,使用 git log 查看本地 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.转到您的 github 并导航到您的提交历史记录。 You should see a commit prior to the last push "some init msg" that overwrote your other files.您应该在上次推送“some init msg”之前看到一个覆盖了其他文件的提交。 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#从您的 git 终端,您想使用以下命令: git checkout Copyhex#

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.但是,您将处于分离的 HEAD 状态,并且应该收到一条有关该效果的消息。 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)您需要使用以下命令将其设置为一个新分支: git checkout -b some_new_branch_name 然后您可以照常进行(将其与 master 合并或继续单独工作,推送等)

More helpful info here: https://www.atlassian.com/git/tutorials/undoing-changes这里有更多有用的信息: 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).主要方式:找一份原始仓库的备份副本/克隆(或者求GitHub管理员找一份)。

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.一种临时方式:如果您有一个哈希 ID 显示在窗口中的某处或写在纸或白板上的某处,并且可以导航该提交的 GitHub URL(例如, https://github.com/git/git/ commit/b9e62f60115c75c5be5de593862925c8b8d7e683是 GitHub 上此特定 Git 存储库中一个特定提交的 URL,用于 Git),通过单击“浏览文件”使用它来访问对象,并使用它来访问您的文件。 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.之后,GitHub 的维护清理器将删除提交,除非通过备份副本或其他克隆,否则它们将无法恢复。


Remember, what Git stores are commits .请记住,Git 存储的是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.每个提交都有一个唯一的哈希 ID,因此任何 Git 存储库都可以通过检查哈希 ID 立即判断它是否具有该提交。 If the repository has a commit with that hash ID, it has that commit .如果存储库具有具有哈希 ID 的提交,则它具有该 commit

Meanwhile, of course, every repository holds some set of commits.同时,当然,每个存储库都持有一些提交。 Your GitHub repository had some set of commits, with your files in them.您的 GitHub 存储库有一组提交,其中包含您的文件。

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":它有一些丑陋的大哈希 ID,但我们称它为H表示“哈希”:

H   <-- master

Meanwhile, the GitHub repository at https://github.com/myname/Python_Algorithms.git has other commit(s).同时,位于https://github.com/myname/Python_Algorithms.git的 GitHub 存储库还有其他提交。 Let's assume it has four commits, and call them A , B , C , and D .假设它有四个提交,并称它们为ABCD 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:master保持提交的散列ID D ,这点回到提交C ,这点回到B ,这点至A ,其在存储库,第一承诺,因此不指向任何地方:

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

When you run git push without -f :当你在没有-f情况下运行git push

 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.你的 Git 会调用另一个 Git 并提供你的一次提交,你有而他们没有。 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 .然后,您的 Git 对他们的 Git 说:请,如果可以,请使用此提交的哈希 ID 来设置您的分支名称master

Their Git looks in their repository, which has a chain of commits ending at D .他们的 Git 在他们的存储库中查找,其中有一个以D结尾的提交链。 It tries following commit H backwards, to see if that will get it to commit D .它尝试向后提交H ,以查看是否会使其提交D But commit H has no parent: it's a new root commit, like A .但是提交H没有父级:它是一个新的根提交,就像A So H doesn't lead back to D , and GitHub responds to your Git: No!所以H不会回到D ,GitHub 回应你的 Git:不! If I overwrite my name master with commit hash H , I'll lose commit D and thereby all earlier commits too!如果我用提交哈希H覆盖我的名字master ,我将丢失提交D ,从而也丢失所有早期的提交!

Alas, you told your Git to git push -f origin master , adding the force flag.唉,你告诉你的 Git git push -f origin master ,添加强制标志。 The force flag changes your Git's polite Please, if it is OK request into a command: Set your master ! force 标志改变了你的 Git 的礼貌,如果可以的话,请求变成一个命令:设置你的master

The Git over on GitHub obeyed. GitHub 上的 Git 服从了。 He set his master to point to H :他让他的master指向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.此时,普通 Git 机制无法访问 GitHub 存储库中的旧提交。 Eventually, their Git maintenance / janitor processing will come around and sweep away the original chain of commits forever.最终,他们的 Git 维护/管理员处理将彻底清除原始提交链。 Until then, access by direct URL through the .../commit/<hash> URL bypasses the normal Git mechanisms, so it can still work.在此之前,通过.../commit/<hash> URL 的直接 URL 访问绕过了正常的 Git 机制,因此它仍然可以工作。 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 .但是所有常规 Git 操作都被他们的master现在指向提交H并且他们的 Git 无法找到提交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).您或其他人制作的其他克隆可能包含提交D (如果是这样,它也可能有AC ,或者它可能只有AC因为在添加D后它从未更新,或者任何)。 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.如果你能找到这样的存储库,并且可以访问它的提交——通过哈希 ID 或像master这样的名字——你可以从这些提交中以这种方式获取你的文件。 If not ... well, that's why git push --force is dangerous!如果没有......好吧,这就是为什么git push --force很危险!

FIXED: Thanks to torek comment, I fixed it as follows.修正:感谢 torek 评论,我修正了它如下。 From:从:

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

I found the old HASH_ID, before the force push happened.在强制推送发生之前,我找到了旧的 HASH_ID。 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感谢托雷克斯

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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