Reputation: 6300
We have a policy to not bloat commit history, as it is a big project. So what I usually do, is on my feature branch, I push -f origin featbranch
daily, and when finished, I issue a PR.
This approach left me damaged today.
I finished my work on my featbranch
. After running all tests etc. successfully, I did a first push -f origin featbranch
. origin
is my own clone of the repo we work, upstream
being the one the PR is issued to.
Then I recalled that upstream/master
may have changed already, so in order to keep my featbranch
up-to-date, I wanted to rebase:
git fetch upstream master
git rebase upstream/master
git push -f origin featbranch
No errors. I assumed all was ok (I had just double-checked all tests etc....), but to may horrific dismay, I now realize that all my latest changes are lost.
I am left with a strange situation now, and I don't know what happened. In fact it looks like I am left with the very first commit on featbranch
: there is a file in featbranch
which is definitely not in upstream/master
. So I am baffled and don't know what happened here, github says the commit in that branch is from 13 days ago when I actually pushed yesterday.
I guess, due to the -f origin featbranch
, that my latest commit can't be recovered - not locally, not on github. I will ignore the policy above from now on and always do daily pushes but without forcing. Nevertheless I would like to understand what happened here.
Upvotes: 0
Views: 999
Reputation: 45659
As you may have learned the hard way here, workflows that make routine use of push -f
are dangerous. That push -f
doesn't give errors does not mean the operation was safe. Never use force-pushing without understainding the risks and other implications.
However, you may not be as lost as you think.
I don't see anything in the procedure you published that would cause the symptom you describe. I suspect some step was taken that isn't clearly spelled out here. But either way, force pushing doesn't modify your local state. You can still use the reflogs to try to recover your work.
git reflog featbranch
This will show you a history of the featbranch
ref, which does two things for you:
First, each time the ref moves, the resulting reflog entry records why it moved; so maybe you can see what actually caused the apparent loss of work.
Second, the ref log also records "before and after" commit ID for each time the ref moved - which means you can recover any previous state as long as it hasn't rolled off the log. In fact the reflog gives a convenient name to each previous state of the ref
git checkout featbranch@{3}
says to go to featbranch
as it looked before the 3 most recent changes. The reflog command will tell you the names associated with each such state.
Upvotes: 4
Reputation: 492
git has methods for recovering lost commits: git reflog
Furthermore, as you have gathered yourself, the -f option of git push should not be part of your normal workflow. If you want to keep the commit history clean, consider doing it like this.
Upvotes: 2
Reputation: 156
Use
git reflog
to find the state you want to get back to.
See e.g. https://stackoverflow.com/a/1270608/2738122
Upvotes: 2