Joey Hess <joey@xxxxxxxxxxx> writes: > So, my question is, assuming this is not a straight up bug in git, would > it make sense to avoid this gotcha in some way? The "push" support was originally written for people who push into their own repositories for publishing (i.e. almost always fast-forwarding) and lacked the elaborate common ancestor discovery negotiation the "fetch" side had. Suppose you have a rewound or forked history, like this: (their side) *---Y pu / *---X / *---*---Z master (your side) *---X---*---A pu / *---*---Z---*---B master - You were in sync when the 'pu' was at X with them; somebody pushed a few commits on top of it (forked case); or - You were in sync when the 'pu' was at Y with them (you pushed it their last time yourself), but you rebuilt 'pu' since then (rewound case). If you run "git push there master +pu", it learns that the tips of 'master' and 'pu' are at Z and Y respectively at their end. Because the protocol did not negotiate the common ancestor, it would try to send: rev-list A B ^Z ^Y but using only the information available at your end locally. Because you either never have heard of (in a forked case) or no longer know (in a rewound case) what 'Y' is, in order to update 'pu', you end up sending commits 'Z..A', duplicating 'Z..X' part, because "^Y" cannot participate in the ancestory computation. Commits 'Z..B' will be sent to update 'master'. And this aspect of "git push" protocol hasn't changed much since it was written. In contrast, the protocol used for "fetch" tries to discover 'X' in such a case by a little exchange, like this: downloader: Your tip is at 'Y'? I've never heard of it. Please tell me about its parents. uploader: It is this "Y^", and its parent is 'X', and ... downloader: Ok, I know what 'X' is. I heard enough to proceed. Thank you. -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html