A force-push merely tells the remote to move the given label(s) even if the move is not a fast-forward operation.1 A non-fast-forward can (does not necessarily) result in "abandoned" commits: commits that are no longer reachable from some reference.
(It does not do this when the label motion occurs on a part of the graph that is referenced elsewhere. For instance, if branch xyzzy
points to commit D
in the sequence:
A-B-C-E <-- plugh
\ /
D <-- xyzzy
then it is irrelevant what happens to label xyzzy
, as label plugh
makes commit D
reachable. So moving xyzzy
in a non-fast-forward fashion to, e.g., point to commit C
does not affect commit D
at all. Likewise, deleting label xyzzy
entirely is also harmless, at least in terms of the commit graph structure.)
Remote bare repositories (to which one generally pushes) often do not log all ref updates, so this tends to trigger rapid garbage-collection of any abandoned commits. (Note that if you keep them in your own repository, you can restore gc'ed commits later—but that requires that you send the data over the network again, and exposes you to data loss risk if your own repo gets corrupted via, say, a power failure, or your computer catching on fire.)
If you have some third-party software that assumes that (some or all) branch labels only move in fast-forward fashion, said software could fail in interesting ways. I know of no such software and if it exists I would call it "broken", but people do often seem to write broken code and then depend on it.
1Older versions of git allowed tags to move without a force-push if the move was fast-forward, in the same way that branch labels are expected to move. Newer versions (I think introduced in 1.8.2, but that's just from memory) reject any tag motion unless you use force. Of course you can always delete, then re-create (possibly at a different point), a label, and the built-in hook is OK with that. So there are other ways to move a tag or branch, in arbitrary fashion, even without force. Just make sure the parts of the commit graph you want to retain have some label across each operation.
As for making (your own) rebasing harder later: yes, it can have that effect, because you might force-push from "desktop" and thus, in effect, rearrange "shared-bare-repo". Later, on "laptop", you might not be able to remember just which commits you rebased, and figuring it out can be a little tricky, especially in a large, highly-active repository.
Fortunately, the new upcoming git release has a new feature that uses your reflogs to figure out if and when an "upstream rebase" has occurred. That is, in the above situation, you would be able (on "laptop") to ask git to automatically discover which commits were rebased in shared-bare-repo and "re-rebase" your laptop work on that. (This is a generalization of the method used with git pull --rebase
today, in git 1.8.x.)