Compare commits

...

9 Commits

Author SHA1 Message Date
John Olheiser
84a5b81d27 Changelog 1.7.5 (#6444)
Signed-off-by: jolheiser <john.olheiser@gmail.com>
2019-03-27 11:40:39 -04:00
kolaente
84f41d9d92 Fixed unitTypeCode not being used (#6423) 2019-03-24 17:31:01 +00:00
Lunny Xiao
acb9ae4c4d fix bug manifest.json will not request with cookie so that session will created every request (#6372) (#6383) 2019-03-19 22:19:54 -04:00
mrsdizzie
b76d899f7a Fix ParsePatch function to work with quoted diff --git strings (#6323) (#6332)
Backport of #6323
2019-03-14 19:59:29 +00:00
John Olheiser
9f33aa61bd Proposed changelog for 1.7.4 (#6316)
* Proposed changelog for 1.7.4

Signed-off-by: jolheiser <john.olheiser@gmail.com>

* Updated security fix description with @zeripath suggestion.

* Added 6292

* Update CHANGELOG.md

* Update CHANGELOG.md
2019-03-13 09:02:58 +08:00
Lunny Xiao
d0bbfd835f update git vendor to fix wrong release commit id and add migrations (#6224) (#6300) 2019-03-12 13:39:20 -04:00
techknowlogick
c7bbfd8f5e backport 6306 (#6308) 2019-03-12 18:58:49 +08:00
Muhammed TİFTİKÇİ
59a64c0e1d Fix #5580 : Make organization dropdown scrollable when using mouse wh… (#6246)
* Fix #5580 : Make organization dropdown scrollable when using mouse wheel.

* build less file with old makefile
2019-03-05 13:27:50 -05:00
Lunny Xiao
6a86a82368 fix display dashboard even if require to change password (#6214) (#6215)
* fix display dashboard even if require to change password

* fix comments
2019-02-28 19:36:57 +08:00
22 changed files with 308 additions and 88 deletions

View File

@@ -4,6 +4,21 @@ This changelog goes through all the changes that have been made in each release
without substantial changes to our git log; to see the highlights of what has without substantial changes to our git log; to see the highlights of what has
been added to each release, please refer to the [blog](https://blog.gitea.io). been added to each release, please refer to the [blog](https://blog.gitea.io).
## [1.7.5](https://github.com/go-gitea/gitea/releases/tag/v1.7.5) - 2019-03-27
* BUGFIXES
* Fix unitTypeCode not being used in accessLevelUnit (#6419) (#6423)
* Fix bug where manifest.json was being requested without cookies and continuously creating new sessions (#6372) (#6383)
* Fix ParsePatch function to work with quoted diff --git strings (#6323) (#6332)
## [1.7.4](https://github.com/go-gitea/gitea/releases/tag/v1.7.4) - 2019-03-12
* SECURITY
* Fix potential XSS vulnerability in repository description. (#6306) (#6308)
* BUGFIXES
* Fix wrong release commit id (#6224) (#6300)
* Fix panic on empty signed commits (#6292) (#6300)
* Fix organization dropdown not being scrollable when using mouse wheel (#5988) (#6246)
* Fix displaying dashboard even if required to change password (#6214) (#6215)
## [1.7.3](https://github.com/go-gitea/gitea/releases/tag/v1.7.3) - 2019-02-27 ## [1.7.3](https://github.com/go-gitea/gitea/releases/tag/v1.7.3) - 2019-02-27
* BUGFIXES * BUGFIXES
* Fix server 500 when trying to migrate to an already existing repository (#6188) (#6197) * Fix server 500 when trying to migrate to an already existing repository (#6188) (#6197)

5
Gopkg.lock generated
View File

@@ -3,11 +3,11 @@
[[projects]] [[projects]]
branch = "master" branch = "master"
digest = "1:ab875622908a804a327a95a1701002b150806a3c5406df51ec231eac16d3a1ca" digest = "1:e1fa64238b0a2dbf1edf98c4af8d1b8cb65179e286d7f28006b50fa9f508ee9d"
name = "code.gitea.io/git" name = "code.gitea.io/git"
packages = ["."] packages = ["."]
pruneopts = "NUT" pruneopts = "NUT"
revision = "389d3c803e12a30dffcbb54a15c2242521bc4333" revision = "74d7c14dd4a3ed9c5def0dc3c1aeede399ddc5c5"
[[projects]] [[projects]]
branch = "master" branch = "master"
@@ -1173,7 +1173,6 @@
"github.com/keybase/go-crypto/openpgp", "github.com/keybase/go-crypto/openpgp",
"github.com/keybase/go-crypto/openpgp/armor", "github.com/keybase/go-crypto/openpgp/armor",
"github.com/keybase/go-crypto/openpgp/packet", "github.com/keybase/go-crypto/openpgp/packet",
"github.com/klauspost/compress/gzip",
"github.com/lafriks/xormstore", "github.com/lafriks/xormstore",
"github.com/lib/pq", "github.com/lib/pq",
"github.com/lunny/dingtalk_webhook", "github.com/lunny/dingtalk_webhook",

View File

@@ -550,7 +550,12 @@ func ParsePatch(maxLines, maxLineCharacters, maxFiles int, reader io.Reader) (*D
beg := len(cmdDiffHead) beg := len(cmdDiffHead)
a := line[beg+2 : middle] a := line[beg+2 : middle]
b := line[middle+3:] b := line[middle+3:]
if hasQuote { if hasQuote {
// Keep the entire string in double quotes for now
a = line[beg:middle]
b = line[middle+1:]
var err error var err error
a, err = strconv.Unquote(a) a, err = strconv.Unquote(a)
if err != nil { if err != nil {
@@ -560,6 +565,10 @@ func ParsePatch(maxLines, maxLineCharacters, maxFiles int, reader io.Reader) (*D
if err != nil { if err != nil {
return nil, fmt.Errorf("Unquote: %v", err) return nil, fmt.Errorf("Unquote: %v", err)
} }
// Now remove the /a /b
a = a[2:]
b = b[2:]
} }
curFile = &DiffFile{ curFile = &DiffFile{
@@ -637,6 +646,7 @@ func ParsePatch(maxLines, maxLineCharacters, maxFiles int, reader io.Reader) (*D
} }
} }
} }
return diff, nil return diff, nil
} }

View File

@@ -5,6 +5,8 @@ import (
"strings" "strings"
"testing" "testing"
"code.gitea.io/gitea/modules/setting"
dmp "github.com/sergi/go-diff/diffmatchpatch" dmp "github.com/sergi/go-diff/diffmatchpatch"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@@ -99,6 +101,59 @@ func ExampleCutDiffAroundLine() {
println(result) println(result)
} }
func TestParsePatch(t *testing.T) {
var diff = `diff --git "a/README.md" "b/README.md"
--- a/README.md
+++ b/README.md
@@ -1,3 +1,6 @@
# gitea-github-migrator
+
+ Build Status
- Latest Release
Docker Pulls
+ cut off
+ cut off`
result, err := ParsePatch(setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(diff))
if err != nil {
t.Errorf("ParsePatch failed: %s", err)
}
println(result)
var diff2 = `diff --git "a/A \\ B" "b/A \\ B"
--- "a/A \\ B"
+++ "b/A \\ B"
@@ -1,3 +1,6 @@
# gitea-github-migrator
+
+ Build Status
- Latest Release
Docker Pulls
+ cut off
+ cut off`
result, err = ParsePatch(setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(diff2))
if err != nil {
t.Errorf("ParsePatch failed: %s", err)
}
println(result)
var diff3 = `diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,3 +1,6 @@
# gitea-github-migrator
+
+ Build Status
- Latest Release
Docker Pulls
+ cut off
+ cut off`
result, err = ParsePatch(setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(diff3))
if err != nil {
t.Errorf("ParsePatch failed: %s", err)
}
println(result)
}
func setupDefaultDiff() *Diff { func setupDefaultDiff() *Diff {
return &Diff{ return &Diff{
Files: []*DiffFile{ Files: []*DiffFile{

View File

@@ -719,10 +719,12 @@ var (
// DescriptionHTML does special handles to description and return HTML string. // DescriptionHTML does special handles to description and return HTML string.
func (repo *Repository) DescriptionHTML() template.HTML { func (repo *Repository) DescriptionHTML() template.HTML {
sanitize := func(s string) string { desc, err := markup.RenderDescriptionHTML([]byte(repo.Description), repo.HTMLURL(), repo.ComposeMetas())
return fmt.Sprintf(`<a href="%[1]s" target="_blank" rel="noopener noreferrer">%[1]s</a>`, s) if err != nil {
log.Error(4, "Failed to render description for %s (ID: %d): %v", repo.Name, repo.ID, err)
return template.HTML(markup.Sanitize(repo.Description))
} }
return template.HTML(descPattern.ReplaceAllStringFunc(markup.Sanitize(repo.Description), sanitize)) return template.HTML(markup.Sanitize(string(desc)))
} }
// LocalCopyPath returns the local repository copy path. // LocalCopyPath returns the local repository copy path.

View File

@@ -70,10 +70,6 @@ func (repo *Repository) CheckBranchName(name string) error {
return err return err
} }
if _, err := gitRepo.GetTag(name); err == nil {
return ErrTagAlreadyExists{name}
}
branches, err := repo.GetBranches() branches, err := repo.GetBranches()
if err != nil { if err != nil {
return err return err
@@ -87,6 +83,11 @@ func (repo *Repository) CheckBranchName(name string) error {
return ErrBranchNameConflict{branch.Name} return ErrBranchNameConflict{branch.Name}
} }
} }
if _, err := gitRepo.GetTag(name); err == nil {
return ErrTagAlreadyExists{name}
}
return nil return nil
} }

View File

@@ -238,7 +238,7 @@ func accessLevelUnit(e Engine, user *User, repo *Repository, unitType UnitType)
if err != nil { if err != nil {
return AccessModeNone, err return AccessModeNone, err
} }
return perm.UnitAccessMode(UnitTypeCode), nil return perm.UnitAccessMode(unitType), nil
} }
func hasAccessUnit(e Engine, user *User, repo *Repository, unitType UnitType, testMode AccessMode) (bool, error) { func hasAccessUnit(e Engine, user *User, repo *Repository, unitType UnitType, testMode AccessMode) (bool, error) {

View File

@@ -44,21 +44,17 @@ func Toggle(options *ToggleOptions) macaron.Handler {
return return
} }
// prevent infinite redirection
// also make sure that the form cannot be accessed by
// users who don't need this
if ctx.Req.URL.Path == "/user/settings/change_password" {
if !ctx.User.MustChangePassword {
ctx.Redirect(setting.AppSubURL + "/")
}
return
}
if ctx.User.MustChangePassword { if ctx.User.MustChangePassword {
ctx.Data["Title"] = ctx.Tr("auth.must_change_password") if ctx.Req.URL.Path != "/user/settings/change_password" {
ctx.Data["ChangePasscodeLink"] = setting.AppSubURL + "/user/change_password" ctx.Data["Title"] = ctx.Tr("auth.must_change_password")
ctx.SetCookie("redirect_to", url.QueryEscape(setting.AppSubURL+ctx.Req.RequestURI), 0, setting.AppSubURL) ctx.Data["ChangePasscodeLink"] = setting.AppSubURL + "/user/change_password"
ctx.Redirect(setting.AppSubURL + "/user/settings/change_password") ctx.SetCookie("redirect_to", url.QueryEscape(setting.AppSubURL+ctx.Req.RequestURI), 0, setting.AppSubURL)
ctx.Redirect(setting.AppSubURL + "/user/settings/change_password")
return
}
} else if ctx.Req.URL.Path == "/user/settings/change_password" {
// make sure that the form cannot be accessed by users who don't need this
ctx.Redirect(setting.AppSubURL + "/")
return return
} }
} }

View File

@@ -234,6 +234,23 @@ func RenderCommitMessage(
return ctx.postProcess(rawHTML) return ctx.postProcess(rawHTML)
} }
// RenderDescriptionHTML will use similar logic as PostProcess, but will
// use a single special linkProcessor.
func RenderDescriptionHTML(
rawHTML []byte,
urlPrefix string,
metas map[string]string,
) ([]byte, error) {
ctx := &postProcessCtx{
metas: metas,
urlPrefix: urlPrefix,
procs: []processor{
descriptionLinkProcessor,
},
}
return ctx.postProcess(rawHTML)
}
var byteBodyTag = []byte("<body>") var byteBodyTag = []byte("<body>")
var byteBodyTagClosing = []byte("</body>") var byteBodyTagClosing = []byte("</body>")
@@ -668,3 +685,34 @@ func genDefaultLinkProcessor(defaultLink string) processor {
node.FirstChild, node.LastChild = ch, ch node.FirstChild, node.LastChild = ch, ch
} }
} }
// descriptionLinkProcessor creates links for DescriptionHTML
func descriptionLinkProcessor(ctx *postProcessCtx, node *html.Node) {
m := linkRegex.FindStringIndex(node.Data)
if m == nil {
return
}
uri := node.Data[m[0]:m[1]]
replaceContent(node, m[0], m[1], createDescriptionLink(uri, uri))
}
func createDescriptionLink(href, content string) *html.Node {
textNode := &html.Node{
Type: html.TextNode,
Data: content,
}
linkNode := &html.Node{
FirstChild: textNode,
LastChild: textNode,
Type: html.ElementNode,
Data: "a",
DataAtom: atom.A,
Attr: []html.Attribute{
{Key: "href", Val: href},
{Key: "target", Val: "_blank"},
{Key: "rel", Val: "noopener noreferrer"},
},
}
textNode.Parent = linkNode
return linkNode
}

File diff suppressed because one or more lines are too long

View File

@@ -384,33 +384,12 @@ pre, code {
} }
.overflow.menu { .ui.floating.dropdown {
.items { .overflow.menu {
max-height: 300px; .scrolling.menu.items {
overflow-y: auto; border-radius: 0px !important;
.item { box-shadow: none !important;
position: relative; border-bottom: 1px solid rgba(34, 36, 38, 0.15);
cursor: pointer;
display: block;
border: none;
height: auto;
border-top: none;
line-height: 1em;
color: rgba(0,0,0,.8);
padding: .71428571em 1.14285714em !important;
font-size: 1rem;
text-transform: none;
font-weight: 400;
box-shadow: none;
-webkit-touch-callout: none;
&.active {
font-weight: 700;
}
&:hover {
background: rgba(0,0,0,.05);
color: rgba(0,0,0,.8);
z-index: 13;
}
} }
} }
} }

View File

@@ -6,6 +6,7 @@ package routers
import ( import (
"bytes" "bytes"
"net/url"
"strings" "strings"
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
@@ -43,6 +44,11 @@ func Home(ctx *context.Context) {
log.Info("Failed authentication attempt for %s from %s", ctx.User.Name, ctx.RemoteAddr()) log.Info("Failed authentication attempt for %s from %s", ctx.User.Name, ctx.RemoteAddr())
ctx.Data["Title"] = ctx.Tr("auth.prohibit_login") ctx.Data["Title"] = ctx.Tr("auth.prohibit_login")
ctx.HTML(200, "user/auth/prohibit_login") ctx.HTML(200, "user/auth/prohibit_login")
} else if ctx.User.MustChangePassword {
ctx.Data["Title"] = ctx.Tr("auth.must_change_password")
ctx.Data["ChangePasscodeLink"] = setting.AppSubURL + "/user/change_password"
ctx.SetCookie("redirect_to", url.QueryEscape(setting.AppSubURL+ctx.Req.RequestURI), 0, setting.AppSubURL)
ctx.Redirect(setting.AppSubURL + "/user/settings/change_password")
} else { } else {
user.Dashboard(ctx) user.Dashboard(ctx)
} }

View File

@@ -50,7 +50,7 @@ func renderDirectory(ctx *context.Context, treeLink string) {
} }
entries.CustomSort(base.NaturalSortLess) entries.CustomSort(base.NaturalSortLess)
ctx.Data["Files"], err = entries.GetCommitsInfo(ctx.Repo.Commit, ctx.Repo.TreePath) ctx.Data["Files"], err = entries.GetCommitsInfo(ctx.Repo.Commit, ctx.Repo.TreePath, nil)
if err != nil { if err != nil {
ctx.ServerError("GetCommitsInfo", err) ctx.ServerError("GetCommitsInfo", err)
return return

View File

@@ -5,7 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="x-ua-compatible" content="ie=edge"> <meta http-equiv="x-ua-compatible" content="ie=edge">
<title>{{if .Title}}{{.Title}} - {{end}}{{AppName}}</title> <title>{{if .Title}}{{.Title}} - {{end}}{{AppName}}</title>
<link rel="manifest" href="{{AppSubUrl}}/manifest.json"> <link rel="manifest" href="{{AppSubUrl}}/manifest.json" crossorigin="use-credentials">
<script> <script>
if ('serviceWorker' in navigator) { if ('serviceWorker' in navigator) {

View File

@@ -11,7 +11,7 @@
<div class="ui header"> <div class="ui header">
{{.i18n.Tr "home.switch_dashboard_context"}} {{.i18n.Tr "home.switch_dashboard_context"}}
</div> </div>
<div class="items"> <div class="scrolling menu items">
<a class="{{if eq .ContextUser.ID .SignedUser.ID}}active selected{{end}} item" href="{{AppSubUrl}}/{{if .PageIsIssues}}issues{{else if .PageIsPulls}}pulls{{end}}"> <a class="{{if eq .ContextUser.ID .SignedUser.ID}}active selected{{end}} item" href="{{AppSubUrl}}/{{if .PageIsIssues}}issues{{else if .PageIsPulls}}pulls{{end}}">
<img class="ui avatar image" src="{{.SignedUser.RelAvatarLink}}"> <img class="ui avatar image" src="{{.SignedUser.RelAvatarLink}}">
{{.SignedUser.Name}} {{.SignedUser.Name}}

11
vendor/code.gitea.io/git/cache.go generated vendored Normal file
View File

@@ -0,0 +1,11 @@
// Copyright 2019 The Gitea 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 git
// LastCommitCache cache
type LastCommitCache interface {
Get(repoPath, ref, entryPath string) (*Commit, error)
Put(repoPath, ref, entryPath string, commit *Commit) error
}

53
vendor/code.gitea.io/git/commit.go generated vendored
View File

@@ -1,4 +1,5 @@
// Copyright 2015 The Gogs Authors. All rights reserved. // Copyright 2015 The Gogs Authors. All rights reserved.
// Copyright 2018 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
@@ -9,6 +10,7 @@ import (
"bytes" "bytes"
"container/list" "container/list"
"fmt" "fmt"
"io"
"net/http" "net/http"
"strconv" "strconv"
"strings" "strings"
@@ -16,6 +18,7 @@ import (
// Commit represents a git commit. // Commit represents a git commit.
type Commit struct { type Commit struct {
Branch string // Branch this commit belongs to
Tree Tree
ID SHA1 // The ID of this commit object ID SHA1 // The ID of this commit object
Author *Signature Author *Signature
@@ -279,6 +282,56 @@ func (c *Commit) GetSubModule(entryname string) (*SubModule, error) {
return nil, nil return nil, nil
} }
// CommitFileStatus represents status of files in a commit.
type CommitFileStatus struct {
Added []string
Removed []string
Modified []string
}
// NewCommitFileStatus creates a CommitFileStatus
func NewCommitFileStatus() *CommitFileStatus {
return &CommitFileStatus{
[]string{}, []string{}, []string{},
}
}
// GetCommitFileStatus returns file status of commit in given repository.
func GetCommitFileStatus(repoPath, commitID string) (*CommitFileStatus, error) {
stdout, w := io.Pipe()
done := make(chan struct{})
fileStatus := NewCommitFileStatus()
go func() {
scanner := bufio.NewScanner(stdout)
for scanner.Scan() {
fields := strings.Fields(scanner.Text())
if len(fields) < 2 {
continue
}
switch fields[0][0] {
case 'A':
fileStatus.Added = append(fileStatus.Added, fields[1])
case 'D':
fileStatus.Removed = append(fileStatus.Removed, fields[1])
case 'M':
fileStatus.Modified = append(fileStatus.Modified, fields[1])
}
}
done <- struct{}{}
}()
stderr := new(bytes.Buffer)
err := NewCommand("show", "--name-status", "--pretty=format:''", commitID).RunInDirPipeline(repoPath, w, stderr)
w.Close() // Close writer to exit parsing goroutine
if err != nil {
return nil, concatenateError(err, stderr.String())
}
<-done
return fileStatus, nil
}
// GetFullCommitID returns full length (40) of commit ID by given short SHA in a repository. // GetFullCommitID returns full length (40) of commit ID by given short SHA in a repository.
func GetFullCommitID(repoPath, shortID string) (string, error) { func GetFullCommitID(repoPath, shortID string) (string, error) {
if len(shortID) >= 40 { if len(shortID) >= 40 {

View File

@@ -72,13 +72,20 @@ func (state *getCommitsInfoState) getTargetedEntryPath() string {
} }
// repeatedly perform targeted searches for unpopulated entries // repeatedly perform targeted searches for unpopulated entries
func targetedSearch(state *getCommitsInfoState, done chan error) { func targetedSearch(state *getCommitsInfoState, done chan error, cache LastCommitCache) {
for { for {
entryPath := state.getTargetedEntryPath() entryPath := state.getTargetedEntryPath()
if len(entryPath) == 0 { if len(entryPath) == 0 {
done <- nil done <- nil
return return
} }
if cache != nil {
commit, err := cache.Get(state.headCommit.repo.Path, state.headCommit.ID.String(), entryPath)
if err == nil && commit != nil {
state.update(entryPath, commit)
continue
}
}
command := NewCommand("rev-list", "-1", state.headCommit.ID.String(), "--", entryPath) command := NewCommand("rev-list", "-1", state.headCommit.ID.String(), "--", entryPath)
output, err := command.RunInDir(state.headCommit.repo.Path) output, err := command.RunInDir(state.headCommit.repo.Path)
if err != nil { if err != nil {
@@ -96,6 +103,9 @@ func targetedSearch(state *getCommitsInfoState, done chan error) {
return return
} }
state.update(entryPath, commit) state.update(entryPath, commit)
if cache != nil {
cache.Put(state.headCommit.repo.Path, state.headCommit.ID.String(), entryPath, commit)
}
} }
} }
@@ -118,9 +128,9 @@ func initGetCommitInfoState(entries Entries, headCommit *Commit, treePath string
} }
// GetCommitsInfo gets information of all commits that are corresponding to these entries // GetCommitsInfo gets information of all commits that are corresponding to these entries
func (tes Entries) GetCommitsInfo(commit *Commit, treePath string) ([][]interface{}, error) { func (tes Entries) GetCommitsInfo(commit *Commit, treePath string, cache LastCommitCache) ([][]interface{}, error) {
state := initGetCommitInfoState(tes, commit, treePath) state := initGetCommitInfoState(tes, commit, treePath)
if err := getCommitsInfo(state); err != nil { if err := getCommitsInfo(state, cache); err != nil {
return nil, err return nil, err
} }
if len(state.commits) < len(state.entryPaths) { if len(state.commits) < len(state.entryPaths) {
@@ -188,7 +198,7 @@ func (state *getCommitsInfoState) update(entryPath string, commit *Commit) bool
const getCommitsInfoPretty = "--pretty=format:%H %ct %s" const getCommitsInfoPretty = "--pretty=format:%H %ct %s"
func getCommitsInfo(state *getCommitsInfoState) error { func getCommitsInfo(state *getCommitsInfoState, cache LastCommitCache) error {
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute) ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute)
defer cancel() defer cancel()
@@ -215,7 +225,7 @@ func getCommitsInfo(state *getCommitsInfoState) error {
numThreads := runtime.NumCPU() numThreads := runtime.NumCPU()
done := make(chan error, numThreads) done := make(chan error, numThreads)
for i := 0; i < numThreads; i++ { for i := 0; i < numThreads; i++ {
go targetedSearch(state, done) go targetedSearch(state, done, cache)
} }
scanner := bufio.NewScanner(readCloser) scanner := bufio.NewScanner(readCloser)

View File

@@ -10,7 +10,7 @@ import (
"strconv" "strconv"
"strings" "strings"
"github.com/mcuadros/go-version" version "github.com/mcuadros/go-version"
) )
// GetRefCommitID returns the last commit ID string of given reference (branch or tag). // GetRefCommitID returns the last commit ID string of given reference (branch or tag).
@@ -32,7 +32,14 @@ func (repo *Repository) GetBranchCommitID(name string) (string, error) {
// GetTagCommitID returns last commit ID string of given tag. // GetTagCommitID returns last commit ID string of given tag.
func (repo *Repository) GetTagCommitID(name string) (string, error) { func (repo *Repository) GetTagCommitID(name string) (string, error) {
return repo.GetRefCommitID(TagPrefix + name) stdout, err := NewCommand("rev-list", "-n", "1", name).RunInDir(repo.Path)
if err != nil {
if strings.Contains(err.Error(), "unknown revision or path") {
return "", ErrNotExist{name, ""}
}
return "", err
}
return strings.TrimSpace(stdout), nil
} }
// parseCommitData parses commit information from the (uncompressed) raw // parseCommitData parses commit information from the (uncompressed) raw
@@ -94,7 +101,11 @@ l:
sig, err := newGPGSignatureFromCommitline(data, (nextline+1)+sigindex, true) sig, err := newGPGSignatureFromCommitline(data, (nextline+1)+sigindex, true)
if err == nil && sig != nil { if err == nil && sig != nil {
// remove signature from commit message // remove signature from commit message
cm = cm[:sigindex-1] if sigindex == 0 {
cm = ""
} else {
cm = cm[:sigindex-1]
}
commit.Signature = sig commit.Signature = sig
} }
} }
@@ -130,6 +141,14 @@ func (repo *Repository) getCommit(id SHA1) (*Commit, error) {
commit.repo = repo commit.repo = repo
commit.ID = id commit.ID = id
data, err = NewCommand("name-rev", id.String()).RunInDirBytes(repo.Path)
if err != nil {
return nil, err
}
// name-rev commitID ouput will be "COMMIT_ID master" or "COMMIT_ID master~12"
commit.Branch = strings.Split(strings.Split(string(data), " ")[1], "~")[0]
repo.commitCache.Set(id.String(), commit) repo.commitCache.Set(id.String(), commit)
return commit, nil return commit, nil
} }
@@ -138,10 +157,14 @@ func (repo *Repository) getCommit(id SHA1) (*Commit, error) {
func (repo *Repository) GetCommit(commitID string) (*Commit, error) { func (repo *Repository) GetCommit(commitID string) (*Commit, error) {
if len(commitID) != 40 { if len(commitID) != 40 {
var err error var err error
commitID, err = NewCommand("rev-parse", commitID).RunInDir(repo.Path) actualCommitID, err := NewCommand("rev-parse", commitID).RunInDir(repo.Path)
if err != nil { if err != nil {
if strings.Contains(err.Error(), "unknown revision or path") {
return nil, ErrNotExist{commitID, ""}
}
return nil, err return nil, err
} }
commitID = actualCommitID
} }
id, err := NewIDFromString(commitID) id, err := NewIDFromString(commitID)
if err != nil { if err != nil {

20
vendor/code.gitea.io/git/repo_tag.go generated vendored
View File

@@ -76,12 +76,12 @@ func (repo *Repository) getTag(id SHA1) (*Tag, error) {
// GetTag returns a Git tag by given name. // GetTag returns a Git tag by given name.
func (repo *Repository) GetTag(name string) (*Tag, error) { func (repo *Repository) GetTag(name string) (*Tag, error) {
stdout, err := NewCommand("show-ref", "--tags", name).RunInDir(repo.Path) idStr, err := repo.GetTagCommitID(name)
if err != nil { if err != nil {
return nil, err return nil, err
} }
id, err := NewIDFromString(strings.Split(stdout, " ")[0]) id, err := NewIDFromString(idStr)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -103,26 +103,18 @@ func (repo *Repository) GetTagInfos() ([]*Tag, error) {
} }
tagNames := strings.Split(stdout, "\n") tagNames := strings.Split(stdout, "\n")
var tags []*Tag var tags = make([]*Tag, 0, len(tagNames))
for _, tagName := range tagNames { for _, tagName := range tagNames {
tagName = strings.TrimSpace(tagName) tagName = strings.TrimSpace(tagName)
if len(tagName) == 0 { if len(tagName) == 0 {
continue continue
} }
commitID, err := NewCommand("rev-parse", tagName).RunInDir(repo.Path)
tag, err := repo.GetTag(tagName)
if err != nil { if err != nil {
return nil, err return nil, err
} }
commit, err := repo.GetCommit(commitID) tags = append(tags, tag)
if err != nil {
return nil, err
}
tags = append(tags, &Tag{
Name: tagName,
Message: commit.Message(),
Object: commit.ID,
Tagger: commit.Author,
})
} }
sortTagsByTime(tags) sortTagsByTime(tags)
return tags, nil return tags, nil

View File

@@ -29,13 +29,12 @@ func NewSubModuleFile(c *Commit, refURL, refID string) *SubModuleFile {
} }
} }
// RefURL guesses and returns reference URL. func getRefURL(refURL, urlPrefix, parentPath string) string {
func (sf *SubModuleFile) RefURL(urlPrefix string, parentPath string) string { if refURL == "" {
if sf.refURL == "" {
return "" return ""
} }
url := strings.TrimSuffix(sf.refURL, ".git") url := strings.TrimSuffix(refURL, ".git")
// git://xxx/user/repo // git://xxx/user/repo
if strings.HasPrefix(url, "git://") { if strings.HasPrefix(url, "git://") {
@@ -67,12 +66,21 @@ func (sf *SubModuleFile) RefURL(urlPrefix string, parentPath string) string {
if strings.Contains(urlPrefix, url[i+1:j]) { if strings.Contains(urlPrefix, url[i+1:j]) {
return urlPrefix + url[j+1:] return urlPrefix + url[j+1:]
} }
if strings.HasPrefix(url, "ssh://") || strings.HasPrefix(url, "git+ssh://") {
k := strings.Index(url[j+1:], "/")
return "http://" + url[i+1:j] + "/" + url[j+1:][k+1:]
}
return "http://" + url[i+1:j] + "/" + url[j+1:] return "http://" + url[i+1:j] + "/" + url[j+1:]
} }
return url return url
} }
// RefURL guesses and returns reference URL.
func (sf *SubModuleFile) RefURL(urlPrefix string, parentPath string) string {
return getRefURL(sf.refURL, urlPrefix, parentPath)
}
// RefID returns reference ID. // RefID returns reference ID.
func (sf *SubModuleFile) RefID() string { func (sf *SubModuleFile) RefID() string {
return sf.refID return sf.refID

22
vendor/code.gitea.io/git/tree.go generated vendored
View File

@@ -18,6 +18,9 @@ type Tree struct {
entries Entries entries Entries
entriesParsed bool entriesParsed bool
entriesRecursive Entries
entriesRecursiveParsed bool
} }
// NewTree create a new tree according the repository and commit id // NewTree create a new tree according the repository and commit id
@@ -67,20 +70,29 @@ func (t *Tree) ListEntries() (Entries, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
t.entries, err = parseTreeEntries(stdout, t) t.entries, err = parseTreeEntries(stdout, t)
if err == nil {
t.entriesParsed = true
}
return t.entries, err return t.entries, err
} }
// ListEntriesRecursive returns all entries of current tree recursively including all subtrees // ListEntriesRecursive returns all entries of current tree recursively including all subtrees
func (t *Tree) ListEntriesRecursive() (Entries, error) { func (t *Tree) ListEntriesRecursive() (Entries, error) {
if t.entriesParsed { if t.entriesRecursiveParsed {
return t.entries, nil return t.entriesRecursive, nil
} }
stdout, err := NewCommand("ls-tree", "-t", "-r", t.ID.String()).RunInDirBytes(t.repo.Path) stdout, err := NewCommand("ls-tree", "-t", "-r", t.ID.String()).RunInDirBytes(t.repo.Path)
if err != nil { if err != nil {
return nil, err return nil, err
} }
t.entries, err = parseTreeEntries(stdout, t)
return t.entries, err t.entriesRecursive, err = parseTreeEntries(stdout, t)
if err == nil {
t.entriesRecursiveParsed = true
}
return t.entriesRecursive, err
} }