(ctx context.Context, parent *branches.Config, retries int, author, message string)
| 292 | } |
| 293 | |
| 294 | func (b *Branch) buildMergeObject(ctx context.Context, parent *branches.Config, retries int, author, message string) (*commits.Object, error) { |
| 295 | childPath, err := b.pool.commits.Path(ctx, b.Commit) |
| 296 | if err != nil { |
| 297 | return nil, err |
| 298 | } |
| 299 | parentPath, err := b.pool.commits.Path(ctx, parent.Commit) |
| 300 | if err != nil { |
| 301 | return nil, err |
| 302 | } |
| 303 | baseID := commonAncestor(parentPath, childPath) |
| 304 | if baseID == ksuid.Nil { |
| 305 | //XXX this shouldn't happen because because all of the branches |
| 306 | // should live in a single tree. |
| 307 | //XXX hmm, except if you branch main when it is empty...? |
| 308 | // we shoudl detect this and not allow it...? |
| 309 | return nil, errors.New("system error: cannot locate common ancestor for branch merge") |
| 310 | } |
| 311 | // Compute the snapshot of the common ancestor then compute patches |
| 312 | // along each branch and make sure the two patches do not have a |
| 313 | // delete conflict. For now, this is the only kind of merge update |
| 314 | // conflict we detect. |
| 315 | base, err := b.pool.commits.Snapshot(ctx, baseID) |
| 316 | if err != nil { |
| 317 | return nil, err |
| 318 | } |
| 319 | childPatch, err := b.pool.commits.PatchOfPath(ctx, base, baseID, b.Commit) |
| 320 | if err != nil { |
| 321 | return nil, err |
| 322 | } |
| 323 | parentPatch, err := b.pool.commits.PatchOfPath(ctx, base, baseID, parent.Commit) |
| 324 | if err != nil { |
| 325 | return nil, err |
| 326 | } |
| 327 | if message == "" { |
| 328 | message = fmt.Sprintf("merged %q into %q", b.Name, parent.Name) |
| 329 | } |
| 330 | // Now compute the diff between the parent patch and the child patch so that |
| 331 | // the diff patch will reflect the changes from the child into the parent. |
| 332 | // Diff() will also check for delete conflicts. |
| 333 | diff, err := commits.Diff(parentPatch, childPatch) |
| 334 | if err != nil { |
| 335 | return nil, fmt.Errorf("error merging %q into %q: %w", b.Name, parent.Name, err) |
| 336 | } |
| 337 | return diff.NewCommitObject(parent.Commit, retries, author, message, super.Null), nil |
| 338 | } |
| 339 | |
| 340 | func commonAncestor(a, b []ksuid.KSUID) ksuid.KSUID { |
| 341 | m := make(map[ksuid.KSUID]struct{}) |
no test coverage detected