Hi Junio, On 09/19/2020 13:03, Junio C Hamano wrote: > Srinidhi Kaushik <shrinidhi.kaushik@xxxxxxxxx> writes: > > > Adds a check to verify if the remote-tracking ref of the local branch > > is reachable from one of its "reflog" entries. > > s/Adds/Add/ Gotcha, I will reword the commit messages for all three commits. in the patch series. > > When "--force-with-includes" is used along with "--force-with-lease", > > A misspelt name for the new option is found here. *Facepalm.* Thanks, will update. > > [...] > Makes me wonder, if in_merge_bases() is so expensive that it makes > sense to split the "were we exactly at the tip?" and "is one of the > commits we were at a descendant of the tip?" into separate phases, > if this part should be calling in_merge_bases() one by one. > > Would it make more sense to iterate over reflog entries from newer > to older, collect them in an array of pointers to "struct commit" in > a batch of say 8 commits or less, and then ask in_merge_bases_many() > if the remote_commit is an ancestor of one of these local commits? > > The traversal cost to start from one "local commit" to see if > remote_commit is an ancestor of it using in_merge_bases() and > in_merge_bases_many() should be the same and an additional traversal > cost to start from more local commits should be negligible compared > to the traversal itself, so making a call to in_merge_bases() for > each local_commit smells somewhat suboptimal. > > If we were talking about older parts of the history, optional > generation numbers could change the equation somewhat, but the > common case for the workflow this series is trying to help is that > these local commits ane the remote tip are relatively new and it is > not unlikely that the generation numbers have not been computed for > them, which is why I suspect that in_merges_many may be a win. Nice! We can definitely try batching commits from the reflog and pass it along to "in_merge_bases_many()". As for being faster than calling "in_merge_bases()" for each commit entry in the reflog -- I am not familiar with how the former works. Do we still keep the "reflog_entry_exists()" part? It might still be faster to go through the entries once to check with "oideq()" in the first run. Also, I was wondering if it is worth considering this: - check if the reflog of the HEAD has the remote ref - check if the reflog of the local branch has the remote ref - check if the remote ref is reachable from any of the local ref's "reflog" entries using "in_merge_bases_many()" in batches as suggested here. The first two (we can even skip the second one) runs are relatively fast, and the third one might be faster than checking "in_merge_bases()" for each reflog entry. I suppose adding these three steps would make the process slower overall, though. For context, I was referring to your message [1] on the other thread regarding checking the HEAD's reflog. > > [...] > > + /* > > + * If "compare-and-swap" is in "use_tracking[_for_rest]" > > + * mode, and if "--foce-if-includes" was specified, run > > + * the check. > > + */ > > + if (ref->if_includes) > > + check_if_includes_upstream(ref); > > s/foce/force/; Yes, sorry about that; will update. > I can see that the code is checking "and if force-if-includes was > specified" part, but it is not immediately clear where the code > checks if "--force-with-lease" is used with "tracking" and not with > "the other side must be exactly this commit" mode here. > > ... goes and looks ... > > Ah, ok, I found out. > > The field name "if_includes", and the comment for the field in > remote.h, are both misleading. It gives an impression that the > field being true means "--force-if-included is in use", but in > reality the field means a lot more. When it is true, it signals > that "--force-if-included" is in use *and* for this ref we were told > to use the "--force-with-lease" without an exact object name. And > that logic is not here, but has already happened in apply_cas(). > > Which makes the above comment correct. We however need a better > name for this field and/or an explanation for the field in the > header file, or both, to avoid misleading readers. > > > diff --git a/remote.h b/remote.h > > index 5e3ea5a26d..38ab8539e2 100644 > > --- a/remote.h > > +++ b/remote.h > > @@ -104,7 +104,9 @@ struct ref { > > forced_update:1, > > expect_old_sha1:1, > > exact_oid:1, > > - deletion:1; > > + deletion:1, > > + if_includes:1, /* If "--force-with-includes" was specified. */ > > The description needs to be tightened. > > > + unreachable:1; /* For "if_includes"; unreachable in reflog. */ OK, you're right. Perhaps, we could rename it to something like "if_includes_for_tracking" and update the comment description with saying something along the lines of: + /* + * Set when "--force-if-includes" is enabled, and + * if "compare-and-swap" is not provided with the + * exact commit to be expected on the remote (in + * "use_tracking" or use_tracking_for_rest" mode). + */ [1]: https://public-inbox.org/git/xmqqsgbdk69b.fsf@xxxxxxxxxxxxxxxxxxxxxx Thanks again, for taking the time to review this. -- Srinidhi Kaushik