Remove unreachable commits during update

master
Vitaliy Filippov 2017-04-13 01:11:58 +03:00
parent 6204444dbe
commit 2055178f3c
2 changed files with 67 additions and 2 deletions

View File

@ -108,6 +108,8 @@ func PushUpdate(opts PushUpdateOptions) (err error) {
var l *list.List
// Skip read parent commits when delete branch
if !isDelRef {
var oldCommit *git.Commit
// Push new branch
newCommit, err := gitRepo.GetCommit(opts.NewCommitID)
if err != nil {
@ -120,9 +122,13 @@ func PushUpdate(opts PushUpdateOptions) (err error) {
return fmt.Errorf("CommitsBefore [commit_id: %s]: %v", newCommit.ID, err)
}
} else {
l, err = newCommit.CommitsBeforeUntil(opts.OldCommitID)
oldCommit, err = gitRepo.GetCommit(opts.OldCommitID)
if err != nil {
return fmt.Errorf("CommitsBeforeUntil [commit_id: %s]: %v", opts.OldCommitID, err)
return fmt.Errorf("GetCommit [commit_id: %s]: %v", opts.OldCommitID, err)
}
l, err = gitRepo.CommitsBefore(newCommit, oldCommit)
if err != nil {
return fmt.Errorf("CommitsBetween [before: %s, until: %s]: %v", opts.NewCommitID, opts.OldCommitID, err)
}
}
@ -142,6 +148,34 @@ func PushUpdate(opts PushUpdateOptions) (err error) {
})
}
x.Insert(searchCommits)
if !isNewRef {
// Remove deleted commits if any
var d *list.List
d, err = gitRepo.CommitsBefore(oldCommit, newCommit)
if err != nil {
return fmt.Errorf("CommitsBetween [before: %s, until: %s]: %v", opts.OldCommitID, opts.NewCommitID, err)
}
rebasedCommits := make([]string, 0)
for e := d.Front(); e != nil; e = e.Next() {
commit := e.Value.(*git.Commit)
rebasedCommits = append(rebasedCommits, commit.ID.String())
}
if len(rebasedCommits) > 0 {
d, err = gitRepo.CommitsUnreachable(rebasedCommits)
if err != nil {
return fmt.Errorf("CommitsUnreachable: %v", err)
}
rebasedCommits = make([]string, 0)
for e := d.Front(); e != nil; e = e.Next() {
commit := e.Value.(*git.Commit)
rebasedCommits = append(rebasedCommits, commit.ID.String())
}
if len(rebasedCommits) > 0 {
x.In("sha", rebasedCommits).Delete(new(Commit))
}
}
}
}
if err := CommitRepoAction(CommitRepoActionOptions{

View File

@ -10,6 +10,7 @@ import (
"fmt"
"strconv"
"strings"
"errors"
"github.com/mcuadros/go-version"
)
@ -259,6 +260,18 @@ func (repo *Repository) FilesCountBetween(startCommitID, endCommitID string) (in
return len(strings.Split(stdout, "\n")) - 1, nil
}
// CommitsBetween returns a list that contains commits between (since, before].
func (repo *Repository) CommitsBefore(before *Commit, since *Commit) (*list.List, error) {
if version.Compare(gitVersion, "1.8.0", ">=") {
stdout, err := NewCommand("rev-list", since.ID.String()+".."+before.ID.String()).RunInDirBytes(repo.Path)
if err != nil {
return nil, err
}
return repo.parsePrettyFormatLogToList(bytes.TrimSpace(stdout))
}
return nil, errors.New("too old git")
}
// CommitsBetween returns a list that contains commits between [last, before).
func (repo *Repository) CommitsBetween(last *Commit, before *Commit) (*list.List, error) {
if version.Compare(gitVersion, "1.8.0", ">=") {
@ -379,3 +392,21 @@ func (repo *Repository) getCommitsBeforeLimit(id sha1, num int) (*list.List, err
l := list.New()
return l, repo.commitsBefore(l, nil, id, 1, num)
}
func (repo *Repository) CommitsUnreachable(ids []string) (*list.List, error) {
par := make([]string, len(ids)+6)
par[0] = "log"
par[1] = "--not"
par[2] = "--branches"
par[3] = "--tags"
par[4] = "--remotes"
for i, _ := range ids {
par[i+5] = ids[i]+".."
}
par[len(ids)+5] = _PRETTY_LOG_FORMAT
stdout, err := NewCommand(par...).RunInDirBytes(repo.Path)
if err != nil {
return nil, err
}
return repo.parsePrettyFormatLogToList(stdout)
}