Toon Claes <toon@xxxxxxxxx> writes: > The changes in commit c06793a4ed (allow git-bundle to create bottomless > bundle, 2007-08-08) ensure annotated tags are properly preserved when > creating a bundle using a revision range operation. > > At the time the range notation would peel the ends to their > corresponding commit, meaning ref v2.0 would point to the v2.0^0 commit. > So the above workaround was introduced. This code looks up the ref > before it's written to the bundle, and if the ref doesn't point to the > object we expect (for tags this would be a tag object), we skip the ref > from the bundle. Instead, when the ref is a tag that's the positive end > of the range (e.g. v2.0 from the range "v1.0..v2.0"), then that ref is > written to the bundle instead. > > Later, in 895c5ba3c1 (revision: do not peel tags used in range notation, > 2013-09-19), the behavior of parsing ranges was changed and the problem > was fixed at the cause. But the workaround in bundle.c was not reverted. > > Now it seems this workaround can cause a race condition. git-bundle(1) > uses setup_revisions() to parse the input into `struct rev_info`. Later, > in write_bundle_refs(), it uses this info to write refs to the bundle. > As mentioned at this point each ref is looked up again and checked > whether it points to the object we expect. If not, the ref is not > written to the bundle. But, when creating a bundle in a heavy traffic > repository (a repo with many references, and frequent ref updates) it's > possible a branch ref was updated between setup_revisions() and > write_bundle_refs() and thus the extra check causes the ref to be > skipped. > > The workaround was originally added to deal with tags, but the code path > also gets hit by non-tag refs, causing this race condition. Because it's > no longer needed, remove it and fix the possible race condition. It is always a pleasure to read a patch based on the idea to directly target a nicely analyzed "root cause". Thanks.