func valueFromGit(out io.Writer, tag, defValue string) (int, error) { writeValue := func(value string) (int, error) { return out.Write(bytes.NewBufferString(value).Bytes()) } writeError := func(err error) (int, error) { if defValue == "" { return 0, fmt.Errorf("failed resolving variable {git.%s}: %s", tag, err) } logging.Log.Warnf("Failed to get variable \"git.%s\", using default", tag) return writeValue(defValue) } write := func(value string, err error) (int, error) { if err != nil { return writeError(err) } return writeValue(value) } repo, err := git.OpenRepository(".") if err != nil { return writeError(err) } switch tag { case "branch": branch, err := repo.GetHEADBranch() return write(branch.Name, err) case "sha": commit, err := repo.GetCommit("HEAD") return write(commit.ID.String(), err) case "short-sha": commit, err := repo.GetCommit("HEAD") return write(commit.ID.String()[:10], err) default: return 0, fmt.Errorf("unknown variable \"git.%s\"", tag) } }
// PushUpdate must be called for any push actions in order to // generates necessary push action history feeds. func PushUpdate(opts PushUpdateOptions) (err error) { isNewRef := strings.HasPrefix(opts.OldCommitID, "0000000") isDelRef := strings.HasPrefix(opts.NewCommitID, "0000000") if isNewRef && isDelRef { return fmt.Errorf("Old and new revisions both start with 000000") } repoPath := RepoPath(opts.RepoUserName, opts.RepoName) gitUpdate := exec.Command("git", "update-server-info") gitUpdate.Dir = repoPath if err = gitUpdate.Run(); err != nil { return fmt.Errorf("Fail to call 'git update-server-info': %v", err) } if isDelRef { log.GitLogger.Info("Reference '%s' has been deleted from '%s/%s' by %d", opts.RefName, opts.RepoUserName, opts.RepoName, opts.PusherName) return nil } gitRepo, err := git.OpenRepository(repoPath) if err != nil { return fmt.Errorf("OpenRepository: %v", err) } repoUser, err := GetUserByName(opts.RepoUserName) if err != nil { return fmt.Errorf("GetUserByName: %v", err) } repo, err := GetRepositoryByName(repoUser.Id, opts.RepoName) if err != nil { return fmt.Errorf("GetRepositoryByName: %v", err) } // Push tags. if strings.HasPrefix(opts.RefName, "refs/tags/") { tag, err := gitRepo.GetTag(git.RefEndName(opts.RefName)) if err != nil { return fmt.Errorf("gitRepo.GetTag: %v", err) } // When tagger isn't available, fall back to get committer email. var actEmail string if tag.Tagger != nil { actEmail = tag.Tagger.Email } else { cmt, err := tag.Commit() if err != nil { return fmt.Errorf("tag.Commit: %v", err) } actEmail = cmt.Committer.Email } commit := &PushCommits{} if err = CommitRepoAction(opts.PusherID, repoUser.Id, opts.PusherName, actEmail, repo.ID, opts.RepoUserName, opts.RepoName, opts.RefName, commit, opts.OldCommitID, opts.NewCommitID); err != nil { return fmt.Errorf("CommitRepoAction (tag): %v", err) } return err } newCommit, err := gitRepo.GetCommit(opts.NewCommitID) if err != nil { return fmt.Errorf("gitRepo.GetCommit: %v", err) } // Push new branch. var l *list.List if isNewRef { l, err = newCommit.CommitsBeforeLimit(10) if err != nil { return fmt.Errorf("newCommit.CommitsBeforeLimit: %v", err) } } else { l, err = newCommit.CommitsBeforeUntil(opts.OldCommitID) if err != nil { return fmt.Errorf("newCommit.CommitsBeforeUntil: %v", err) } } if err = CommitRepoAction(opts.PusherID, repoUser.Id, opts.PusherName, repoUser.Email, repo.ID, opts.RepoUserName, opts.RepoName, opts.RefName, ListToPushCommits(l), opts.OldCommitID, opts.NewCommitID); err != nil { return fmt.Errorf("CommitRepoAction (branch): %v", err) } return nil }
// PushUpdate must be called for any push actions in order to // generates necessary push action history feeds. func PushUpdate(opts PushUpdateOptions) (err error) { isNewRef := opts.OldCommitID == git.EMPTY_SHA isDelRef := opts.NewCommitID == git.EMPTY_SHA if isNewRef && isDelRef { return fmt.Errorf("Old and new revisions are both %s", git.EMPTY_SHA) } repoPath := RepoPath(opts.RepoUserName, opts.RepoName) gitUpdate := exec.Command("git", "update-server-info") gitUpdate.Dir = repoPath if err = gitUpdate.Run(); err != nil { return fmt.Errorf("Fail to call 'git update-server-info': %v", err) } if isDelRef { log.GitLogger.Info("Reference '%s' has been deleted from '%s/%s' by %d", opts.RefFullName, opts.RepoUserName, opts.RepoName, opts.PusherName) return nil } gitRepo, err := git.OpenRepository(repoPath) if err != nil { return fmt.Errorf("OpenRepository: %v", err) } owner, err := GetUserByName(opts.RepoUserName) if err != nil { return fmt.Errorf("GetUserByName: %v", err) } repo, err := GetRepositoryByName(owner.ID, opts.RepoName) if err != nil { return fmt.Errorf("GetRepositoryByName: %v", err) } // Push tags. if strings.HasPrefix(opts.RefFullName, git.TAG_PREFIX) { if err := CommitRepoAction(CommitRepoActionOptions{ PusherName: opts.PusherName, RepoOwnerID: owner.ID, RepoName: repo.Name, RefFullName: opts.RefFullName, OldCommitID: opts.OldCommitID, NewCommitID: opts.NewCommitID, Commits: &PushCommits{}, }); err != nil { return fmt.Errorf("CommitRepoAction (tag): %v", err) } return nil } newCommit, err := gitRepo.GetCommit(opts.NewCommitID) if err != nil { return fmt.Errorf("gitRepo.GetCommit: %v", err) } // Push new branch. var l *list.List if isNewRef { l, err = newCommit.CommitsBeforeLimit(10) if err != nil { return fmt.Errorf("newCommit.CommitsBeforeLimit: %v", err) } } else { l, err = newCommit.CommitsBeforeUntil(opts.OldCommitID) if err != nil { return fmt.Errorf("newCommit.CommitsBeforeUntil: %v", err) } } if err := CommitRepoAction(CommitRepoActionOptions{ PusherName: opts.PusherName, RepoOwnerID: owner.ID, RepoName: repo.Name, RefFullName: opts.RefFullName, OldCommitID: opts.OldCommitID, NewCommitID: opts.NewCommitID, Commits: ListToPushCommits(l), }); err != nil { return fmt.Errorf("CommitRepoAction (branch): %v", err) } return nil }
// UpdateRepoFile adds or updates a file in repository. func (repo *Repository) UpdateRepoFile(doer *User, opts UpdateRepoFileOptions) (err error) { repoWorkingPool.CheckIn(com.ToStr(repo.ID)) defer repoWorkingPool.CheckOut(com.ToStr(repo.ID)) if err = repo.DiscardLocalRepoBranchChanges(opts.OldBranch); err != nil { return fmt.Errorf("DiscardLocalRepoBranchChanges [branch: %s]: %v", opts.OldBranch, err) } else if err = repo.UpdateLocalCopyBranch(opts.OldBranch); err != nil { return fmt.Errorf("UpdateLocalCopyBranch [branch: %s]: %v", opts.OldBranch, err) } if opts.OldBranch != opts.NewBranch { if err := repo.CheckoutNewBranch(opts.OldBranch, opts.NewBranch); err != nil { return fmt.Errorf("CheckoutNewBranch [old_branch: %s, new_branch: %s]: %v", opts.OldBranch, opts.NewBranch, err) } } localPath := repo.LocalCopyPath() oldFilePath := path.Join(localPath, opts.OldTreeName) filePath := path.Join(localPath, opts.NewTreeName) os.MkdirAll(path.Dir(filePath), os.ModePerm) // If it's meant to be a new file, make sure it doesn't exist. if opts.IsNewFile { if com.IsExist(filePath) { return ErrRepoFileAlreadyExist{filePath} } } // Ignore move step if it's a new file under a directory. // Otherwise, move the file when name changed. if com.IsFile(oldFilePath) && opts.OldTreeName != opts.NewTreeName { if err = git.MoveFile(localPath, opts.OldTreeName, opts.NewTreeName); err != nil { return fmt.Errorf("git mv %s %s: %v", opts.OldTreeName, opts.NewTreeName, err) } } if err = ioutil.WriteFile(filePath, []byte(opts.Content), 0666); err != nil { return fmt.Errorf("WriteFile: %v", err) } if err = git.AddChanges(localPath, true); err != nil { return fmt.Errorf("git add --all: %v", err) } else if err = git.CommitChanges(localPath, git.CommitChangesOptions{ Committer: doer.NewGitSig(), Message: opts.Message, }); err != nil { return fmt.Errorf("CommitChanges: %v", err) } else if err = git.Push(localPath, "origin", opts.NewBranch); err != nil { return fmt.Errorf("git push origin %s: %v", opts.NewBranch, err) } gitRepo, err := git.OpenRepository(repo.RepoPath()) if err != nil { log.Error(4, "OpenRepository: %v", err) return nil } commit, err := gitRepo.GetBranchCommit(opts.NewBranch) if err != nil { log.Error(4, "GetBranchCommit [branch: %s]: %v", opts.NewBranch, err) return nil } // Simulate push event. pushCommits := &PushCommits{ Len: 1, Commits: []*PushCommit{CommitToPushCommit(commit)}, } oldCommitID := opts.LastCommitID if opts.NewBranch != opts.OldBranch { oldCommitID = git.EMPTY_SHA } if err := CommitRepoAction(CommitRepoActionOptions{ PusherName: doer.Name, RepoOwnerID: repo.MustOwner().ID, RepoName: repo.Name, RefFullName: git.BRANCH_PREFIX + opts.NewBranch, OldCommitID: oldCommitID, NewCommitID: commit.ID.String(), Commits: pushCommits, }); err != nil { log.Error(4, "CommitRepoAction: %v", err) return nil } return nil }
func (repo *Repository) UploadRepoFiles(doer *User, opts UploadRepoFileOptions) (err error) { if len(opts.Files) == 0 { return nil } uploads, err := GetUploadsByUUIDs(opts.Files) if err != nil { return fmt.Errorf("GetUploadsByUUIDs [uuids: %v]: %v", opts.Files, err) } repoWorkingPool.CheckIn(com.ToStr(repo.ID)) defer repoWorkingPool.CheckOut(com.ToStr(repo.ID)) if err = repo.DiscardLocalRepoBranchChanges(opts.OldBranch); err != nil { return fmt.Errorf("DiscardLocalRepoBranchChanges [branch: %s]: %v", opts.OldBranch, err) } else if err = repo.UpdateLocalCopyBranch(opts.OldBranch); err != nil { return fmt.Errorf("UpdateLocalCopyBranch [branch: %s]: %v", opts.OldBranch, err) } if opts.OldBranch != opts.NewBranch { if err = repo.CheckoutNewBranch(opts.OldBranch, opts.NewBranch); err != nil { return fmt.Errorf("CheckoutNewBranch [old_branch: %s, new_branch: %s]: %v", opts.OldBranch, opts.NewBranch, err) } } localPath := repo.LocalCopyPath() dirPath := path.Join(localPath, opts.TreePath) os.MkdirAll(dirPath, os.ModePerm) // Copy uploaded files into repository. for _, upload := range uploads { tmpPath := upload.LocalPath() targetPath := path.Join(dirPath, upload.Name) if !com.IsFile(tmpPath) { continue } if err = com.Copy(tmpPath, targetPath); err != nil { return fmt.Errorf("Copy: %v", err) } } if err = git.AddChanges(localPath, true); err != nil { return fmt.Errorf("git add --all: %v", err) } else if err = git.CommitChanges(localPath, git.CommitChangesOptions{ Committer: doer.NewGitSig(), Message: opts.Message, }); err != nil { return fmt.Errorf("CommitChanges: %v", err) } else if err = git.Push(localPath, "origin", opts.NewBranch); err != nil { return fmt.Errorf("git push origin %s: %v", opts.NewBranch, err) } gitRepo, err := git.OpenRepository(repo.RepoPath()) if err != nil { log.Error(4, "OpenRepository: %v", err) return nil } commit, err := gitRepo.GetBranchCommit(opts.NewBranch) if err != nil { log.Error(4, "GetBranchCommit [branch: %s]: %v", opts.NewBranch, err) return nil } // Simulate push event. pushCommits := &PushCommits{ Len: 1, Commits: []*PushCommit{CommitToPushCommit(commit)}, } if err := CommitRepoAction(CommitRepoActionOptions{ PusherName: doer.Name, RepoOwnerID: repo.MustOwner().ID, RepoName: repo.Name, RefFullName: git.BRANCH_PREFIX + opts.NewBranch, OldCommitID: opts.LastCommitID, NewCommitID: commit.ID.String(), Commits: pushCommits, }); err != nil { log.Error(4, "CommitRepoAction: %v", err) return nil } return DeleteUploads(uploads...) }
func (repo *Repository) DeleteRepoFile(doer *User, opts DeleteRepoFileOptions) (err error) { repoWorkingPool.CheckIn(com.ToStr(repo.ID)) defer repoWorkingPool.CheckOut(com.ToStr(repo.ID)) if err = repo.DiscardLocalRepoBranchChanges(opts.OldBranch); err != nil { return fmt.Errorf("DiscardLocalRepoBranchChanges [branch: %s]: %v", opts.OldBranch, err) } else if err = repo.UpdateLocalCopyBranch(opts.OldBranch); err != nil { return fmt.Errorf("UpdateLocalCopyBranch [branch: %s]: %v", opts.OldBranch, err) } if opts.OldBranch != opts.NewBranch { if err := repo.CheckoutNewBranch(opts.OldBranch, opts.NewBranch); err != nil { return fmt.Errorf("CheckoutNewBranch [old_branch: %s, new_branch: %s]: %v", opts.OldBranch, opts.NewBranch, err) } } localPath := repo.LocalCopyPath() if err = os.Remove(path.Join(localPath, opts.TreePath)); err != nil { return fmt.Errorf("Remove: %v", err) } if err = git.AddChanges(localPath, true); err != nil { return fmt.Errorf("git add --all: %v", err) } else if err = git.CommitChanges(localPath, git.CommitChangesOptions{ Committer: doer.NewGitSig(), Message: opts.Message, }); err != nil { return fmt.Errorf("CommitChanges: %v", err) } else if err = git.Push(localPath, "origin", opts.NewBranch); err != nil { return fmt.Errorf("git push origin %s: %v", opts.NewBranch, err) } gitRepo, err := git.OpenRepository(repo.RepoPath()) if err != nil { log.Error(4, "OpenRepository: %v", err) return nil } commit, err := gitRepo.GetBranchCommit(opts.NewBranch) if err != nil { log.Error(4, "GetBranchCommit [branch: %s]: %v", opts.NewBranch, err) return nil } // Simulate push event. pushCommits := &PushCommits{ Len: 1, Commits: []*PushCommit{CommitToPushCommit(commit)}, } if err := CommitRepoAction(CommitRepoActionOptions{ PusherName: doer.Name, RepoOwnerID: repo.MustOwner().ID, RepoName: repo.Name, RefFullName: git.BRANCH_PREFIX + opts.NewBranch, OldCommitID: opts.LastCommitID, NewCommitID: commit.ID.String(), Commits: pushCommits, }); err != nil { log.Error(4, "CommitRepoAction: %v", err) return nil } return nil }