How can git lose history when pushing a non-fast-forward commit?
I know that sometimes when I run
git push, I get this error:
error: failed to push some refs To prevent you from losing history, non-fast-forward updates were rejected
Can someone give an example of a situation where history would be lost if I pushed a non-fast-forward update? From my understanding, when I do
git push, git will simply push my commits to the remote repository and not delete any of the existing commits, so how will it lose the history?
- Why does HEAD~394 not work if I have 394 unpushed git commits?
- Process 'command 'git' finished with non-zero exit value 1
- How can I split up a Git commit buried in history?
- remove commits (forever) from git history
- How can I efficiently navigate a Git repo to follow project development?
- How to overcome git merge history ambiguity/obfuscation with '--ours'?
2 Solutions collect form web for “How can git lose history when pushing a non-fast-forward commit?”
push, you send your commit, but you also update the remote branch.
Say a remote repo is:
A <- B <- C (master)
Now you clone it, make some dev starting with commit A, and end up with:
A <- B <- C (origin/master) <- D <- E (master)
If you force push, the remote repo will look like:
A <- D <- E (master) <- B <- C
So commits B and C still exist, but they aren’t reachable with a branch.
And if someone clones the repo now, he will locally have:
A <- D <- E (master; origin/master)
ie: from his point of view, commits B and C are lost
- “the commits still exist” means:
Say my commit B has the sha1
abcdef. Then, there’s a file
objects/ab/cdef (at the root of the remote repo, and in the .git directory on my local clone) which represents this commit.
push -f, it won’t delete this remote file, hence, commit B still exists on the remote repo. (At least, as long as it is not garbage collected)
- “but they aren’t reachable with a branch” implies:
When someone else clones this remote after I pushed force, he’ll get this
.git/objects/ab/cdef file. However, unless he is looking for it, he won’t be aware this commit once existed. For example it will not be displayed by
Suppose you push your local
master to the remote
If your local branch and the remote branch have diverged (both have had commits since last you pulled), how would that be handled?
One way would be to declare the current commit for your local
master as the new remote
master. But that would loose the history of commits that are currently on the remote
master, since they would never appear in the ancestry of your commit.
(I suppose that the “lost” commits would still exist remotely, but they would not be on the