func ForkRepository(u *User, oldRepo *Repository, name, desc string) (_ *Repository, err error) { repo := &Repository{ OwnerID: u.Id, Owner: u, Name: name, LowerName: strings.ToLower(name), Description: desc, DefaultBranch: oldRepo.DefaultBranch, IsPrivate: oldRepo.IsPrivate, IsFork: true, ForkID: oldRepo.ID, } sess := x.NewSession() defer sessionRelease(sess) if err = sess.Begin(); err != nil { return nil, err } if err = createRepository(sess, u, repo); err != nil { return nil, err } if _, err = sess.Exec("UPDATE `repository` SET num_forks=num_forks+1 WHERE id=?", oldRepo.ID); err != nil { return nil, err } // else if _, err = sess.Insert(&ForkInfo{ // ForkID: oldRepo.ID, // RepoID: repo.ID, // StartCommitID: "", // }); err != nil { // return nil, fmt.Errorf("insert fork info: %v", err) // } oldRepoPath, err := oldRepo.RepoPath() if err != nil { return nil, fmt.Errorf("get old repository path: %v", err) } repoPath := RepoPath(u.Name, repo.Name) _, stderr, err := process.ExecTimeout(10*time.Minute, fmt.Sprintf("ForkRepository(git clone): %s/%s", u.Name, repo.Name), "git", "clone", "--bare", oldRepoPath, repoPath) if err != nil { return nil, fmt.Errorf("git clone: %v", stderr) } _, stderr, err = process.ExecDir(-1, repoPath, fmt.Sprintf("ForkRepository(git update-server-info): %s", repoPath), "git", "update-server-info") if err != nil { return nil, fmt.Errorf("git update-server-info: %v", err) } if err = createUpdateHook(repoPath); err != nil { return nil, fmt.Errorf("createUpdateHook: %v", err) } return repo, sess.Commit() }
// MigrateRepository migrates a existing repository from other project hosting. func MigrateRepository(u *User, name, desc string, private, mirror bool, url string) (*Repository, error) { repo, err := CreateRepository(u, CreateRepoOptions{ Name: name, Description: desc, IsPrivate: private, IsMirror: mirror, }) if err != nil { return nil, err } // Clone to temprory path and do the init commit. tmpDir := filepath.Join(os.TempDir(), fmt.Sprintf("%d", time.Now().Nanosecond())) os.MkdirAll(tmpDir, os.ModePerm) repoPath := RepoPath(u.Name, name) if u.IsOrganization() { t, err := u.GetOwnerTeam() if err != nil { return nil, err } repo.NumWatches = t.NumMembers } else { repo.NumWatches = 1 } repo.IsBare = false if mirror { if err = MirrorRepository(repo.ID, u.Name, repo.Name, repoPath, url); err != nil { return repo, err } repo.IsMirror = true return repo, UpdateRepository(repo, false) } else { os.RemoveAll(repoPath) } // FIXME: this command could for both migrate and mirror _, stderr, err := process.ExecTimeout(10*time.Minute, fmt.Sprintf("MigrateRepository: %s", repoPath), "git", "clone", "--mirror", "--bare", "--quiet", url, repoPath) if err != nil { return repo, fmt.Errorf("git clone --mirror --bare --quiet: %v", stderr) } else if err = createUpdateHook(repoPath); err != nil { return repo, fmt.Errorf("create update hook: %v", err) } // Check if repository has master branch, if so set it to default branch. gitRepo, err := git.OpenRepository(repoPath) if err != nil { return repo, fmt.Errorf("open git repository: %v", err) } if gitRepo.IsBranchExist("master") { repo.DefaultBranch = "master" } return repo, UpdateRepository(repo, false) }
// MirrorRepository creates a mirror repository from source. func MirrorRepository(repoId int64, userName, repoName, repoPath, url string) error { _, stderr, err := process.ExecTimeout(10*time.Minute, fmt.Sprintf("MirrorRepository: %s/%s", userName, repoName), "git", "clone", "--mirror", url, repoPath) if err != nil { return errors.New("git clone --mirror: " + stderr) } if _, err = x.InsertOne(&Mirror{ RepoID: repoId, Interval: 24, NextUpdate: time.Now().Add(24 * time.Hour), }); err != nil { return err } return nil }