| 
															
																@@ -8,7 +8,7 @@ import ( 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 	"gopkg.in/src-d/go-git.v4/plumbing/object" 
															 | 
															
															 | 
															
																 	"gopkg.in/src-d/go-git.v4/plumbing/object" 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 	"gopkg.in/src-d/go-git.v4/plumbing" 
															 | 
															
															 | 
															
																 	"gopkg.in/src-d/go-git.v4/plumbing" 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 	"gopkg.in/src-d/hercules.v4/internal/toposort" 
															 | 
															
															 | 
															
																 	"gopkg.in/src-d/hercules.v4/internal/toposort" 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-		) 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+) 
															 | 
														
													
												
													
														
															| 
															 | 
															
																  
															 | 
															
															 | 
															
																  
															 | 
														
													
												
													
														
															| 
															 | 
															
																 // OneShotMergeProcessor provides the convenience method to consume merges only once. 
															 | 
															
															 | 
															
																 // OneShotMergeProcessor provides the convenience method to consume merges only once. 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 type OneShotMergeProcessor struct { 
															 | 
															
															 | 
															
																 type OneShotMergeProcessor struct { 
															 | 
														
													
												
											
												
													
														
															 | 
															
																@@ -77,6 +77,8 @@ const ( 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 	runActionFork = iota 
															 | 
															
															 | 
															
																 	runActionFork = iota 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 	// runActionMerge merges several branches together 
															 | 
															
															 | 
															
																 	// runActionMerge merges several branches together 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 	runActionMerge = iota 
															 | 
															
															 | 
															
																 	runActionMerge = iota 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+	// runActionEmerge starts a root branch 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+	runActionEmerge = iota 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 	// runActionDelete removes the branch as it is no longer needed 
															 | 
															
															 | 
															
																 	// runActionDelete removes the branch as it is no longer needed 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 	runActionDelete = iota 
															 | 
															
															 | 
															
																 	runActionDelete = iota 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 ) 
															 | 
															
															 | 
															
																 ) 
															 | 
														
													
												
											
												
													
														
															 | 
															
																@@ -130,7 +132,6 @@ func getMasterBranch(branches map[int][]PipelineItem) []PipelineItem { 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 func prepareRunPlan(commits []*object.Commit) []runAction { 
															 | 
															
															 | 
															
																 func prepareRunPlan(commits []*object.Commit) []runAction { 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 	hashes, dag := buildDag(commits) 
															 | 
															
															 | 
															
																 	hashes, dag := buildDag(commits) 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 	leaveRootComponent(hashes, dag) 
															 | 
															
															 | 
															
																 	leaveRootComponent(hashes, dag) 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-	numParents := bindNumParents(hashes, dag) 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 	mergedDag, mergedSeq := mergeDag(hashes, dag) 
															 | 
															
															 | 
															
																 	mergedDag, mergedSeq := mergeDag(hashes, dag) 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 	orderNodes := bindOrderNodes(mergedDag) 
															 | 
															
															 | 
															
																 	orderNodes := bindOrderNodes(mergedDag) 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 	collapseFastForwards(orderNodes, hashes, mergedDag, dag, mergedSeq) 
															 | 
															
															 | 
															
																 	collapseFastForwards(orderNodes, hashes, mergedDag, dag, mergedSeq) 
															 | 
														
													
												
											
												
													
														
															 | 
															
																@@ -143,7 +144,7 @@ func prepareRunPlan(commits []*object.Commit) []runAction { 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 		} 
															 | 
															
															 | 
															
																 		} 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 	} 
															 | 
															
															 | 
															
																 	} 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 	fmt.Printf("}\n")*/ 
															 | 
															
															 | 
															
																 	fmt.Printf("}\n")*/ 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-	plan := generatePlan(orderNodes, numParents, hashes, mergedDag, dag, mergedSeq) 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+	plan := generatePlan(orderNodes, hashes, mergedDag, dag, mergedSeq) 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 	plan = optimizePlan(plan) 
															 | 
															
															 | 
															
																 	plan = optimizePlan(plan) 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 	/*for _, p := range plan { 
															 | 
															
															 | 
															
																 	/*for _, p := range plan { 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 		firstItem := p.Items[0] 
															 | 
															
															 | 
															
																 		firstItem := p.Items[0] 
															 | 
														
													
												
											
												
													
														
															 | 
															
																@@ -186,26 +187,6 @@ func buildDag(commits []*object.Commit) ( 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 	return hashes, dag 
															 | 
															
															 | 
															
																 	return hashes, dag 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 } 
															 | 
															
															 | 
															
																 } 
															 | 
														
													
												
													
														
															| 
															 | 
															
																  
															 | 
															
															 | 
															
																  
															 | 
														
													
												
													
														
															| 
															 | 
															
																-// bindNumParents returns curried "numParents" function. 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-func bindNumParents( 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-	hashes map[string]*object.Commit, 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-	dag map[plumbing.Hash][]*object.Commit) func(c *object.Commit) int { 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-	return func(c *object.Commit) int { 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-		r := 0 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-		for _, parent := range c.ParentHashes { 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-			if p, exists := hashes[parent.String()]; exists { 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-				for _, pc := range dag[p.Hash] { 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-					if pc.Hash == c.Hash { 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-						r++ 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-						break 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-					} 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-				} 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-			} 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-		} 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-		return r 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-	} 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-} 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																- 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 // leaveRootComponent runs connected components analysis and throws away everything 
															 | 
															
															 | 
															
																 // leaveRootComponent runs connected components analysis and throws away everything 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 // but the part which grows from the root. 
															 | 
															
															 | 
															
																 // but the part which grows from the root. 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 func leaveRootComponent( 
															 | 
															
															 | 
															
																 func leaveRootComponent( 
															 | 
														
													
												
											
												
													
														
															 | 
															
																@@ -306,18 +287,24 @@ func bindOrderNodes(mergedDag map[plumbing.Hash][]*object.Commit) orderer { 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 	} 
															 | 
															
															 | 
															
																 	} 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 } 
															 | 
															
															 | 
															
																 } 
															 | 
														
													
												
													
														
															| 
															 | 
															
																  
															 | 
															
															 | 
															
																  
															 | 
														
													
												
													
														
															| 
															 | 
															
																-// mergeDag turns sequences of consecutive commits into single nodes. 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-func mergeDag( 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-	hashes map[string]*object.Commit, 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-	dag map[plumbing.Hash][]*object.Commit) ( 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-	mergedDag, mergedSeq map[plumbing.Hash][]*object.Commit) { 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																- 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+// inverts `dag` 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+func buildParents(dag map[plumbing.Hash][]*object.Commit) map[plumbing.Hash][]plumbing.Hash { 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 	parents := map[plumbing.Hash][]plumbing.Hash{} 
															 | 
															
															 | 
															
																 	parents := map[plumbing.Hash][]plumbing.Hash{} 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 	for key, vals := range dag { 
															 | 
															
															 | 
															
																 	for key, vals := range dag { 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 		for _, val := range vals { 
															 | 
															
															 | 
															
																 		for _, val := range vals { 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 			parents[val.Hash] = append(parents[val.Hash], key) 
															 | 
															
															 | 
															
																 			parents[val.Hash] = append(parents[val.Hash], key) 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 		} 
															 | 
															
															 | 
															
																 		} 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 	} 
															 | 
															
															 | 
															
																 	} 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+	return parents 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+} 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+ 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+// mergeDag turns sequences of consecutive commits into single nodes. 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+func mergeDag( 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+	hashes map[string]*object.Commit, 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+	dag map[plumbing.Hash][]*object.Commit) ( 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+	mergedDag, mergedSeq map[plumbing.Hash][]*object.Commit) { 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+ 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+	parents := buildParents(dag) 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 	mergedDag = map[plumbing.Hash][]*object.Commit{} 
															 | 
															
															 | 
															
																 	mergedDag = map[plumbing.Hash][]*object.Commit{} 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 	mergedSeq = map[plumbing.Hash][]*object.Commit{} 
															 | 
															
															 | 
															
																 	mergedSeq = map[plumbing.Hash][]*object.Commit{} 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 	visited := map[plumbing.Hash]bool{} 
															 | 
															
															 | 
															
																 	visited := map[plumbing.Hash]bool{} 
															 | 
														
													
												
											
												
													
														
															 | 
															
																@@ -357,12 +344,7 @@ func collapseFastForwards( 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 	orderNodes orderer, hashes map[string]*object.Commit, 
															 | 
															
															 | 
															
																 	orderNodes orderer, hashes map[string]*object.Commit, 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 	mergedDag, dag, mergedSeq map[plumbing.Hash][]*object.Commit)  { 
															 | 
															
															 | 
															
																 	mergedDag, dag, mergedSeq map[plumbing.Hash][]*object.Commit)  { 
															 | 
														
													
												
													
														
															| 
															 | 
															
																  
															 | 
															
															 | 
															
																  
															 | 
														
													
												
													
														
															| 
															 | 
															
																-	parents := map[plumbing.Hash][]plumbing.Hash{} 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-	for key, vals := range mergedDag { 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-		for _, val := range vals { 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-			parents[val.Hash] = append(parents[val.Hash], key) 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-		} 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-	} 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+	parents := buildParents(mergedDag) 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 	processed := map[plumbing.Hash]bool{} 
															 | 
															
															 | 
															
																 	processed := map[plumbing.Hash]bool{} 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 	for _, strkey := range orderNodes(false, true) { 
															 | 
															
															 | 
															
																 	for _, strkey := range orderNodes(false, true) { 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 		key := hashes[strkey].Hash 
															 | 
															
															 | 
															
																 		key := hashes[strkey].Hash 
															 | 
														
													
												
											
												
													
														
															 | 
															
																@@ -473,18 +455,24 @@ func collapseFastForwards( 
															 | 
														
													
												
													
														
															| 
															 | 
															
																  
															 | 
															
															 | 
															
																  
															 | 
														
													
												
													
														
															| 
															 | 
															
																 // generatePlan creates the list of actions from the commit DAG. 
															 | 
															
															 | 
															
																 // generatePlan creates the list of actions from the commit DAG. 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 func generatePlan( 
															 | 
															
															 | 
															
																 func generatePlan( 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-	orderNodes orderer, numParents func(c *object.Commit) int, 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-	hashes map[string]*object.Commit, 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+	orderNodes orderer, hashes map[string]*object.Commit, 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 	mergedDag, dag, mergedSeq map[plumbing.Hash][]*object.Commit) []runAction { 
															 | 
															
															 | 
															
																 	mergedDag, dag, mergedSeq map[plumbing.Hash][]*object.Commit) []runAction { 
															 | 
														
													
												
													
														
															| 
															 | 
															
																  
															 | 
															
															 | 
															
																  
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+	parents := buildParents(dag) 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 	var plan []runAction 
															 | 
															
															 | 
															
																 	var plan []runAction 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 	branches := map[plumbing.Hash]int{} 
															 | 
															
															 | 
															
																 	branches := map[plumbing.Hash]int{} 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 	branchers := map[plumbing.Hash]map[plumbing.Hash]int{} 
															 | 
															
															 | 
															
																 	branchers := map[plumbing.Hash]map[plumbing.Hash]int{} 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-	counter := 1 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-	for seqIndex, name := range orderNodes(false, true) { 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+	counter := 0 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+	for _, name := range orderNodes(false, true) { 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 		commit := hashes[name] 
															 | 
															
															 | 
															
																 		commit := hashes[name] 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-		if seqIndex == 0 { 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-			branches[commit.Hash] = 0 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+		if len(parents[commit.Hash]) == 0 { 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+			branches[commit.Hash] = counter 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+			plan = append(plan, runAction{ 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+				Action: runActionEmerge, 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+				Commit: commit, 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+				Items: []int{counter}, 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+			}) 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+			counter++ 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 		} 
															 | 
															
															 | 
															
																 		} 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 		var branch int 
															 | 
															
															 | 
															
																 		var branch int 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 		{ 
															 | 
															
															 | 
															
																 		{ 
															 | 
														
													
												
											
												
													
														
															 | 
															
																@@ -504,16 +492,13 @@ func generatePlan( 
															 | 
														
													
												
													
														
															| 
															 | 
															
																  
															 | 
															
															 | 
															
																  
															 | 
														
													
												
													
														
															| 
															 | 
															
																 		} 
															 | 
															
															 | 
															
																 		} 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 		appendMergeIfNeeded := func() { 
															 | 
															
															 | 
															
																 		appendMergeIfNeeded := func() { 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-			if numParents(commit) < 2 { 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+			if len(parents[commit.Hash]) < 2 { 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 				return 
															 | 
															
															 | 
															
																 				return 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 			} 
															 | 
															
															 | 
															
																 			} 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 			// merge after the merge commit (the first in the sequence) 
															 | 
															
															 | 
															
																 			// merge after the merge commit (the first in the sequence) 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 			var items []int 
															 | 
															
															 | 
															
																 			var items []int 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 			minBranch := 1 << 31 
															 | 
															
															 | 
															
																 			minBranch := 1 << 31 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-			for _, parent := range commit.ParentHashes { 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-				if _, exists := hashes[parent.String()]; !exists { 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-					continue 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-				} 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+			for _, parent := range parents[commit.Hash] { 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 				parentBranch := -1 
															 | 
															
															 | 
															
																 				parentBranch := -1 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 				if parents, exists := branchers[commit.Hash]; exists { 
															 | 
															
															 | 
															
																 				if parents, exists := branchers[commit.Hash]; exists { 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 					if inheritedBranch, exists := parents[parent]; exists { 
															 | 
															
															 | 
															
																 					if inheritedBranch, exists := parents[parent]; exists { 
															 | 
														
													
												
											
												
													
														
															 | 
															
																@@ -522,6 +507,10 @@ func generatePlan( 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 				} 
															 | 
															
															 | 
															
																 				} 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 				if parentBranch == -1 { 
															 | 
															
															 | 
															
																 				if parentBranch == -1 { 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 					parentBranch = branches[parent] 
															 | 
															
															 | 
															
																 					parentBranch = branches[parent] 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+					if parentBranch == -1 { 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+						log.Panicf("parent %s > %s does not have a branch assigned", 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+							parent.String(), commit.Hash.String()) 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+					} 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 				} 
															 | 
															
															 | 
															
																 				} 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 				if len(dag[parent]) == 1 && minBranch > parentBranch { 
															 | 
															
															 | 
															
																 				if len(dag[parent]) == 1 && minBranch > parentBranch { 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 					minBranch = parentBranch 
															 | 
															
															 | 
															
																 					minBranch = parentBranch 
															 | 
														
													
												
											
												
													
														
															 | 
															
																@@ -531,6 +520,7 @@ func generatePlan( 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 					appendCommit(commit, parentBranch) 
															 | 
															
															 | 
															
																 					appendCommit(commit, parentBranch) 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 				} 
															 | 
															
															 | 
															
																 				} 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 			} 
															 | 
															
															 | 
															
																 			} 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+			// there should be no duplicates in items 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 			if minBranch < 1 << 31 { 
															 | 
															
															 | 
															
																 			if minBranch < 1 << 31 { 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 				branch = minBranch 
															 | 
															
															 | 
															
																 				branch = minBranch 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 				branches[commit.Hash] = minBranch 
															 | 
															
															 | 
															
																 				branches[commit.Hash] = minBranch 
															 | 
														
													
												
											
												
													
														
															 | 
															
																@@ -606,12 +596,19 @@ func optimizePlan(plan []runAction) []runAction { 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 		case runActionCommit: 
															 | 
															
															 | 
															
																 		case runActionCommit: 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 			lives[firstItem]++ 
															 | 
															
															 | 
															
																 			lives[firstItem]++ 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 			lastMentioned[firstItem] = i 
															 | 
															
															 | 
															
																 			lastMentioned[firstItem] = i 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+			if firstItem == -1 { 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+				log.Panicf("commit %s does not have an assigned branch", 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+					p.Commit.Hash.String()) 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+			} 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 		case runActionFork: 
															 | 
															
															 | 
															
																 		case runActionFork: 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 			lastMentioned[firstItem] = i 
															 | 
															
															 | 
															
																 			lastMentioned[firstItem] = i 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 		case runActionMerge: 
															 | 
															
															 | 
															
																 		case runActionMerge: 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 			for _, item := range p.Items { 
															 | 
															
															 | 
															
																 			for _, item := range p.Items { 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 				lastMentioned[item] = i 
															 | 
															
															 | 
															
																 				lastMentioned[item] = i 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 			} 
															 | 
															
															 | 
															
																 			} 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+		case runActionEmerge: 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+			lives[firstItem]++ 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+			lastMentioned[firstItem] = i 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 		} 
															 | 
															
															 | 
															
																 		} 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 	} 
															 | 
															
															 | 
															
																 	} 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 	branchesToDelete := map[int]bool{} 
															 | 
															
															 | 
															
																 	branchesToDelete := map[int]bool{} 
															 | 
														
													
												
											
												
													
														
															 | 
															
																@@ -673,6 +670,8 @@ func optimizePlan(plan []runAction) []runAction { 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 						Items:  newBranches, 
															 | 
															
															 | 
															
																 						Items:  newBranches, 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 					}) 
															 | 
															
															 | 
															
																 					}) 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 				} 
															 | 
															
															 | 
															
																 				} 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+			case runActionEmerge: 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+				optimizedPlan = append(optimizedPlan, p) 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 			} 
															 | 
															
															 | 
															
																 			} 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 		} 
															 | 
															
															 | 
															
																 		} 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 		if pair[1] >= 0 { 
															 | 
															
															 | 
															
																 		if pair[1] >= 0 { 
															 |