Alex Riesen <raa.lkml@xxxxxxxxx> writes: > Junio C Hamano, Sun, May 06, 2007 10:00:25 +0200: >> >> > Is that possible? I'm fairly sure it used to be. >> >> I doubt we had that bug. If you allowed overwriting with +, it >> would not have prevented a rewind (i.e. pull from Linus and then >> pull from somebody who pulled from Linus earlier than you did). >> If you didn't, then it would have failed the fetch. >> > > Maybe we should not fail in the case the remote repo is older then > local, but just to try to fast-forward local reference after a fetch > and fail only if the fast-forward fails? > Or introduce a new syntax for the strict reference succession and make > fetch+fast-forward the default? > Or the other way around, use something like "-from:to" to ignore > fast-forwards failed because the "from" already has all the "to" has, > which has precedents: make and its "-include", which ignores errors > from non-existing files. I think the whole issue would disappear if David stops using the same 'linus' tracking branch to track origins from *different* repositories (see my other message on the thread), and I think it makes the above suggestions fall somewhat in "solutions looking for a problem" category. If this is a common enough misconfiguration, we might want to add a sanity check to catch Pull: lines in different remotes/ files and remote.*.fetch configurations for different remotes cause the same tracking branch to be updated, but I personally do not think it is even worth it. Having said that, I suspect that making the default <src>:<dst> (without 'force') to ignore pure rewind (not rewind+rebuild) might make sense without having much downside. If the remote repository owner rewinds its tip, current code catches it as a possible mistake of the remote side, but until it starts building a different history on top of that rewound head, there really is no harm done. One common case that can be helped with such a behaviour change is when your remote.*.url points at a single URL that actually is backed by more than one mirrors --- think of www.kernel.org which resolves to two actual hosts via DNS round robin. If you fetch from one server, and then fetch again from the other server that was behind (maybe rsync cron job got stuck for some unspecified reason), you would observe that the tip was rewound. Something like this untested patch should be sufficient if we want to go this route, but I am not convinced yet that this is the right thing to do. For one thing, it is not clear to me what should happen if --force is in effect. Should this honor the "wish" of the remote repository owner to rewind this ref, or should we assume that it was two servers with mirroring inconsistency fluke and ignore the rewind, hoping that the next round will straighten the situation out? What does --force instructs us to do in such a case? diff --git a/builtin-fetch--tool.c b/builtin-fetch--tool.c index 2065466..29d7fe1 100644 --- a/builtin-fetch--tool.c +++ b/builtin-fetch--tool.c @@ -119,6 +119,12 @@ static int update_local_ref(const char *name, return update_ref("fast forward", name, sha1_new, sha1_old); } if (!force) { + if (in_merge_bases(updated, ¤t, 1)) { + fprintf(stderr, "* %s: ignoring straight rewind %s\n", + name, note); + fprintf(stderr, " old..new: %s..%s\n", oldh, newh); + return 0; + } fprintf(stderr, "* %s: not updating to non-fast forward %s\n", name, note); - 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