mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-31 21:28:11 +09:00 
			
		
		
		
	Initial cut of git fork
This commit is contained in:
		| @@ -20,7 +20,6 @@ import ( | |||||||
| var ( | var ( | ||||||
| 	x      *xorm.Engine | 	x      *xorm.Engine | ||||||
| 	tables []interface{} | 	tables []interface{} | ||||||
|  |  | ||||||
| 	HasEngine bool | 	HasEngine bool | ||||||
|  |  | ||||||
| 	DbCfg struct { | 	DbCfg struct { | ||||||
|   | |||||||
							
								
								
									
										127
									
								
								models/repo.go
									
									
									
									
									
								
							
							
						
						
									
										127
									
								
								models/repo.go
									
									
									
									
									
								
							| @@ -174,6 +174,10 @@ func (repo *Repository) GetMirror() (err error) { | |||||||
| 	return err | 	return err | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func (repo *Repository) GetPath() string { | ||||||
|  |         return RepoPath(repo.Owner.Name, repo.Name) | ||||||
|  | } | ||||||
|  |  | ||||||
| // DescriptionHtml does special handles to description and return HTML string. | // DescriptionHtml does special handles to description and return HTML string. | ||||||
| func (repo *Repository) DescriptionHtml() template.HTML { | func (repo *Repository) DescriptionHtml() template.HTML { | ||||||
| 	sanitize := func(s string) string { | 	sanitize := func(s string) string { | ||||||
| @@ -1224,6 +1228,127 @@ func IsStaring(uid, repoId int64) bool { | |||||||
| 	return has | 	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, | ||||||
|  |         } | ||||||
|  |      | ||||||
|  |         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 err = sess.Commit(); err != nil { | ||||||
|  |             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) | ||||||
|  |         } | ||||||
|  |     | ||||||
|  |      | ||||||
|  |         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 | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -217,6 +217,15 @@ func Action(ctx *middleware.Context) { | |||||||
| 		err = models.StarRepo(ctx.User.Id, ctx.Repo.Repository.Id, true) | 		err = models.StarRepo(ctx.User.Id, ctx.Repo.Repository.Id, true) | ||||||
| 	case "unstar": | 	case "unstar": | ||||||
| 		err = models.StarRepo(ctx.User.Id, ctx.Repo.Repository.Id, false) | 		err = models.StarRepo(ctx.User.Id, ctx.Repo.Repository.Id, false) | ||||||
|  |         case "fork": | ||||||
|  |                 repo, error := models.ForkRepository(ctx.User, ctx.Repo.Repository) | ||||||
|  |                 log.Info("Tried to fork a repo!") | ||||||
|  |                 log.Info("Repo thing is " + repo.Name) | ||||||
|  |                 if error != nil { | ||||||
|  |                          | ||||||
|  |                         ctx.Redirect(setting.AppSubUrl + "/" + ctx.User.Name + "/" + repo.Name) | ||||||
|  |                         return | ||||||
|  |                 } | ||||||
| 	case "desc": | 	case "desc": | ||||||
| 		if !ctx.Repo.IsOwner { | 		if !ctx.Repo.IsOwner { | ||||||
| 			ctx.Error(404) | 			ctx.Error(404) | ||||||
|   | |||||||
| @@ -96,6 +96,7 @@ | |||||||
|                 <table> |                 <table> | ||||||
|                     <tbody> |                     <tbody> | ||||||
|                         {{range .Sections}} |                         {{range .Sections}} | ||||||
|  |                         Test: {{ .NumLines}} | ||||||
|                         {{range .Lines}} |                         {{range .Lines}} | ||||||
|                         <tr class="{{DiffLineTypeToStr .Type}}-code nl-1 ol-1"> |                         <tr class="{{DiffLineTypeToStr .Type}}-code nl-1 ol-1"> | ||||||
|                             <td class="lines-num lines-num-old"> |                             <td class="lines-num lines-num-old"> | ||||||
| @@ -104,6 +105,7 @@ | |||||||
|                             <td class="lines-num lines-num-new"> |                             <td class="lines-num lines-num-new"> | ||||||
|                                 <span rel="L1">{{if .RightIdx}}{{.RightIdx}}{{end}}</span> |                                 <span rel="L1">{{if .RightIdx}}{{.RightIdx}}{{end}}</span> | ||||||
|                             </td> |                             </td> | ||||||
|  |                              | ||||||
|                             <td class="lines-code"> |                             <td class="lines-code"> | ||||||
|                                 <pre>{{ToUtf8 .Content}}</pre> |                                 <pre>{{ToUtf8 .Content}}</pre> | ||||||
|                             </td> |                             </td> | ||||||
|   | |||||||
| @@ -44,14 +44,14 @@ | |||||||
|                     </button> |                     </button> | ||||||
|                 </a> |                 </a> | ||||||
|             </li> |             </li> | ||||||
|             <!-- <li id="repo-header-fork"> |             <li id="repo-header-fork"> | ||||||
|                 <a id="repo-header-fork-btn" href="{{.RepoLink}}/action/fork"> |                 <a id="repo-header-fork-btn" href="{{.RepoLink}}/action/fork"> | ||||||
|                     <button class="btn btn-gray text-bold btn-radius"> |                     <button class="btn btn-gray text-bold btn-radius"> | ||||||
|                         <i class="octicon octicon-repo-forked"></i>{{.i18n.Tr "repo.fork"}} |                         <i class="octicon octicon-repo-forked"></i>{{.i18n.Tr "repo.fork"}} | ||||||
|                         <span class="num">{{.Repository.NumForks}}</span> |                         <span class="num">{{.Repository.NumForks}}</span> | ||||||
|                     </button> |                     </button> | ||||||
|                 </a> |                 </a> | ||||||
|             </li> --> |             </li> | ||||||
|         </ul> |         </ul> | ||||||
|     </div> |     </div> | ||||||
| </div> | </div> | ||||||
		Reference in New Issue
	
	Block a user