Преглед на файлове

Fix getting the results from a tree history

Vadim Markovtsev преди 6 години
родител
ревизия
8ef665fbfe
променени са 2 файла, в които са добавени 63 реда и са изтрити 67 реда
  1. 17 25
      internal/core/pipeline.go
  2. 46 42
      internal/core/pipeline_test.go

+ 17 - 25
internal/core/pipeline.go

@@ -362,31 +362,18 @@ func (pipeline *Pipeline) Len() int {
 	return len(pipeline.items)
 }
 
-// Commits returns the critical path in the repository's history. It starts
-// from HEAD and traces commits backwards till the root. When it encounters
-// a merge (more than one parent), it always chooses the first parent.
+// Commits returns the list of commits from the history similar to `git log` over the HEAD.
 func (pipeline *Pipeline) Commits() []*object.Commit {
-	result := []*object.Commit{}
-	repository := pipeline.repository
-	head, err := repository.Head()
+	cit, err := pipeline.repository.Log(&git.LogOptions{From: plumbing.ZeroHash})
 	if err != nil {
-		panic(err)
+		log.Fatalf("unable to collect the commit history: %v", err)
 	}
-	commit, err := repository.CommitObject(head.Hash())
-	if err != nil {
-		panic(err)
-	}
-	// the first parent matches the head
-	for ; err != io.EOF; commit, err = commit.Parents().Next() {
-		if err != nil {
-			panic(err)
-		}
+	defer cit.Close()
+	var result []*object.Commit
+	cit.ForEach(func(commit *object.Commit) error {
 		result = append(result, commit)
-	}
-	// reverse the order
-	for i, j := 0, len(result)-1; i < j; i, j = i+1, j-1 {
-		result[i], result[j] = result[j], result[i]
-	}
+		return nil
+	})
 	return result
 }
 
@@ -567,6 +554,7 @@ func (pipeline *Pipeline) Run(commits []*object.Commit) (map[LeafPipelineItem]in
 	plan := prepareRunPlan(commits)
 	progressSteps := len(plan) + 2
 	branches := map[int][]PipelineItem{0: pipeline.items}
+	var newestTime int64
 
 	for index, step := range plan {
 		onProgress(index + 1, progressSteps)
@@ -592,6 +580,10 @@ func (pipeline *Pipeline) Run(commits []*object.Commit) (map[LeafPipelineItem]in
 					state[key] = val
 				}
 			}
+			commitTime := step.Commit.Author.When.Unix()
+			if commitTime > newestTime {
+				newestTime = commitTime
+			}
 		case runActionFork:
 			for i, clone := range cloneItems(branches[firstItem], len(step.Items)-1) {
 				branches[step.Items[i+1]] = clone
@@ -608,15 +600,15 @@ func (pipeline *Pipeline) Run(commits []*object.Commit) (map[LeafPipelineItem]in
 	}
 	onProgress(len(plan) + 1, progressSteps)
 	result := map[LeafPipelineItem]interface{}{}
-	for _, item := range getMasterBranch(branches) {
+	for index, item := range getMasterBranch(branches) {
 		if casted, ok := item.(LeafPipelineItem); ok {
-			result[casted] = casted.Finalize()
+			result[pipeline.items[index].(LeafPipelineItem)] = casted.Finalize()
 		}
 	}
 	onProgress(progressSteps, progressSteps)
 	result[nil] = &CommonAnalysisResult{
-		BeginTime:     commits[0].Author.When.Unix(),
-		EndTime:       commits[len(commits)-1].Author.When.Unix(),
+		BeginTime:     plan[0].Commit.Author.When.Unix(),
+		EndTime:       newestTime,
 		CommitsNumber: len(commits),
 		RunTime:       time.Since(startRunTime),
 	}

+ 46 - 42
internal/core/pipeline_test.go

@@ -285,12 +285,14 @@ func TestPipelineOnProgress(t *testing.T) {
 func TestPipelineCommits(t *testing.T) {
 	pipeline := NewPipeline(test.Repository)
 	commits := pipeline.Commits()
-	assert.True(t, len(commits) >= 90)
-	assert.Equal(t, commits[0].Hash, plumbing.NewHash(
+	assert.True(t, len(commits) >= 100)
+	hashMap := map[plumbing.Hash]bool{}
+	for _, c := range commits {
+		hashMap[c.Hash] = true
+	}
+	assert.Equal(t, len(commits), len(hashMap))
+	assert.Contains(t, hashMap, plumbing.NewHash(
 		"cce947b98a050c6d356bc6ba95030254914027b1"))
-	assert.Equal(t, commits[89].Hash, plumbing.NewHash(
-		"6db8065cdb9bb0758f36a7e75fc72ab95f9e8145"))
-	assert.NotEqual(t, commits[len(commits)-1], commits[len(commits)-2])
 }
 
 func TestLoadCommitsFromFile(t *testing.T) {
@@ -491,50 +493,52 @@ func TestPrepareRunPlanBig(t *testing.T) {
 		{2018, 5, 16, 13, 9, 13, 13},
 	}
 	for _, testCase := range cases {
-		cit, err := test.Repository.Log(&git.LogOptions{From: plumbing.ZeroHash})
-		if err != nil {
-			panic(err)
-		}
-		defer cit.Close()
-		var commits []*object.Commit
-		timeCutoff := time.Date(
-			testCase[0], time.Month(testCase[1]), testCase[2], 0, 0, 0, 0, time.FixedZone("CET", 7200))
-		cit.ForEach(func(commit *object.Commit) error {
-			reliableTime := time.Date(commit.Author.When.Year(), commit.Author.When.Month(),
-				commit.Author.When.Day(), commit.Author.When.Hour(), commit.Author.When.Minute(),
-				commit.Author.When.Second(), 0, time.FixedZone("CET", 7200))
-			if reliableTime.Before(timeCutoff) {
-				commits = append(commits, commit)
+		func() {
+			cit, err := test.Repository.Log(&git.LogOptions{From: plumbing.ZeroHash})
+			if err != nil {
+				panic(err)
 			}
-			return nil
-		})
-		plan := prepareRunPlan(commits)
-		/*for _, p := range plan {
+			defer cit.Close()
+			var commits []*object.Commit
+			timeCutoff := time.Date(
+				testCase[0], time.Month(testCase[1]), testCase[2], 0, 0, 0, 0, time.FixedZone("CET", 7200))
+			cit.ForEach(func(commit *object.Commit) error {
+				reliableTime := time.Date(commit.Author.When.Year(), commit.Author.When.Month(),
+					commit.Author.When.Day(), commit.Author.When.Hour(), commit.Author.When.Minute(),
+					commit.Author.When.Second(), 0, time.FixedZone("CET", 7200))
+				if reliableTime.Before(timeCutoff) {
+					commits = append(commits, commit)
+				}
+				return nil
+			})
+			plan := prepareRunPlan(commits)
+			/*for _, p := range plan {
 			if p.Commit != nil {
 				fmt.Println(p.Action, p.Commit.Hash.String(), p.Items)
 			} else {
 				fmt.Println(p.Action, strings.Repeat(" ", 40), p.Items)
 			}
 		}*/
-		numCommits := 0
-		numForks := 0
-		numMerges := 0
-		numDeletes := 0
-		for _, p := range plan {
-			switch p.Action {
-			case runActionCommit:
-				numCommits++
-			case runActionFork:
-				numForks++
-			case runActionMerge:
-				numMerges++
-			case runActionDelete:
-				numDeletes++
+			numCommits := 0
+			numForks := 0
+			numMerges := 0
+			numDeletes := 0
+			for _, p := range plan {
+				switch p.Action {
+				case runActionCommit:
+					numCommits++
+				case runActionFork:
+					numForks++
+				case runActionMerge:
+					numMerges++
+				case runActionDelete:
+					numDeletes++
+				}
 			}
-		}
-		assert.Equal(t, numCommits, len(commits)+testCase[3], fmt.Sprintf("commits %v", testCase))
-		assert.Equal(t, numForks, testCase[4], fmt.Sprintf("forks %v", testCase))
-		assert.Equal(t, numMerges, testCase[5], fmt.Sprintf("merges %v", testCase))
-		assert.Equal(t, numMerges, testCase[6], fmt.Sprintf("deletes %v", testCase))
+			assert.Equal(t, numCommits, len(commits)+testCase[3], fmt.Sprintf("commits %v", testCase))
+			assert.Equal(t, numForks, testCase[4], fmt.Sprintf("forks %v", testCase))
+			assert.Equal(t, numMerges, testCase[5], fmt.Sprintf("merges %v", testCase))
+			assert.Equal(t, numMerges, testCase[6], fmt.Sprintf("deletes %v", testCase))
+		}()
 	}
 }