When you 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
Edit:
- "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.
If you 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 gitk --all
.