Bare Repositories and git push

As a consequence of the peer-to-peer semantics of Git repositories, all repositories are of equal stature. You can push to and fetch from development and bare repositories equally, as there is no fundamental implementation distinction between them. This symmetric design is critically important to Git, but it also leads to some unexpected behavior if you try to treat bare and development repositories as exact equals.

Recall that the git push command does not check out files in the receiving repository. It simply transfers objects from the source repository to the receiving repository and then updates the corresponding refs on the receiving end.

In a bare repository, this behavior is all that can be expected, because there is no working directory that might be updated by checked-out files. That’s good. However, in a development repository that is the recipient of a push operation, it can later cause confusion to anyone using the development repository.

The push operation can update the repository state, including the HEAD commit. That is, even though the developer at the remote end has done nothing, the branch refs and HEAD might change, becoming out of sync with the checked-out files and index.

A developer who is actively working in a repository into which an asynchronous push happens will not see the push But a subsequent commit by that developer will occur on an unexpected HEAD, creating an odd history. A forced push will lose pushed commits from the ...

Get Version Control with Git now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.