mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 16:40:24 +08:00 
			
		
		
		
	Initial cut of git fork
This commit is contained in:
		@@ -20,7 +20,6 @@ import (
 | 
			
		||||
var (
 | 
			
		||||
	x      *xorm.Engine
 | 
			
		||||
	tables []interface{}
 | 
			
		||||
 | 
			
		||||
	HasEngine bool
 | 
			
		||||
 | 
			
		||||
	DbCfg struct {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										127
									
								
								models/repo.go
									
									
									
									
									
								
							
							
						
						
									
										127
									
								
								models/repo.go
									
									
									
									
									
								
							@@ -174,6 +174,10 @@ func (repo *Repository) GetMirror() (err error) {
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (repo *Repository) GetPath() string {
 | 
			
		||||
        return RepoPath(repo.Owner.Name, repo.Name)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DescriptionHtml does special handles to description and return HTML string.
 | 
			
		||||
func (repo *Repository) DescriptionHtml() template.HTML {
 | 
			
		||||
	sanitize := func(s string) string {
 | 
			
		||||
@@ -1224,6 +1228,127 @@ 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,
 | 
			
		||||
        }
 | 
			
		||||
    
 | 
			
		||||
        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)
 | 
			
		||||
	case "unstar":
 | 
			
		||||
		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":
 | 
			
		||||
		if !ctx.Repo.IsOwner {
 | 
			
		||||
			ctx.Error(404)
 | 
			
		||||
 
 | 
			
		||||
@@ -96,6 +96,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">
 | 
			
		||||
@@ -104,6 +105,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>
 | 
			
		||||
 
 | 
			
		||||
@@ -44,14 +44,14 @@
 | 
			
		||||
                    </button>
 | 
			
		||||
                </a>
 | 
			
		||||
            </li>
 | 
			
		||||
            <!-- <li id="repo-header-fork">
 | 
			
		||||
            <li id="repo-header-fork">
 | 
			
		||||
                <a id="repo-header-fork-btn" href="{{.RepoLink}}/action/fork">
 | 
			
		||||
                    <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>
 | 
			
		||||
		Reference in New Issue
	
	Block a user