Skip to content

Commit

Permalink
Feature/list commits with children (#458)
Browse files Browse the repository at this point in the history
  • Loading branch information
tzahij authored Aug 16, 2020
1 parent 76aed24 commit 74b2cf5
Show file tree
Hide file tree
Showing 5 changed files with 159 additions and 15 deletions.
2 changes: 1 addition & 1 deletion catalog/cataloger_diff.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ func (c *cataloger) diffFromChild(tx db.Tx, childID, parentID int64) (Difference
return nil, fmt.Errorf("child lineage failed: %w", err)
}

childLineageValues := getLineageAsValues(childLineage, childID)
childLineageValues := getLineageAsValues(childLineage, childID, MaxCommitID)
mainDiffFromChild := sqDiffFromChildV(parentID, childID, effectiveCommits.ParentEffectiveCommit, effectiveCommits.ChildEffectiveCommit, parentLineage, childLineageValues)
diffFromChildSQL, args, err := mainDiffFromChild.
Prefix("CREATE TEMP TABLE " + diffResultsTableName + " ON COMMIT DROP AS").
Expand Down
15 changes: 11 additions & 4 deletions catalog/cataloger_list_commits.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,21 @@ func (c *cataloger) ListCommits(ctx context.Context, repository, branch string,
if err != nil {
return nil, err
}
lineage, err := getLineage(tx, branchID, CommittedID)
lineage, err := getLineage(tx, branchID, fromCommitID)
if err != nil {
return nil, fmt.Errorf("get lineage: %w", err)
}
lineageAsValuesTable := getLineageAsValues(lineage, branchID)
query := `SELECT b_name.name as branch_name,c.commit_id,c.previous_commit_id,c.committer,c.message,c.creation_date,c.metadata,
lineageAsValuesTable := getLineageAsValues(lineage, branchID, fromCommitID)
cte := `WITH RECURSIVE lineage_graph AS (
select branch_id,commit_id from ` + lineageAsValuesTable + `
union all
select * from (Select distinct on (c.branch_id,c.merge_source_branch) merge_source_branch,merge_source_commit from catalog_commits c
join lineage_graph l on l.branch_id = c.branch_id and c.merge_type='from_child' and c.merge_source_commit < l.commit_id
order by c.branch_id,c.merge_source_branch,c.commit_id desc )t)
`
query := cte + `SELECT b_name.name as branch_name,c.commit_id,c.previous_commit_id,c.committer,c.message,c.creation_date,c.metadata,
COALESCE(bb.name,'') as merge_source_branch_name,COALESCE(c.merge_source_commit,0) as merge_source_commit
FROM catalog_commits c JOIN (SELECT * FROM ` + lineageAsValuesTable + `) l ON c.branch_id = l.branch_id and c.commit_id <= l.commit_id
FROM catalog_commits c JOIN lineage_graph l ON c.branch_id = l.branch_id and c.commit_id <= l.commit_id
JOIN catalog_branches b_name ON c.branch_id = b_name.id
LEFT JOIN catalog_branches bb ON bb.id = c.merge_source_branch
WHERE c.commit_id < $1
Expand Down
151 changes: 144 additions & 7 deletions catalog/cataloger_list_commits_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ func TestCataloger_ListCommits(t *testing.T) {
limit: -1,
},
want: []*CommitLog{
{Reference: commits[2].Reference, Committer: "tester", Message: "commit3", Metadata: Metadata{}, Parents: []string{"~KJ8Wd1Rs96a"}},
{Reference: commits[1].Reference, Committer: "tester", Message: "commit2", Metadata: Metadata{}, Parents: []string{"~KJ8Wd1Rs96Z"}},
{Reference: commits[0].Reference, Committer: "tester", Message: "commit1", Metadata: Metadata{}, Parents: []string{"~KJ8Wd1Rs96Y"}},
{Reference: commits[2].Reference, Committer: "tester", Message: "commit3 on branch master", Metadata: Metadata{}, Parents: []string{"~KJ8Wd1Rs96a"}},
{Reference: commits[1].Reference, Committer: "tester", Message: "commit2 on branch master", Metadata: Metadata{}, Parents: []string{"~KJ8Wd1Rs96Z"}},
{Reference: commits[0].Reference, Committer: "tester", Message: "commit1 on branch master", Metadata: Metadata{}, Parents: []string{"~KJ8Wd1Rs96Y"}},
{Reference: initialCommitReference, Committer: CatalogerCommitter, Message: createRepositoryCommitMessage, Metadata: Metadata{}},
},
wantMore: false,
Expand All @@ -62,8 +62,8 @@ func TestCataloger_ListCommits(t *testing.T) {
limit: 2,
},
want: []*CommitLog{
{Reference: commits[2].Reference, Committer: "tester", Message: "commit3", Metadata: Metadata{}, Parents: []string{"~KJ8Wd1Rs96a"}},
{Reference: commits[1].Reference, Committer: "tester", Message: "commit2", Metadata: Metadata{}, Parents: []string{"~KJ8Wd1Rs96Z"}},
{Reference: commits[2].Reference, Committer: "tester", Message: "commit3 on branch master", Metadata: Metadata{}, Parents: []string{"~KJ8Wd1Rs96a"}},
{Reference: commits[1].Reference, Committer: "tester", Message: "commit2 on branch master", Metadata: Metadata{}, Parents: []string{"~KJ8Wd1Rs96Z"}},
},
wantMore: true,
wantErr: false,
Expand Down Expand Up @@ -91,7 +91,7 @@ func TestCataloger_ListCommits(t *testing.T) {
limit: 1,
},
want: []*CommitLog{
{Reference: commits[1].Reference, Committer: "tester", Message: "commit2", Metadata: Metadata{}, Parents: []string{"~KJ8Wd1Rs96Z"}},
{Reference: commits[1].Reference, Committer: "tester", Message: "commit2 on branch master", Metadata: Metadata{}, Parents: []string{"~KJ8Wd1Rs96Z"}},
},
wantMore: true,
wantErr: false,
Expand Down Expand Up @@ -204,7 +204,7 @@ func setupListCommitsByBranchData(t *testing.T, ctx context.Context, c Cataloger
}, CreateEntryParams{}); err != nil {
t.Fatal("Write entry for list repository commits failed", err)
}
message := "commit" + strconv.Itoa(i+1)
message := "commit" + strconv.Itoa(i+1) + " on branch " + branch
commitLog, err := c.Commit(ctx, repository, branch, message, "tester", nil)
if err != nil {
t.Fatalf("Commit for list repository commits failed '%s': %s", message, err)
Expand Down Expand Up @@ -270,3 +270,140 @@ func TestCataloger_ListCommits_Lineage(t *testing.T) {
t.Error("br_1 did not inherit commits correctly", diff)
}
}

func TestCataloger_ListCommits_LineageFromChild(t *testing.T) {
ctx := context.Background()
c := testCataloger(t)

repository := testCatalogerRepo(t, ctx, c, "repository", "master")
_ = setupListCommitsByBranchData(t, ctx, c, repository, "master")

testCatalogerBranch(t, ctx, c, repository, "br_1_1", "master")
testCatalogerBranch(t, ctx, c, repository, "br_1_2", "br_1_1")
masterCommits, _, err := c.ListCommits(ctx, repository, "master", "", 100)
testutil.MustDo(t, "list master commits", err)

br1Commits, _, err := c.ListCommits(ctx, repository, "br_1_1", "", 100)
testutil.MustDo(t, "list br_1_1 commits", err)

// get all commits without the first one
if diff := deep.Equal(masterCommits, br1Commits[1:]); diff != nil {
t.Error("br_1_1 did not inherit commits correctly", diff)
}

b2Commits, _, err := c.ListCommits(ctx, repository, "br_1_2", "", 100)
testutil.MustDo(t, "list br_1_2 commits", err)

if diff := deep.Equal(br1Commits, b2Commits[1:]); diff != nil {
t.Error("br_1_2 did not inherit commits correctly", diff)
}

if err := c.CreateEntry(ctx, repository, "master", Entry{
Path: "master-file",
Checksum: "ssss",
PhysicalAddress: "xxxxxxx",
Size: 10000,
}, CreateEntryParams{}); err != nil {
t.Fatal("Write entry for list repository commits failed", err)
}
_, err = c.Commit(ctx, repository, "master", "commit master-file on master", "tester", nil)
if err != nil {
t.Fatalf("Commit for list repository commits failed '%s': %s", "master commit failed", err)
}
_, err = c.Merge(ctx, repository, "master", "br_1_1", "tester", "merge master to br_1_1", nil)
testutil.MustDo(t, "merge master into br_1_1", err)

got, _, err := c.ListCommits(ctx, repository, "br_1_2", "", 100)
testutil.MustDo(t, "list br_1_2 commits", err)
if diff := deep.Equal(got, b2Commits); diff != nil {
t.Error("br_1_2 changed although not merged", diff)
}
masterCommits, _, err = c.ListCommits(ctx, repository, "master", "", 100)
testutil.MustDo(t, "list master commits", err)

br11BaseList, _, err := c.ListCommits(ctx, repository, "br_1_1", "", 100)
testutil.MustDo(t, "list br_1_1 commits", err)
if diff := deep.Equal(masterCommits[0], br11BaseList[1]); diff != nil {
t.Error("br_1_1 did not inherit commits correctly", diff)
}

testCatalogerBranch(t, ctx, c, repository, "br_2_1", "master")
testCatalogerBranch(t, ctx, c, repository, "br_2_2", "br_2_1")
if err := c.CreateEntry(ctx, repository, "br_2_2", Entry{
Path: "master-file",
Checksum: "zzzzz",
PhysicalAddress: "yyyyy",
Size: 20000,
}, CreateEntryParams{}); err != nil {
t.Fatal("Write entry to br_2_2 failed", err)
}
_, err = c.Commit(ctx, repository, "br_2_2", "commit master-file to br_2_2", "tester", nil)
if err != nil {
t.Fatalf("Commit for list repository commits failed '%s': %s", "br_2_2 commit failed", err)
}
br22List, _, err := c.ListCommits(ctx, repository, "br_2_2", "", 100)
testutil.MustDo(t, "list br_2_2 commits", err)
_ = br22List
_, err = c.Merge(ctx, repository, "br_2_2", "br_2_1", "tester", "merge br_2_2 to br_2_1", nil)
testutil.MustDo(t, "merge br_2_2 into br_2_1", err)
br21List, _, err := c.ListCommits(ctx, repository, "br_2_1", "", 100)
testutil.MustDo(t, "list br_2_1 commits", err)
_ = br21List
masterList, _, err := c.ListCommits(ctx, repository, "master", "", 100)
testutil.MustDo(t, "list master commits", err)
if diff := deep.Equal(masterCommits, masterList); diff != nil {
t.Error("master commits changed before merge", diff)
}
merge2, err := c.Merge(ctx, repository, "br_2_1", "master", "tester", "merge br_2_1 to master", nil)
testutil.MustDo(t, "merge br_2_1 into master", err)
if merge2.Differences[0].Type != DifferenceTypeChanged || merge2.Differences[0].Path != "master-file" {
t.Error("merge br_2_1 into master with unexpected results", merge2.Differences[0])
}

masterList, _, err = c.ListCommits(ctx, repository, "master", "", 100)
testutil.MustDo(t, "list master commits", err)
if diff := deep.Equal(br21List, masterList[1:]); diff != nil {
t.Error("master commits list mismatch with br_2_1_list", diff)
}

br11List, _, err := c.ListCommits(ctx, repository, "br_1_1", "", 100)
testutil.MustDo(t, "list br_1_1 commits", err)
if diff := deep.Equal(br11BaseList, br11List); diff != nil {
t.Error("br_1_1 commits changed before merge", diff)
}
_, err = c.Merge(ctx, repository, "master", "br_1_1", "tester", "merge master to br_1_1", nil)
testutil.MustDo(t, "merge master into br_1_1", err)
br11List, _, err = c.ListCommits(ctx, repository, "br_1_1", "", 100)
testutil.MustDo(t, "list br_1_1 commits", err)
if diff := deep.Equal(masterList[:5], br11List[1:6]); diff != nil {
t.Error("master 5 first different from br_1_1 [1:6]", diff)
}
if diff := deep.Equal(masterList[6:], br11List[9:]); diff != nil {
t.Error("master 5 first different from br_1_1 [1:6]", diff)
}
// test that a change to br_2_2 does not propagate to master
if err := c.CreateEntry(ctx, repository, "br_2_2", Entry{
Path: "no-propagate-file",
Checksum: "aaaaaaaa",
PhysicalAddress: "yybbbbbbyyy",
Size: 20000,
}, CreateEntryParams{}); err != nil {
t.Fatal("Write no-propagate-file to br_2_2 failed", err)
}
_, err = c.Commit(ctx, repository, "br_2_2", "commit master-file to br_2_2", "tester", nil)
if err != nil {
t.Fatalf("no-propagate-Commit for list repository commits failed '%s': %s", "br_2_2 commit failed", err)
}
_, err = c.Merge(ctx, repository, "br_2_2", "br_2_1", "tester", "merge br_2_2 to br_2_1", nil)
testutil.MustDo(t, "second merge br_2_2 into br_2_1", err)
newBr21List, _, err := c.ListCommits(ctx, repository, "br_2_1", "", 100)
testutil.MustDo(t, "second list br_2_1 commits", err)
if diff := deep.Equal(br21List, newBr21List); diff == nil {
t.Error("br_2_1 commits did not changed after merge", diff)
}
newMasterList, _, err := c.ListCommits(ctx, repository, "master", "", 100)
testutil.MustDo(t, "third list master commits", err)
if diff := deep.Equal(newMasterList, masterList); diff != nil {
t.Error("master commits changed without merge", diff)
}
}
4 changes: 2 additions & 2 deletions catalog/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,9 +142,9 @@ func getLineage(tx db.Tx, branchID int64, commitID CommitID) ([]lineageCommit, e
return requestedLineage, nil
}

func getLineageAsValues(lineage []lineageCommit, branchID int64) string {
func getLineageAsValues(lineage []lineageCommit, branchID int64, commitID CommitID) string {
valArray := make([]string, 1, len(lineage)+1)
valArray[0] = fmt.Sprintf("(0,%d,%d)", branchID, MaxCommitID)
valArray[0] = fmt.Sprintf("(0,%d::bigint,%d::bigint)", branchID, commitID)
for precedence, lineageBranch := range lineage {
valArray = append(valArray, fmt.Sprintf("(%d,%d,%d)", precedence+1, lineageBranch.BranchID, lineageBranch.CommitID))
}
Expand Down
2 changes: 1 addition & 1 deletion catalog/views.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ func sqDiffFromChildV(parentID, childID int64, parentEffectiveCommit, childEffec
}

func sqDiffFromParentV(parentID, childID int64, lastChildMergeWithParent CommitID, parentUncommittedLineage, childUncommittedLineage []lineageCommit) sq.SelectBuilder {
childLineageValues := getLineageAsValues(childUncommittedLineage, childID)
childLineageValues := getLineageAsValues(childUncommittedLineage, childID, MaxCommitID)
childLineage := sqEntriesLineage(childID, UncommittedID, childUncommittedLineage)
sqChild := sq.Select("*").
FromSelect(childLineage, "s").
Expand Down

0 comments on commit 74b2cf5

Please sign in to comment.