GitHub repo lost much history after forced push - how to restore?

Obviously I'm new to Git and SourceTree. I used SourceTree to force-push 43 commits into our master on GitHub, and now GitHub does not show any of the commits made before the earliest of those 43, which apparently thought it was adding all of its files for the first time.

How can the GitHub repo be set back, as though this force-push never happened, or - better - so that it shows the numerous earlier commits it already knew about before this force-push?

(I've been using the force-push with another repo fine with batches of commits; the problem in this case seems to be that the commit earliest in this batch somehow thought it was an initial load, or something like that, essentially causing the master in GitHub to be reset from that point.)

There is no danger of anyone else pulling from this repo; it's private and just used as a work log at the moment, which is why it's important to get back to the earlier history.

-Ken

4 answers

1 vote
Joseph Clark Atlassian Team Nov 14, 2014

I'm not sure there's any way to do this in SourceTree - it's generally designed to support only the 'happy path' workflows, and not so much the 'oh crap I need to undo this' workflows in my experience smile I don't use it all that much, so happy to be corrected here by someone else.

You should be able to revert to the prior state by accessing the reflog from the terminal (see https://www.atlassian.com/git/tutorials/rewriting-history/git-reflog). Do this by:

  1. Using the git reflog command to identify the last-known-good state of your repo
  2. Then, git reset --hard <commit> to revert back to it
  3. Then, another git push --force to reset the remote repository back to that state
  4. and finally, working out a safe way to re-apply those same 43 commits again in a non-destructive manner

Hope this helps!

 

Was that the pushes did start failing at some point, in both repos. Given the forced push worked fine in the other repo, there was no obvious reason it would fail on this one. The fail was not so much the force push per se, but that the first commit in the pushed batch thought all its files were new, for some reason, apparently. I will turn to StackOverflow if necessary, was hoping the solution could be executed via SourceTree,,

To restore, you're almost certainly going to need to go to the terminal. You'll probably have more luck on StackOverflow in getting an answer with a specific terminal command to run.

Secondly, you shouldn't be force-pushing on a regular basis. If a push needs forced, it's because something has been changed in the local history that will remove commits from your remote's history. Sure, usually it's because you've done some sort of rebase and those commits have been replaced with new ones, but your usage should be: wait until a non-forced push fails, then consider whether a force push is safe this time.

I did spare a typical "don't force push, it'll screw your teammates" speech since you seem to know that already.

Thanks for this. The problem is / was that the pushes did start failing at some point, in both repos.

Given the forced push worked fine in the other repo, there was no obvious reason it would fail on this one. The fail was not so much the force push per se, but that the first commit in the pushed batch thought all its files were new, for some reason, apparently.

I will turn to StackOverflow if necessary, was hoping the solution could be executed via SourceTree.

-Ken

 

I wasn't trying to suggest that a force push was the core cause, but forcing a push with your local repo in the condition of forgetting the history is the problem. I was just recommending you be more cautious in the future before force-pushing, and to avoid getting in the habit of checking the "force" box when it isn't necessary. There certainly may be a way to do this in SourceTree, and it would be wise to wait for an answer (for all you know I've never even used the thing). But, in my experience, SourceTree does not display commits that aren't associated to a branch, and you would need to either see the commits or (at least) know one of their commit hashes in order to fix your repo. I know you can do this via git commands, I've seen answers on Stack regarding similar issues. Good luck!

The easiest way is to force push the original state from somebody else's clone if there is somebody else who has not pulled your changes yet.

Thanks for your replies. We did find a local clone and force-pushed that, but now the Github copy is back to what it was, without the latest 50+ commits.

Attached is a screenshot from SourceTree that shows the current situation: we have the purple line of commits simply stopping, then the blue line starts. The first blue-line commit is one where Git thinks all the files in the project are being added.

How do we make the two lines become one?

-Ken

Screen Shot 2014-11-25 at 2.47.04 PM.png

 

 

Here's what I'd do. First, checkout the highlighted commit. Copy the files somewhere outside of your git working copy. Next, checkout master (or create a new branch from master and checkout that). Next, overwrite your working copy with the earlier backup, then commit any changes with the original commit message ("Manual update..."). From here, you should be able to cherry pick each of the remaining commits into your new branch. A merge between the two will probably fail because, to git, you've added two different files with the same name in the same location (and you've done this possibly hundreds or thousands of times), and (in my experience) it will fail rather than make an attempt to merge those together.

There is probably a faster way to accomplish what you want be rewriting the git history via the command line, but I'm not enough of a Git wizard for that. It might be worthwhile to take your question to StackOverflow or a Git IRC.

Suggest an answer

Log in or Sign up to answer
How to earn badges on the Atlassian Community

How to earn badges on the Atlassian Community

Badges are a great way to show off community activity, whether you’re a newbie or a Champion.

Learn more
Community showcase
Published May 30, 2018 in Sourcetree

Tip from the team: configuring Git or Mercurial in Sourcetree

Supported Platforms macOS Windows To make using Sourcetree as simple yet powerful as possible we embed (bundle) dependencies such as Git, Git LFS, and Mercurial. We strive to keep these...

393 views 0 1
Read article

Atlassian User Groups

Connect with like-minded Atlassian users at free events near you!

Find a group

Connect with like-minded Atlassian users at free events near you!

Find my local user group

Unfortunately there are no AUG chapters near you at the moment.

Start an AUG

You're one step closer to meeting fellow Atlassian users at your local meet up. Learn more about AUGs

Groups near you