Well, yes, git is not google docs. What's happening is that initially, your two local repositories (the one on your computer and on your friend's) are synchronized, but when your friend pushes his modifications to the main repository, that repository is now out of date with yours, and when you try to push your own modifications, the push will probably fail since your repository is out of date. In this case you need to update your repository (git pull) and hope that doesn't trash your work in case your friend was working with the same files you were. Then you should be able to push (unless your friend pushed again since then, as you can see this can be frustrating).
A good idea is to not push as often - prefer to just commit, which only makes changes to your local repository, and only push once you've accomplished enough work and your friend can update his repository (hopefully you didn't write over what he is currently working on - good project management will prevent that). In fact, ideally since you are working on unrelated features of a modular system, people don't need to pull your modifications to keep working, unless it's a major bug that affects the entire codebase. They'll just do their own stuff, push to their respective files and the end user can then grab the most up to date repository, regardless of who's done or not. This doesn't directly apply to you, obviously, since on a two-man team the code you're working on will likely be very related, but the idea still stands - don't push unless your friend needs your code to keep working (or you are finished for the day).
Another approach is to push to an integration manager (as you saw on those links above) which'll optionally decide what to pull into the repository (for non-trusted collaborators) and merge everything together correctly, in case you were working on the same things. This is important in big projects with lots of random collaborators, since people don't communicate as much between one another and you can't just trust people to behave properly and not break each other's code, so you have a "gatekeeper" which prevents that.
The bottom line being that there is no good way to work together on the same piece of code, really. The whole point of collaboration is to get work done faster, and you can't achieve that by having people fight over the same lines of code. It's like asking nine woman to have a baby in a month, it doesn't work that way. So perhaps for a two-man team you could try to divide your work by having your game logic (is it a game you're making?) flexible, accepting well-defined interfaces to whatever modules you are going to use, and then have him work on the character system while you get the graphics up and running, etc.. does that make sense?
Edited by Bacterius, 26 December 2012 - 03:22 AM.
The slowsort algorithm is a perfect illustration of the multiply and surrender paradigm, which is perhaps the single most important paradigm in the development of reluctant algorithms. The basic multiply and surrender strategy consists in replacing the problem at hand by two or more subproblems, each slightly simpler than the original, and continue multiplying subproblems and subsubproblems recursively in this fashion as long as possible. At some point the subproblems will all become so simple that their solution can no longer be postponed, and we will have to surrender. Experience shows that, in most cases, by the time this point is reached the total work will be substantially higher than what could have been wasted by a more direct approach.
- Pessimal Algorithms and Simplexity Analysis