@@ -251,21 +251,57 @@ struct commit_list *get_shallow_commits_by_rev_list(struct strvec *argv,
251251 * commit A is processed first, then commit B, whose parent is
252252 * A, later. If NOT_SHALLOW on A is cleared at step 1, B
253253 * itself is considered border at step 2, which is incorrect.
254+ *
255+ * We must also consider that B has multiple parents which may
256+ * not all be marked NOT_SHALLOW (as they weren't traversed into
257+ * the not_shallow_list from revs in the first place). Because of
258+ * that an additional step is required to reconsider B as border.
259+ * A commit from the not_shallow_list is considered border only
260+ * when ALL its parents weren't on the not_shallow_list.
261+ * When one or more parents of a commit from the not_shellow_list
262+ * also come from that list, the commit is not considered border,
263+ * but its non-listed parents are considered border commits.
264+ *
265+ * The general processing goes like this:
266+ * 1. Above we've painted the whole not_shallow_list of commits
267+ * NOT_SHALLOW.
268+ * 2. For each commit from the not_shallow_list (the code below)
269+ * we paint SHALLOW this commit and its parent for all its
270+ * parents that had not yet been painted NOT_SHALLOW.
271+ * 3. Commits with all parents being painted only SHALLOW remain
272+ * shallow and are being added to result list.
273+ * 4. Commits without all parents being painted only SHALLOW are
274+ * being excluded as borders, however their parents painted only
275+ * SHALLOW are being added to the result borders list.
254276 */
255277 for (p = not_shallow_list ; p ; p = p -> next ) {
256278 struct commit * c = p -> item ;
257279 struct commit_list * parent ;
280+ int must_not_be_shallow = 0 ;
258281
259282 if (repo_parse_commit (the_repository , c ))
260283 die ("unable to parse commit %s" ,
261284 oid_to_hex (& c -> object .oid ));
262285
263286 for (parent = c -> parents ; parent ; parent = parent -> next )
264- if (!(parent -> item -> object .flags & not_shallow_flag )) {
287+ if (parent -> item -> object .flags & not_shallow_flag ) {
288+ must_not_be_shallow = 1 ;
289+ } else {
265290 c -> object .flags |= shallow_flag ;
266- commit_list_insert (c , & result );
267- break ;
291+ parent -> item -> object .flags |= shallow_flag ;
268292 }
293+ if (must_not_be_shallow ) {
294+ c -> object .flags &= ~shallow_flag ;
295+ for (parent = c -> parents ; parent ; parent = parent -> next )
296+ if (parent -> item -> object .flags & shallow_flag ) {
297+ parent -> item -> object .flags |= not_shallow_flag ;
298+ commit_list_insert (parent -> item , & result );
299+ }
300+ } else {
301+ for (parent = c -> parents ; parent ; parent = parent -> next )
302+ parent -> item -> object .flags &= ~shallow_flag ;
303+ commit_list_insert (c , & result );
304+ }
269305 }
270306 free_commit_list (not_shallow_list );
271307
0 commit comments