devel-importer: handle history rewrite
Imports can have history rewritten because email addresses can change in OBS and are not recorded as in git commits. This can be handled via comparing Tree objects and rebasing new changes ontop.
This commit is contained in:
parent
9de8cf698f
commit
86df1921e0
@ -105,7 +105,7 @@ func (e *GitHandler) CloneDevel(gitDir, outName, urlString string) error {
|
||||
params = append(params, url.String(), outName)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("error parsing SSH URL. %w", err);
|
||||
return fmt.Errorf("error parsing SSH URL. %w", err)
|
||||
}
|
||||
out, err := e.GitExecWithOutput(gitDir, params...)
|
||||
if err != nil {
|
||||
@ -472,6 +472,53 @@ func parseGitBlob(data <-chan byte) ([]byte, error) {
|
||||
return d, nil
|
||||
}
|
||||
|
||||
func (e *GitHandler) GitParseCommits(cwd string, commitIDs []string) (parsedCommits []commit, err error) {
|
||||
var done sync.Mutex
|
||||
|
||||
done.Lock()
|
||||
data_in, data_out := ChanIO{make(chan byte, 256)}, ChanIO{make(chan byte, 70)}
|
||||
parsedCommits = make([]commit, 0, len(commitIDs))
|
||||
|
||||
go func() {
|
||||
defer done.Unlock()
|
||||
defer close(data_out.ch)
|
||||
|
||||
for _, id := range commitIDs {
|
||||
data_out.Write([]byte(id))
|
||||
data_out.ch <- '\x00'
|
||||
c, e := parseGitCommit(data_in.ch)
|
||||
if e != nil {
|
||||
err = fmt.Errorf("Error parsing git commit: %w", e)
|
||||
return
|
||||
}
|
||||
|
||||
parsedCommits = append(parsedCommits, c)
|
||||
}
|
||||
}()
|
||||
|
||||
cmd := exec.Command("/usr/bin/git", "cat-file", "--batch", "-Z")
|
||||
cmd.Env = []string{
|
||||
"GIT_CEILING_DIRECTORIES=" + e.GitPath,
|
||||
"GIT_CONFIG_GLOBAL=/dev/null",
|
||||
}
|
||||
cmd.Dir = filepath.Join(e.GitPath, cwd)
|
||||
cmd.Stdout = &data_in
|
||||
cmd.Stdin = &data_out
|
||||
cmd.Stderr = writeFunc(func(data []byte) (int, error) {
|
||||
if e.DebugLogger {
|
||||
log.Printf(string(data))
|
||||
}
|
||||
return len(data), nil
|
||||
})
|
||||
if e.DebugLogger {
|
||||
log.Printf("command run: %v\n", cmd.Args)
|
||||
}
|
||||
err = cmd.Run()
|
||||
|
||||
done.Lock()
|
||||
return
|
||||
}
|
||||
|
||||
// TODO: support sub-trees
|
||||
func (e *GitHandler) GitCatFile(cwd, commitId, filename string) (data []byte, err error) {
|
||||
var done sync.Mutex
|
||||
|
@ -245,20 +245,54 @@ func main() {
|
||||
out, err = git.GitExecWithOutput(pkgName, "rev-list", head_branch)
|
||||
if err != nil {
|
||||
head_branch = "HEAD"
|
||||
out = git.GitExecWithOutputOrPanic(pkgName, "rev-list", "HEAD")
|
||||
out = git.GitExecWithOutputOrPanic(pkgName, "rev-list", head_branch)
|
||||
}
|
||||
old_revs := strings.Split(out, "\n")
|
||||
added_revs := []string{}
|
||||
out = git.GitExecWithOutputOrPanic(pkgName, "rev-list", head_branch, "^factory/factory")
|
||||
added_revs = strings.Split(out, "\n")
|
||||
added_rpm_revs := []string{}
|
||||
added_rpm_revs := old_revs
|
||||
if slices.Contains(remotes, "rpm") {
|
||||
out = git.GitExecWithOutputOrPanic(pkgName, "rev-list", head_branch, "^rpm/factory")
|
||||
added_rpm_revs = strings.Split(out, "\n")
|
||||
}
|
||||
|
||||
if len(added_revs) == len(old_revs) && len(added_rpm_revs) == len(old_revs) {
|
||||
log.Printf("Something is wrong with rev-ist for (len %d): %s\n", len(added_revs), pkgName)
|
||||
reposOK = false
|
||||
|
||||
// check if we have broken history in OBS and that Tree objects are still matching
|
||||
newCommits, err := git.GitParseCommits(pkgName, old_revs)
|
||||
if err != nil {
|
||||
log.Panicln("failed to parse commitids", err)
|
||||
}
|
||||
factoryCommitIDs := common.SplitStringNoEmpty(git.GitExecWithOutputOrPanic(pkgName, "rev-list", "factory/factory"), "\n")
|
||||
factoryCommits, err := git.GitParseCommits(pkgName, factoryCommitIDs)
|
||||
if err != nil {
|
||||
log.Panicln("failed to parse factory commits")
|
||||
}
|
||||
|
||||
// find first common trees
|
||||
found := false
|
||||
foundMatch:
|
||||
for i := range newCommits {
|
||||
for j := range factoryCommits {
|
||||
if newCommits[i].Tree == factoryCommits[i].Tree {
|
||||
log.Println("found match", i, "vs", j)
|
||||
git.GitExecOrPanic(pkgName, "checkout", "-B", "factory", added_revs[j])
|
||||
if i != 0 {
|
||||
// chrry pick on top
|
||||
for commitIndex := i - 1; commitIndex >= 0; i-- {
|
||||
git.GitExecOrPanic(pkgName, "cherry-pick", factoryCommitIDs[commitIndex])
|
||||
}
|
||||
}
|
||||
found = true
|
||||
break foundMatch
|
||||
}
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
reposOK = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -271,13 +305,13 @@ func main() {
|
||||
args = append(args, develProjectPackages...)
|
||||
cmd = exec.Command("./git-importer", args...)
|
||||
out, err = cmd.CombinedOutput()
|
||||
log.Println(out)
|
||||
log.Println(string(out))
|
||||
if err != nil {
|
||||
log.Panicln("Error returned by importer.", err)
|
||||
}
|
||||
|
||||
if !reposOK {
|
||||
log.Println("aborting import due to broken repos above...")
|
||||
log.Panicln("aborting import due to broken repos above...")
|
||||
}
|
||||
|
||||
for _, pkg := range factoryRepos {
|
||||
@ -289,7 +323,7 @@ func main() {
|
||||
Organization: org,
|
||||
}), r.DefaultAuthentication)
|
||||
if err != nil {
|
||||
log.Panicln("Error while trying to create fork from pool/", pkg.Name, err)
|
||||
log.Panicln("Error while trying to create fork from pool", pkg.Name, err)
|
||||
}
|
||||
|
||||
repo := fork.Payload
|
||||
|
Loading…
x
Reference in New Issue
Block a user