Web editor: improve edit file and diff preview

This commit is contained in:
Unknwon committed 2016-08-14 23:52:24 -07:00
1 parent 660e7a178a
commit cd89f6c502
15 files changed
+477 -475

No files matched your search

+13 -15
View File
@@ -440,36 +440,34 @@ edit_this_file = Edit this file
edit_file = Edit file
delete_confirm_message = Are you sure you want to delete this file?
delete_commit_message = Write a note about this delete (optional)
file_editing_no_longer_exists = The file you are editing no longer exists in the repository
file_already_exists = A file by that name already exists
unable_to_update_file = Unable to update this file, error occurred
add = Add
update = Update
filename_cannot_be_empty = Filename cannot be empty
directory_is_a_file = One of the directories in the path is already a file in this repository
filename_is_a_directory = The filename given is an existing directory in the repository
must_be_on_branch = You must be on a branch to make or propose changes to this file
must_be_writer = You must have write access to make or propose changes to this file
cannot_edit_binary_files = Cannot edit binary files
filename_help = To add directory, just type it and press /. To remove a directory, go to the beginning of the field and press backspace.
fork_before_edit = You must fork this before editing
branch_already_exists = Branch already exists
create_new_branch = Create a %s for this commit and start a pull request.
new_branch = new branch
commit_directly_to_this_branch = Commit directly to the %s branch.
editor.commit_directly_to_this_branch = Commit directly to the <strong class="branch-name">%s</strong> branch.
editor.create_new_branch = Create a <strong>new branch</strong> for this commit and start a pull request.
editor.filename_cannot_be_empty = Filename cannot be empty.
editor.branch_already_exists = Branch '%s' already exists in this repository.
editor.directory_is_a_file = Entry '%s' in the parent path is a file not a directory in this repository.
editor.filename_is_a_directory = The filename '%s' is an existing directory in this repository.
editor.file_editing_no_longer_exists = The file '%s' you are editing no longer exists in the repository.
editor.file_changed_while_editing = File content has been changed since you started editing. <a target="_blank" href="%s">Click here</a> to see what have been changed or <strong>press commit again</strong> to overwrite those changes.
editor.file_already_exists = A file with name '%s' already exists in this repository.
editor.add = Add '%s'
editor.update = Update '%s'
editor.failed_to_upload_files = An error occurred while updating file: %v
editor.no_changes_to_show = There are no changes to show.
create_branch = Create branch
from = from
upload_file = Upload file
add_files_to_dir = Add files to %s
unable_to_upload_files = Unable to upload files, an error occurred.
add_subdir = Add subdirectory...
name_your_file = Name your file...
user_has_committed_since_you_started_editing = %s has committed since you started editing.
see_what_changed = See what changed.
pressing_commit_again_will_overwrite_those_changes = Pressing '%s' again will overwrite those changes.
copy_file_path_to_clipboard = Copy file path to clipboard
preview_changes = Preview Changes
no_changes_to_show = There are no changes to show.
commits.commits = Commits
commits.search = Search commits
+1 -1
View File
@@ -434,7 +434,7 @@ func GetDiffRange(repoPath, beforeCommitID, afterCommitID string, maxLines, maxL
return nil, fmt.Errorf("Start: %v", err)
}
pid := process.Add(fmt.Sprintf("GetDiffRange (%s)", repoPath), cmd)
pid := process.Add(fmt.Sprintf("GetDiffRange [repo_path: %s]", repoPath), cmd)
defer process.Remove(pid)
diff, err := ParsePatch(maxLines, maxLineCharacteres, maxFiles, stdout)
+5 -10
View File
@@ -334,6 +334,9 @@ var patchConflicts = []string{
// testPatch checks if patch can be merged to base repository without conflit.
// FIXME: make a mechanism to clean up stable local copies.
func (pr *PullRequest) testPatch() (err error) {
repoWorkingPool.CheckIn(com.ToStr(pr.BaseRepoID))
defer repoWorkingPool.CheckOut(com.ToStr(pr.BaseRepoID))
if pr.BaseRepo == nil {
pr.BaseRepo, err = GetRepositoryByID(pr.BaseRepoID)
if err != nil {
@@ -354,20 +357,12 @@ func (pr *PullRequest) testPatch() (err error) {
log.Trace("PullRequest[%d].testPatch (patchPath): %s", pr.ID, patchPath)
if err := pr.BaseRepo.UpdateLocalCopy(pr.BaseRepo.DefaultBranch); err != nil {
if err := pr.BaseRepo.UpdateLocalCopyBranch(pr.BaseBranch); err != nil {
return fmt.Errorf("UpdateLocalCopy: %v", err)
}
// Checkout base branch.
_, stderr, err := process.ExecDir(-1, pr.BaseRepo.LocalCopyPath(),
fmt.Sprintf("PullRequest.Merge (git checkout): %v", pr.BaseRepo.ID),
"git", "checkout", pr.BaseBranch)
if err != nil {
return fmt.Errorf("git checkout: %s", stderr)
}
pr.Status = PULL_REQUEST_STATUS_CHECKING
_, stderr, err = process.ExecDir(-1, pr.BaseRepo.LocalCopyPath(),
_, stderr, err := process.ExecDir(-1, pr.BaseRepo.LocalCopyPath(),
fmt.Sprintf("testPatch (git apply --check): %d", pr.BaseRepo.ID),
"git", "apply", "--check", patchPath)
if err != nil {
+22 -182
View File
@@ -437,10 +437,14 @@ func (repo *Repository) DescriptionHtml() template.HTML {
}
func (repo *Repository) LocalCopyPath() string {
return path.Join(setting.AppDataPath, "tmp/local", com.ToStr(repo.ID))
return path.Join(setting.AppDataPath, "tmp/local-rpeo", com.ToStr(repo.ID))
}
func updateLocalCopy(repoPath, localPath, branch string) error {
// UpdateLocalCopy pulls latest changes of given branch from repoPath to localPath.
// It creates a new clone if local copy does not exist.
// This function checks out target branch by default, it is safe to assume subsequent
// operations are operating against target branch when caller has confidence for no race condition.
func UpdateLocalCopyBranch(repoPath, localPath, branch string) error {
if !com.IsExist(localPath) {
if err := git.Clone(repoPath, localPath, git.CloneRepoOptions{
Timeout: time.Duration(setting.Git.Timeout.Clone) * time.Second,
@@ -450,13 +454,11 @@ func updateLocalCopy(repoPath, localPath, branch string) error {
}
} else {
if err := git.Checkout(localPath, git.CheckoutOptions{
Branch: branch,
Timeout: time.Duration(setting.Git.Timeout.Pull) * time.Second,
Branch: branch,
}); err != nil {
return fmt.Errorf("Checkout: %v", err)
}
if err := git.Pull(localPath, git.PullRemoteOptions{
All: false,
Remote: "origin",
Branch: branch,
Timeout: time.Duration(setting.Git.Timeout.Pull) * time.Second,
@@ -467,9 +469,9 @@ func updateLocalCopy(repoPath, localPath, branch string) error {
return nil
}
// UpdateLocalCopy makes sure the local copy of repository is up-to-date.
func (repo *Repository) UpdateLocalCopy(branch string) error {
return updateLocalCopy(repo.RepoPath(), repo.LocalCopyPath(), branch)
// UpdateLocalCopy makes sure the branch of local copy of repository is up-to-date.
func (repo *Repository) UpdateLocalCopyBranch(branch string) error {
return UpdateLocalCopyBranch(repo.RepoPath(), repo.LocalCopyPath(), branch)
}
// PatchPath returns corresponding patch file path of repository by given issue ID.
@@ -2238,168 +2240,6 @@ func (repo *Repository) GetForks() ([]*Repository, error) {
return forks, x.Find(&forks, &Repository{ForkID: repo.ID})
}
// ___________ .___.__ __ ___________.__.__
// \_ _____/ __| _/|__|/ |_ \_ _____/|__| | ____
// | __)_ / __ | | \ __\ | __) | | | _/ __ \
// | \/ /_/ | | || | | \ | | |_\ ___/
// /_______ /\____ | |__||__| \___ / |__|____/\___ >
// \/ \/ \/ \/
func (repo *Repository) LocalRepoPath() string {
return path.Join(setting.AppDataPath, "tmp/local-repo", com.ToStr(repo.ID))
}
// UpdateLocalRepo makes sure the local copy of repository is up-to-date.
func (repo *Repository) UpdateLocalRepo(branchName string) error {
return updateLocalCopy(repo.RepoPath(), repo.LocalRepoPath(), branchName)
}
// DiscardLocalRepoChanges makes sure the local copy of repository is the same as the source
func (repo *Repository) DiscardLocalRepoChanges(branchName string) error {
return discardLocalRepoChanges(repo.LocalRepoPath(), branchName)
}
// discardLocalRepoChanges discards local commits make sure
// it is even to remote branch when local copy exists.
func discardLocalRepoChanges(localPath string, branch string) error {
if !com.IsExist(localPath) {
return nil
}
// No need to check if nothing in the repository.
if !git.IsBranchExist(localPath, branch) {
return nil
}
if err := git.ResetHEAD(localPath, true, "origin/"+branch); err != nil {
return fmt.Errorf("ResetHEAD: %v", err)
}
return nil
}
// CheckoutNewBranch checks out a new branch from the given branch name
func (repo *Repository) CheckoutNewBranch(oldBranchName, newBranchName string) error {
return checkoutNewBranch(repo.RepoPath(), repo.LocalRepoPath(), oldBranchName, newBranchName)
}
func checkoutNewBranch(repoPath, localPath, oldBranch, newBranch string) error {
if !com.IsExist(localPath) {
if err := updateLocalCopy(repoPath, localPath, oldBranch); err != nil {
return err
}
}
if err := git.Checkout(localPath, git.CheckoutOptions{
Branch: newBranch,
OldBranch: oldBranch,
Timeout: time.Duration(setting.Git.Timeout.Pull) * time.Second,
}); err != nil {
return fmt.Errorf("Checkout New Branch: %v", err)
}
return nil
}
// updateRepoFile adds new file to repository.
func (repo *Repository) UpdateRepoFile(doer *User, oldBranchName, branchName, oldTreeName, treeName, content, message string, isNewFile bool) (err error) {
repoWorkingPool.CheckIn(com.ToStr(repo.ID))
defer repoWorkingPool.CheckOut(com.ToStr(repo.ID))
if err = repo.DiscardLocalRepoChanges(oldBranchName); err != nil {
return fmt.Errorf("discardLocalRepoChanges: %s - %v", oldBranchName, err)
} else if err = repo.UpdateLocalRepo(oldBranchName); err != nil {
return fmt.Errorf("UpdateLocalRepo: %s - %v", oldBranchName, err)
}
if oldBranchName != branchName {
if err := repo.CheckoutNewBranch(oldBranchName, branchName); err != nil {
return fmt.Errorf("CheckoutNewBranch: %s - %s: %v", oldBranchName, branchName, err)
}
}
localPath := repo.LocalRepoPath()
filePath := path.Join(localPath, treeName)
if len(message) == 0 {
if isNewFile {
message = "Add '" + treeName + "'"
} else {
message = "Update '" + treeName + "'"
}
}
os.MkdirAll(filepath.Dir(filePath), os.ModePerm)
// If new file, make sure it doesn't exist; if old file, move if file name change
if isNewFile {
if com.IsExist(filePath) {
return ErrRepoFileAlreadyExist{filePath}
}
} else if oldTreeName != "" && treeName != "" && treeName != oldTreeName {
if err = git.MoveFile(localPath, oldTreeName, treeName); err != nil {
return fmt.Errorf("MoveFile: %v", err)
}
}
if err = ioutil.WriteFile(filePath, []byte(content), 0666); err != nil {
return fmt.Errorf("WriteFile: %v", err)
}
if err = git.AddChanges(localPath, true); err != nil {
return fmt.Errorf("AddChanges: %v", err)
} else if err = git.CommitChanges(localPath, message, doer.NewGitSig()); err != nil {
return fmt.Errorf("CommitChanges: %v", err)
} else if err = git.Push(localPath, "origin", branchName); err != nil {
return fmt.Errorf("Push: %v", err)
}
return nil
}
func (repo *Repository) GetPreviewDiff(repoPath, branchName, treeName, text string, maxlines, maxchars, maxfiles int) (diff *Diff, err error) {
repoWorkingPool.CheckIn(com.ToStr(repo.ID))
defer repoWorkingPool.CheckOut(com.ToStr(repo.ID))
if err = repo.DiscardLocalRepoChanges(branchName); err != nil {
return nil, fmt.Errorf("discardLocalRepoChanges: %s - %v", branchName, err)
} else if err = repo.UpdateLocalRepo(branchName); err != nil {
return nil, fmt.Errorf("UpdateLocalRepo: %s - %v", branchName, err)
}
localPath := repo.LocalRepoPath()
filePath := path.Join(localPath, treeName)
os.MkdirAll(filepath.Dir(filePath), os.ModePerm)
if err = ioutil.WriteFile(filePath, []byte(text), 0666); err != nil {
return nil, fmt.Errorf("WriteFile: %v", err)
}
var cmd *exec.Cmd
cmd = exec.Command("git", "diff", treeName)
cmd.Dir = localPath
cmd.Stderr = os.Stderr
stdout, err := cmd.StdoutPipe()
if err != nil {
return nil, fmt.Errorf("StdoutPipe: %v", err)
}
if err = cmd.Start(); err != nil {
return nil, fmt.Errorf("Start: %v", err)
}
pid := process.Add(fmt.Sprintf("GetDiffRange (%s)", repoPath), cmd)
defer process.Remove(pid)
diff, err = ParsePatch(maxlines, maxchars, maxfiles, stdout)
if err != nil {
return nil, fmt.Errorf("ParsePatch: %v", err)
}
if err = cmd.Wait(); err != nil {
return nil, fmt.Errorf("Wait: %v", err)
}
return diff, nil
}
// ________ .__ __ ___________.__.__
// \______ \ ____ | | _____/ |_ ____ \_ _____/|__| | ____
// | | \_/ __ \| | _/ __ \ __\/ __ \ | __) | | | _/ __ \
@@ -2412,11 +2252,11 @@ func (repo *Repository) DeleteRepoFile(doer *User, branch, treeName, message str
repoWorkingPool.CheckIn(com.ToStr(repo.ID))
defer repoWorkingPool.CheckOut(com.ToStr(repo.ID))
localPath := repo.LocalRepoPath()
if err = discardLocalRepoChanges(localPath, branch); err != nil {
localPath := repo.LocalCopyPath()
if err = discardLocalRepoBranchChanges(localPath, branch); err != nil {
return fmt.Errorf("discardLocalRepoChanges: %v", err)
} else if err = repo.UpdateLocalRepo(branch); err != nil {
return fmt.Errorf("UpdateLocalRepo: %v", err)
} else if err = repo.UpdateLocalCopyBranch(branch); err != nil {
return fmt.Errorf("UpdateLocalCopyBranch: %v", err)
}
filePath := path.Join(localPath, treeName)
@@ -2450,12 +2290,12 @@ func (repo *Repository) UploadRepoFiles(doer *User, oldBranchName, branchName, t
repoWorkingPool.CheckIn(com.ToStr(repo.ID))
defer repoWorkingPool.CheckOut(com.ToStr(repo.ID))
localPath := repo.LocalRepoPath()
localPath := repo.LocalCopyPath()
if err = discardLocalRepoChanges(localPath, oldBranchName); err != nil {
if err = discardLocalRepoBranchChanges(localPath, oldBranchName); err != nil {
return fmt.Errorf("discardLocalRepoChanges: %v", err)
} else if err = repo.UpdateLocalRepo(oldBranchName); err != nil {
return fmt.Errorf("UpdateLocalRepo: %v", err)
} else if err = repo.UpdateLocalCopyBranch(oldBranchName); err != nil {
return fmt.Errorf("UpdateLocalCopyBranch: %v", err)
}
if oldBranchName != branchName {
@@ -2637,12 +2477,12 @@ func (repo *Repository) CreateNewBranch(doer *User, oldBranchName, branchName st
repoWorkingPool.CheckIn(com.ToStr(repo.ID))
defer repoWorkingPool.CheckOut(com.ToStr(repo.ID))
localPath := repo.LocalRepoPath()
localPath := repo.LocalCopyPath()
if err = discardLocalRepoChanges(localPath, oldBranchName); err != nil {
if err = discardLocalRepoBranchChanges(localPath, oldBranchName); err != nil {
return fmt.Errorf("discardLocalRepoChanges: %v", err)
} else if err = repo.UpdateLocalRepo(oldBranchName); err != nil {
return fmt.Errorf("UpdateLocalRepo: %v", err)
} else if err = repo.UpdateLocalCopyBranch(oldBranchName); err != nil {
return fmt.Errorf("UpdateLocalCopyBranch: %v", err)
}
if err = repo.CheckoutNewBranch(oldBranchName, branchName); err != nil {
+211
View File
@@ -0,0 +1,211 @@
// 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 models
import (
"fmt"
"io/ioutil"
"os"
"os/exec"
"path"
"path/filepath"
"time"
"github.com/Unknwon/com"
git "github.com/gogits/git-module"
"github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/process"
"github.com/gogits/gogs/modules/setting"
)
// ___________ .___.__ __ ___________.__.__
// \_ _____/ __| _/|__|/ |_ \_ _____/|__| | ____
// | __)_ / __ | | \ __\ | __) | | | _/ __ \
// | \/ /_/ | | || | | \ | | |_\ ___/
// /_______ /\____ | |__||__| \___ / |__|____/\___ >
// \/ \/ \/ \/
// discardLocalRepoBranchChanges discards local commits of given branch
// to make sure it is even to remote branch when local copy exists.
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) {
return nil
}
if err := git.ResetHEAD(localPath, true, "origin/"+branch); err != nil {
return fmt.Errorf("ResetHEAD: %v", err)
}
return nil
}
func (repo *Repository) DiscardLocalRepoBranchChanges(branch string) error {
return discardLocalRepoBranchChanges(repo.LocalCopyPath(), branch)
}
func checkoutNewBranch(repoPath, localPath, oldBranch, newBranch string) error {
if !com.IsExist(localPath) {
if err := UpdateLocalCopyBranch(repoPath, localPath, oldBranch); err != nil {
return err
}
}
if err := git.Checkout(localPath, git.CheckoutOptions{
Branch: newBranch,
OldBranch: oldBranch,
Timeout: time.Duration(setting.Git.Timeout.Pull) * time.Second,
}); err != nil {
return fmt.Errorf("Checkout: %v", err)
}
return nil
}
// CheckoutNewBranch checks out a new branch from the given branch name.
func (repo *Repository) CheckoutNewBranch(oldBranch, newBranch string) error {
return checkoutNewBranch(repo.RepoPath(), repo.LocalCopyPath(), oldBranch, newBranch)
}
type UpdateRepoFileOptions struct {
LastCommitID string
OldBranch string
NewBranch string
OldTreeName string
NewTreeName string
Message string
Content string
IsNewFile bool
}
// updateRepoFile adds new file to repository.
func (repo *Repository) UpdateRepoFile(doer *User, opts *UpdateRepoFileOptions) (err error) {
repoWorkingPool.CheckIn(com.ToStr(repo.ID))
defer repoWorkingPool.CheckOut(com.ToStr(repo.ID))
if err = repo.DiscardLocalRepoBranchChanges(opts.OldBranch); err != nil {
return fmt.Errorf("DiscardLocalRepoBranchChanges [branch: %s]: %v", opts.OldBranch, err)
} else if err = repo.UpdateLocalCopyBranch(opts.OldBranch); err != nil {
return fmt.Errorf("UpdateLocalCopyBranch [branch: %s]: %v", opts.OldBranch, err)
}
if opts.OldBranch != opts.NewBranch {
if err := repo.CheckoutNewBranch(opts.OldBranch, opts.NewBranch); err != nil {
return fmt.Errorf("CheckoutNewBranch [old_branch: %s, new_branch: %s]: %v", opts.OldBranch, opts.NewBranch, err)
}
}
localPath := repo.LocalCopyPath()
filePath := path.Join(localPath, opts.NewTreeName)
if len(opts.Message) == 0 {
if opts.IsNewFile {
opts.Message = "Add '" + opts.NewTreeName + "'"
} else {
opts.Message = "Update '" + opts.NewTreeName + "'"
}
}
os.MkdirAll(path.Dir(filePath), os.ModePerm)
// If new file, make sure it doesn't exist; if old file, move if file name change.
if opts.IsNewFile {
if com.IsExist(filePath) {
return ErrRepoFileAlreadyExist{filePath}
}
} else if len(opts.OldTreeName) > 0 && len(opts.NewTreeName) > 0 && opts.NewTreeName != opts.OldTreeName {
if err = git.MoveFile(localPath, opts.OldTreeName, opts.NewTreeName); err != nil {
return fmt.Errorf("MoveFile [old_tree_name: %s, new_tree_name: %s]: %v", opts.OldTreeName, opts.NewTreeName, err)
}
}
if err = ioutil.WriteFile(filePath, []byte(opts.Content), 0666); err != nil {
return fmt.Errorf("WriteFile: %v", err)
}
if err = git.AddChanges(localPath, true); err != nil {
return fmt.Errorf("AddChanges: %v", err)
} else if err = git.CommitChanges(localPath, opts.Message, doer.NewGitSig()); err != nil {
return fmt.Errorf("CommitChanges: %v", err)
} else if err = git.Push(localPath, "origin", opts.NewBranch); err != nil {
return fmt.Errorf("Push: %v", err)
}
gitRepo, err := git.OpenRepository(repo.RepoPath())
if err != nil {
log.Error(4, "OpenRepository: %v", err)
return nil
}
commit, err := gitRepo.GetBranchCommit(opts.NewBranch)
if err != nil {
log.Error(4, "GetBranchCommit [branch: %s]: %v", opts.NewBranch, err)
return nil
}
pushCommits := &PushCommits{
Len: 1,
Commits: []*PushCommit{CommitToPushCommit(commit)},
}
oldCommitID := opts.LastCommitID
if opts.NewBranch != opts.OldBranch {
oldCommitID = "0000000000000000000000000000000000000000" // New Branch so we use all 0s
}
if err := CommitRepoAction(doer.ID, repo.MustOwner().ID, doer.Name, doer.Email,
repo.ID, repo.MustOwner().Name, repo.Name, git.BRANCH_PREFIX+opts.NewBranch,
pushCommits, oldCommitID, commit.ID.String()); err != nil {
log.Error(4, "CommitRepoAction: %v", err)
return nil
}
go HookQueue.Add(repo.ID)
return nil
}
func (repo *Repository) GetDiffPreview(branch, treeName, content string) (diff *Diff, err error) {
repoWorkingPool.CheckIn(com.ToStr(repo.ID))
defer repoWorkingPool.CheckOut(com.ToStr(repo.ID))
if err = repo.DiscardLocalRepoBranchChanges(branch); err != nil {
return nil, fmt.Errorf("discardLocalRepoChanges: %s - %v", branch, err)
} else if err = repo.UpdateLocalCopyBranch(branch); err != nil {
return nil, fmt.Errorf("UpdateLocalCopyBranch: %s - %v", branch, err)
}
localPath := repo.LocalCopyPath()
filePath := path.Join(localPath, treeName)
os.MkdirAll(filepath.Dir(filePath), os.ModePerm)
if err = ioutil.WriteFile(filePath, []byte(content), 0666); err != nil {
return nil, fmt.Errorf("WriteFile: %v", err)
}
cmd := exec.Command("git", "diff", treeName)
cmd.Dir = localPath
cmd.Stderr = os.Stderr
stdout, err := cmd.StdoutPipe()
if err != nil {
return nil, fmt.Errorf("StdoutPipe: %v", err)
}
if err = cmd.Start(); err != nil {
return nil, fmt.Errorf("Start: %v", err)
}
pid := process.Add(fmt.Sprintf("GetDiffRange [repo_path: %s]", repo.RepoPath()), cmd)
defer process.Remove(pid)
diff, err = ParsePatch(setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, stdout)
if err != nil {
return nil, fmt.Errorf("ParsePatch: %v", err)
}
if err = cmd.Wait(); err != nil {
return nil, fmt.Errorf("Wait: %v", err)
}
return diff, nil
}
+2 -15
View File
@@ -76,24 +76,11 @@ func (repo *Repository) LocalWikiPath() string {
// UpdateLocalWiki makes sure the local copy of repository wiki is up-to-date.
func (repo *Repository) UpdateLocalWiki() error {
return updateLocalCopy(repo.WikiPath(), repo.LocalWikiPath(), "")
return UpdateLocalCopyBranch(repo.WikiPath(), repo.LocalWikiPath(), "master")
}
// discardLocalWikiChanges discards local commits make sure
// it is even to remote branch when local copy exists.
func discardLocalWikiChanges(localPath string) error {
if !com.IsExist(localPath) {
return nil
}
// No need to check if nothing in the repository.
if !git.IsBranchExist(localPath, "master") {
return nil
}
if err := git.ResetHEAD(localPath, true, "origin/master"); err != nil {
return fmt.Errorf("ResetHEAD: %v", err)
}
return nil
return discardLocalRepoBranchChanges(localPath, "master")
}
// updateWikiPage adds new page to repository wiki.
+3 -3
View File
@@ -301,7 +301,7 @@ func confAppIni() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "conf/app.ini", size: 13460, mode: os.FileMode(420), modTime: time.Unix(1471215929, 0)}
info := bindataFileInfo{name: "conf/app.ini", size: 13460, mode: os.FileMode(420), modTime: time.Unix(1471235101, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -4346,7 +4346,7 @@ func confLocaleLocale_deDeIni() (*asset, error) {
return a, nil
}
var _confLocaleLocale_enUsIni = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xac\xbd\xfb\x72\xdb\x48\x92\x2f\xfc\x3f\x9e\x02\xed\x09\x87\xed\x08\x99\x1d\x3d\xb3\xdf\x25\x3a\xfa\xf2\xa9\xe5\xf6\x65\xd7\xb2\xb5\x96\x7a\xe6\x9b\xd3\xe1\x60\x83\x24\x44\x62\x4d\x02\x1c\x00\xb4\xac\x99\x98\x37\x38\x0f\x70\x9e\xef\x3c\xc9\xc9\xfc\x65\x66\x55\x16\x00\x4a\x76\xcf\xfa\x0f\x0b\xac\xca\xba\x67\x65\xe5\xad\xb2\x8a\xfd\x7e\xbe\x2a\xbb\x65\xfe\x7d\x7e\x9a\xef\x8b\xaa\xde\x96\x5d\x97\x77\xe5\xf6\xfa\xe9\xa6\xe9\xfa\x72\x95\xbf\xa8\x7a\xfa\xdd\x7e\xac\x96\x65\x96\x6d\x9a\x5d\x49\xa0\x2f\xe9\x4f\xb6\x2a\xba\xcd\xa2\x29\xda\x15\x25\x3c\xb3\xef\xac\xfc\xb4\xdf\x36\x2d\x03\xfd\x2c\x5f\xd9\xa6\xdc\xee\xb9\x0c\xfd\xc9\xba\x6a\x5d\xcf\xab\x9a\x7e\x5e\xd2\x57\xfe\xaa\x96\x94\xe6\xd0\x5b\xd2\xdb\x43\x2f\x69\x87\xbd\x25\xfd\xb2\xcf\xda\x72\x5d\x51\x6f\x5a\x4a\x7a\xa7\x9f\xd9\x4d\xb9\xe8\xaa\x9e\x5b\xfa\x8b\x7c\x65\x1f\xcb\xb6\xab\x1a\xae\xfd\xcf\xf2\x95\xed\x8b\x35\x03\x5c\xd0\x9f\xac\x2f\x77\xfb\x6d\x81\x02\x57\xfa\x99\x6d\x8b\x7a\x7d\x10\x98\xd7\xfa\x99\x2d\xdb\x92\xb2\xe6\x75\x79\x43\xa9\x67\xf8\x31\x9b\xcd\xb2\x03\x4d\xc2\x7c\xdf\x36\xd7\xd5\xb6\x9c\x17\xf5\x6a\xbe\x93\x61\xfe\x42\xe9\xb9\xa6\xe7\x94\x9e\x73\x3a\x86\x50\xae\x68\xa8\xf3\xa2\xd3\x71\xd0\x5c\xd2\xc8\x8b\x2e\x43\x55\x75\xb1\xb3\xd2\xfc\x99\x95\xbb\xa2\xda\xf2\xac\xf1\x5f\xea\x77\xd7\xdd\x34\x98\xda\x0b\xfd\xa4\x39\x98\xf7\xb7\xfb\x12\x53\xf0\xf4\x8a\xbe\xb2\x65\xb1\xef\x97\x9b\x82\xbb\x29\x5f\x19\x01\xed\x1b\x9a\x8b\xa6\xbd\x05\x9c\xfd\xc8\x9a\x76\x5d\xd4\xd5\xdf\x8b\x5e\xe6\xe7\xad\xfb\x99\xed\xaa\xb6\x6d\x78\x6a\xcf\xf1\x91\xd1\xc8\xe7\x5c\x0f\xa5\xbc\xa1\x49\x70\xb5\x70\xce\xae\x5a\xb7\x32\x8b\x9c\x79\x8e\x5f\x5c\x8b\xe4\x69\x4d\x92\x15\x6a\xbb\x6e\xda\x0f\x9a\xfa\x9c\x3f\x07\x55\x52\xe7\x34\x37\xed\x57\x51\xd3\x7a\x68\xee\x39\x7e\x24\x00\x5d\x56\xac\x76\x34\xc3\xfb\xa2\x2e\x79\xea\x4e\xf9\x17\xcd\x17\xfd\xca\x8a\xe5\xb2\x39\xd4\xfd\xbc\x2b\xfb\xbe\xaa\xd7\xbc\x06\xa7\x92\x94\x5f\x6a\x52\xe6\xf2\x42\xda\x6d\x73\x08\xab\x4c\xe9\x7f\xa5\x9f\xf9\x85\xfc\x94\x3c\x57\x08\x99\xa1\x24\x35\xd9\x57\x1f\xab\xbe\x2a\xa5\x31\xfb\x91\xed\x0f\xdb\x2d\xcd\xe7\xdf\x0e\x65\xd7\x73\xd6\x05\xfd\xa6\x19\x90\xdf\x59\xd5\x75\x07\x94\x78\x85\x8f\x8c\x16\xb5\x5e\x62\x38\x67\xf8\xc8\xb2\x5f\xab\xba\xeb\x8b\xed\xf6\x7d\xa6\x1f\x0c\x2c\x5f\x32\x4f\x7d\xd5\xa3\xb3\x9a\x98\x5f\xf6\xe5\xbe\xe3\x89\xce\x9f\x57\x6d\xd7\x3f\xed\x2b\x42\xb5\x77\x87\x3a\x5b\x35\xcb\x0f\x84\xc4\xbc\x21\xb1\x95\x5e\x5d\xe7\x34\xa6\x47\x84\xc6\xed\xa1\xae\x69\x14\xf9\x8b\x86\x46\x46\xcd\x54\xab\x32\x7f\x06\xe8\x93\x7c\xbf\x2d\x8b\x8e\x40\xca\x62\x95\x7f\x57\xe4\x7d\xd1\xae\xcb\xfe\xfb\x07\xf3\x05\x6d\x9e\x0f\x0f\xf2\x4d\x5b\x5e\x7f\xff\xe0\x61\xf7\xe0\x87\x17\x07\x2a\xb6\xad\xea\xb2\xfb\xee\xeb\xe2\x87\x7c\x59\x50\x0e\x8d\xf5\x36\x5f\x94\xd7\xbc\x57\xa8\xad\x9c\x90\xb4\x5e\xf3\x3e\xb9\xed\x37\xdc\x20\x2d\x18\x7d\x74\x39\x6f\xd4\xaf\x32\x9e\x25\xda\xc8\xf3\xd5\xc2\x88\x12\x3a\x84\xe4\x96\x66\xe9\xfc\xf6\xf2\x3f\x5f\x9f\xe4\x17\x44\x99\xd6\x6d\x89\x6f\xfa\x8f\x4a\xfc\x29\xa7\xd1\x5e\x55\xcf\x7e\x9a\x65\x54\xd6\x26\xe4\x59\xd1\x17\x0b\xee\x7b\x58\x24\xce\x94\x3d\x14\xf2\xb0\x93\x98\xd6\x81\xae\x75\x3d\x76\xa7\xee\xcc\xc9\x7d\x48\x75\xe8\xe6\x0d\x75\xbc\xe1\x1d\x4c\xe9\x61\x66\x2f\x64\xce\xa8\xaa\xfc\xd5\x9b\x37\x6f\x9f\xfd\x94\x97\xf5\x9a\x66\x26\xbf\xa9\xfa\x4d\x7e\xe8\xaf\xff\xdf\xf9\xba\xac\xcb\xb6\xd8\xce\x97\x15\x4f\x4a\x4b\x78\x95\xd3\x2c\xc9\x10\x67\x59\xd7\x6d\x89\xc0\xac\xb8\x95\xcb\xcb\xd7\xf9\x39\x7d\x52\x67\xa8\x2c\x77\xa4\xdf\x64\xdd\xdf\xb6\x3c\x51\xa1\xc1\xab\x4d\x99\x03\x67\x01\xd4\x5c\x0f\xe7\x25\x5f\x69\x5f\x67\xf9\x77\x8b\xf6\x07\xd7\xbf\x62\xd1\x35\xdb\x43\xaf\x25\x6f\x36\x65\x8d\x85\x22\x54\x6a\x7b\xa2\x56\x46\xfb\x67\x59\xd9\xb6\x73\xa2\x9b\xfd\x2d\x2f\x8f\xf6\xe5\x58\x2b\x52\x19\xa1\x72\xdd\xf4\xb4\xfc\x39\xca\x49\x15\x55\xfd\xb1\xd8\x56\x2b\x5a\xa4\x38\x91\x69\x59\x24\xae\x1a\x5a\x6f\x2e\x4d\x18\xdd\xdc\x60\x8a\x68\x83\x11\x59\xcf\x1f\xcc\x1e\x80\xce\x3e\x78\xfa\x60\x96\xd5\xcd\x5c\x88\x00\x53\xe4\x55\xd5\x15\x0b\xa2\xce\x72\x5a\xb4\x46\xec\xfe\xca\x78\x27\x5d\x51\x88\x3c\x81\xe0\x35\xe1\x13\x08\x84\x9f\x91\xb2\x20\x32\x0d\x5a\xa2\x54\xc4\x8f\xdd\x48\x4e\xc0\x0b\xa1\x3a\x21\x61\x34\xe6\xcc\x16\xda\xb0\xf2\x74\xbf\xdf\x56\x4b\x69\xfa\x85\xe4\x45\x04\xe5\xf3\x58\x27\xc5\xc3\x01\xc1\x2c\xcf\xa1\x19\xf5\x9a\xa9\x52\x9e\x90\x77\x94\xdf\x94\xb4\xe3\x36\x87\xb5\x9c\x49\xdb\xe6\xb0\xfa\x0a\x87\x83\xad\x5c\x24\xc1\xf9\xbb\x86\x3a\x0c\xac\x0a\x00\xb1\x89\x53\x22\x28\xcc\x02\xb4\xe5\xae\xe9\x79\xe2\xb4\x18\x93\xb9\x9b\x8a\x32\x69\xa4\x5d\xf1\x91\x0e\xb7\xbe\x91\xad\xbc\xa2\xad\xba\xe4\x8a\x67\x19\x91\x95\xb9\x6e\x27\xa2\x3f\xb2\xa5\x2c\x2d\xc5\x5d\x40\xed\x0e\xb4\x0b\x37\x54\x19\x4f\x3c\xf3\x21\x54\xe5\x54\x3f\x31\x24\xaa\x07\xd4\x81\x76\x7c\x43\x67\x26\x2f\xf4\x33\x7c\xe8\x6f\x5f\x3f\xf5\xaa\xb8\xbe\xa6\x5e\x75\xb4\x9b\x5e\xe6\xcb\x6d\x43\x5b\xf1\x97\x77\xaf\x3b\xde\x68\x9b\xf9\xbe\x69\xc1\x7f\x50\xd6\x05\x7d\x86\x34\x37\xd1\x0c\x51\x1f\x76\x0b\xfa\x75\xb3\xa9\x96\x1b\x99\x76\x2e\xc1\xfb\x83\x52\xa9\x8Line truncated
var _confLocaleLocale_enUsIni = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xac\xbd\xfb\x72\xdb\x48\x92\x2f\xfc\x3f\x9e\x02\xed\x09\x87\xed\x08\x99\x1d\x3d\xb3\xdf\x25\x3a\xfa\xf2\xa9\xe5\xf6\x65\xd7\xb2\xb5\x96\x7a\xe6\x9b\xd3\xe1\x60\x83\x24\x44\x62\x4d\x02\x1c\x00\xb4\xac\x99\x98\x37\x38\x0f\x70\x9e\xef\x3c\xc9\xc9\xfc\x65\x66\x55\x16\x00\x4a\x76\xcf\xfa\x0f\x8b\xa8\xca\xba\x67\x65\xe5\xad\xb2\x8a\xfd\x7e\xbe\x2a\xbb\x65\xfe\x7d\x7e\x9a\xef\x8b\xaa\xde\x96\x5d\x97\x77\xe5\xf6\xfa\xe9\xa6\xe9\xfa\x72\x95\xbf\xa8\x7a\xfa\x6e\x3f\x56\xcb\x32\xcb\x36\xcd\xae\x24\xd0\x97\xf4\x27\x5b\x15\xdd\x66\xd1\x14\xed\x8a\x12\x9e\xd9\xef\xac\xfc\xb4\xdf\x36\x2d\x03\xfd\x2c\xbf\xb2\x4d\xb9\xdd\x73\x19\xfa\x93\x75\xd5\xba\x9e\x57\x35\x7d\x5e\xd2\xaf\xfc\x55\x2d\x29\xcd\xa1\xb7\xa4\xb7\x87\x5e\xd2\x0e\x7b\x4b\xfa\x65\x9f\xb5\xe5\xba\xa2\xde\xb4\x94\xf4\x4e\x7f\x66\x37\xe5\xa2\xab\x7a\x6e\xe9\x2f\xf2\x2b\xfb\x58\xb6\x5d\xd5\x70\xed\x7f\x96\x5f\xd9\xbe\x58\x33\xc0\x05\xfd\xc9\xfa\x72\xb7\xdf\x16\x28\x70\xa5\x3f\xb3\x6d\x51\xaf\x0f\x02\xf3\x5a\x7f\x66\xcb\xb6\xa4\xac\x79\x5d\xde\x50\xea\x19\x3e\x66\xb3\x59\x76\xa0\x49\x98\xef\xdb\xe6\xba\xda\x96\xf3\xa2\x5e\xcd\x77\x32\xcc\x5f\x28\x3d\xd7\xf4\x9c\xd2\x73\x4e\xc7\x10\xca\x15\x0d\x75\x5e\x74\x3a\x0e\x9a\x4b\x1a\x79\xd1\x65\xa8\xaa\x2e\x76\x56\x9a\x7f\x66\xe5\xae\xa8\xb6\x3c\x6b\xfc\x97\xfa\xdd\x75\x37\x0d\xa6\xf6\x42\x7f\xd2\x1c\xcc\xfb\xdb\x7d\x89\x29\x78\x7a\x45\xbf\xb2\x65\xb1\xef\x97\x9b\x82\xbb\x29\xbf\x32\x02\xda\x37\x34\x17\x4d\x7b\x0b\x38\xfb\xc8\x9a\x76\x5d\xd4\xd5\xdf\x8b\x5e\xe6\xe7\xad\xfb\xcc\x76\x55\xdb\x36\x3c\xb5\xe7\xf8\x91\xd1\xc8\xe7\x5c\x0f\xa5\xbc\xa1\x49\x70\xb5\x70\xce\xae\x5a\xb7\x32\x8b\x9c\x79\x8e\x2f\xae\x45\xf2\xb4\x26\xc9\x0a\xb5\x5d\x37\xed\x07\x4d\x7d\xce\x3f\x07\x55\x52\xe7\x34\x37\xed\x57\x51\xd3\x7a\x68\xee\x39\x3e\x12\x80\x2e\x2b\x56\x3b\x9a\xe1\x7d\x51\x97\x3c\x75\xa7\xfc\x45\xf3\x45\x5f\x59\xb1\x5c\x36\x87\xba\x9f\x77\x65\xdf\x57\xf5\x9a\xd7\xe0\x54\x92\xf2\x4b\x4d\xca\x5c\x5e\x48\xbb\x6d\x0e\x61\x95\x29\xfd\xaf\xf4\x99\x5f\xc8\xa7\xe4\xb9\x42\xc8\x0c\x25\xa9\xc9\xbe\xfa\x58\xf5\x55\x29\x8d\xd9\x47\xb6\x3f\x6c\xb7\x34\x9f\x7f\x3b\x94\x5d\xcf\x59\x17\xf4\x4d\x33\x20\xdf\x59\xd5\x75\x07\x94\x78\x85\x1f\x19\x2d\x6a\xbd\xc4\x70\xce\xf0\x23\xcb\x7e\xad\xea\xae\x2f\xb6\xdb\xf7\x99\xfe\x60\x60\xf9\x25\xf3\xd4\x57\x3d\x3a\xab\x89\xf9\x65\x5f\xee\x3b\x9e\xe8\xfc\x79\xd5\x76\xfd\xd3\xbe\x22\x54\x7b\x77\xa8\xb3\x55\xb3\xfc\x40\x48\xcc\x1b\x12\x5b\xe9\xd5\x75\x4e\x63\x7a\x44\x68\xdc\x1e\xea\x9a\x46\x91\xbf\x68\x68\x64\xd4\x4c\xb5\x2a\xf3\x67\x80\x3e\xc9\xf7\xdb\xb2\xe8\x08\xa4\x2c\x56\xf9\x77\x45\xde\x17\xed\xba\xec\xbf\x7f\x30\x5f\xd0\xe6\xf9\xf0\x20\xdf\xb4\xe5\xf5\xf7\x0f\x1e\x76\x0f\x7e\x78\x71\xa0\x62\xdb\xaa\x2e\xbb\xef\xbe\x2e\x7e\xc8\x97\x05\xe5\xd0\x58\x6f\xf3\x45\x79\xcd\x7b\x85\xda\xca\x09\x49\xeb\x35\xef\x93\xdb\x7e\xc3\x0d\xd2\x82\xd1\x8f\x2e\xe7\x8d\xfa\x55\xc6\xb3\x44\x1b\x79\xbe\x5a\x18\x51\x42\x87\x90\xdc\xd2\x2c\x9d\xdf\x5e\xfe\xe7\xeb\x93\xfc\x82\x28\xd3\xba\x2d\xf1\x9b\xfe\xa3\x12\x7f\xca\x69\xb4\x57\xd5\xb3\x9f\x66\x19\x95\xb5\x09\x79\x56\xf4\xc5\x82\xfb\x1e\x16\x89\x33\x65\x0f\x85\x3c\xec\x24\xa6\x75\xa0\x6b\x5d\x8f\xdd\xa9\x3b\x73\x72\x1f\x52\x1d\xba\x79\x43\x1d\x6f\x78\x07\x53\x7a\x98\xd9\x0b\x99\x33\xaa\x2a\x7f\xf5\xe6\xcd\xdb\x67\x3f\xe5\x65\xbd\xa6\x99\xc9\x6f\xaa\x7e\x93\x1f\xfa\xeb\xff\x77\xbe\x2e\xeb\xb2\x2d\xb6\xf3\x65\xc5\x93\xd2\x12\x5e\xe5\x34\x4b\x32\xc4\x59\xd6\x75\x5b\x22\x30\x2b\x6e\xe5\xf2\xf2\x75\x7e\x4e\x3f\xa9\x33\x54\x96\x3b\xd2\x6f\xb2\xee\x6f\x5b\x9e\xa8\xd0\xe0\xd5\xa6\xcc\x81\xb3\x00\x6a\xae\x87\xf3\x92\xaf\xb4\xaf\xb3\xfc\xbb\x45\xfb\x83\xeb\x5f\xb1\xe8\x9a\xed\xa1\xd7\x92\x37\x9b\xb2\xc6\x42\x11\x2a\xb5\x3d\x51\x2b\xa3\xfd\xb3\xac\x6c\xdb\x39\xd1\xcd\xfe\x96\x97\x47\xfb\x72\xac\x15\xa9\x8c\x50\xb9\x6e\x7a\x5a\xfe\x1c\xe5\xa4\x8a\xaa\xfe\x58\x6c\xab\x15\x2d\x52\x9c\xc8\xb4\x2c\x12\x57\x0d\xad\x37\x97\x26\x8c\x6e\x6e\x30\x45\xb4\xc1\x88\xac\xe7\x0f\x66\x0f\x40\x67\x1f\x3c\x7d\x30\xcb\xea\x66\x2e\x44\x80\x29\xf2\xaa\xea\x8a\x05\x51\x67\x39\x2d\x5a\x23\x76\x7f\x65\xbc\x93\xae\x28\x44\x9e\x40\xf0\x9a\xf0\x09\x04\xc2\xcf\x48\x59\x10\x99\x06\x2d\x51\x2a\xe2\xc7\x6e\x24\x27\xe0\x85\x50\x9d\x90\x30\x1a\x73\x66\x0b\x6d\x58\x79\xba\xdf\x6f\xab\xa5\x34\xfd\x42\xf2\x22\x82\xf2\x79\xac\x93\xe2\xe1\x80\x60\x96\xe7\xd0\x8c\x7a\xcd\x54\x29\x4f\xc8\x3b\xca\x6f\x4a\xda\x71\x9b\xc3\x5a\xce\xa4\x6d\x73\x58\x7d\x85\xc3\xc1\x56\x2e\x92\xe0\xfc\x5d\x43\x1d\x06\x56\x05\x80\xd8\xc4\x29\x11\x14\x66\x01\xda\x72\xd7\xf4\x3c\x71\x5a\x8c\xc9\xdc\x4d\x45\x99\x34\xd2\xae\xf8\x48\x87\x5b\xdf\xc8\x56\x5e\xd1\x56\x5d\x72\xc5\xb3\x8c\xc8\xca\x5c\xb7\x13\xd1\x1f\xd9\x52\x96\x96\xe2\x2e\xa0\x76\x07\xda\x85\x1b\xaa\x8c\x27\x9e\xf9\x10\xaa\x72\xaa\x9f\x18\x12\xd5\x03\xea\x40\x3b\xbe\xa1\x33\x93\x17\xfa\x19\x7e\xe8\xb7\xaf\x9f\x7a\x55\x5c\x5f\x53\xaf\x3a\xda\x4d\x2f\xf3\xe5\xb6\xa1\xad\xf8\xcb\xbb\xd7\x1d\x6f\xb4\xcd\x7c\xdf\xb4\xe0\x3f\x28\xeb\x82\x7e\x86\x34\x37\xd1\x0c\x51\x1f\x76\x0b\xfa\xba\xd9\x54\xcb\x8d\x4c\x3b\x97\xe0\xfd\x41\xa9\xdLine truncated
func confLocaleLocale_enUsIniBytes() ([]byte, error) {
return bindataRead(
@@ -4361,7 +4361,7 @@ func confLocaleLocale_enUsIni() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "conf/locale/locale_en-US.ini", size: 55126, mode: os.FileMode(420), modTime: time.Unix(1471215870, 0)}
info := bindataFileInfo{name: "conf/locale/locale_en-US.ini", size: 55343, mode: os.FileMode(420), modTime: time.Unix(1471240680, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
+3 -3
View File
@@ -40,14 +40,14 @@ func NewBranchPost(ctx *context.Context, form auth.NewBranchForm) {
branchName := form.BranchName
if ctx.HasError() || !ctx.Repo.IsWriter() || branchName == oldBranchName {
ctx.Redirect(EscapeUrl(ctx.Repo.RepoLink + "/src/" + oldBranchName))
ctx.Redirect(ctx.Repo.RepoLink + "/src/" + oldBranchName)
return
}
branchName = url.QueryEscape(strings.Replace(strings.Trim(branchName, " "), " ", "-", -1))
if _, err := ctx.Repo.Repository.GetBranch(branchName); err == nil {
ctx.Redirect(EscapeUrl(ctx.Repo.RepoLink + "/src/" + branchName))
ctx.Redirect(ctx.Repo.RepoLink + "/src/" + branchName)
return
}
@@ -77,5 +77,5 @@ func NewBranchPost(ctx *context.Context, form auth.NewBranchForm) {
models.HookQueue.Add(ctx.Repo.Repository.ID)
}
ctx.Redirect(EscapeUrl(ctx.Repo.RepoLink + "/src/" + branchName))
ctx.Redirect(ctx.Repo.RepoLink + "/src/" + branchName)
}
+120 -145
View File
@@ -20,28 +20,24 @@ import (
)
const (
EDIT base.TplName = "repo/edit"
DIFF_PREVIEW base.TplName = "repo/diff_preview"
DIFF_PREVIEW_NEW base.TplName = "repo/diff_preview_new"
EDIT base.TplName = "repo/editor/edit"
DIFF_PREVIEW base.TplName = "repo/editor/diff_preview"
DIFF_PREVIEW_NEW base.TplName = "repo/editor/diff_preview_new"
)
func EditFile(ctx *context.Context) {
editFile(ctx, false)
}
func NewFile(ctx *context.Context) {
editFile(ctx, true)
}
func editFile(ctx *context.Context, isNewFile bool) {
// Don't allow edit a file in a specific commit.
if ctx.Repo.IsViewCommit {
ctx.Handle(404, "", nil)
return
}
ctx.Data["PageIsEdit"] = true
ctx.Data["IsNewFile"] = isNewFile
ctx.Data["RequireHighlightJS"] = true
ctx.Data["RequireSimpleMDE"] = true
userName := ctx.Repo.Owner.Name
repoName := ctx.Repo.Repository.Name
branchName := ctx.Repo.BranchName
branchLink := ctx.Repo.RepoLink + "/src/" + branchName
branchLink := ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchName
treeName := ctx.Repo.TreeName
var treeNames []string
@@ -51,19 +47,22 @@ func editFile(ctx *context.Context, isNewFile bool) {
if !isNewFile {
entry, err := ctx.Repo.Commit.GetTreeEntryByPath(treeName)
if err != nil && git.IsErrNotExist(err) {
ctx.Handle(404, "GetTreeEntryByPath", err)
if err != nil {
if git.IsErrNotExist(err) {
ctx.Handle(404, "GetTreeEntryByPath", err)
} else {
ctx.Handle(500, "GetTreeEntryByPath", err)
}
return
}
if (ctx.Repo.IsViewCommit) || entry == nil || entry.IsDir() {
ctx.Handle(404, "repo.Home", nil)
// No way to edit a directory online.
if entry.IsDir() {
ctx.Handle(404, "", nil)
return
}
blob := entry.Blob()
dataRc, err := blob.Data()
if err != nil {
ctx.Handle(404, "blob.Data", err)
@@ -79,16 +78,15 @@ func editFile(ctx *context.Context, isNewFile bool) {
buf = buf[:n]
}
// Only text file are editable online.
_, isTextFile := base.IsTextFile(buf)
if !isTextFile {
ctx.Handle(404, "repo.Home", nil)
ctx.Handle(404, "", nil)
return
}
d, _ := ioutil.ReadAll(dataRc)
buf = append(buf, d...)
if err, content := template.ToUTF8WithErr(buf); err != nil {
if err != nil {
log.Error(4, "Convert content encoding: %s", err)
@@ -98,47 +96,38 @@ func editFile(ctx *context.Context, isNewFile bool) {
ctx.Data["FileContent"] = content
}
} else {
treeNames = append(treeNames, "")
treeNames = append(treeNames, "") // Append empty string to allow user name the new file.
}
ctx.Data["RequireSimpleMDE"] = true
ctx.Data["UserName"] = userName
ctx.Data["RepoName"] = repoName
ctx.Data["BranchName"] = branchName
ctx.Data["TreeName"] = treeName
ctx.Data["TreeNames"] = treeNames
ctx.Data["BranchLink"] = branchLink
ctx.Data["CommitSummary"] = ""
ctx.Data["CommitMessage"] = ""
ctx.Data["CommitChoice"] = "direct"
ctx.Data["NewBranchName"] = ""
ctx.Data["CommitDirectlyToThisBranch"] = ctx.Tr("repo.commit_directly_to_this_branch", "<strong class=\"branch-name\">"+branchName+"</strong>")
ctx.Data["CreateNewBranch"] = ctx.Tr("repo.create_new_branch", "<strong>"+ctx.Tr("repo.new_branch")+"</strong>")
ctx.Data["LastCommit"] = ctx.Repo.Commit.ID
ctx.Data["commit_summary"] = ""
ctx.Data["commit_message"] = ""
ctx.Data["commit_choice"] = "direct"
ctx.Data["new_branch_name"] = ""
ctx.Data["last_commit"] = ctx.Repo.Commit.ID
ctx.Data["MarkdownFileExts"] = strings.Join(setting.Markdown.FileExtensions, ",")
ctx.Data["LineWrapExtensions"] = strings.Join(setting.Repository.Editor.LineWrapExtensions, ",")
ctx.Data["PreviewableFileModes"] = strings.Join(setting.Repository.Editor.PreviewableFileModes, ",")
ctx.Data["PreviewDiffURL"] = ctx.Repo.RepoLink + "/preview/" + branchName + "/" + treeName
ctx.HTML(200, EDIT)
}
func EditFilePost(ctx *context.Context, form auth.EditRepoFileForm) {
editFilePost(ctx, form, false)
func EditFile(ctx *context.Context) {
editFile(ctx, false)
}
func NewFilePost(ctx *context.Context, form auth.EditRepoFileForm) {
editFilePost(ctx, form, true)
func NewFile(ctx *context.Context) {
editFile(ctx, true)
}
func editFilePost(ctx *context.Context, form auth.EditRepoFileForm, isNewFile bool) {
ctx.Data["PageIsEdit"] = true
ctx.Data["IsNewFile"] = isNewFile
ctx.Data["RequireHighlightJS"] = true
ctx.Data["RequireSimpleMDE"] = true
userName := ctx.Repo.Owner.Name
repoName := ctx.Repo.Repository.Name
oldBranchName := ctx.Repo.BranchName
branchName := oldBranchName
branchLink := ctx.Repo.RepoLink + "/src/" + branchName
@@ -160,26 +149,18 @@ func editFilePost(ctx *context.Context, form auth.EditRepoFileForm, isNewFile bo
treeNames = strings.Split(treeName, "/")
}
ctx.Data["RequireSimpleMDE"] = true
ctx.Data["UserName"] = userName
ctx.Data["RepoName"] = repoName
ctx.Data["BranchName"] = branchName
ctx.Data["TreeName"] = treeName
ctx.Data["TreeNames"] = treeNames
ctx.Data["BranchLink"] = branchLink
ctx.Data["FileContent"] = content
ctx.Data["CommitSummary"] = form.CommitSummary
ctx.Data["CommitMessage"] = form.CommitMessage
ctx.Data["CommitChoice"] = commitChoice
ctx.Data["NewBranchName"] = branchName
ctx.Data["CommitDirectlyToThisBranch"] = ctx.Tr("repo.commit_directly_to_this_branch", "<strong class=\"branch-name\">"+oldBranchName+"</strong>")
ctx.Data["CreateNewBranch"] = ctx.Tr("repo.create_new_branch", "<strong>"+ctx.Tr("repo.new_branch")+"</strong>")
ctx.Data["LastCommit"] = ctx.Repo.Commit.ID
ctx.Data["commit_summary"] = form.CommitSummary
ctx.Data["commit_message"] = form.CommitMessage
ctx.Data["commit_choice"] = commitChoice
ctx.Data["new_branch_name"] = branchName
ctx.Data["last_commit"] = ctx.Repo.Commit.ID
ctx.Data["MarkdownFileExts"] = strings.Join(setting.Markdown.FileExtensions, ",")
ctx.Data["LineWrapExtensions"] = strings.Join(setting.Repository.Editor.LineWrapExtensions, ",")
ctx.Data["PreviewableFileModes"] = strings.Join(setting.Repository.Editor.PreviewableFileModes, ",")
ctx.Data["PreviewDiffURL"] = ctx.Repo.RepoLink + "/preview/" + branchName + "/" + treeName
if ctx.HasError() {
ctx.HTML(200, EDIT)
@@ -188,41 +169,41 @@ func editFilePost(ctx *context.Context, form auth.EditRepoFileForm, isNewFile bo
if len(treeName) == 0 {
ctx.Data["Err_Filename"] = true
ctx.RenderWithErr(ctx.Tr("repo.filename_cannot_be_empty"), EDIT, &form)
log.Error(4, "%s: %s", "EditFile", "Filename can't be empty")
ctx.RenderWithErr(ctx.Tr("repo.editor.filename_cannot_be_empty"), EDIT, &form)
return
}
if oldBranchName != branchName {
if _, err := ctx.Repo.Repository.GetBranch(branchName); err == nil {
ctx.Data["Err_Branchname"] = true
ctx.RenderWithErr(ctx.Tr("repo.branch_already_exists"), EDIT, &form)
log.Error(4, "%s: %s - %s", "BranchName", branchName, "Branch already exists")
ctx.RenderWithErr(ctx.Tr("repo.editor.branch_already_exists", branchName), EDIT, &form)
return
}
}
treepath := ""
var treepath string
for index, part := range treeNames {
treepath = path.Join(treepath, part)
entry, err := ctx.Repo.Commit.GetTreeEntryByPath(treepath)
if err != nil {
// Means there is no item with that name, so we're good
break
if git.IsErrNotExist(err) {
// Means there is no item with that name, so we're good
break
}
ctx.Handle(500, "GetTreeEntryByPath", err)
return
}
if index != len(treeNames)-1 {
if !entry.IsDir() {
ctx.Data["Err_Filename"] = true
ctx.RenderWithErr(ctx.Tr("repo.directory_is_a_file"), EDIT, &form)
log.Error(4, "%s: %s - %s", "EditFile", treeName, "Directory given is a file")
ctx.RenderWithErr(ctx.Tr("repo.editor.directory_is_a_file", part), EDIT, &form)
return
}
} else {
if entry.IsDir() {
ctx.Data["Err_Filename"] = true
ctx.RenderWithErr(ctx.Tr("repo.filename_is_a_directory"), EDIT, &form)
log.Error(4, "%s: %s - %s", "EditFile", treeName, "Filename given is a dirctory")
ctx.RenderWithErr(ctx.Tr("repo.editor.filename_is_a_directory", part), EDIT, &form)
return
}
}
@@ -230,125 +211,119 @@ func editFilePost(ctx *context.Context, form auth.EditRepoFileForm, isNewFile bo
if !isNewFile {
_, err := ctx.Repo.Commit.GetTreeEntryByPath(oldTreeName)
if err != nil && git.IsErrNotExist(err) {
ctx.Data["Err_Filename"] = true
ctx.RenderWithErr(ctx.Tr("repo.file_editing_no_longer_exists"), EDIT, &form)
log.Error(4, "%s: %s / %s - %s", "EditFile", branchName, oldTreeName, "File doesn't exist for editing")
if err != nil {
if git.IsErrNotExist(err) {
ctx.Data["Err_Filename"] = true
ctx.RenderWithErr(ctx.Tr("repo.editor.file_editing_no_longer_exists", oldTreeName), EDIT, &form)
} else {
ctx.Handle(500, "GetTreeEntryByPath", err)
}
return
}
if lastCommit != ctx.Repo.CommitID {
if files, err := ctx.Repo.Commit.GetFilesChangedSinceCommit(lastCommit); err == nil {
for _, file := range files {
if file == treeName {
name := ctx.Repo.Commit.Author.Name
if u, err := models.GetUserByEmail(ctx.Repo.Commit.Author.Email); err == nil {
name = `<a href="` + setting.AppSubUrl + "/" + u.Name + `" target="_blank">` + u.Name + `</a>`
}
message := ctx.Tr("repo.user_has_committed_since_you_started_editing", name) +
` <a href="` + ctx.Repo.RepoLink + "/commit/" + ctx.Repo.CommitID + `" target="_blank">` + ctx.Tr("repo.see_what_changed") + `</a>` +
" " + ctx.Tr("repo.pressing_commit_again_will_overwrite_those_changes", "<em>"+ctx.Tr("repo.commit_changes")+"</em>")
log.Error(4, "%s: %s / %s - %s", "EditFile", branchName, oldTreeName, "File updated by another user")
ctx.RenderWithErr(message, EDIT, &form)
return
}
files, err := ctx.Repo.Commit.GetFilesChangedSinceCommit(lastCommit)
if err != nil {
ctx.Handle(500, "GetFilesChangedSinceCommit", err)
return
}
for _, file := range files {
if file == treeName {
ctx.RenderWithErr(ctx.Tr("repo.editor.file_changed_while_editing", ctx.Repo.RepoLink+"/compare/"+lastCommit+"..."+ctx.Repo.CommitID), EDIT, &form)
return
}
}
}
}
if oldTreeName != treeName {
// We have a new filename (rename or completely new file) so we need to make sure it doesn't already exist, can't clobber
_, err := ctx.Repo.Commit.GetTreeEntryByPath(treeName)
if err == nil {
// We have a new filename (rename or completely new file) so we need to make sure it doesn't already exist, can't clobber.
entry, err := ctx.Repo.Commit.GetTreeEntryByPath(treeName)
if err != nil {
if !git.IsErrNotExist(err) {
ctx.Handle(500, "GetTreeEntryByPath", err)
return
}
}
if entry != nil {
ctx.Data["Err_Filename"] = true
ctx.RenderWithErr(ctx.Tr("repo.file_already_exists"), EDIT, &form)
log.Error(4, "%s: %s - %s", "NewFile", treeName, "File already exists, can't create new")
ctx.RenderWithErr(ctx.Tr("repo.editor.file_already_exists", treeName), EDIT, &form)
return
}
}
message := ""
if form.CommitSummary != "" {
message = strings.Trim(form.CommitSummary, " ")
var message string
if len(form.CommitSummary) > 0 {
message = strings.TrimSpace(form.CommitSummary)
} else {
if isNewFile {
message = ctx.Tr("repo.add") + " '" + treeName + "'"
message = ctx.Tr("repo.editor.add", treeName)
} else {
message = ctx.Tr("repo.update") + " '" + treeName + "'"
message = ctx.Tr("repo.editor.update", treeName)
}
}
if strings.Trim(form.CommitMessage, " ") != "" {
message += "\n\n" + strings.Trim(form.CommitMessage, " ")
form.CommitMessage = strings.TrimSpace(form.CommitMessage)
if len(form.CommitMessage) > 0 {
message += "\n\n" + form.CommitMessage
}
if err := ctx.Repo.Repository.UpdateRepoFile(ctx.User, oldBranchName, branchName, oldTreeName, treeName, content, message, isNewFile); err != nil {
if err := ctx.Repo.Repository.UpdateRepoFile(ctx.User, &models.UpdateRepoFileOptions{
LastCommitID: lastCommit,
OldBranch: oldBranchName,
NewBranch: branchName,
OldTreeName: oldTreeName,
NewTreeName: treeName,
Message: message,
Content: content,
IsNewFile: isNewFile,
}); err != nil {
ctx.Data["Err_Filename"] = true
ctx.RenderWithErr(ctx.Tr("repo.unable_to_update_file"), EDIT, &form)
log.Error(4, "%s: %v", "EditFile", err)
ctx.RenderWithErr(ctx.Tr("repo.editor.failed_to_update_file", err), EDIT, &form)
return
}
if branch, err := ctx.Repo.Repository.GetBranch(branchName); err != nil {
log.Error(4, "repo.Repository.GetBranch(%s): %v", branchName, err)
} else if commit, err := branch.GetCommit(); err != nil {
log.Error(4, "branch.GetCommit(): %v", err)
} else {
pc := &models.PushCommits{
Len: 1,
Commits: []*models.PushCommit{models.CommitToPushCommit(commit)},
}
oldCommitID := ctx.Repo.CommitID
newCommitID := commit.ID.String()
if branchName != oldBranchName {
oldCommitID = "0000000000000000000000000000000000000000" // New Branch so we use all 0s
}
if err := models.CommitRepoAction(ctx.User.ID, ctx.Repo.Owner.ID, ctx.User.LowerName, ctx.Repo.Owner.Email,
ctx.Repo.Repository.ID, ctx.Repo.Owner.LowerName, ctx.Repo.Repository.Name, "refs/heads/"+branchName, pc,
oldCommitID, newCommitID); err != nil {
log.Error(4, "models.CommitRepoAction(branch = %s): %v", branchName, err)
}
models.HookQueue.Add(ctx.Repo.Repository.ID)
}
ctx.Redirect(ctx.Repo.RepoLink + "/src/" + branchName + "/" + treeName)
}
// Leaving this off until forked repos that get a branch can compare with forks master and not upstream
//if oldBranchName != branchName {
// ctx.Redirect(EscapeUrl(ctx.Repo.RepoLink + "/compare/" + oldBranchName + "..." + branchName))
//} else {
ctx.Redirect(EscapeUrl(ctx.Repo.RepoLink + "/src/" + branchName + "/" + treeName))
//}
func EditFilePost(ctx *context.Context, form auth.EditRepoFileForm) {
editFilePost(ctx, form, false)
}
func NewFilePost(ctx *context.Context, form auth.EditRepoFileForm) {
editFilePost(ctx, form, true)
}
func DiffPreviewPost(ctx *context.Context, form auth.EditPreviewDiffForm) {
userName := ctx.Repo.Owner.Name
repoName := ctx.Repo.Repository.Name
branchName := ctx.Repo.BranchName
treeName := ctx.Repo.TreeName
content := form.Content
entry, err := ctx.Repo.Commit.GetTreeEntryByPath(treeName)
if (err != nil && git.IsErrNotExist(err)) || entry.IsDir() {
ctx.Data["FileContent"] = content
ctx.HTML(200, DIFF_PREVIEW_NEW)
if err != nil {
if git.IsErrNotExist(err) {
ctx.Data["FileContent"] = content
ctx.HTML(200, DIFF_PREVIEW_NEW)
} else {
ctx.Error(500, "GetTreeEntryByPath: "+err.Error())
}
return
}
if entry.IsDir() {
ctx.Error(422)
return
}
diff, err := ctx.Repo.Repository.GetPreviewDiff(models.RepoPath(userName, repoName), branchName, treeName, content, setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles)
diff, err := ctx.Repo.Repository.GetDiffPreview(ctx.Repo.BranchName, treeName, content)
if err != nil {
ctx.Error(404, err.Error())
log.Error(4, "%s: %v", "GetPreviewDiff", err)
ctx.Error(500, "GetDiffPreview: "+err.Error())
return
}
if diff.NumFiles() == 0 {
ctx.Error(200, ctx.Tr("repo.no_changes_to_show"))
ctx.PlainText(200, []byte(ctx.Tr("repo.editor.no_changes_to_show")))
return
}
ctx.Data["IsSplitStyle"] = ctx.Query("style") == "split"
ctx.Data["File"] = diff.Files[0]
ctx.HTML(200, DIFF_PREVIEW)
}
func EscapeUrl(str string) string {
return strings.NewReplacer("?", "%3F", "%", "%25", "#", "%23", " ", "%20", "^", "%5E", "\\", "%5C", "{", "%7B", "}", "%7D", "|", "%7C").Replace(str)
}
+1 -6
View File
@@ -170,12 +170,7 @@ func UploadFilePost(ctx *context.Context, form auth.UploadRepoFileForm) {
models.HookQueue.Add(ctx.Repo.Repository.ID)
}
// Leaving this off until forked repos that get a branch can compare with forks master and not upstream
//if oldBranchName != branchName {
// ctx.Redirect(EscapeUrl(ctx.Repo.RepoLink + "/compare/" + oldBranchName + "..." + branchName))
//} else {
ctx.Redirect(EscapeUrl(ctx.Repo.RepoLink + "/src/" + branchName + "/" + treeName))
//}
ctx.Redirect(ctx.Repo.RepoLink + "/src/" + branchName + "/" + treeName)
}
func UploadFileToServer(ctx *context.Context) {
+84 -82
View File
@@ -75,110 +75,112 @@ func Home(ctx *context.Context) {
}
entry, err := ctx.Repo.Commit.GetTreeEntryByPath(treename)
if err != nil && git.IsErrNotExist(err) {
ctx.Handle(404, "GetTreeEntryByPath", err)
if err != nil {
if git.IsErrNotExist(err) {
ctx.Handle(404, "GetTreeEntryByPath", err)
} else {
ctx.Handle(500, "GetTreeEntryByPath", err)
}
return
}
if len(treename) != 0 && entry == nil {
ctx.Handle(404, "repo.Home", nil)
return
}
if entry != nil && !entry.IsDir() {
if !entry.IsDir() {
blob := entry.Blob()
if dataRc, err := blob.Data(); err != nil {
dataRc, err := blob.Data()
if err != nil {
ctx.Handle(404, "blob.Data", err)
return
} else {
ctx.Data["FileSize"] = blob.Size()
ctx.Data["IsFile"] = true
ctx.Data["FileName"] = blob.Name()
ctx.Data["HighlightClass"] = highlight.FileNameToHighlightClass(blob.Name())
ctx.Data["FileLink"] = rawLink + "/" + treename
}
buf := make([]byte, 1024)
n, _ := dataRc.Read(buf)
if n > 0 {
buf = buf[:n]
}
ctx.Data["FileSize"] = blob.Size()
ctx.Data["IsFile"] = true
ctx.Data["FileName"] = blob.Name()
ctx.Data["HighlightClass"] = highlight.FileNameToHighlightClass(blob.Name())
ctx.Data["FileLink"] = rawLink + "/" + treename
_, isTextFile := base.IsTextFile(buf)
_, isImageFile := base.IsImageFile(buf)
_, isPDFFile := base.IsPDFFile(buf)
ctx.Data["IsFileText"] = isTextFile
buf := make([]byte, 1024)
n, _ := dataRc.Read(buf)
if n > 0 {
buf = buf[:n]
}
switch {
case isPDFFile:
ctx.Data["IsPDFFile"] = true
ctx.Data["FileEditLinkTooltip"] = ctx.Tr("repo.cannot_edit_binary_files")
case isImageFile:
ctx.Data["IsImageFile"] = true
ctx.Data["FileEditLinkTooltip"] = ctx.Tr("repo.cannot_edit_binary_files")
case isTextFile:
if blob.Size() >= setting.UI.MaxDisplayFileSize {
ctx.Data["IsFileTooLarge"] = true
_, isTextFile := base.IsTextFile(buf)
_, isImageFile := base.IsImageFile(buf)
_, isPDFFile := base.IsPDFFile(buf)
ctx.Data["IsFileText"] = isTextFile
switch {
case isPDFFile:
ctx.Data["IsPDFFile"] = true
ctx.Data["FileEditLinkTooltip"] = ctx.Tr("repo.cannot_edit_binary_files")
case isImageFile:
ctx.Data["IsImageFile"] = true
ctx.Data["FileEditLinkTooltip"] = ctx.Tr("repo.cannot_edit_binary_files")
case isTextFile:
if blob.Size() >= setting.UI.MaxDisplayFileSize {
ctx.Data["IsFileTooLarge"] = true
} else {
ctx.Data["IsFileTooLarge"] = false
d, _ := ioutil.ReadAll(dataRc)
buf = append(buf, d...)
readmeExist := markdown.IsMarkdownFile(blob.Name()) || markdown.IsReadmeFile(blob.Name())
isMarkdown := readmeExist || markdown.IsMarkdownFile(blob.Name())
ctx.Data["ReadmeExist"] = readmeExist
ctx.Data["IsMarkdown"] = isMarkdown
if isMarkdown {
ctx.Data["FileContent"] = string(markdown.Render(buf, path.Dir(treeLink), ctx.Repo.Repository.ComposeMetas()))
} else {
ctx.Data["IsFileTooLarge"] = false
d, _ := ioutil.ReadAll(dataRc)
buf = append(buf, d...)
readmeExist := markdown.IsMarkdownFile(blob.Name()) || markdown.IsReadmeFile(blob.Name())
isMarkdown := readmeExist || markdown.IsMarkdownFile(blob.Name())
ctx.Data["ReadmeExist"] = readmeExist
ctx.Data["IsMarkdown"] = isMarkdown
if isMarkdown {
ctx.Data["FileContent"] = string(markdown.Render(buf, path.Dir(treeLink), ctx.Repo.Repository.ComposeMetas()))
// Building code view blocks with line number on server side.
var filecontent string
if err, content := template.ToUTF8WithErr(buf); err != nil {
if err != nil {
log.Error(4, "ToUTF8WithErr: %s", err)
}
filecontent = string(buf)
} else {
// Building code view blocks with line number on server side.
var filecontent string
if err, content := template.ToUTF8WithErr(buf); err != nil {
if err != nil {
log.Error(4, "ToUTF8WithErr: %s", err)
}
filecontent = string(buf)
} else {
filecontent = content
}
var output bytes.Buffer
lines := strings.Split(filecontent, "\n")
for index, line := range lines {
output.WriteString(fmt.Sprintf(`<li class="L%d" rel="L%d">%s</li>`, index+1, index+1, gotemplate.HTMLEscapeString(line)) + "\n")
}
ctx.Data["FileContent"] = gotemplate.HTML(output.String())
output.Reset()
for i := 0; i < len(lines); i++ {
output.WriteString(fmt.Sprintf(`<span id="L%d">%d</span>`, i+1, i+1))
}
ctx.Data["LineNums"] = gotemplate.HTML(output.String())
filecontent = content
}
}
if ctx.Repo.IsWriter() && ctx.Repo.IsViewBranch {
ctx.Data["FileEditLink"] = editLink + "/" + treename
ctx.Data["FileEditLinkTooltip"] = ctx.Tr("repo.edit_this_file")
} else {
if !ctx.Repo.IsViewBranch {
ctx.Data["FileEditLinkTooltip"] = ctx.Tr("repo.must_be_on_branch")
} else if !ctx.Repo.IsWriter() {
ctx.Data["FileEditLink"] = forkLink
ctx.Data["FileEditLinkTooltip"] = ctx.Tr("repo.fork_before_edit")
var output bytes.Buffer
lines := strings.Split(filecontent, "\n")
for index, line := range lines {
output.WriteString(fmt.Sprintf(`<li class="L%d" rel="L%d">%s</li>`, index+1, index+1, gotemplate.HTMLEscapeString(line)) + "\n")
}
ctx.Data["FileContent"] = gotemplate.HTML(output.String())
output.Reset()
for i := 0; i < len(lines); i++ {
output.WriteString(fmt.Sprintf(`<span id="L%d">%d</span>`, i+1, i+1))
}
ctx.Data["LineNums"] = gotemplate.HTML(output.String())
}
default:
ctx.Data["FileEditLinkTooltip"] = ctx.Tr("repo.cannot_edit_binary_files")
}
if ctx.Repo.IsWriter() && ctx.Repo.IsViewBranch {
ctx.Data["FileDeleteLink"] = deleteLink + "/" + treename
ctx.Data["FileDeleteLinkTooltip"] = ctx.Tr("repo.delete_this_file")
ctx.Data["FileEditLink"] = editLink + "/" + treename
ctx.Data["FileEditLinkTooltip"] = ctx.Tr("repo.edit_this_file")
} else {
if !ctx.Repo.IsViewBranch {
ctx.Data["FileDeleteLinkTooltip"] = ctx.Tr("repo.must_be_on_branch")
ctx.Data["FileEditLinkTooltip"] = ctx.Tr("repo.must_be_on_branch")
} else if !ctx.Repo.IsWriter() {
ctx.Data["FileDeleteLinkTooltip"] = ctx.Tr("repo.must_be_writer")
ctx.Data["FileEditLink"] = forkLink
ctx.Data["FileEditLinkTooltip"] = ctx.Tr("repo.fork_before_edit")
}
}
default:
ctx.Data["FileEditLinkTooltip"] = ctx.Tr("repo.cannot_edit_binary_files")
}
if ctx.Repo.IsWriter() && ctx.Repo.IsViewBranch {
ctx.Data["FileDeleteLink"] = deleteLink + "/" + treename
ctx.Data["FileDeleteLinkTooltip"] = ctx.Tr("repo.delete_this_file")
} else {
if !ctx.Repo.IsViewBranch {
ctx.Data["FileDeleteLinkTooltip"] = ctx.Tr("repo.must_be_on_branch")
} else if !ctx.Repo.IsWriter() {
ctx.Data["FileDeleteLinkTooltip"] = ctx.Tr("repo.must_be_writer")
}
}
} else {
// Directory and file list.
tree, err := ctx.Repo.Commit.SubTree(treename)
+2 -2
View File
@@ -71,9 +71,9 @@
{{if not $file.IsSubmodule}}
<div class="ui right">
{{if $file.IsDeleted}}
<a class="ui basic tiny button" rel="nofollow" href="{{EscapePound $.BeforeSourcePath}}/{{EscapePound .Name}}">{{$.i18n.Tr "repo.diff.view_file"}}</a>
<a class="ui basic grey tiny button" rel="nofollow" href="{{EscapePound $.BeforeSourcePath}}/{{EscapePound .Name}}">{{$.i18n.Tr "repo.diff.view_file"}}</a>
{{else}}
<a class="ui basic tiny button" rel="nofollow" href="{{EscapePound $.SourcePath}}/{{EscapePound .Name}}">{{$.i18n.Tr "repo.diff.view_file"}}</a>
<a class="ui basic grey tiny button" rel="nofollow" href="{{EscapePound $.SourcePath}}/{{EscapePound .Name}}">{{$.i18n.Tr "repo.diff.view_file"}}</a>
{{end}}
</div>
{{end}}
File renamed without changes.
@@ -2,11 +2,10 @@
<div class="repository file edit">
{{template "repo/header" .}}
<div class="ui container">
{{.branchName}}
{{template "base/alert" .}}
<form class="ui edit form" action="{{EscapePound $.Link}}" method="post">
{{.CsrfTokenHtml}}
<input type="hidden" name="last_commit" value="{{.LastCommit}}">
<input type="hidden" name="last_commit" value="{{.last_commit}}">
<div class="ui secondary menu">
<div class="item fitted" style="width:100%;">
<div class="ui breadcrumb field{{if .Err_Filename}} error{{end}}">
@@ -31,7 +30,7 @@
<div class="ui top attached tabular menu" data-write="write" data-preview="preview" data-diff="diff">
<a class="active item" data-tab="write"><i class="octicon octicon-code"></i> {{.i18n.Tr "repo.edit_file"}}</a>
<a class="item" data-tab="preview" data-url="{{AppSubUrl}}/api/v1/markdown" data-context="{{.RepoLink}}" data-preview-file-modes="{{.PreviewableFileModes}}"><i class="octicon octicon-eye"></i> {{.i18n.Tr "repo.release.preview"}}</a>
<a class="item" data-tab="diff" data-url="{{.PreviewDiffURL}}" data-context="{{.BranchLink}}"><i class="octicon octicon-diff"></i> {{.i18n.Tr "repo.preview_changes"}}</a>
<a class="item" data-tab="diff" data-url="{{.RepoLink}}/preview/{{.BranchName}}/{{.TreeName}}" data-context="{{.BranchLink}}"><i class="octicon octicon-diff"></i> {{.i18n.Tr "repo.preview_changes"}}</a>
</div>
<div class="ui bottom attached active tab segment" data-tab="write">
<textarea id="edit_area" name="content" data-id="repo-{{.Repository.Name}}-{{.TreeName}}"
@@ -53,26 +52,26 @@
<div class="commit-form">
<h3>{{.i18n.Tr "repo.commit_changes"}}</h3>
<div class="field">
<input name="commit_summary" placeholder="{{if .IsNewFile}}{{.i18n.Tr "repo.add"}} '{{.TreeName}}/<filename>'{{else}}{{.i18n.Tr "repo.update"}} '{{.TreeName}}'{{end}}" value="{{.CommitSummary}}">
<input name="commit_summary" placeholder="{{if .IsNewFile}}{{.i18n.Tr "repo.add"}} '{{.TreeName}}/<filename>'{{else}}{{.i18n.Tr "repo.update"}} '{{.TreeName}}'{{end}}" value="{{.commit_summary}}">
</div>
<div class="field">
<textarea name="commit_message" placeholder="{{.i18n.Tr "repo.default_commit_message"}}">{{.CommitMessage}}</textarea>
<textarea name="commit_message" placeholder="{{.i18n.Tr "repo.default_commit_message"}}">{{.commit_message}}</textarea>
</div>
<div class="quick-pull-choice js-quick-pull-choice ">
<div class="quick-pull-choice js-quick-pull-choice">
<dl class="form-group">
<dd>
<div class="form-checkbox">
<label>
<input type="radio" class="js-quick-pull-choice-option" name="commit_choice" value="direct"{{if eq .CommitChoice "direct"}} checked="checked"{{end}}>
<input type="radio" class="js-quick-pull-choice-option" name="commit_choice" value="direct"{{if eq .commit_choice "direct"}} checked="checked"{{end}}>
<i class="octicon octicon-git-commit" height="16" width="14"></i>
{{.CommitDirectlyToThisBranch | Safe}}
{{.i18n.Tr "repo.editor.commit_directly_to_this_branch" .BranchName | Safe}}
</label>
</div>
<div class="form-checkbox">
<label>
<input type="radio" class="js-quick-pull-choice-option" name="commit_choice" value="commit-to-new-branch"{{if eq .CommitChoice "commit-to-new-branch"}} checked="checked"{{end}}>
<input type="radio" class="js-quick-pull-choice-option" name="commit_choice" value="commit-to-new-branch"{{if eq .commit_choice "commit-to-new-branch"}} checked="checked"{{end}}>
<i class="octicon octicon-git-pull-request" height="16" width="12"></i>
{{.CreateNewBranch | Safe}}
{{.i18n.Tr "repo.editor.create_new_branch" | Safe}}
</label>
</div>
</dd>
@@ -80,7 +79,7 @@
<div class="quick-pull-branch-name">
<div class="new-branch-name-input{{if .Err_Branchname}} error{{end}}">
<i class="octicon octicon-git-branch quick-pull-new-branch-icon" height="16" width="10"></i>
<input type="text" name="new_branch_name" value="{{.NewBranchName}}" class="form-control input-contrast mr-2 js-quick-pull-new-branch-name" placeholder="New branch name…">
<input type="text" name="new_branch_name" value="{{.new_branch_name}}" class="form-control input-contrast mr-2 js-quick-pull-new-branch-name" placeholder="New branch name…">
<span class="text-muted js-quick-pull-normalization-info"></span>
</div>
</div>