diff options
author | 无闻 <joe2010xtmf@163.com> | 2014-10-18 23:59:36 -0400 |
---|---|---|
committer | 无闻 <joe2010xtmf@163.com> | 2014-10-18 23:59:36 -0400 |
commit | d7d167ac63e0ada717f78383016f5b208a1b209a (patch) | |
tree | b341240313a833311299ccd1594f3b92a4d44c1e | |
parent | 146c8efee3d01e220aa8f8554b69b6f76a0820e4 (diff) | |
parent | 8d2a6fc484b540819e211d52b8d54e97269f0918 (diff) | |
download | gitea-d7d167ac63e0ada717f78383016f5b208a1b209a.tar.gz gitea-d7d167ac63e0ada717f78383016f5b208a1b209a.zip |
Merge pull request #560 from evolvedlight/master
First cut of fork repo
-rw-r--r-- | models/models.go | 1 | ||||
-rw-r--r-- | models/repo.go | 148 | ||||
-rw-r--r-- | routers/repo/repo.go | 15 | ||||
-rw-r--r-- | templates/repo/diff.tmpl | 2 | ||||
-rw-r--r-- | templates/repo/header.tmpl | 7 |
5 files changed, 168 insertions, 5 deletions
diff --git a/models/models.go b/models/models.go index 35eb4c9692..4dcc447b34 100644 --- a/models/models.go +++ b/models/models.go @@ -20,7 +20,6 @@ import ( var ( x *xorm.Engine tables []interface{} - HasEngine bool DbCfg struct { diff --git a/models/repo.go b/models/repo.go index 419d034c66..d156621c83 100644 --- a/models/repo.go +++ b/models/repo.go @@ -177,6 +177,14 @@ func (repo *Repository) GetMirror() (err error) { return err } +func (repo *Repository) GetPath() string { + return RepoPath(repo.Owner.Name, repo.Name) +} + +func (repo *Repository) IsOwnedBy(u *User) bool { + return repo.OwnerId == u.Id +} + func (repo *Repository) HasAccess(uname string) bool { if err := repo.GetOwner(); err != nil { return false @@ -939,6 +947,13 @@ func DeleteRepository(uid, repoId int64, userName string) error { sess.Rollback() return err } + + if repo.IsFork { + if _, err = sess.Exec("UPDATE `repository` SET num_forks = num_forks - 1 WHERE id = ?", repo.ForkId); err != nil { + sess.Rollback() + return err + } + } if _, err = sess.Exec("UPDATE `user` SET num_repos = num_repos - 1 WHERE id = ?", uid); err != nil { sess.Rollback() @@ -1240,6 +1255,137 @@ func IsStaring(uid, repoId int64) bool { return has } -func ForkRepository(repoName string, uid int64) { +func ForkRepository(u *User, oldRepo *Repository) (*Repository, error) { + isExist, err := IsRepositoryExist(u, oldRepo.Name) + if err != nil { + return nil, err + } else if isExist { + return nil, ErrRepoAlreadyExist + } + + sess := x.NewSession() + defer sess.Close() + if err = sess.Begin(); err != nil { + return nil, err + } + + repo := &Repository{ + OwnerId: u.Id, + Owner: u, + Name: oldRepo.Name, + LowerName: oldRepo.LowerName, + Description: oldRepo.Description, + IsPrivate: oldRepo.IsPrivate, + IsFork: true, + ForkId: oldRepo.Id, + } + + if _, err = sess.Insert(repo); err != nil { + sess.Rollback() + return nil, err + } + + var t *Team // Owner team. + + mode := WRITABLE + + access := &Access{ + UserName: u.LowerName, + RepoName: path.Join(u.LowerName, repo.LowerName), + Mode: mode, + } + // Give access to all members in owner team. + if u.IsOrganization() { + t, err = u.GetOwnerTeam() + if err != nil { + sess.Rollback() + return nil, err + } + if err = t.GetMembers(); err != nil { + sess.Rollback() + return nil, err + } + for _, u := range t.Members { + access.Id = 0 + access.UserName = u.LowerName + if _, err = sess.Insert(access); err != nil { + sess.Rollback() + return nil, err + } + } + } else { + if _, err = sess.Insert(access); err != nil { + sess.Rollback() + return nil, err + } + } + + if _, err = sess.Exec( + "UPDATE `user` SET num_repos = num_repos + 1 WHERE id = ?", u.Id); err != nil { + sess.Rollback() + return nil, err + } + + // Update owner team info and count. + if u.IsOrganization() { + t.RepoIds += "$" + com.ToStr(repo.Id) + "|" + t.NumRepos++ + if _, err = sess.Id(t.Id).AllCols().Update(t); err != nil { + sess.Rollback() + return nil, err + } + } + + + + if u.IsOrganization() { + t, err := u.GetOwnerTeam() + if err != nil { + log.Error(4, "GetOwnerTeam: %v", err) + } else { + if err = t.GetMembers(); err != nil { + log.Error(4, "GetMembers: %v", err) + } else { + for _, u := range t.Members { + if err = WatchRepo(u.Id, repo.Id, true); err != nil { + log.Error(4, "WatchRepo2: %v", err) + } + } + } + } + } else { + if err = WatchRepo(u.Id, repo.Id, true); err != nil { + log.Error(4, "WatchRepo3: %v", err) + } + } + + if err = NewRepoAction(u, repo); err != nil { + log.Error(4, "NewRepoAction: %v", err) + } + + if _, err = sess.Exec( + "UPDATE `repository` SET num_forks = num_forks + 1 WHERE id = ?", oldRepo.Id); err != nil { + sess.Rollback() + return nil, err + } + + if err = sess.Commit(); err != nil { + return nil, err + } + + repoPath := RepoPath(u.Name, repo.Name) + _, stderr, err := process.ExecTimeout(10*time.Minute, + fmt.Sprintf("ForkRepository: %s/%s", u.Name, repo.Name), + "git", "clone", oldRepo.GetPath(), repoPath) + + _, stderr, err = process.ExecDir(-1, + repoPath, fmt.Sprintf("CreateRepository(git update-server-info): %s", repoPath), + "git", "update-server-info") + if err != nil { + return nil, errors.New("CreateRepository(git update-server-info): " + stderr) + } + + return repo, nil + } diff --git a/routers/repo/repo.go b/routers/repo/repo.go index 5562a8400a..8b18eb25bf 100644 --- a/routers/repo/repo.go +++ b/routers/repo/repo.go @@ -217,6 +217,21 @@ func Action(ctx *middleware.Context) { err = models.StarRepo(ctx.User.Id, ctx.Repo.Repository.Id, true) case "unstar": err = models.StarRepo(ctx.User.Id, ctx.Repo.Repository.Id, false) + case "fork": + repo, error := models.ForkRepository(ctx.User, ctx.Repo.Repository) + if error != nil { + log.Error(4, "Action(%s): %v", ctx.Params(":action"), error) + ctx.JSON(200, map[string]interface{}{ + "ok": false, + "err": error.Error(), + }) + return + } + if error == nil { + ctx.Redirect(setting.AppSubUrl + "/" + repo.Owner.Name + "/" + repo.Name) + + return + } case "desc": if !ctx.Repo.IsOwner { ctx.Error(404) diff --git a/templates/repo/diff.tmpl b/templates/repo/diff.tmpl index 0376664669..199324a163 100644 --- a/templates/repo/diff.tmpl +++ b/templates/repo/diff.tmpl @@ -101,6 +101,7 @@ <table> <tbody> {{range .Sections}} + Test: {{ .NumLines}} {{range .Lines}} <tr class="{{DiffLineTypeToStr .Type}}-code nl-1 ol-1"> <td class="lines-num lines-num-old"> @@ -109,6 +110,7 @@ <td class="lines-num lines-num-new"> <span rel="L1">{{if .RightIdx}}{{.RightIdx}}{{end}}</span> </td> + <td class="lines-code"> <pre>{{ToUtf8 .Content}}</pre> </td> diff --git a/templates/repo/header.tmpl b/templates/repo/header.tmpl index 699e90461e..884910d1c5 100644 --- a/templates/repo/header.tmpl +++ b/templates/repo/header.tmpl @@ -44,14 +44,15 @@ </button> </a> </li> - <!-- <li id="repo-header-fork"> - <a id="repo-header-fork-btn" href="{{.RepoLink}}/action/fork"> + <li id="repo-header-fork"> + <a id="repo-header-fork-btn" {{if not .IsRepositoryOwner}} href="{{.RepoLink}}/action/fork"{{end}}> <button class="btn btn-gray text-bold btn-radius"> <i class="octicon octicon-repo-forked"></i>{{.i18n.Tr "repo.fork"}} <span class="num">{{.Repository.NumForks}}</span> </button> </a> - </li> --> + + </li> </ul> </div> </div>
\ No newline at end of file |