diff options
author | ᴜɴᴋɴᴡᴏɴ <u@gogs.io> | 2020-03-08 19:09:31 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-03-08 19:09:31 +0800 |
commit | 6437d0180b97a26319b50c2e22927dac7c94fcdd (patch) | |
tree | 3d0d097e7f498e4b970065096e7500876d365a8b /internal/db | |
parent | c65b5b9f84dee21dc362311b299694e8e00f6ac6 (diff) |
git: migrate to github.com/gogs/git-module@v1.0.0 (#5958)
* WIP
* Finish `internal/db/git_diff.go`
* FInish internal/db/mirror.go
* Finish internal/db/pull.go
* Finish internal/db/release.go
* Finish internal/db/repo.go
* Finish internal/db/repo_branch.go
* Finish internal/db/repo_editor.go
* Finish internal/db/update.go
* Save my work
* Add license header
* Compile!
* Merge master
* Finish internal/cmd/hook.go
* Finish internal/conf/static.go
* Finish internal/context/repo.go
* Finish internal/db/action.go
* Finish internal/db/git_diff.go
* Fix submodule URL inferring
* Finish internal/db/mirror.go
* Updat to beta.4
* css: update fonts
* Finish internal/db/pull.go
* Finish internal/db/release.go
* Finish internal/db/repo_branch.go
* Finish internal/db/wiki.go
* gitutil: enhance infer submodule UR
* Finish internal/route/api/v1/repo/commits.go
* mirror: only collect branch commits after sync
* mirror: fix tag support
* Finish internal/db/repo.go
* Finish internal/db/repo_editor.go
* Finish internal/db/update.go
* Finish internal/gitutil/pull_request.go
* Make it compile
* Finish internal/route/repo/setting.go
* Finish internal/route/repo/branch.go
* Finish internal/route/api/v1/repo/file.go
* Finish internal/route/repo/download.go
* Finish internal/route/repo/editor.go
* Use helper
* Finish internal/route/repo/issue.go
* Finish internal/route/repo/pull.go
* Finish internal/route/repo/release.go
* Finish internal/route/repo/repo.go
* Finish internal/route/repo/wiki.go
* Finish internal/route/repo/commit.go
* Finish internal/route/repo/view.go
* Finish internal/gitutil/tag.go
* go.sum
Diffstat (limited to 'internal/db')
-rw-r--r-- | internal/db/action.go | 28 | ||||
-rw-r--r-- | internal/db/git_diff.go | 194 | ||||
-rw-r--r-- | internal/db/git_diff_test.go | 35 | ||||
-rw-r--r-- | internal/db/migrations/v16.go | 10 | ||||
-rw-r--r-- | internal/db/mirror.go | 155 | ||||
-rw-r--r-- | internal/db/mirror_test.go | 107 | ||||
-rw-r--r-- | internal/db/pull.go | 101 | ||||
-rw-r--r-- | internal/db/release.go | 12 | ||||
-rw-r--r-- | internal/db/repo.go | 117 | ||||
-rw-r--r-- | internal/db/repo_branch.go | 28 | ||||
-rw-r--r-- | internal/db/repo_editor.go | 126 | ||||
-rw-r--r-- | internal/db/update.go | 51 | ||||
-rw-r--r-- | internal/db/user.go | 29 | ||||
-rw-r--r-- | internal/db/webhook_dingtalk.go | 6 | ||||
-rw-r--r-- | internal/db/webhook_discord.go | 6 | ||||
-rw-r--r-- | internal/db/webhook_slack.go | 6 | ||||
-rw-r--r-- | internal/db/wiki.go | 34 |
17 files changed, 345 insertions, 700 deletions
diff --git a/internal/db/action.go b/internal/db/action.go index 3fe56dd1..0b803836 100644 --- a/internal/db/action.go +++ b/internal/db/action.go @@ -268,9 +268,9 @@ func (pc *PushCommits) ToApiPayloadCommits(repoPath, repoURL string) ([]*api.Pay return nil, fmt.Errorf("GetUserByEmail: %v", err) } - fileStatus, err := git.GetCommitFileStatus(repoPath, commit.Sha1) + nameStatus, err := git.RepoShowNameStatus(repoPath, commit.Sha1) if err != nil { - return nil, fmt.Errorf("FileStatus [commit_sha1: %s]: %v", commit.Sha1, err) + return nil, fmt.Errorf("show name status [commit_sha1: %s]: %v", commit.Sha1, err) } commits[i] = &api.PayloadCommit{ @@ -287,9 +287,9 @@ func (pc *PushCommits) ToApiPayloadCommits(repoPath, repoURL string) ([]*api.Pay Email: commit.CommitterEmail, UserName: committerUsername, }, - Added: fileStatus.Added, - Removed: fileStatus.Removed, - Modified: fileStatus.Modified, + Added: nameStatus.Added, + Removed: nameStatus.Removed, + Modified: nameStatus.Modified, Timestamp: commit.Timestamp, } } @@ -298,21 +298,21 @@ func (pc *PushCommits) ToApiPayloadCommits(repoPath, repoURL string) ([]*api.Pay // AvatarLink tries to match user in database with e-mail // in order to show custom avatar, and falls back to general avatar link. -func (push *PushCommits) AvatarLink(email string) string { - _, ok := push.avatars[email] +func (pcs *PushCommits) AvatarLink(email string) string { + _, ok := pcs.avatars[email] if !ok { u, err := GetUserByEmail(email) if err != nil { - push.avatars[email] = tool.AvatarLink(email) + pcs.avatars[email] = tool.AvatarLink(email) if !errors.IsUserNotExist(err) { log.Error("GetUserByEmail: %v", err) } } else { - push.avatars[email] = u.RelAvatarLink() + pcs.avatars[email] = u.RelAvatarLink() } } - return push.avatars[email] + return pcs.avatars[email] } // UpdateIssuesCommit checks if issues are manipulated by commit message. @@ -474,12 +474,12 @@ func CommitRepoAction(opts CommitRepoActionOptions) error { return fmt.Errorf("UpdateRepository: %v", err) } - isNewRef := opts.OldCommitID == git.EMPTY_SHA - isDelRef := opts.NewCommitID == git.EMPTY_SHA + isNewRef := opts.OldCommitID == git.EmptyID + isDelRef := opts.NewCommitID == git.EmptyID opType := ACTION_COMMIT_REPO // Check if it's tag push or branch. - if strings.HasPrefix(opts.RefFullName, git.TAG_PREFIX) { + if strings.HasPrefix(opts.RefFullName, git.RefsTags) { opType = ACTION_PUSH_TAG } else { // if not the first commit, set the compare URL. @@ -504,7 +504,7 @@ func CommitRepoAction(opts CommitRepoActionOptions) error { return fmt.Errorf("Marshal: %v", err) } - refName := git.RefEndName(opts.RefFullName) + refName := git.RefShortName(opts.RefFullName) action := &Action{ ActUserID: pusher.ID, ActUserName: pusher.Name, diff --git a/internal/db/git_diff.go b/internal/db/git_diff.go deleted file mode 100644 index a8b43554..00000000 --- a/internal/db/git_diff.go +++ /dev/null @@ -1,194 +0,0 @@ -// Copyright 2014 The Gogs Authors. All rights reserved. -// Use of this source code is governed by a MIT-style -// license that can be found in the LICENSE file. - -package db - -import ( - "bytes" - "fmt" - "html" - "html/template" - "io" - - "github.com/sergi/go-diff/diffmatchpatch" - "golang.org/x/net/html/charset" - "golang.org/x/text/transform" - - "github.com/gogs/git-module" - - "gogs.io/gogs/internal/conf" - "gogs.io/gogs/internal/template/highlight" - "gogs.io/gogs/internal/tool" -) - -type DiffSection struct { - *git.DiffSection -} - -var ( - addedCodePrefix = []byte("<span class=\"added-code\">") - removedCodePrefix = []byte("<span class=\"removed-code\">") - codeTagSuffix = []byte("</span>") -) - -func diffToHTML(diffs []diffmatchpatch.Diff, lineType git.DiffLineType) template.HTML { - buf := bytes.NewBuffer(nil) - - // Reproduce signs which are cutted for inline diff before. - switch lineType { - case git.DIFF_LINE_ADD: - buf.WriteByte('+') - case git.DIFF_LINE_DEL: - buf.WriteByte('-') - } - - for i := range diffs { - switch { - case diffs[i].Type == diffmatchpatch.DiffInsert && lineType == git.DIFF_LINE_ADD: - buf.Write(addedCodePrefix) - buf.WriteString(html.EscapeString(diffs[i].Text)) - buf.Write(codeTagSuffix) - case diffs[i].Type == diffmatchpatch.DiffDelete && lineType == git.DIFF_LINE_DEL: - buf.Write(removedCodePrefix) - buf.WriteString(html.EscapeString(diffs[i].Text)) - buf.Write(codeTagSuffix) - case diffs[i].Type == diffmatchpatch.DiffEqual: - buf.WriteString(html.EscapeString(diffs[i].Text)) - } - } - - return template.HTML(buf.Bytes()) -} - -var diffMatchPatch = diffmatchpatch.New() - -func init() { - diffMatchPatch.DiffEditCost = 100 -} - -// ComputedInlineDiffFor computes inline diff for the given line. -func (diffSection *DiffSection) ComputedInlineDiffFor(diffLine *git.DiffLine) template.HTML { - if conf.Git.DisableDiffHighlight { - return template.HTML(html.EscapeString(diffLine.Content[1:])) - } - var ( - compareDiffLine *git.DiffLine - diff1 string - diff2 string - ) - - // try to find equivalent diff line. ignore, otherwise - switch diffLine.Type { - case git.DIFF_LINE_ADD: - compareDiffLine = diffSection.Line(git.DIFF_LINE_DEL, diffLine.RightIdx) - if compareDiffLine == nil { - return template.HTML(html.EscapeString(diffLine.Content)) - } - diff1 = compareDiffLine.Content - diff2 = diffLine.Content - case git.DIFF_LINE_DEL: - compareDiffLine = diffSection.Line(git.DIFF_LINE_ADD, diffLine.LeftIdx) - if compareDiffLine == nil { - return template.HTML(html.EscapeString(diffLine.Content)) - } - diff1 = diffLine.Content - diff2 = compareDiffLine.Content - default: - return template.HTML(html.EscapeString(diffLine.Content)) - } - - diffRecord := diffMatchPatch.DiffMain(diff1[1:], diff2[1:], true) - diffRecord = diffMatchPatch.DiffCleanupEfficiency(diffRecord) - - return diffToHTML(diffRecord, diffLine.Type) -} - -type DiffFile struct { - *git.DiffFile - Sections []*DiffSection -} - -func (diffFile *DiffFile) HighlightClass() string { - return highlight.FileNameToHighlightClass(diffFile.Name) -} - -type Diff struct { - *git.Diff - Files []*DiffFile -} - -func NewDiff(gitDiff *git.Diff) *Diff { - diff := &Diff{ - Diff: gitDiff, - Files: make([]*DiffFile, gitDiff.NumFiles()), - } - - // FIXME: detect encoding while parsing. - var buf bytes.Buffer - for i := range gitDiff.Files { - buf.Reset() - - diff.Files[i] = &DiffFile{ - DiffFile: gitDiff.Files[i], - Sections: make([]*DiffSection, gitDiff.Files[i].NumSections()), - } - - for j := range gitDiff.Files[i].Sections { - diff.Files[i].Sections[j] = &DiffSection{ - DiffSection: gitDiff.Files[i].Sections[j], - } - - for k := range diff.Files[i].Sections[j].Lines { - buf.WriteString(diff.Files[i].Sections[j].Lines[k].Content) - buf.WriteString("\n") - } - } - - charsetLabel, err := tool.DetectEncoding(buf.Bytes()) - if charsetLabel != "UTF-8" && err == nil { - encoding, _ := charset.Lookup(charsetLabel) - if encoding != nil { - d := encoding.NewDecoder() - for j := range diff.Files[i].Sections { - for k := range diff.Files[i].Sections[j].Lines { - if c, _, err := transform.String(d, diff.Files[i].Sections[j].Lines[k].Content); err == nil { - diff.Files[i].Sections[j].Lines[k].Content = c - } - } - } - } - } - } - - return diff -} - -func ParsePatch(maxLines, maxLineCharacteres, maxFiles int, reader io.Reader) (*Diff, error) { - done := make(chan error) - var gitDiff *git.Diff - go func() { - gitDiff = git.ParsePatch(done, maxLines, maxLineCharacteres, maxFiles, reader) - }() - - if err := <-done; err != nil { - return nil, fmt.Errorf("ParsePatch: %v", err) - } - return NewDiff(gitDiff), nil -} - -func GetDiffRange(repoPath, beforeCommitID, afterCommitID string, maxLines, maxLineCharacteres, maxFiles int) (*Diff, error) { - gitDiff, err := git.GetDiffRange(repoPath, beforeCommitID, afterCommitID, maxLines, maxLineCharacteres, maxFiles) - if err != nil { - return nil, fmt.Errorf("GetDiffRange: %v", err) - } - return NewDiff(gitDiff), nil -} - -func GetDiffCommit(repoPath, commitID string, maxLines, maxLineCharacteres, maxFiles int) (*Diff, error) { - gitDiff, err := git.GetDiffCommit(repoPath, commitID, maxLines, maxLineCharacteres, maxFiles) - if err != nil { - return nil, fmt.Errorf("GetDiffCommit: %v", err) - } - return NewDiff(gitDiff), nil -} diff --git a/internal/db/git_diff_test.go b/internal/db/git_diff_test.go deleted file mode 100644 index 697e8dc7..00000000 --- a/internal/db/git_diff_test.go +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2016 The Gogs Authors. All rights reserved. -// Use of this source code is governed by a MIT-style -// license that can be found in the LICENSE file. - -package db - -import ( - "html/template" - "testing" - - "github.com/gogs/git-module" - dmp "github.com/sergi/go-diff/diffmatchpatch" -) - -func assertEqual(t *testing.T, s1 string, s2 template.HTML) { - if s1 != string(s2) { - t.Errorf("%s should be equal %s", s2, s1) - } -} - -func Test_diffToHTML(t *testing.T) { - assertEqual(t, "+foo <span class=\"added-code\">bar</span> biz", diffToHTML([]dmp.Diff{ - {Type: dmp.DiffEqual, Text: "foo "}, - {Type: dmp.DiffInsert, Text: "bar"}, - {Type: dmp.DiffDelete, Text: " baz"}, - {Type: dmp.DiffEqual, Text: " biz"}, - }, git.DiffLineAdd)) - - assertEqual(t, "-foo <span class=\"removed-code\">bar</span> biz", diffToHTML([]dmp.Diff{ - {Type: dmp.DiffEqual, Text: "foo "}, - {Type: dmp.DiffDelete, Text: "bar"}, - {Type: dmp.DiffInsert, Text: " baz"}, - {Type: dmp.DiffEqual, Text: " biz"}, - }, git.DiffLineDel)) -} diff --git a/internal/db/migrations/v16.go b/internal/db/migrations/v16.go index 572dba9c..f60f9d15 100644 --- a/internal/db/migrations/v16.go +++ b/internal/db/migrations/v16.go @@ -18,7 +18,7 @@ import ( ) func updateRepositorySizes(x *xorm.Engine) (err error) { - log.Info("This migration could take up to minutes, please be patient.") + log.Info("[migrations.v16] This migration could take up to minutes, please be patient.") type Repository struct { ID int64 OwnerID int64 @@ -41,7 +41,7 @@ func updateRepositorySizes(x *xorm.Engine) (err error) { Find(&repos); err != nil { return fmt.Errorf("select repos [offset: %d]: %v", offset, err) } - log.Trace("Select [offset: %d, repos: %d]", offset, len(repos)) + log.Trace("[migrations.v16] Select [offset: %d, repos: %d]", offset, len(repos)) if len(repos) == 0 { break } @@ -60,10 +60,10 @@ func updateRepositorySizes(x *xorm.Engine) (err error) { continue } - repoPath := filepath.Join(conf.Repository.Root, strings.ToLower(user.Name), strings.ToLower(repo.Name)) + ".git" - countObject, err := git.GetRepoSize(repoPath) + repoPath := strings.ToLower(filepath.Join(conf.Repository.Root, user.Name, repo.Name)) + ".git" + countObject, err := git.RepoCountObjects(repoPath) if err != nil { - log.Warn("GetRepoSize: %v", err) + log.Warn("[migrations.v16] Count repository objects: %v", err) continue } diff --git a/internal/db/mirror.go b/internal/db/mirror.go index dd767990..f1b6f3d5 100644 --- a/internal/db/mirror.go +++ b/internal/db/mirror.go @@ -5,7 +5,6 @@ package db import ( - "container/list" "fmt" "net/url" "strings" @@ -72,54 +71,17 @@ func (m *Mirror) ScheduleNextSync() { m.NextSync = time.Now().Add(time.Duration(m.Interval) * time.Hour) } -// findPasswordInMirrorAddress returns start (inclusive) and end index (exclusive) -// of password portion of credentials in given mirror address. -// It returns a boolean value to indicate whether password portion is found. -func findPasswordInMirrorAddress(addr string) (start int, end int, found bool) { - // Find end of credentials (start of path) - end = strings.LastIndex(addr, "@") - if end == -1 { - return -1, -1, false - } - - // Find delimiter of credentials (end of username) - start = strings.Index(addr, "://") - if start == -1 { - return -1, -1, false - } - start += 3 - delim := strings.Index(addr[start:], ":") - if delim == -1 { - return -1, -1, false - } - delim += 1 - - if start+delim >= end { - return -1, -1, false // No password portion presented - } - - return start + delim, end, true -} - -// unescapeMirrorCredentials returns mirror address with unescaped credentials. -func unescapeMirrorCredentials(addr string) string { - start, end, found := findPasswordInMirrorAddress(addr) - if !found { - return addr - } - - password, _ := url.QueryUnescape(addr[start:end]) - return addr[:start] + password + addr[end:] -} - func (m *Mirror) readAddress() { if len(m.address) > 0 { return } - cfg, err := ini.Load(m.Repo.GitConfigPath()) + cfg, err := ini.LoadSources( + ini.LoadOptions{IgnoreInlineComment: true}, + m.Repo.GitConfigPath(), + ) if err != nil { - log.Error("Load: %v", err) + log.Error("load config: %v", err) return } m.address = cfg.Section("remote \"origin\"").Key("url").Value() @@ -128,6 +90,7 @@ func (m *Mirror) readAddress() { // HandleMirrorCredentials replaces user credentials from HTTP/HTTPS URL // with placeholder <credentials>. // It returns original string if protocol is not HTTP/HTTPS. +// TODO(unknwon): Use url.Parse. func HandleMirrorCredentials(url string, mosaics bool) string { i := strings.Index(url, "@") if i == -1 { @@ -161,34 +124,21 @@ func (m *Mirror) RawAddress() string { return m.address } -// FullAddress returns mirror address from Git repository config with unescaped credentials. -func (m *Mirror) FullAddress() string { - m.readAddress() - return unescapeMirrorCredentials(m.address) -} - -// escapeCredentials returns mirror address with escaped credentials. -func escapeMirrorCredentials(addr string) string { - start, end, found := findPasswordInMirrorAddress(addr) - if !found { - return addr - } - - return addr[:start] + url.QueryEscape(addr[start:end]) + addr[end:] -} - // SaveAddress writes new address to Git repository config. func (m *Mirror) SaveAddress(addr string) error { repoPath := m.Repo.RepoPath() - err := git.RemoveRemote(repoPath, "origin") + err := git.RepoRemoveRemote(repoPath, "origin") if err != nil { return fmt.Errorf("remove remote 'origin': %v", err) } - err = git.AddRemote(repoPath, "origin", addr, git.AddRemoteOptions{ - Mirror: true, - }) + addrURL, err := url.Parse(addr) + if err != nil { + return err + } + + err = git.RepoAddRemote(repoPath, "origin", addrURL.String(), git.AddRemoteOptions{MirrorFetch: true}) if err != nil { return fmt.Errorf("add remote 'origin': %v", err) } @@ -196,7 +146,7 @@ func (m *Mirror) SaveAddress(addr string) error { return nil } -const GIT_SHORT_EMPTY_SHA = "0000000" +const gitShortEmptyID = "0000000" // mirrorSyncResult contains information of a updated reference. // If the oldCommitID is "0000000", it means a new reference, the value of newCommitID is empty. @@ -223,12 +173,12 @@ func parseRemoteUpdateOutput(output string) []*mirrorSyncResult { case strings.HasPrefix(lines[i], " * "): // New reference results = append(results, &mirrorSyncResult{ refName: refName, - oldCommitID: GIT_SHORT_EMPTY_SHA, + oldCommitID: gitShortEmptyID, }) case strings.HasPrefix(lines[i], " - "): // Delete reference results = append(results, &mirrorSyncResult{ refName: refName, - newCommitID: GIT_SHORT_EMPTY_SHA, + newCommitID: gitShortEmptyID, }) case strings.HasPrefix(lines[i], " "): // New commits of a reference delimIdx := strings.Index(lines[i][3:], " ") @@ -262,10 +212,7 @@ func (m *Mirror) runSync() ([]*mirrorSyncResult, bool) { // Do a fast-fail testing against on repository URL to ensure it is accessible under // good condition to prevent long blocking on URL resolution without syncing anything. - if !git.IsRepoURLAccessible(git.NetworkOptions{ - URL: m.RawAddress(), - Timeout: 10 * time.Second, - }) { + if !git.IsURLAccessible(time.Minute, m.RawAddress()) { desc := fmt.Sprintf("Source URL of mirror repository '%s' is not accessible: %s", m.Repo.FullName(), m.MosaicsAddress()) if err := CreateRepositoryNotice(desc); err != nil { log.Error("CreateRepositoryNotice: %v", err) @@ -393,15 +340,14 @@ func SyncMirrors() { // - Create "Mirror Sync" webhook event // - Create mirror sync (create, push and delete) events and trigger the "mirror sync" webhooks - var gitRepo *git.Repository if len(results) == 0 { log.Trace("SyncMirrors [repo_id: %d]: no commits fetched", m.RepoID) - } else { - gitRepo, err = git.OpenRepository(m.Repo.RepoPath()) - if err != nil { - log.Error("OpenRepository [%d]: %v", m.RepoID, err) - continue - } + } + + gitRepo, err := git.Open(m.Repo.RepoPath()) + if err != nil { + log.Error("Failed to open repository [repo_id: %d]: %v", m.RepoID, err) + continue } for _, result := range results { @@ -411,7 +357,7 @@ func SyncMirrors() { } // Delete reference - if result.newCommitID == GIT_SHORT_EMPTY_SHA { + if result.newCommitID == gitShortEmptyID { if err = MirrorSyncDeleteAction(m.Repo, result.refName); err != nil { log.Error("MirrorSyncDeleteAction [repo_id: %d]: %v", m.RepoID, err) } @@ -420,7 +366,7 @@ func SyncMirrors() { // New reference isNewRef := false - if result.oldCommitID == GIT_SHORT_EMPTY_SHA { + if result.oldCommitID == gitShortEmptyID { if err = MirrorSyncCreateAction(m.Repo, result.refName); err != nil { log.Error("MirrorSyncCreateAction [repo_id: %d]: %v", m.RepoID, err) continue @@ -429,49 +375,52 @@ func SyncMirrors() { } // Push commits - var commits *list.List + var commits []*git.Commit var oldCommitID string var newCommitID string if !isNewRef { - oldCommitID, err = git.GetFullCommitID(gitRepo.Path, result.oldCommitID) + oldCommitID, err = gitRepo.RevParse(result.oldCommitID) if err != nil { - log.Error("GetFullCommitID [%d]: %v", m.RepoID, err) + log.Error("Failed to parse revision [repo_id: %d, old_commit_id: %s]: %v", m.RepoID, result.oldCommitID, err) continue } - newCommitID, err = git.GetFullCommitID(gitRepo.Path, result.newCommitID) + newCommitID, err = gitRepo.RevParse(result.newCommitID) if err != nil { - log.Error("GetFullCommitID [%d]: %v", m.RepoID, err) + log.Error("Failed to parse revision [repo_id: %d, new_commit_id: %s]: %v", m.RepoID, result.newCommitID, err) continue } - commits, err = gitRepo.CommitsBetweenIDs(newCommitID, oldCommitID) + commits, err = gitRepo.RevList([]string{oldCommitID + "..." + newCommitID}) if err != nil { - log.Error("CommitsBetweenIDs [repo_id: %d, new_commit_id: %s, old_commit_id: %s]: %v", m.RepoID, newCommitID, oldCommitID, err) + log.Error("Failed to list commits [repo_id: %d, old_commit_id: %s, new_commit_id: %s]: %v", m.RepoID, oldCommitID, newCommitID, err) continue } - } else { - refNewCommitID, err := gitRepo.GetBranchCommitID(result.refName) + + } else if gitRepo.HasBranch(result.refName) { + refNewCommit, err := gitRepo.BranchCommit(result.refName) if err != nil { - log.Error("GetFullCommitID [%d]: %v", m.RepoID, err) + log.Error("Failed to get branch commit [repo_id: %d, branch: %s]: %v", m.RepoID, result.refName, err) continue } - if newCommit, err := gitRepo.GetCommit(refNewCommitID); err != nil { - log.Error("GetCommit [repo_id: %d, commit_id: %s]: %v", m.RepoID, refNewCommitID, err) + + // TODO(unknwon): Get the commits for the new ref until the closest ancestor branch like GitHub does. + commits, err = refNewCommit.Ancestors(git.LogOptions{MaxCount: 9}) + if err != nil { + log.Error("Failed to get ancestors [repo_id: %d, commit_id: %s]: %v", m.RepoID, refNewCommit.ID, err) continue - } else { - // TODO: Get the commits for the new ref until the closest ancestor branch like Github does - commits, err = newCommit.CommitsBeforeLimit(10) - if err != nil { - log.Error("CommitsBeforeLimit [repo_id: %d, commit_id: %s]: %v", m.RepoID, refNewCommitID, err) - } - oldCommitID = git.EMPTY_SHA - newCommitID = refNewCommitID } + + // Put the latest commit in front of ancestors + commits = append([]*git.Commit{refNewCommit}, commits...) + + oldCommitID = git.EmptyID + newCommitID = refNewCommit.ID.String() } + if err = MirrorSyncPushAction(m.Repo, MirrorSyncPushActionOptions{ RefName: result.refName, OldCommitID: oldCommitID, NewCommitID: newCommitID, - Commits: ListToPushCommits(commits), + Commits: CommitsToPushCommits(commits), }); err != nil { log.Error("MirrorSyncPushAction [repo_id: %d]: %v", m.RepoID, err) continue @@ -485,15 +434,15 @@ func SyncMirrors() { // Get latest commit date and compare to current repository updated time, // update if latest commit date is newer. - commitDate, err := git.GetLatestCommitDate(m.Repo.RepoPath(), "") + latestCommitTime, err := gitRepo.LatestCommitTime() if err != nil { log.Error("GetLatestCommitDate [%d]: %v", m.RepoID, err) continue - } else if commitDate.Before(m.Repo.Updated) { + } else if !latestCommitTime.After(m.Repo.Updated) { continue } - if _, err = x.Exec("UPDATE repository SET updated_unix = ? WHERE id = ?", commitDate.Unix(), m.RepoID); err != nil { + if _, err = x.Exec("UPDATE repository SET updated_unix = ? WHERE id = ?", latestCommitTime.Unix(), m.RepoID); err != nil { log.Error("Update 'repository.updated_unix' [%d]: %v", m.RepoID, err) continue } diff --git a/internal/db/mirror_test.go b/internal/db/mirror_test.go index cc85546a..74f1d936 100644 --- a/internal/db/mirror_test.go +++ b/internal/db/mirror_test.go @@ -7,102 +7,31 @@ package db import ( "testing" - . "github.com/smartystreets/goconvey/convey" + "github.com/stretchr/testify/assert" ) func Test_parseRemoteUpdateOutput(t *testing.T) { - Convey("Parse mirror remote update output", t, func() { - testCases := []struct { - output string - results []*mirrorSyncResult - }{ - { - ` + tests := []struct { + output string + expResults []*mirrorSyncResult + }{ + { + ` From https://try.gogs.io/unknwon/upsteam * [new branch] develop -> develop b0bb24f..1d85a4f master -> master - [deleted] (none) -> bugfix `, - []*mirrorSyncResult{ - {"develop", GIT_SHORT_EMPTY_SHA, ""}, - {"master", "b0bb24f", "1d85a4f"}, - {"bugfix", "", GIT_SHORT_EMPTY_SHA}, - }, + []*mirrorSyncResult{ + {"develop", gitShortEmptyID, ""}, + {"master", "b0bb24f", "1d85a4f"}, + {"bugfix", "", gitShortEmptyID}, }, - } - - for _, tc := range testCases { - results := parseRemoteUpdateOutput(tc.output) - So(len(results), ShouldEqual, len(tc.results)) - - for i := range tc.results { - So(tc.results[i].refName, ShouldEqual, results[i].refName) - So(tc.results[i].oldCommitID, ShouldEqual, results[i].oldCommitID) - So(tc.results[i].newCommitID, ShouldEqual, results[i].newCommitID) - } - } - }) -} - -func Test_findPasswordInMirrorAddress(t *testing.T) { - Convey("Find password portion in mirror address", t, func() { - testCases := []struct { - addr string - start, end int - found bool - password string - }{ - {"http://localhost:3000/user/repo.git", -1, -1, false, ""}, - {"http://user@localhost:3000/user/repo.git", -1, -1, false, ""}, - {"http://user:@localhost:3000/user/repo.git", -1, -1, false, ""}, - {"http://user:password@localhost:3000/user/repo.git", 12, 20, true, "password"}, - {"http://username:my%3Asecure%3Bpassword@localhost:3000/user/repo.git", 16, 38, true, "my%3Asecure%3Bpassword"}, - {"http://username:my%40secure%23password@localhost:3000/user/repo.git", 16, 38, true, "my%40secure%23password"}, - {"http://username:@@localhost:3000/user/repo.git", 16, 17, true, "@"}, - } - - for _, tc := range testCases { - start, end, found := findPasswordInMirrorAddress(tc.addr) - So(start, ShouldEqual, tc.start) - So(end, ShouldEqual, tc.end) - So(found, ShouldEqual, tc.found) - if found { - So(tc.addr[start:end], ShouldEqual, tc.password) - } - } - }) -} - -func Test_unescapeMirrorCredentials(t *testing.T) { - Convey("Escape credentials in mirror address", t, func() { - testCases := []string{ - "http://localhost:3000/user/repo.git", "http://localhost:3000/user/repo.git", - "http://user@localhost:3000/user/repo.git", "http://user@localhost:3000/user/repo.git", - "http://user:@localhost:3000/user/repo.git", "http://user:@localhost:3000/user/repo.git", - "http://user:password@localhost:3000/user/repo.git", "http://user:password@localhost:3000/user/repo.git", - "http://user:my%3Asecure%3Bpassword@localhost:3000/user/repo.git", "http://user:my:secure;password@localhost:3000/user/repo.git", - "http://user:my%40secure%23password@localhost:3000/user/repo.git", "http://user:my@secure#password@localhost:3000/user/repo.git", - } - - for i := 0; i < len(testCases); i += 2 { - So(unescapeMirrorCredentials(testCases[i]), ShouldEqual, testCases[i+1]) - } - }) -} - -func Test_escapeMirrorCredentials(t *testing.T) { - Convey("Escape credentials in mirror address", t, func() { - testCases := []string{ - "http://localhost:3000/user/repo.git", "http://localhost:3000/user/repo.git", - "http://user@localhost:3000/user/repo.git", "http://user@localhost:3000/user/repo.git", - "http://user:@localhost:3000/user/repo.git", "http://user:@localhost:3000/user/repo.git", - "http://user:password@localhost:3000/user/repo.git", "http://user:password@localhost:3000/user/repo.git", - "http://user:my:secure;password@localhost:3000/user/repo.git", "http://user:my%3Asecure%3Bpassword@localhost:3000/user/repo.git", - "http://user:my@secure#password@localhost:3000/user/repo.git", "http://user:my%40secure%23password@localhost:3000/user/repo.git", - } - - for i := 0; i < len(testCases); i += 2 { - So(escapeMirrorCredentials(testCases[i]), ShouldEqual, testCases[i+1]) - } - }) + }, + } + for _, test := range tests { + t.Run("", func(t *testing.T) { + assert.Equal(t, test.expResults, parseRemoteUpdateOutput(test.output)) + }) + } } diff --git a/internal/db/pull.go b/internal/db/pull.go index 6f4f574b..cd08813f 100644 --- a/internal/db/pull.go +++ b/internal/db/pull.go @@ -7,7 +7,6 @@ package db import ( "fmt" "os" - "path" "path/filepath" "strings" "time" @@ -212,9 +211,9 @@ func (pr *PullRequest) Merge(doer *User, baseGitRepo *git.Repository, mergeStyle } headRepoPath := RepoPath(pr.HeadUserName, pr.HeadRepo.Name) - headGitRepo, err := git.OpenRepository(headRepoPath) + headGitRepo, err := git.Open(headRepoPath) if err != nil { - return fmt.Errorf("OpenRepository: %v", err) + return fmt.Errorf("open repository: %v", err) } // Create temporary directory to store temporary copy of the base repository, @@ -228,7 +227,7 @@ func (pr *PullRequest) Merge(doer *User, baseGitRepo *git.Repository, mergeStyle var stderr string if _, stderr, err = process.ExecTimeout(5*time.Minute, fmt.Sprintf("PullRequest.Merge (git clone): %s", tmpBasePath), - "git", "clone", "-b", pr.BaseBranch, baseGitRepo.Path, tmpBasePath); err != nil { + "git", "clone", "-b", pr.BaseBranch, baseGitRepo.Path(), tmpBasePath); err != nil { return fmt.Errorf("git clone: %s", stderr) } @@ -311,13 +310,13 @@ func (pr *PullRequest) Merge(doer *User, baseGitRepo *git.Repository, mergeStyle // Push changes on base branch to upstream. if _, stderr, err = process.ExecDir(-1, tmpBasePath, fmt.Sprintf("PullRequest.Merge (git push): %s", tmpBasePath), - "git", "push", baseGitRepo.Path, pr.BaseBranch); err != nil { + "git", "push", baseGitRepo.Path(), pr.BaseBranch); err != nil { return fmt.Errorf("git push: %s", stderr) } - pr.MergedCommitID, err = headGitRepo.GetBranchCommitID(pr.HeadBranch) + pr.MergedCommitID, err = headGitRepo.BranchCommitID(pr.HeadBranch) if err != nil { - return fmt.Errorf("GetBranchCommit: %v", err) + return fmt.Errorf("get head branch %q commit ID: %v", pr.HeadBranch, err) } pr.HasMerged = true @@ -351,42 +350,42 @@ func (pr *PullRequest) Merge(doer *User, baseGitRepo *git.Repository, mergeStyle return nil } - l, err := headGitRepo.CommitsBetweenIDs(pr.MergedCommitID, pr.MergeBase) + commits, err := headGitRepo.RevList([]string{pr.MergeBase + "..." + pr.MergedCommitID}) if err != nil { - log.Error("CommitsBetweenIDs: %v", err) + log.Error("Failed to list commits [merge_base: %s, merged_commit_id: %s]: %v", pr.MergeBase, pr.MergedCommitID, err) return nil } - // It is possible that head branch is not fully sync with base branch for merge commits, - // so we need to get latest head commit and append merge commit manully - // to avoid strange diff commits produced. - mergeCommit, err := baseGitRepo.GetBranchCommit(pr.BaseBranch) + // NOTE: It is possible that head branch is not fully sync with base branch + // for merge commits, so we need to get latest head commit and append merge + // commit manully to avoid strange diff commits produced. + mergeCommit, err := baseGitRepo.BranchCommit(pr.BaseBranch) if err != nil { - log.Error("GetBranchCommit: %v", err) + log.Error("Failed to get base branch %q commit: %v", pr.BaseBranch, err) return nil } if mergeStyle == MERGE_STYLE_REGULAR { - l.PushFront(mergeCommit) + commits = append([]*git.Commit{mergeCommit}, commits...) } - commits, err := ListToPushCommits(l).ToApiPayloadCommits(pr.BaseRepo.RepoPath(), pr.BaseRepo.HTMLURL()) + pcs, err := CommitsToPushCommits(commits).ToApiPayloadCommits(pr.BaseRepo.RepoPath(), pr.BaseRepo.HTMLURL()) if err != nil { - log.Error("ToApiPayloadCommits: %v", err) + log.Error("Failed to convert to API payload commits: %v", err) return nil } p := &api.PushPayload{ - Ref: git.BRANCH_PREFIX + pr.BaseBranch, + Ref: git.RefsHeads + pr.BaseBranch, Before: pr.MergeBase, After: mergeCommit.ID.String(), CompareURL: conf.Server.ExternalURL + pr.BaseRepo.ComposeCompareURL(pr.MergeBase, pr.MergedCommitID), - Commits: commits, + Commits: pcs, Repo: pr.BaseRepo.APIFormat(nil), Pusher: pr.HeadRepo.MustOwner().APIFormat(), Sender: doer.APIFormat(), } if err = PrepareWebhooks(pr.BaseRepo, HOOK_EVENT_PUSH, p); err != nil { - log.Error("PrepareWebhooks: %v", err) + log.Error("Failed to prepare webhooks: %v", err) return nil } return nil @@ -599,36 +598,42 @@ func (pr *PullRequest) UpdatePatch() (err error) { return nil } - headGitRepo, err := git.OpenRepository(pr.HeadRepo.RepoPath()) + headGitRepo, err := git.Open(pr.HeadRepo.RepoPath()) if err != nil { - return fmt.Errorf("OpenRepository: %v", err) + return fmt.Errorf("open repository: %v", err) } // Add a temporary remote. tmpRemote := com.ToStr(time.Now().UnixNano()) - if err = headGitRepo.AddRemote(tmpRemote, RepoPath(pr.BaseRepo.MustOwner().Name, pr.BaseRepo.Name), true); err != nil { - return fmt.Errorf("AddRemote: %v", err) + baseRepoPath := RepoPath(pr.BaseRepo.MustOwner().Name, pr.BaseRepo.Name) + err = headGitRepo.AddRemote(tmpRemote, baseRepoPath, git.AddRemoteOptions{Fetch: true}) + if err != nil { + return fmt.Errorf("add remote %q [repo_id: %d]: %v", tmpRemote, pr.HeadRepoID, err) } defer func() { - headGitRepo.RemoveRemote(tmpRemote) + if err := headGitRepo.RemoveRemote(tmpRemote); err != nil { + log.Error("Failed to remove remote %q [repo_id: %d]: %v", tmpRemote, pr.HeadRepoID, err) + } }() + remoteBranch := "remotes/" + tmpRemote + "/" + pr.BaseBranch - pr.MergeBase, err = headGitRepo.GetMergeBase(remoteBranch, pr.HeadBranch) + pr.MergeBase, err = headGitRepo.MergeBase(remoteBranch, pr.HeadBranch) if err != nil { - return fmt.Errorf("GetMergeBase: %v", err) + return fmt.Errorf("get merge base: %v", err) } else if err = pr.Update(); err != nil { - return fmt.Errorf("Update: %v", err) + return fmt.Errorf("update: %v", err) } - patch, err := headGitRepo.GetPatch(pr.MergeBase, pr.HeadBranch) + patch, err := headGitRepo.DiffBinary(pr.MergeBase, pr.HeadBranch) if err != nil { - return fmt.Errorf("GetPatch: %v", err) + return fmt.Errorf("get binary patch: %v", err) } if err = pr.BaseRepo.SavePatch(pr.Index, patch); err != nil { - return fmt.Errorf("BaseRepo.SavePatch: %v", err) + return fmt.Errorf("save patch: %v", err) } + log.Trace("PullRequest[%d].UpdatePatch: patch saved", pr.ID) return nil } @@ -639,25 +644,35 @@ func (pr *PullRequest) PushToBaseRepo() (err error) { log.Trace("PushToBaseRepo[%d]: pushing commits to base repo 'refs/pull/%d/head'", pr.BaseRepoID, pr.Index) headRepoPath := pr.HeadRepo.RepoPath() - headGitRepo, err := git.OpenRepository(headRepoPath) + headGitRepo, err := git.Open(headRepoPath) if err != nil { - return fmt.Errorf("OpenRepository: %v", err) + return fmt.Errorf("open repository: %v", err) } - tmpRemoteName := fmt.Sprintf("tmp-pull-%d", pr.ID) - if err = headGitRepo.AddRemote(tmpRemoteName, pr.BaseRepo.RepoPath(), false); err != nil { - return fmt.Errorf("headGitRepo.AddRemote: %v", err) + tmpRemote := fmt.Sprintf("tmp-pull-%d", pr.ID) + if err = headGitRepo.AddRemote(tmpRemote, pr.BaseRepo.RepoPath()); err != nil { + return fmt.Errorf("add remote %q [repo_id: %d]: %v", tmpRemote, pr.HeadRepoID, err) } - // Make sure to remove the remote even if the push fails - defer headGitRepo.RemoveRemote(tmpRemoteName) - headFile := fmt.Sprintf("refs/pull/%d/head", pr.Index) + // Make sure to remove the remote even if the push fails + defer func() { + if err := headGitRepo.RemoveRemote(tmpRemote); err != nil { + log.Error("Failed to remove remote %q [repo_id: %d]: %v", tmpRemote, pr.HeadRepoID, err) + } + }() - // Remove head in case there is a conflict. - os.Remove(path.Join(pr.BaseRepo.RepoPath(), headFile)) + headRefspec := fmt.Sprintf("refs/pull/%d/head", pr.Index) + headFile := filepath.Join(pr.BaseRepo.RepoPath(), headRefspec) + if osutil.IsExist(headFile) { + err = os.Remove(headFile) + if err != nil { + return fmt.Errorf("remove head file [repo_id: %d]: %v", pr.BaseRepoID, err) + } + } - if err = git.Push(headRepoPath, tmpRemoteName, fmt.Sprintf("%s:%s", pr.HeadBranch, headFile)); err != nil { - return fmt.Errorf("Push: %v", err) + err = headGitRepo.Push(tmpRemote, fmt.Sprintf("%s:%s", pr.HeadBranch, headRefspec)) + if err != nil { + return fmt.Errorf("push: %v", err) } return nil diff --git a/internal/db/release.go b/internal/db/release.go index d0c4fbe6..fa69fba8 100644 --- a/internal/db/release.go +++ b/internal/db/release.go @@ -119,10 +119,10 @@ func IsReleaseExist(repoID int64, tagName string) (bool, error) { func createTag(gitRepo *git.Repository, r *Release) error { // Only actual create when publish. if !r.IsDraft { - if !gitRepo.IsTagExist(r.TagName) { - commit, err := gitRepo.GetBranchCommit(r.Target) + if !gitRepo.HasTag(r.TagName) { + commit, err := gitRepo.BranchCommit(r.Target) if err != nil { - return fmt.Errorf("GetBranchCommit: %v", err) + return fmt.Errorf("get branch commit: %v", err) } // Trim '--' prefix to prevent command line argument vulnerability. @@ -134,15 +134,15 @@ func createTag(gitRepo *git.Repository, r *Release) error { return err } } else { - commit, err := gitRepo.GetTagCommit(r.TagName) + commit, err := gitRepo.TagCommit(r.TagName) if err != nil { - return fmt.Errorf("GetTagCommit: %v", err) + return fmt.Errorf("get tag commit: %v", err) } r.Sha1 = commit.ID.String() r.NumCommits, err = commit.CommitsCount() if err != nil { - return fmt.Errorf("CommitsCount: %v", err) + return fmt.Errorf("count commits: %v", err) } } } diff --git a/internal/db/repo.go b/internal/db/repo.go index e28258e1..7e607dc0 100644 --- a/internal/db/repo.go +++ b/internal/db/repo.go @@ -119,9 +119,6 @@ func NewRepoContext() { if version.Compare("1.8.3", conf.Git.Version, ">") { log.Fatal("Gogs requires Git version greater or equal to 1.8.3") } - git.HookDir = "custom_hooks" - git.HookSampleDir = "hooks" - git.DefaultCommitsPageSize = conf.UI.User.CommitsPagingNum // Git requires setting user.name and user.email in order to commit changes. for configKey, defaultValue := range map[string]string{"user.name": "Gogs", "user.email": "gogs@fake.local"} { @@ -420,9 +417,9 @@ func (repo *Repository) mustOwner(e Engine) *User { } func (repo *Repository) UpdateSize() error { - countObject, err := git.GetRepoSize(repo.RepoPath()) + countObject, err := git.RepoCountObjects(repo.RepoPath()) if err != nil { - return fmt.Errorf("GetRepoSize: %v", err) + return fmt.Errorf("count repository objects: %v", err) } repo.Size = countObject.Size + countObject.SizePack @@ -602,33 +599,41 @@ func (repo *Repository) LocalCopyPath() string { // assume subsequent operations are against target branch when caller has confidence // about no race condition. func UpdateLocalCopyBranch(repoPath, localPath, branch string, isWiki bool) (err error) { - if !com.IsExist(localPath) { + if !osutil.IsExist(localPath) { // Checkout to a specific branch fails when wiki is an empty repository. if isWiki { branch = "" } - if err = git.Clone(repoPath, localPath, git.CloneRepoOptions{ - Timeout: time.Duration(conf.Git.Timeout.Clone) * time.Second, + if err = git.Clone(repoPath, localPath, git.CloneOptions{ Branch: branch, + Timeout: time.Duration(conf.Git.Timeout.Clone) * time.Second, }); err != nil { - return fmt.Errorf("git clone %s: %v", branch, err) - } - } else { - if err = git.Fetch(localPath, git.FetchRemoteOptions{ - Prune: true, - }); err != nil { - return fmt.Errorf("git fetch: %v", err) - } - if err = git.Checkout(localPath, git.CheckoutOptions{ - Branch: branch, - }); err != nil { - return fmt.Errorf("git checkout %s: %v", branch, err) + return fmt.Errorf("git clone [branch: %s]: %v", branch, err) } + return nil + } - // Reset to align with remote in case of force push. - if err = git.ResetHEAD(localPath, true, "origin/"+branch); err != nil { - return fmt.Errorf("git reset --hard origin/%s: %v", branch, err) - } + gitRepo, err := git.Open(localPath) + if err != nil { + return fmt.Errorf("open repository: %v", err) + } + + if err = gitRepo.Fetch(git.FetchOptions{ + Prune: true, + }); err != nil { + return fmt.Errorf("fetch: %v", err) + } + + if err = gitRepo.Checkout(branch); err != nil { + return fmt.Errorf("checkout [branch: %s]: %v", branch, err) + } + + // Reset to align with remote in case of force push. + rev := "origin/" + branch + if err = gitRepo.Reset(rev, git.ResetOptions{ + Hard: true, + }); err != nil { + return fmt.Errorf("reset [revision: %s]: %v", rev, err) } return nil } @@ -729,9 +734,7 @@ func wikiRemoteURL(remote string) string { remote = strings.TrimSuffix(remote, ".git") for _, suffix := range commonWikiURLSuffixes { wikiURL := remote + suffix - if git.IsRepoURLAccessible(git.NetworkOptions{ - URL: wikiURL, - }) { + if git.IsURLAccessible(time.Minute, wikiURL) { return wikiURL } } @@ -766,23 +769,23 @@ func MigrateRepository(doer, owner *User, opts MigrateRepoOptions) (*Repository, migrateTimeout := time.Duration(conf.Git.Timeout.Migrate) * time.Second RemoveAllWithNotice("Repository path erase before creation", repoPath) - if err = git.Clone(opts.RemoteAddr, repoPath, git.CloneRepoOptions{ + if err = git.Clone(opts.RemoteAddr, repoPath, git.CloneOptions{ Mirror: true, Quiet: true, Timeout: migrateTimeout, }); err != nil { - return repo, fmt.Errorf("Clone: %v", err) + return repo, fmt.Errorf("clone: %v", err) } wikiRemotePath := wikiRemoteURL(opts.RemoteAddr) if len(wikiRemotePath) > 0 { RemoveAllWithNotice("Repository wiki path erase before creation", wikiPath) - if err = git.Clone(wikiRemotePath, wikiPath, git.CloneRepoOptions{ + if err = git.Clone(wikiRemotePath, wikiPath, git.CloneOptions{ Mirror: true, Quiet: true, Timeout: migrateTimeout, }); err != nil { - log.Trace("Failed to clone wiki: %v", err) + log.Error("Failed to clone wiki: %v", err) RemoveAllWithNotice("Delete repository wiki for initialization failure", wikiPath) } } @@ -799,17 +802,15 @@ func MigrateRepository(doer, owner *User, opts MigrateRepoOptions) (*Repository, if !repo.IsBare { // Try to get HEAD branch and set it as default branch. - gitRepo, err := git.OpenRepository(repoPath) + gitRepo, err := git.Open(repoPath) if err != nil { - return repo, fmt.Errorf("OpenRepository: %v", err) + return repo, fmt.Errorf("open repository: %v", err) } - headBranch, err := gitRepo.GetHEADBranch() + refspec, err := gitRepo.SymbolicRef() if err != nil { - return repo, fmt.Errorf("GetHEADBranch: %v", err) - } - if headBranch != nil { - repo.DefaultBranch = headBranch.Name + return repo, fmt.Errorf("get HEAD branch: %v", err) } + repo.DefaultBranch = git.RefShortName(refspec) if err = repo.UpdateSize(); err != nil { log.Error("UpdateSize [repo_id: %d]: %v", repo.ID, err) @@ -847,15 +848,15 @@ func cleanUpMigrateGitConfig(configPath string) error { return nil } -var hooksTpls = map[string]string{ +var hooksTpls = map[git.HookName]string{ "pre-receive": "#!/usr/bin/env %s\n\"%s\" hook --config='%s' pre-receive\n", "update": "#!/usr/bin/env %s\n\"%s\" hook --config='%s' update $1 $2 $3\n", "post-receive": "#!/usr/bin/env %s\n\"%s\" hook --config='%s' post-receive\n", } func createDelegateHooks(repoPath string) (err error) { - for _, name := range git.HookNames { - hookPath := filepath.Join(repoPath, "hooks", name) + for _, name := range git.ServerSideHooks { + hookPath := filepath.Join(repoPath, "hooks", string(name)) if err = ioutil.WriteFile(hookPath, []byte(fmt.Sprintf(hooksTpls[name], conf.Repository.ScriptType, conf.AppPath(), conf.CustomConf)), os.ModePerm); err != nil { @@ -1005,8 +1006,8 @@ func initRepository(e Engine, repoPath string, doer *User, repo *Repository, opt } // Init bare new repository. - if err = git.InitRepository(repoPath, true); err != nil { - return fmt.Errorf("InitRepository: %v", err) + if err = git.Init(repoPath, git.InitOptions{Bare: true}); err != nil { + return fmt.Errorf("init repository: %v", err) } else if err = createDelegateHooks(repoPath); err != nil { return fmt.Errorf("createDelegateHooks: %v", err) } @@ -1880,9 +1881,9 @@ func ReinitMissingRepositories() error { for _, repo := range repos { log.Trace("Initializing %d/%d...", repo.OwnerID, repo.ID) - if err := git.InitRepository(repo.RepoPath(), true); err != nil { - if err2 := CreateRepositoryNotice(fmt.Sprintf("InitRepository [%d]: %v", repo.ID, err)); err2 != nil { - return fmt.Errorf("CreateRepositoryNotice: %v", err) + if err := git.Init(repo.RepoPath(), git.InitOptions{Bare: true}); err != nil { + if err2 := CreateRepositoryNotice(fmt.Sprintf("init repository [repo_id: %d]: %v", repo.ID, err)); err2 != nil { + return fmt.Errorf("create repository notice: %v", err) } } } @@ -1930,7 +1931,11 @@ func GitFsck() { func(idx int, bean interface{}) error { repo := bean.(*Repository) repoPath := repo.RepoPath() - if err := git.Fsck(repoPath, conf.Cron.RepoHealthCheck.Timeout, conf.Cron.RepoHealthCheck.Args...); err != nil { + err := git.RepoFsck(repoPath, git.FsckOptions{ + Args: conf.Cron.RepoHealthCheck.Args, + Timeout: conf.Cron.RepoHealthCheck.Timeout, + }) + if err != nil { desc := fmt.Sprintf("Failed to perform health check on repository '%s': %v", repoPath, err) log.Warn(desc) if err = CreateRepositoryNotice(desc); err != nil { @@ -2441,24 +2446,24 @@ func (repo *Repository) GetForks() ([]*Repository, error) { // \/ \/ \/ \/ \/ // -func (repo *Repository) CreateNewBranch(doer *User, oldBranchName, branchName string) (err error) { +func (repo *Repository) CreateNewBranch(oldBranch, newBranch string) (err error) { repoWorkingPool.CheckIn(com.ToStr(repo.ID)) defer repoWorkingPool.CheckOut(com.ToStr(repo.ID)) localPath := repo.LocalCopyPath() - if err = discardLocalRepoBranchChanges(localPath, oldBranchName); err != nil { - return fmt.Errorf("discardLocalRepoChanges: %v", err) - } else if err = repo.UpdateLocalCopyBranch(oldBranchName); err != nil { - return fmt.Errorf("UpdateLocalCopyBranch: %v", err) + if err = discardLocalRepoBranchChanges(localPath, oldBranch); err != nil { + return fmt.Errorf("discard changes in local copy [path: %s, branch: %s]: %v", localPath, oldBranch, err) + } else if err = repo.UpdateLocalCopyBranch(oldBranch); err != nil { + return fmt.Errorf("update branch for local copy [path: %s, branch: %s]: %v", localPath, oldBranch, err) } - if err = repo.CheckoutNewBranch(oldBranchName, branchName); err != nil { - return fmt.Errorf("CreateNewBranch: %v", err) + if err = repo.CheckoutNewBranch(oldBranch, newBranch); err != nil { + return fmt.Errorf("create new branch [base: %s, new: %s]: %v", oldBranch, newBranch, err) } - if err = git.Push(localPath, "origin", branchName); err != nil { - return fmt.Errorf("Push: %v", err) + if err = git.RepoPush(localPath, "origin", newBranch); err != nil { + return fmt.Errorf("push [branch: %s]: %v", newBranch, err) } return nil diff --git a/internal/db/repo_branch.go b/internal/db/repo_branch.go index 94313101..a4d38ecb 100644 --- a/internal/db/repo_branch.go +++ b/internal/db/repo_branch.go @@ -24,33 +24,33 @@ type Branch struct { } func GetBranchesByPath(path string) ([]*Branch, error) { - gitRepo, err := git.OpenRepository(path) + gitRepo, err := git.Open(path) if err != nil { - return nil, err + return nil, fmt.Errorf("open repository: %v", err) } - brs, err := gitRepo.GetBranches() + names, err := gitRepo.Branches() if err != nil { - return nil, err + return nil, fmt.Errorf("list branches") } - branches := make([]*Branch, len(brs)) - for i := range brs { + branches := make([]*Branch, len(names)) + for i := range names { branches[i] = &Branch{ RepoPath: path, - Name: brs[i], + Name: names[i], } } return branches, nil } -func (repo *Repository) GetBranch(br string) (*Branch, error) { - if !git.IsBranchExist(repo.RepoPath(), br) { - return nil, errors.ErrBranchNotExist{Name: br} +func (repo *Repository) GetBranch(name string) (*Branch, error) { + if !git.RepoHasBranch(repo.RepoPath(), name) { + return nil, errors.ErrBranchNotExist{Name: name} } return &Branch{ RepoPath: repo.RepoPath(), - Name: br, + Name: name, }, nil } @@ -59,11 +59,11 @@ func (repo *Repository) GetBranches() ([]*Branch, error) { } func (br *Branch) GetCommit() (*git.Commit, error) { - gitRepo, err := git.OpenRepository(br.RepoPath) + gitRepo, err := git.Open(br.RepoPath) if err != nil { - return nil, err + return nil, fmt.Errorf("open repository: %v", err) } - return gitRepo.GetBranchCommit(br.Name) + return gitRepo.BranchCommit(br.Name) } type ProtectBranchWhitelist struct { diff --git a/internal/db/repo_editor.go b/internal/db/repo_editor.go index 7aa1cd7a..cf711557 100644 --- a/internal/db/repo_editor.go +++ b/internal/db/repo_editor.go @@ -23,6 +23,7 @@ import ( "gogs.io/gogs/internal/conf" "gogs.io/gogs/internal/db/errors" + "gogs.io/gogs/internal/gitutil" "gogs.io/gogs/internal/osutil" "gogs.io/gogs/internal/process" "gogs.io/gogs/internal/tool" @@ -58,7 +59,7 @@ func ComposeHookEnvs(opts ComposeHookEnvsOptions) []string { ENV_REPO_OWNER_SALT_MD5 + "=" + tool.MD5(opts.OwnerSalt), ENV_REPO_ID + "=" + com.ToStr(opts.RepoID), ENV_REPO_NAME + "=" + opts.RepoName, - ENV_REPO_CUSTOM_HOOKS_PATH + "=" + path.Join(opts.RepoPath, "custom_hooks"), + ENV_REPO_CUSTOM_HOOKS_PATH + "=" + filepath.Join(opts.RepoPath, "custom_hooks"), } return envs } @@ -76,14 +77,15 @@ func discardLocalRepoBranchChanges(localPath, branch string) error { if !com.IsExist(localPath) { return nil } + // No need to check if nothing in the repository. - if !git.IsBranchExist(localPath, branch) { + if !git.RepoHasBranch(localPath, branch) { return nil } - refName := "origin/" + branch - if err := git.ResetHEAD(localPath, true, refName); err != nil { - return fmt.Errorf("git reset --hard %s: %v", refName, err) + rev := "origin/" + branch + if err := git.RepoReset(localPath, rev, git.ResetOptions{Hard: true}); err != nil { + return fmt.Errorf("reset [revision: %s]: %v", rev, err) } return nil } @@ -92,22 +94,17 @@ func (repo *Repository) DiscardLocalRepoBranchChanges(branch string) error { return discardLocalRepoBranchChanges(repo.LocalCopyPath(), branch) } -// checkoutNewBranch checks out to a new branch from the a branch name. -func checkoutNewBranch(repoPath, localPath, oldBranch, newBranch string) error { - if err := git.Checkout(localPath, git.CheckoutOptions{ - Timeout: time.Duration(conf.Git.Timeout.Pull) * time.Second, - Branch: newBranch, - OldBranch: oldBranch, +// CheckoutNewBranch checks out to a new branch from the a branch name. +func (repo *Repository) CheckoutNewBranch(oldBranch, newBranch string) error { + if err := git.RepoCheckout(repo.LocalCopyPath(), newBranch, git.CheckoutOptions{ + BaseBranch: oldBranch, + Timeout: time.Duration(conf.Git.Timeout.Pull) * time.Second, }); err != nil { - return fmt.Errorf("git checkout -b %s %s: %v", newBranch, oldBranch, err) + return fmt.Errorf("checkout [base: %s, new: %s]: %v", oldBranch, newBranch, err) } return nil } -func (repo *Repository) CheckoutNewBranch(oldBranch, newBranch string) error { - return checkoutNewBranch(repo.RepoPath(), repo.LocalCopyPath(), oldBranch, newBranch) -} - type UpdateRepoFileOptions struct { LastCommitID string OldBranch string @@ -135,16 +132,16 @@ func (repo *Repository) UpdateRepoFile(doer *User, opts UpdateRepoFileOptions) ( if opts.OldBranch != opts.NewBranch { // Directly return error if new branch already exists in the server - if git.IsBranchExist(repoPath, opts.NewBranch) { + if git.RepoHasBranch(repoPath, opts.NewBranch) { return errors.BranchAlreadyExists{Name: opts.NewBranch} } // Otherwise, delete branch from local copy in case out of sync - if git.IsBranchExist(localPath, opts.NewBranch) { - if err = git.DeleteBranch(localPath, opts.NewBranch, git.DeleteBranchOptions{ + if git.RepoHasBranch(localPath, opts.NewBranch) { + if err = git.RepoDeleteBranch(localPath, opts.NewBranch, git.DeleteBranchOptions{ Force: true, }); err != nil { - return fmt.Errorf("delete branch[%s]: %v", opts.NewBranch, err) + return fmt.Errorf("delete branch %q: %v", opts.NewBranch, err) } } @@ -167,7 +164,7 @@ func (repo *Repository) UpdateRepoFile(doer *User, opts UpdateRepoFileOptions) ( // Ignore move step if it's a new file under a directory. // Otherwise, move the file when name changed. if osutil.IsFile(oldFilePath) && opts.OldTreeName != opts.NewTreeName { - if err = git.MoveFile(localPath, opts.OldTreeName, opts.NewTreeName); err != nil { + if err = git.RepoMove(localPath, opts.OldTreeName, opts.NewTreeName); err != nil { return fmt.Errorf("git mv %q %q: %v", opts.OldTreeName, opts.NewTreeName, err) } } @@ -176,29 +173,28 @@ func (repo *Repository) UpdateRepoFile(doer *User, opts UpdateRepoFileOptions) ( return fmt.Errorf("write file: %v", err) } - if err = git.AddChanges(localPath, true); err != nil { + if err = git.RepoAdd(localPath, git.AddOptions{All: 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 { + } else if err = git.RepoCommit(localPath, doer.NewGitSig(), opts.Message); err != nil { return fmt.Errorf("commit changes on %q: %v", localPath, err) - } else if err = git.PushWithEnvs(localPath, "origin", opts.NewBranch, - ComposeHookEnvs(ComposeHookEnvsOptions{ - AuthUser: doer, - OwnerName: repo.MustOwner().Name, - OwnerSalt: repo.MustOwner().Salt, - RepoID: repo.ID, - RepoName: repo.Name, - RepoPath: repo.RepoPath(), - })); err != nil { + } + + envs := ComposeHookEnvs(ComposeHookEnvsOptions{ + AuthUser: doer, + OwnerName: repo.MustOwner().Name, + OwnerSalt: repo.MustOwner().Salt, + RepoID: repo.ID, + RepoName: repo.Name, + RepoPath: repo.RepoPath(), + }) + if err = git.RepoPush(localPath, "origin", opts.NewBranch, git.PushOptions{Envs: envs}); err != nil { return fmt.Errorf("git push origin %s: %v", opts.NewBranch, err) } return nil } // GetDiffPreview produces and returns diff result of a file which is not yet committed. -func (repo *Repository) GetDiffPreview(branch, treePath, content string) (diff *Diff, err error) { +func (repo *Repository) GetDiffPreview(branch, treePath, content string) (diff *gitutil.Diff, err error) { repoWorkingPool.CheckIn(com.ToStr(repo.ID)) defer repoWorkingPool.CheckOut(com.ToStr(repo.ID)) @@ -231,9 +227,9 @@ func (repo *Repository) GetDiffPreview(branch, treePath, content string) (diff * pid := process.Add(fmt.Sprintf("GetDiffPreview [repo_path: %s]", repo.RepoPath()), cmd) defer process.Remove(pid) - diff, err = ParsePatch(conf.Git.MaxGitDiffLines, conf.Git.MaxGitDiffLineCharacters, conf.Git.MaxGitDiffFiles, stdout) + diff, err = gitutil.ParseDiff(stdout, conf.Git.MaxDiffFiles, conf.Git.MaxDiffLines, conf.Git.MaxDiffLineChars) if err != nil { - return nil, fmt.Errorf("parse path: %v", err) + return nil, fmt.Errorf("parse diff: %v", err) } if err = cmd.Wait(); err != nil { @@ -280,22 +276,21 @@ func (repo *Repository) DeleteRepoFile(doer *User, opts DeleteRepoFileOptions) ( return fmt.Errorf("remove file %q: %v", opts.TreePath, err) } - if err = git.AddChanges(localPath, true); err != nil { + if err = git.RepoAdd(localPath, git.AddOptions{All: 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 { + } else if err = git.RepoCommit(localPath, doer.NewGitSig(), opts.Message); err != nil { return fmt.Errorf("commit changes to %q: %v", localPath, err) - } else if err = git.PushWithEnvs(localPath, "origin", opts.NewBranch, - ComposeHookEnvs(ComposeHookEnvsOptions{ - AuthUser: doer, - OwnerName: repo.MustOwner().Name, - OwnerSalt: repo.MustOwner().Salt, - RepoID: repo.ID, - RepoName: repo.Name, - RepoPath: repo.RepoPath(), - })); err != nil { + } + + envs := ComposeHookEnvs(ComposeHookEnvsOptions{ + AuthUser: doer, + OwnerName: repo.MustOwner().Name, + OwnerSalt: repo.MustOwner().Salt, + RepoID: repo.ID, + RepoName: repo.Name, + RepoPath: repo.RepoPath(), + }) + if err = git.RepoPush(localPath, "origin", opts.NewBranch, git.PushOptions{Envs: envs}); err != nil { return fmt.Errorf("git push origin %s: %v", opts.NewBranch, err) } return nil @@ -496,22 +491,21 @@ func (repo *Repository) UploadRepoFiles(doer *User, opts UploadRepoFileOptions) } } - if err = git.AddChanges(localPath, true); err != nil { + if err = git.RepoAdd(localPath, git.AddOptions{All: 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 { + } else if err = git.RepoCommit(localPath, doer.NewGitSig(), opts.Message); err != nil { return fmt.Errorf("commit changes on %q: %v", localPath, err) - } else if err = git.PushWithEnvs(localPath, "origin", opts.NewBranch, - ComposeHookEnvs(ComposeHookEnvsOptions{ - AuthUser: doer, - OwnerName: repo.MustOwner().Name, - OwnerSalt: repo.MustOwner().Salt, - RepoID: repo.ID, - RepoName: repo.Name, - RepoPath: repo.RepoPath(), - })); err != nil { + } + + envs := ComposeHookEnvs(ComposeHookEnvsOptions{ + AuthUser: doer, + OwnerName: repo.MustOwner().Name, + OwnerSalt: repo.MustOwner().Salt, + RepoID: repo.ID, + RepoName: repo.Name, + RepoPath: repo.RepoPath(), + }) + if err = git.RepoPush(localPath, "origin", opts.NewBranch, git.PushOptions{Envs: envs}); err != nil { return fmt.Errorf("git push origin %s: %v", opts.NewBranch, err) } diff --git a/internal/db/update.go b/internal/db/update.go index e8fc41ed..94fc4ee3 100644 --- a/internal/db/update.go +++ b/internal/db/update.go @@ -5,19 +5,18 @@ package db import ( - "container/list" "fmt" "os/exec" "strings" - git "github.com/gogs/git-module" + "github.com/gogs/git-module" ) // CommitToPushCommit transforms a git.Commit to PushCommit type. func CommitToPushCommit(commit *git.Commit) *PushCommit { return &PushCommit{ Sha1: commit.ID.String(), - Message: commit.Message(), + Message: commit.Message, AuthorEmail: commit.Author.Email, AuthorName: commit.Author.Name, CommitterEmail: commit.Committer.Email, @@ -26,27 +25,22 @@ func CommitToPushCommit(commit *git.Commit) *PushCommit { } } -func ListToPushCommits(l *list.List) *PushCommits { - if l == nil { +func CommitsToPushCommits(commits []*git.Commit) *PushCommits { + if len(commits) == 0 { return &PushCommits{} } - commits := make([]*PushCommit, 0) - var actEmail string - for e := l.Front(); e != nil; e = e.Next() { - commit := e.Value.(*git.Commit) - if actEmail == "" { - actEmail = commit.Committer.Email - } - commits = append(commits, CommitToPushCommit(commit)) + pcs := make([]*PushCommit, len(commits)) + for i := range commits { + pcs[i] = CommitToPushCommit(commits[i]) } - return &PushCommits{l.Len(), commits, "", nil} + return &PushCommits{len(pcs), pcs, "", nil} } type PushUpdateOptions struct { OldCommitID string NewCommitID string - RefFullName string + FullRefspec string PusherID int64 PusherName string RepoUserName string @@ -56,10 +50,10 @@ type PushUpdateOptions struct { // 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 + isNewRef := strings.HasPrefix(opts.OldCommitID, git.EmptyID) + isDelRef := strings.HasPrefix(opts.NewCommitID, git.EmptyID) if isNewRef && isDelRef { - return fmt.Errorf("Old and new revisions are both %s", git.EMPTY_SHA) + return fmt.Errorf("both old and new revisions are %q", git.EmptyID) } repoPath := RepoPath(opts.RepoUserName, opts.RepoName) @@ -70,9 +64,9 @@ func PushUpdate(opts PushUpdateOptions) (err error) { return fmt.Errorf("run 'git update-server-info': %v", err) } - gitRepo, err := git.OpenRepository(repoPath) + gitRepo, err := git.Open(repoPath) if err != nil { - return fmt.Errorf("OpenRepository: %v", err) + return fmt.Errorf("open repository: %v", err) } owner, err := GetUserByName(opts.RepoUserName) @@ -90,12 +84,12 @@ func PushUpdate(opts PushUpdateOptions) (err error) { } // Push tags - if strings.HasPrefix(opts.RefFullName, git.TAG_PREFIX) { + if strings.HasPrefix(opts.FullRefspec, git.RefsTags) { if err := CommitRepoAction(CommitRepoActionOptions{ PusherName: opts.PusherName, RepoOwnerID: owner.ID, RepoName: repo.Name, - RefFullName: opts.RefFullName, + RefFullName: opts.FullRefspec, OldCommitID: opts.OldCommitID, NewCommitID: opts.NewCommitID, Commits: &PushCommits{}, @@ -105,22 +99,23 @@ func PushUpdate(opts PushUpdateOptions) (err error) { return nil } - var l *list.List + var commits []*git.Commit // Skip read parent commits when delete branch if !isDelRef { // Push new branch - newCommit, err := gitRepo.GetCommit(opts.NewCommitID) + newCommit, err := gitRepo.CatFileCommit(opts.NewCommitID) if err != nil { return fmt.Errorf("GetCommit [commit_id: %s]: %v", opts.NewCommitID, err) } if isNewRef { - l, err = newCommit.CommitsBeforeLimit(10) + commits, err = newCommit.Ancestors(git.LogOptions{MaxCount: 9}) if err != nil { return fmt.Errorf("CommitsBeforeLimit [commit_id: %s]: %v", newCommit.ID, err) } + commits = append([]*git.Commit{newCommit}, commits...) } else { - l, err = newCommit.CommitsBeforeUntil(opts.OldCommitID) + commits, err = newCommit.CommitsAfter(opts.OldCommitID) if err != nil { return fmt.Errorf("CommitsBeforeUntil [commit_id: %s]: %v", opts.OldCommitID, err) } @@ -131,10 +126,10 @@ func PushUpdate(opts PushUpdateOptions) (err error) { PusherName: opts.PusherName, RepoOwnerID: owner.ID, RepoName: repo.Name, - RefFullName: opts.RefFullName, + RefFullName: opts.FullRefspec, OldCommitID: opts.OldCommitID, NewCommitID: opts.NewCommitID, - Commits: ListToPushCommits(l), + Commits: CommitsToPushCommits(commits), }); err != nil { return fmt.Errorf("CommitRepoAction.(branch): %v", err) } diff --git a/internal/db/user.go b/internal/db/user.go index 5f357e28..c3c3f31e 100644 --- a/internal/db/user.go +++ b/internal/db/user.go @@ -6,7 +6,6 @@ package db import ( "bytes" - "container/list" "crypto/sha256" "crypto/subtle" "encoding/hex" @@ -977,28 +976,22 @@ func ValidateCommitWithEmail(c *git.Commit) *User { } // ValidateCommitsWithEmails checks if authors' e-mails of commits are corresponding to users. -func ValidateCommitsWithEmails(oldCommits *list.List) *list.List { - var ( - u *User - emails = map[string]*User{} - newCommits = list.New() - e = oldCommits.Front() - ) - for e != nil { - c := e.Value.(*git.Commit) - - if v, ok := emails[c.Author.Email]; !ok { - u, _ = GetUserByEmail(c.Author.Email) - emails[c.Author.Email] = u +func ValidateCommitsWithEmails(oldCommits []*git.Commit) []*UserCommit { + emails := make(map[string]*User) + newCommits := make([]*UserCommit, len(oldCommits)) + for i := range oldCommits { + var u *User + if v, ok := emails[oldCommits[i].Author.Email]; !ok { + u, _ = GetUserByEmail(oldCommits[i].Author.Email) + emails[oldCommits[i].Author.Email] = u } else { u = v } - newCommits.PushBack(UserCommit{ + newCommits[i] = &UserCommit{ User: u, - Commit: c, - }) - e = e.Next() + Commit: oldCommits[i], + } } return newCommits } diff --git a/internal/db/webhook_dingtalk.go b/internal/db/webhook_dingtalk.go index 4382803d..e747ae14 100644 --- a/internal/db/webhook_dingtalk.go +++ b/internal/db/webhook_dingtalk.go @@ -86,7 +86,7 @@ func GetDingtalkPayload(p api.Payloader, event HookEventType) (payload *Dingtalk } func getDingtalkCreatePayload(p *api.CreatePayload) (*DingtalkPayload, error) { - refName := git.RefEndName(p.Ref) + refName := git.RefShortName(p.Ref) refType := strings.Title(p.RefType) actionCard := NewDingtalkActionCard("View "+refType, p.Repo.HTMLURL+"/src/"+refName) @@ -99,7 +99,7 @@ func getDingtalkCreatePayload(p *api.CreatePayload) (*DingtalkPayload, error) { } func getDingtalkDeletePayload(p *api.DeletePayload) (*DingtalkPayload, error) { - refName := git.RefEndName(p.Ref) + refName := git.RefShortName(p.Ref) refType := strings.Title(p.RefType) actionCard := NewDingtalkActionCard("View Repo", p.Repo.HTMLURL) @@ -122,7 +122,7 @@ func getDingtalkForkPayload(p *api.ForkPayload) (*DingtalkPayload, error) { } func getDingtalkPushPayload(p *api.PushPayload) (*DingtalkPayload, error) { - refName := git.RefEndName(p.Ref) + refName := git.RefShortName(p.Ref) pusher := p.Pusher.FullName if pusher == "" { diff --git a/internal/db/webhook_discord.go b/internal/db/webhook_discord.go index 7442a557..4725f867 100644 --- a/internal/db/webhook_discord.go +++ b/internal/db/webhook_discord.go @@ -71,7 +71,7 @@ func DiscordSHALinkFormatter(url string, text string) string { // getDiscordCreatePayload composes Discord payload for create new branch or tag. func getDiscordCreatePayload(p *api.CreatePayload) (*DiscordPayload, error) { - refName := git.RefEndName(p.Ref) + refName := git.RefShortName(p.Ref) repoLink := DiscordLinkFormatter(p.Repo.HTMLURL, p.Repo.Name) refLink := DiscordLinkFormatter(p.Repo.HTMLURL+"/src/"+refName, refName) content := fmt.Sprintf("Created new %s: %s/%s", p.RefType, repoLink, refLink) @@ -89,7 +89,7 @@ func getDiscordCreatePayload(p *api.CreatePayload) (*DiscordPayload, error) { // getDiscordDeletePayload composes Discord payload for delete a branch or tag. func getDiscordDeletePayload(p *api.DeletePayload) (*DiscordPayload, error) { - refName := git.RefEndName(p.Ref) + refName := git.RefShortName(p.Ref) repoLink := DiscordLinkFormatter(p.Repo.HTMLURL, p.Repo.Name) content := fmt.Sprintf("Deleted %s: %s/%s", p.RefType, repoLink, refName) return &DiscordPayload{ @@ -124,7 +124,7 @@ func getDiscordForkPayload(p *api.ForkPayload) (*DiscordPayload, error) { func getDiscordPushPayload(p *api.PushPayload, slack *SlackMeta) (*DiscordPayload, error) { // n new commits var ( - branchName = git.RefEndName(p.Ref) + branchName = git.RefShortName(p.Ref) commitDesc string commitString string ) diff --git a/internal/db/webhook_slack.go b/internal/db/webhook_slack.go index c18b630f..f824e9bc 100644 --- a/internal/db/webhook_slack.go +++ b/internal/db/webhook_slack.go @@ -72,7 +72,7 @@ func SlackLinkFormatter(url string, text string) string { // getSlackCreatePayload composes Slack payload for create new branch or tag. func getSlackCreatePayload(p *api.CreatePayload) (*SlackPayload, error) { - refName := git.RefEndName(p.Ref) + refName := git.RefShortName(p.Ref) repoLink := SlackLinkFormatter(p.Repo.HTMLURL, p.Repo.Name) refLink := SlackLinkFormatter(p.Repo.HTMLURL+"/src/"+refName, refName) text := fmt.Sprintf("[%s:%s] %s created by %s", repoLink, refLink, p.RefType, p.Sender.UserName) @@ -83,7 +83,7 @@ func getSlackCreatePayload(p *api.CreatePayload) (*SlackPayload, error) { // getSlackDeletePayload composes Slack payload for delete a branch or tag. func getSlackDeletePayload(p *api.DeletePayload) (*SlackPayload, error) { - refName := git.RefEndName(p.Ref) + refName := git.RefShortName(p.Ref) repoLink := SlackLinkFormatter(p.Repo.HTMLURL, p.Repo.Name) text := fmt.Sprintf("[%s:%s] %s deleted by %s", repoLink, refName, p.RefType, p.Sender.UserName) return &SlackPayload{ @@ -104,7 +104,7 @@ func getSlackForkPayload(p *api.ForkPayload) (*SlackPayload, error) { func getSlackPushPayload(p *api.PushPayload, slack *SlackMeta) (*SlackPayload, error) { // n new commits var ( - branchName = git.RefEndName(p.Ref) + branchName = git.RefShortName(p.Ref) commitDesc string commitString string ) diff --git a/internal/db/wiki.go b/internal/db/wiki.go index 85005e7b..5fbb9fb6 100644 --- a/internal/db/wiki.go +++ b/internal/db/wiki.go @@ -62,8 +62,8 @@ func (repo *Repository) InitWiki() error { return nil } - if err := git.InitRepository(repo.WikiPath(), true); err != nil { - return fmt.Errorf("InitRepository: %v", err) + if err := git.Init(repo.WikiPath(), git.InitOptions{Bare: true}); err != nil { + return fmt.Errorf("init repository: %v", err) } else if err = createDelegateHooks(repo.WikiPath()); err != nil { return fmt.Errorf("createDelegateHooks: %v", err) } @@ -125,15 +125,12 @@ func (repo *Repository) updateWikiPage(doer *User, oldTitle, title, content, mes if len(message) == 0 { message = "Update page '" + title + "'" } - if err = git.AddChanges(localPath, true); err != nil { - return fmt.Errorf("AddChanges: %v", err) - } else if err = git.CommitChanges(localPath, git.CommitChangesOptions{ - Committer: doer.NewGitSig(), - Message: message, - }); err != nil { - return fmt.Errorf("CommitChanges: %v", err) - } else if err = git.Push(localPath, "origin", "master"); err != nil { - return fmt.Errorf("Push: %v", err) + if err = git.RepoAdd(localPath, git.AddOptions{All: true}); err != nil { + return fmt.Errorf("add all changes: %v", err) + } else if err = git.RepoCommit(localPath, doer.NewGitSig(), message); err != nil { + return fmt.Errorf("commit changes: %v", err) + } else if err = git.RepoPush(localPath, "origin", "master"); err != nil { + return fmt.Errorf("push: %v", err) } return nil @@ -164,15 +161,12 @@ func (repo *Repository) DeleteWikiPage(doer *User, title string) (err error) { message := "Delete page '" + title + "'" - if err = git.AddChanges(localPath, true); err != nil { - return fmt.Errorf("AddChanges: %v", err) - } else if err = git.CommitChanges(localPath, git.CommitChangesOptions{ - Committer: doer.NewGitSig(), - Message: message, - }); err != nil { - return fmt.Errorf("CommitChanges: %v", err) - } else if err = git.Push(localPath, "origin", "master"); err != nil { - return fmt.Errorf("Push: %v", err) + if err = git.RepoAdd(localPath, git.AddOptions{All: true}); err != nil { + return fmt.Errorf("add all changes: %v", err) + } else if err = git.RepoCommit(localPath, doer.NewGitSig(), message); err != nil { + return fmt.Errorf("commit changes: %v", err) + } else if err = git.RepoPush(localPath, "origin", "master"); err != nil { + return fmt.Errorf("push: %v", err) } return nil |