mirror of
				https://github.com/go-gitea/gitea
				synced 2025-11-03 21:08:25 +00:00 
			
		
		
		
	Web editor: improve edit file and diff preview
This commit is contained in:
		@@ -440,36 +440,34 @@ edit_this_file = Edit this file
 | 
				
			|||||||
edit_file = Edit file
 | 
					edit_file = Edit file
 | 
				
			||||||
delete_confirm_message = Are you sure you want to delete this file?
 | 
					delete_confirm_message = Are you sure you want to delete this file?
 | 
				
			||||||
delete_commit_message = Write a note about this delete (optional)
 | 
					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
 | 
					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_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
 | 
					must_be_writer = You must have write access to make or propose changes to this file
 | 
				
			||||||
cannot_edit_binary_files = Cannot edit binary files
 | 
					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.
 | 
					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
 | 
					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
 | 
					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
 | 
					create_branch = Create branch
 | 
				
			||||||
from = from
 | 
					from = from
 | 
				
			||||||
upload_file = Upload file
 | 
					upload_file = Upload file
 | 
				
			||||||
add_files_to_dir = Add files to %s
 | 
					add_files_to_dir = Add files to %s
 | 
				
			||||||
unable_to_upload_files = Unable to upload files, an error occurred.
 | 
					 | 
				
			||||||
add_subdir = Add subdirectory...
 | 
					add_subdir = Add subdirectory...
 | 
				
			||||||
name_your_file = Name your file...
 | 
					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
 | 
					copy_file_path_to_clipboard = Copy file path to clipboard
 | 
				
			||||||
preview_changes = Preview Changes
 | 
					preview_changes = Preview Changes
 | 
				
			||||||
no_changes_to_show = There are no changes to show.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
commits.commits = Commits
 | 
					commits.commits = Commits
 | 
				
			||||||
commits.search = Search commits
 | 
					commits.search = Search commits
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -434,7 +434,7 @@ func GetDiffRange(repoPath, beforeCommitID, afterCommitID string, maxLines, maxL
 | 
				
			|||||||
		return nil, fmt.Errorf("Start: %v", err)
 | 
							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)
 | 
						defer process.Remove(pid)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	diff, err := ParsePatch(maxLines, maxLineCharacteres, maxFiles, stdout)
 | 
						diff, err := ParsePatch(maxLines, maxLineCharacteres, maxFiles, stdout)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -334,6 +334,9 @@ var patchConflicts = []string{
 | 
				
			|||||||
// testPatch checks if patch can be merged to base repository without conflit.
 | 
					// testPatch checks if patch can be merged to base repository without conflit.
 | 
				
			||||||
// FIXME: make a mechanism to clean up stable local copies.
 | 
					// FIXME: make a mechanism to clean up stable local copies.
 | 
				
			||||||
func (pr *PullRequest) testPatch() (err error) {
 | 
					func (pr *PullRequest) testPatch() (err error) {
 | 
				
			||||||
 | 
						repoWorkingPool.CheckIn(com.ToStr(pr.BaseRepoID))
 | 
				
			||||||
 | 
						defer repoWorkingPool.CheckOut(com.ToStr(pr.BaseRepoID))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if pr.BaseRepo == nil {
 | 
						if pr.BaseRepo == nil {
 | 
				
			||||||
		pr.BaseRepo, err = GetRepositoryByID(pr.BaseRepoID)
 | 
							pr.BaseRepo, err = GetRepositoryByID(pr.BaseRepoID)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
@@ -354,20 +357,12 @@ func (pr *PullRequest) testPatch() (err error) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	log.Trace("PullRequest[%d].testPatch (patchPath): %s", pr.ID, patchPath)
 | 
						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)
 | 
							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
 | 
						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),
 | 
							fmt.Sprintf("testPatch (git apply --check): %d", pr.BaseRepo.ID),
 | 
				
			||||||
		"git", "apply", "--check", patchPath)
 | 
							"git", "apply", "--check", patchPath)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										202
									
								
								models/repo.go
									
									
									
									
									
								
							
							
						
						
									
										202
									
								
								models/repo.go
									
									
									
									
									
								
							@@ -437,10 +437,14 @@ func (repo *Repository) DescriptionHtml() template.HTML {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (repo *Repository) LocalCopyPath() string {
 | 
					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 !com.IsExist(localPath) {
 | 
				
			||||||
		if err := git.Clone(repoPath, localPath, git.CloneRepoOptions{
 | 
							if err := git.Clone(repoPath, localPath, git.CloneRepoOptions{
 | 
				
			||||||
			Timeout: time.Duration(setting.Git.Timeout.Clone) * time.Second,
 | 
								Timeout: time.Duration(setting.Git.Timeout.Clone) * time.Second,
 | 
				
			||||||
@@ -451,12 +455,10 @@ func updateLocalCopy(repoPath, localPath, branch string) error {
 | 
				
			|||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		if err := git.Checkout(localPath, git.CheckoutOptions{
 | 
							if err := git.Checkout(localPath, git.CheckoutOptions{
 | 
				
			||||||
			Branch: branch,
 | 
								Branch: branch,
 | 
				
			||||||
			Timeout: time.Duration(setting.Git.Timeout.Pull) * time.Second,
 | 
					 | 
				
			||||||
		}); err != nil {
 | 
							}); err != nil {
 | 
				
			||||||
			return fmt.Errorf("Checkout: %v", err)
 | 
								return fmt.Errorf("Checkout: %v", err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if err := git.Pull(localPath, git.PullRemoteOptions{
 | 
							if err := git.Pull(localPath, git.PullRemoteOptions{
 | 
				
			||||||
			All:     false,
 | 
					 | 
				
			||||||
			Remote:  "origin",
 | 
								Remote:  "origin",
 | 
				
			||||||
			Branch:  branch,
 | 
								Branch:  branch,
 | 
				
			||||||
			Timeout: time.Duration(setting.Git.Timeout.Pull) * time.Second,
 | 
								Timeout: time.Duration(setting.Git.Timeout.Pull) * time.Second,
 | 
				
			||||||
@@ -467,9 +469,9 @@ func updateLocalCopy(repoPath, localPath, branch string) error {
 | 
				
			|||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// UpdateLocalCopy makes sure the local copy of repository is up-to-date.
 | 
					// UpdateLocalCopy makes sure the branch of local copy of repository is up-to-date.
 | 
				
			||||||
func (repo *Repository) UpdateLocalCopy(branch string) error {
 | 
					func (repo *Repository) UpdateLocalCopyBranch(branch string) error {
 | 
				
			||||||
	return updateLocalCopy(repo.RepoPath(), repo.LocalCopyPath(), branch)
 | 
						return UpdateLocalCopyBranch(repo.RepoPath(), repo.LocalCopyPath(), branch)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// PatchPath returns corresponding patch file path of repository by given issue ID.
 | 
					// 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})
 | 
						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))
 | 
						repoWorkingPool.CheckIn(com.ToStr(repo.ID))
 | 
				
			||||||
	defer repoWorkingPool.CheckOut(com.ToStr(repo.ID))
 | 
						defer repoWorkingPool.CheckOut(com.ToStr(repo.ID))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	localPath := repo.LocalRepoPath()
 | 
						localPath := repo.LocalCopyPath()
 | 
				
			||||||
	if err = discardLocalRepoChanges(localPath, branch); err != nil {
 | 
						if err = discardLocalRepoBranchChanges(localPath, branch); err != nil {
 | 
				
			||||||
		return fmt.Errorf("discardLocalRepoChanges: %v", err)
 | 
							return fmt.Errorf("discardLocalRepoChanges: %v", err)
 | 
				
			||||||
	} else if err = repo.UpdateLocalRepo(branch); err != nil {
 | 
						} else if err = repo.UpdateLocalCopyBranch(branch); err != nil {
 | 
				
			||||||
		return fmt.Errorf("UpdateLocalRepo: %v", err)
 | 
							return fmt.Errorf("UpdateLocalCopyBranch: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	filePath := path.Join(localPath, treeName)
 | 
						filePath := path.Join(localPath, treeName)
 | 
				
			||||||
@@ -2450,12 +2290,12 @@ func (repo *Repository) UploadRepoFiles(doer *User, oldBranchName, branchName, t
 | 
				
			|||||||
	repoWorkingPool.CheckIn(com.ToStr(repo.ID))
 | 
						repoWorkingPool.CheckIn(com.ToStr(repo.ID))
 | 
				
			||||||
	defer repoWorkingPool.CheckOut(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)
 | 
							return fmt.Errorf("discardLocalRepoChanges: %v", err)
 | 
				
			||||||
	} else if err = repo.UpdateLocalRepo(oldBranchName); err != nil {
 | 
						} else if err = repo.UpdateLocalCopyBranch(oldBranchName); err != nil {
 | 
				
			||||||
		return fmt.Errorf("UpdateLocalRepo: %v", err)
 | 
							return fmt.Errorf("UpdateLocalCopyBranch: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if oldBranchName != branchName {
 | 
						if oldBranchName != branchName {
 | 
				
			||||||
@@ -2637,12 +2477,12 @@ func (repo *Repository) CreateNewBranch(doer *User, oldBranchName, branchName st
 | 
				
			|||||||
	repoWorkingPool.CheckIn(com.ToStr(repo.ID))
 | 
						repoWorkingPool.CheckIn(com.ToStr(repo.ID))
 | 
				
			||||||
	defer repoWorkingPool.CheckOut(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)
 | 
							return fmt.Errorf("discardLocalRepoChanges: %v", err)
 | 
				
			||||||
	} else if err = repo.UpdateLocalRepo(oldBranchName); err != nil {
 | 
						} else if err = repo.UpdateLocalCopyBranch(oldBranchName); err != nil {
 | 
				
			||||||
		return fmt.Errorf("UpdateLocalRepo: %v", err)
 | 
							return fmt.Errorf("UpdateLocalCopyBranch: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err = repo.CheckoutNewBranch(oldBranchName, branchName); err != nil {
 | 
						if err = repo.CheckoutNewBranch(oldBranchName, branchName); err != nil {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										211
									
								
								models/repo_editor.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										211
									
								
								models/repo_editor.go
									
									
									
									
									
										Normal 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
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -76,24 +76,11 @@ func (repo *Repository) LocalWikiPath() string {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// UpdateLocalWiki makes sure the local copy of repository wiki is up-to-date.
 | 
					// UpdateLocalWiki makes sure the local copy of repository wiki is up-to-date.
 | 
				
			||||||
func (repo *Repository) UpdateLocalWiki() error {
 | 
					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 {
 | 
					func discardLocalWikiChanges(localPath string) error {
 | 
				
			||||||
	if !com.IsExist(localPath) {
 | 
						return discardLocalRepoBranchChanges(localPath, "master")
 | 
				
			||||||
		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
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// updateWikiPage adds new page to repository wiki.
 | 
					// updateWikiPage adds new page to repository wiki.
 | 
				
			||||||
 
 | 
				
			|||||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							@@ -40,14 +40,14 @@ func NewBranchPost(ctx *context.Context, form auth.NewBranchForm) {
 | 
				
			|||||||
	branchName := form.BranchName
 | 
						branchName := form.BranchName
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ctx.HasError() || !ctx.Repo.IsWriter() || branchName == oldBranchName {
 | 
						if ctx.HasError() || !ctx.Repo.IsWriter() || branchName == oldBranchName {
 | 
				
			||||||
		ctx.Redirect(EscapeUrl(ctx.Repo.RepoLink + "/src/" + oldBranchName))
 | 
							ctx.Redirect(ctx.Repo.RepoLink + "/src/" + oldBranchName)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	branchName = url.QueryEscape(strings.Replace(strings.Trim(branchName, " "), " ", "-", -1))
 | 
						branchName = url.QueryEscape(strings.Replace(strings.Trim(branchName, " "), " ", "-", -1))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if _, err := ctx.Repo.Repository.GetBranch(branchName); err == nil {
 | 
						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
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -77,5 +77,5 @@ func NewBranchPost(ctx *context.Context, form auth.NewBranchForm) {
 | 
				
			|||||||
		models.HookQueue.Add(ctx.Repo.Repository.ID)
 | 
							models.HookQueue.Add(ctx.Repo.Repository.ID)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ctx.Redirect(EscapeUrl(ctx.Repo.RepoLink + "/src/" + branchName))
 | 
						ctx.Redirect(ctx.Repo.RepoLink + "/src/" + branchName)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,28 +20,24 @@ import (
 | 
				
			|||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
	EDIT             base.TplName = "repo/edit"
 | 
						EDIT             base.TplName = "repo/editor/edit"
 | 
				
			||||||
	DIFF_PREVIEW     base.TplName = "repo/diff_preview"
 | 
						DIFF_PREVIEW     base.TplName = "repo/editor/diff_preview"
 | 
				
			||||||
	DIFF_PREVIEW_NEW base.TplName = "repo/diff_preview_new"
 | 
						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) {
 | 
					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["PageIsEdit"] = true
 | 
				
			||||||
	ctx.Data["IsNewFile"] = isNewFile
 | 
						ctx.Data["IsNewFile"] = isNewFile
 | 
				
			||||||
	ctx.Data["RequireHighlightJS"] = true
 | 
						ctx.Data["RequireHighlightJS"] = true
 | 
				
			||||||
 | 
						ctx.Data["RequireSimpleMDE"] = true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	userName := ctx.Repo.Owner.Name
 | 
						branchLink := ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchName
 | 
				
			||||||
	repoName := ctx.Repo.Repository.Name
 | 
					 | 
				
			||||||
	branchName := ctx.Repo.BranchName
 | 
					 | 
				
			||||||
	branchLink := ctx.Repo.RepoLink + "/src/" + branchName
 | 
					 | 
				
			||||||
	treeName := ctx.Repo.TreeName
 | 
						treeName := ctx.Repo.TreeName
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var treeNames []string
 | 
						var treeNames []string
 | 
				
			||||||
@@ -51,19 +47,22 @@ func editFile(ctx *context.Context, isNewFile bool) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	if !isNewFile {
 | 
						if !isNewFile {
 | 
				
			||||||
		entry, err := ctx.Repo.Commit.GetTreeEntryByPath(treeName)
 | 
							entry, err := ctx.Repo.Commit.GetTreeEntryByPath(treeName)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
		if err != nil && git.IsErrNotExist(err) {
 | 
								if git.IsErrNotExist(err) {
 | 
				
			||||||
				ctx.Handle(404, "GetTreeEntryByPath", err)
 | 
									ctx.Handle(404, "GetTreeEntryByPath", err)
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									ctx.Handle(500, "GetTreeEntryByPath", err)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (ctx.Repo.IsViewCommit) || entry == nil || entry.IsDir() {
 | 
							// No way to edit a directory online.
 | 
				
			||||||
			ctx.Handle(404, "repo.Home", nil)
 | 
							if entry.IsDir() {
 | 
				
			||||||
 | 
								ctx.Handle(404, "", nil)
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		blob := entry.Blob()
 | 
							blob := entry.Blob()
 | 
				
			||||||
 | 
					 | 
				
			||||||
		dataRc, err := blob.Data()
 | 
							dataRc, err := blob.Data()
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			ctx.Handle(404, "blob.Data", err)
 | 
								ctx.Handle(404, "blob.Data", err)
 | 
				
			||||||
@@ -79,16 +78,15 @@ func editFile(ctx *context.Context, isNewFile bool) {
 | 
				
			|||||||
			buf = buf[:n]
 | 
								buf = buf[:n]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Only text file are editable online.
 | 
				
			||||||
		_, isTextFile := base.IsTextFile(buf)
 | 
							_, isTextFile := base.IsTextFile(buf)
 | 
				
			||||||
 | 
					 | 
				
			||||||
		if !isTextFile {
 | 
							if !isTextFile {
 | 
				
			||||||
			ctx.Handle(404, "repo.Home", nil)
 | 
								ctx.Handle(404, "", nil)
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		d, _ := ioutil.ReadAll(dataRc)
 | 
							d, _ := ioutil.ReadAll(dataRc)
 | 
				
			||||||
		buf = append(buf, d...)
 | 
							buf = append(buf, d...)
 | 
				
			||||||
 | 
					 | 
				
			||||||
		if err, content := template.ToUTF8WithErr(buf); err != nil {
 | 
							if err, content := template.ToUTF8WithErr(buf); err != nil {
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				log.Error(4, "Convert content encoding: %s", err)
 | 
									log.Error(4, "Convert content encoding: %s", err)
 | 
				
			||||||
@@ -98,47 +96,38 @@ func editFile(ctx *context.Context, isNewFile bool) {
 | 
				
			|||||||
			ctx.Data["FileContent"] = content
 | 
								ctx.Data["FileContent"] = content
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} else {
 | 
						} 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["TreeName"] = treeName
 | 
				
			||||||
	ctx.Data["TreeNames"] = treeNames
 | 
						ctx.Data["TreeNames"] = treeNames
 | 
				
			||||||
	ctx.Data["BranchLink"] = branchLink
 | 
						ctx.Data["BranchLink"] = branchLink
 | 
				
			||||||
	ctx.Data["CommitSummary"] = ""
 | 
						ctx.Data["commit_summary"] = ""
 | 
				
			||||||
	ctx.Data["CommitMessage"] = ""
 | 
						ctx.Data["commit_message"] = ""
 | 
				
			||||||
	ctx.Data["CommitChoice"] = "direct"
 | 
						ctx.Data["commit_choice"] = "direct"
 | 
				
			||||||
	ctx.Data["NewBranchName"] = ""
 | 
						ctx.Data["new_branch_name"] = ""
 | 
				
			||||||
	ctx.Data["CommitDirectlyToThisBranch"] = ctx.Tr("repo.commit_directly_to_this_branch", "<strong class=\"branch-name\">"+branchName+"</strong>")
 | 
						ctx.Data["last_commit"] = ctx.Repo.Commit.ID
 | 
				
			||||||
	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["MarkdownFileExts"] = strings.Join(setting.Markdown.FileExtensions, ",")
 | 
						ctx.Data["MarkdownFileExts"] = strings.Join(setting.Markdown.FileExtensions, ",")
 | 
				
			||||||
	ctx.Data["LineWrapExtensions"] = strings.Join(setting.Repository.Editor.LineWrapExtensions, ",")
 | 
						ctx.Data["LineWrapExtensions"] = strings.Join(setting.Repository.Editor.LineWrapExtensions, ",")
 | 
				
			||||||
	ctx.Data["PreviewableFileModes"] = strings.Join(setting.Repository.Editor.PreviewableFileModes, ",")
 | 
						ctx.Data["PreviewableFileModes"] = strings.Join(setting.Repository.Editor.PreviewableFileModes, ",")
 | 
				
			||||||
	ctx.Data["PreviewDiffURL"] = ctx.Repo.RepoLink + "/preview/" + branchName + "/" + treeName
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ctx.HTML(200, EDIT)
 | 
						ctx.HTML(200, EDIT)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func EditFilePost(ctx *context.Context, form auth.EditRepoFileForm) {
 | 
					func EditFile(ctx *context.Context) {
 | 
				
			||||||
	editFilePost(ctx, form, false)
 | 
						editFile(ctx, false)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func NewFilePost(ctx *context.Context, form auth.EditRepoFileForm) {
 | 
					func NewFile(ctx *context.Context) {
 | 
				
			||||||
	editFilePost(ctx, form, true)
 | 
						editFile(ctx, true)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func editFilePost(ctx *context.Context, form auth.EditRepoFileForm, isNewFile bool) {
 | 
					func editFilePost(ctx *context.Context, form auth.EditRepoFileForm, isNewFile bool) {
 | 
				
			||||||
	ctx.Data["PageIsEdit"] = true
 | 
						ctx.Data["PageIsEdit"] = true
 | 
				
			||||||
	ctx.Data["IsNewFile"] = isNewFile
 | 
						ctx.Data["IsNewFile"] = isNewFile
 | 
				
			||||||
	ctx.Data["RequireHighlightJS"] = true
 | 
						ctx.Data["RequireHighlightJS"] = true
 | 
				
			||||||
 | 
						ctx.Data["RequireSimpleMDE"] = true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	userName := ctx.Repo.Owner.Name
 | 
					 | 
				
			||||||
	repoName := ctx.Repo.Repository.Name
 | 
					 | 
				
			||||||
	oldBranchName := ctx.Repo.BranchName
 | 
						oldBranchName := ctx.Repo.BranchName
 | 
				
			||||||
	branchName := oldBranchName
 | 
						branchName := oldBranchName
 | 
				
			||||||
	branchLink := ctx.Repo.RepoLink + "/src/" + branchName
 | 
						branchLink := ctx.Repo.RepoLink + "/src/" + branchName
 | 
				
			||||||
@@ -160,26 +149,18 @@ func editFilePost(ctx *context.Context, form auth.EditRepoFileForm, isNewFile bo
 | 
				
			|||||||
		treeNames = strings.Split(treeName, "/")
 | 
							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["TreeName"] = treeName
 | 
				
			||||||
	ctx.Data["TreeNames"] = treeNames
 | 
						ctx.Data["TreeNames"] = treeNames
 | 
				
			||||||
	ctx.Data["BranchLink"] = branchLink
 | 
						ctx.Data["BranchLink"] = branchLink
 | 
				
			||||||
	ctx.Data["FileContent"] = content
 | 
						ctx.Data["FileContent"] = content
 | 
				
			||||||
	ctx.Data["CommitSummary"] = form.CommitSummary
 | 
						ctx.Data["commit_summary"] = form.CommitSummary
 | 
				
			||||||
	ctx.Data["CommitMessage"] = form.CommitMessage
 | 
						ctx.Data["commit_message"] = form.CommitMessage
 | 
				
			||||||
	ctx.Data["CommitChoice"] = commitChoice
 | 
						ctx.Data["commit_choice"] = commitChoice
 | 
				
			||||||
	ctx.Data["NewBranchName"] = branchName
 | 
						ctx.Data["new_branch_name"] = branchName
 | 
				
			||||||
	ctx.Data["CommitDirectlyToThisBranch"] = ctx.Tr("repo.commit_directly_to_this_branch", "<strong class=\"branch-name\">"+oldBranchName+"</strong>")
 | 
						ctx.Data["last_commit"] = ctx.Repo.Commit.ID
 | 
				
			||||||
	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["MarkdownFileExts"] = strings.Join(setting.Markdown.FileExtensions, ",")
 | 
						ctx.Data["MarkdownFileExts"] = strings.Join(setting.Markdown.FileExtensions, ",")
 | 
				
			||||||
	ctx.Data["LineWrapExtensions"] = strings.Join(setting.Repository.Editor.LineWrapExtensions, ",")
 | 
						ctx.Data["LineWrapExtensions"] = strings.Join(setting.Repository.Editor.LineWrapExtensions, ",")
 | 
				
			||||||
	ctx.Data["PreviewableFileModes"] = strings.Join(setting.Repository.Editor.PreviewableFileModes, ",")
 | 
						ctx.Data["PreviewableFileModes"] = strings.Join(setting.Repository.Editor.PreviewableFileModes, ",")
 | 
				
			||||||
	ctx.Data["PreviewDiffURL"] = ctx.Repo.RepoLink + "/preview/" + branchName + "/" + treeName
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ctx.HasError() {
 | 
						if ctx.HasError() {
 | 
				
			||||||
		ctx.HTML(200, EDIT)
 | 
							ctx.HTML(200, EDIT)
 | 
				
			||||||
@@ -188,41 +169,41 @@ func editFilePost(ctx *context.Context, form auth.EditRepoFileForm, isNewFile bo
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	if len(treeName) == 0 {
 | 
						if len(treeName) == 0 {
 | 
				
			||||||
		ctx.Data["Err_Filename"] = true
 | 
							ctx.Data["Err_Filename"] = true
 | 
				
			||||||
		ctx.RenderWithErr(ctx.Tr("repo.filename_cannot_be_empty"), EDIT, &form)
 | 
							ctx.RenderWithErr(ctx.Tr("repo.editor.filename_cannot_be_empty"), EDIT, &form)
 | 
				
			||||||
		log.Error(4, "%s: %s", "EditFile", "Filename can't be empty")
 | 
					 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if oldBranchName != branchName {
 | 
						if oldBranchName != branchName {
 | 
				
			||||||
		if _, err := ctx.Repo.Repository.GetBranch(branchName); err == nil {
 | 
							if _, err := ctx.Repo.Repository.GetBranch(branchName); err == nil {
 | 
				
			||||||
			ctx.Data["Err_Branchname"] = true
 | 
								ctx.Data["Err_Branchname"] = true
 | 
				
			||||||
			ctx.RenderWithErr(ctx.Tr("repo.branch_already_exists"), EDIT, &form)
 | 
								ctx.RenderWithErr(ctx.Tr("repo.editor.branch_already_exists", branchName), EDIT, &form)
 | 
				
			||||||
			log.Error(4, "%s: %s - %s", "BranchName", branchName, "Branch already exists")
 | 
					 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	treepath := ""
 | 
						var treepath string
 | 
				
			||||||
	for index, part := range treeNames {
 | 
						for index, part := range treeNames {
 | 
				
			||||||
		treepath = path.Join(treepath, part)
 | 
							treepath = path.Join(treepath, part)
 | 
				
			||||||
		entry, err := ctx.Repo.Commit.GetTreeEntryByPath(treepath)
 | 
							entry, err := ctx.Repo.Commit.GetTreeEntryByPath(treepath)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
 | 
								if git.IsErrNotExist(err) {
 | 
				
			||||||
				// Means there is no item with that name, so we're good
 | 
									// Means there is no item with that name, so we're good
 | 
				
			||||||
				break
 | 
									break
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								ctx.Handle(500, "GetTreeEntryByPath", err)
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		if index != len(treeNames)-1 {
 | 
							if index != len(treeNames)-1 {
 | 
				
			||||||
			if !entry.IsDir() {
 | 
								if !entry.IsDir() {
 | 
				
			||||||
				ctx.Data["Err_Filename"] = true
 | 
									ctx.Data["Err_Filename"] = true
 | 
				
			||||||
				ctx.RenderWithErr(ctx.Tr("repo.directory_is_a_file"), EDIT, &form)
 | 
									ctx.RenderWithErr(ctx.Tr("repo.editor.directory_is_a_file", part), EDIT, &form)
 | 
				
			||||||
				log.Error(4, "%s: %s - %s", "EditFile", treeName, "Directory given is a file")
 | 
					 | 
				
			||||||
				return
 | 
									return
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			if entry.IsDir() {
 | 
								if entry.IsDir() {
 | 
				
			||||||
				ctx.Data["Err_Filename"] = true
 | 
									ctx.Data["Err_Filename"] = true
 | 
				
			||||||
				ctx.RenderWithErr(ctx.Tr("repo.filename_is_a_directory"), EDIT, &form)
 | 
									ctx.RenderWithErr(ctx.Tr("repo.editor.filename_is_a_directory", part), EDIT, &form)
 | 
				
			||||||
				log.Error(4, "%s: %s - %s", "EditFile", treeName, "Filename given is a dirctory")
 | 
					 | 
				
			||||||
				return
 | 
									return
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -230,125 +211,119 @@ func editFilePost(ctx *context.Context, form auth.EditRepoFileForm, isNewFile bo
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	if !isNewFile {
 | 
						if !isNewFile {
 | 
				
			||||||
		_, err := ctx.Repo.Commit.GetTreeEntryByPath(oldTreeName)
 | 
							_, err := ctx.Repo.Commit.GetTreeEntryByPath(oldTreeName)
 | 
				
			||||||
		if err != nil && git.IsErrNotExist(err) {
 | 
							if err != nil {
 | 
				
			||||||
 | 
								if git.IsErrNotExist(err) {
 | 
				
			||||||
				ctx.Data["Err_Filename"] = true
 | 
									ctx.Data["Err_Filename"] = true
 | 
				
			||||||
			ctx.RenderWithErr(ctx.Tr("repo.file_editing_no_longer_exists"), EDIT, &form)
 | 
									ctx.RenderWithErr(ctx.Tr("repo.editor.file_editing_no_longer_exists", oldTreeName), EDIT, &form)
 | 
				
			||||||
			log.Error(4, "%s: %s / %s - %s", "EditFile", branchName, oldTreeName, "File doesn't exist for editing")
 | 
								} else {
 | 
				
			||||||
 | 
									ctx.Handle(500, "GetTreeEntryByPath", err)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if lastCommit != ctx.Repo.CommitID {
 | 
							if lastCommit != ctx.Repo.CommitID {
 | 
				
			||||||
			if files, err := ctx.Repo.Commit.GetFilesChangedSinceCommit(lastCommit); err == nil {
 | 
								files, err := ctx.Repo.Commit.GetFilesChangedSinceCommit(lastCommit)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									ctx.Handle(500, "GetFilesChangedSinceCommit", err)
 | 
				
			||||||
 | 
									return
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			for _, file := range files {
 | 
								for _, file := range files {
 | 
				
			||||||
				if file == treeName {
 | 
									if file == treeName {
 | 
				
			||||||
						name := ctx.Repo.Commit.Author.Name
 | 
										ctx.RenderWithErr(ctx.Tr("repo.editor.file_changed_while_editing", ctx.Repo.RepoLink+"/compare/"+lastCommit+"..."+ctx.Repo.CommitID), EDIT, &form)
 | 
				
			||||||
						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
 | 
										return
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					
 | 
				
			||||||
	if oldTreeName != treeName {
 | 
						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
 | 
							// 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)
 | 
							entry, err := ctx.Repo.Commit.GetTreeEntryByPath(treeName)
 | 
				
			||||||
		if err == nil {
 | 
							if err != nil {
 | 
				
			||||||
 | 
								if !git.IsErrNotExist(err) {
 | 
				
			||||||
 | 
									ctx.Handle(500, "GetTreeEntryByPath", err)
 | 
				
			||||||
 | 
									return
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if entry != nil {
 | 
				
			||||||
			ctx.Data["Err_Filename"] = true
 | 
								ctx.Data["Err_Filename"] = true
 | 
				
			||||||
			ctx.RenderWithErr(ctx.Tr("repo.file_already_exists"), EDIT, &form)
 | 
								ctx.RenderWithErr(ctx.Tr("repo.editor.file_already_exists", treeName), EDIT, &form)
 | 
				
			||||||
			log.Error(4, "%s: %s - %s", "NewFile", treeName, "File already exists, can't create new")
 | 
					 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	message := ""
 | 
						var message string
 | 
				
			||||||
	if form.CommitSummary != "" {
 | 
						if len(form.CommitSummary) > 0 {
 | 
				
			||||||
		message = strings.Trim(form.CommitSummary, " ")
 | 
							message = strings.TrimSpace(form.CommitSummary)
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		if isNewFile {
 | 
							if isNewFile {
 | 
				
			||||||
			message = ctx.Tr("repo.add") + " '" + treeName + "'"
 | 
								message = ctx.Tr("repo.editor.add", treeName)
 | 
				
			||||||
		} else {
 | 
							} 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, " ")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err := ctx.Repo.Repository.UpdateRepoFile(ctx.User, oldBranchName, branchName, oldTreeName, treeName, content, message, isNewFile); err != nil {
 | 
						form.CommitMessage = strings.TrimSpace(form.CommitMessage)
 | 
				
			||||||
 | 
						if len(form.CommitMessage) > 0 {
 | 
				
			||||||
 | 
							message += "\n\n" + form.CommitMessage
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						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.Data["Err_Filename"] = true
 | 
				
			||||||
		ctx.RenderWithErr(ctx.Tr("repo.unable_to_update_file"), EDIT, &form)
 | 
							ctx.RenderWithErr(ctx.Tr("repo.editor.failed_to_update_file", err), EDIT, &form)
 | 
				
			||||||
		log.Error(4, "%s: %v", "EditFile", err)
 | 
					 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if branch, err := ctx.Repo.Repository.GetBranch(branchName); err != nil {
 | 
						ctx.Redirect(ctx.Repo.RepoLink + "/src/" + branchName + "/" + treeName)
 | 
				
			||||||
		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)
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Leaving this off until forked repos that get a branch can compare with forks master and not upstream
 | 
					func EditFilePost(ctx *context.Context, form auth.EditRepoFileForm) {
 | 
				
			||||||
	//if oldBranchName != branchName {
 | 
						editFilePost(ctx, form, false)
 | 
				
			||||||
	//	ctx.Redirect(EscapeUrl(ctx.Repo.RepoLink + "/compare/" + oldBranchName + "..." + branchName))
 | 
					}
 | 
				
			||||||
	//} else {
 | 
					
 | 
				
			||||||
	ctx.Redirect(EscapeUrl(ctx.Repo.RepoLink + "/src/" + branchName + "/" + treeName))
 | 
					func NewFilePost(ctx *context.Context, form auth.EditRepoFileForm) {
 | 
				
			||||||
	//}
 | 
						editFilePost(ctx, form, true)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func DiffPreviewPost(ctx *context.Context, form auth.EditPreviewDiffForm) {
 | 
					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
 | 
						treeName := ctx.Repo.TreeName
 | 
				
			||||||
	content := form.Content
 | 
						content := form.Content
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	entry, err := ctx.Repo.Commit.GetTreeEntryByPath(treeName)
 | 
						entry, err := ctx.Repo.Commit.GetTreeEntryByPath(treeName)
 | 
				
			||||||
	if (err != nil && git.IsErrNotExist(err)) || entry.IsDir() {
 | 
						if err != nil {
 | 
				
			||||||
 | 
							if git.IsErrNotExist(err) {
 | 
				
			||||||
			ctx.Data["FileContent"] = content
 | 
								ctx.Data["FileContent"] = content
 | 
				
			||||||
			ctx.HTML(200, DIFF_PREVIEW_NEW)
 | 
								ctx.HTML(200, DIFF_PREVIEW_NEW)
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								ctx.Error(500, "GetTreeEntryByPath: "+err.Error())
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if entry.IsDir() {
 | 
				
			||||||
 | 
							ctx.Error(422)
 | 
				
			||||||
		return
 | 
							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 {
 | 
						if err != nil {
 | 
				
			||||||
		ctx.Error(404, err.Error())
 | 
							ctx.Error(500, "GetDiffPreview: "+err.Error())
 | 
				
			||||||
		log.Error(4, "%s: %v", "GetPreviewDiff", err)
 | 
					 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if diff.NumFiles() == 0 {
 | 
						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
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	ctx.Data["IsSplitStyle"] = ctx.Query("style") == "split"
 | 
					 | 
				
			||||||
	ctx.Data["File"] = diff.Files[0]
 | 
						ctx.Data["File"] = diff.Files[0]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ctx.HTML(200, DIFF_PREVIEW)
 | 
						ctx.HTML(200, DIFF_PREVIEW)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
func EscapeUrl(str string) string {
 | 
					 | 
				
			||||||
	return strings.NewReplacer("?", "%3F", "%", "%25", "#", "%23", " ", "%20", "^", "%5E", "\\", "%5C", "{", "%7B", "}", "%7D", "|", "%7C").Replace(str)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -170,12 +170,7 @@ func UploadFilePost(ctx *context.Context, form auth.UploadRepoFileForm) {
 | 
				
			|||||||
		models.HookQueue.Add(ctx.Repo.Repository.ID)
 | 
							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
 | 
						ctx.Redirect(ctx.Repo.RepoLink + "/src/" + branchName + "/" + treeName)
 | 
				
			||||||
	//if oldBranchName != branchName {
 | 
					 | 
				
			||||||
	//	ctx.Redirect(EscapeUrl(ctx.Repo.RepoLink + "/compare/" + oldBranchName + "..." + branchName))
 | 
					 | 
				
			||||||
	//} else {
 | 
					 | 
				
			||||||
	ctx.Redirect(EscapeUrl(ctx.Repo.RepoLink + "/src/" + branchName + "/" + treeName))
 | 
					 | 
				
			||||||
	//}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func UploadFileToServer(ctx *context.Context) {
 | 
					func UploadFileToServer(ctx *context.Context) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -75,22 +75,23 @@ func Home(ctx *context.Context) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	entry, err := ctx.Repo.Commit.GetTreeEntryByPath(treename)
 | 
						entry, err := ctx.Repo.Commit.GetTreeEntryByPath(treename)
 | 
				
			||||||
	if err != nil && git.IsErrNotExist(err) {
 | 
						if err != nil {
 | 
				
			||||||
 | 
							if git.IsErrNotExist(err) {
 | 
				
			||||||
			ctx.Handle(404, "GetTreeEntryByPath", err)
 | 
								ctx.Handle(404, "GetTreeEntryByPath", err)
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								ctx.Handle(500, "GetTreeEntryByPath", err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if len(treename) != 0 && entry == nil {
 | 
						if !entry.IsDir() {
 | 
				
			||||||
		ctx.Handle(404, "repo.Home", nil)
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if entry != nil && !entry.IsDir() {
 | 
					 | 
				
			||||||
		blob := entry.Blob()
 | 
							blob := entry.Blob()
 | 
				
			||||||
 | 
							dataRc, err := blob.Data()
 | 
				
			||||||
		if dataRc, err := blob.Data(); err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			ctx.Handle(404, "blob.Data", err)
 | 
								ctx.Handle(404, "blob.Data", err)
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		} else {
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ctx.Data["FileSize"] = blob.Size()
 | 
							ctx.Data["FileSize"] = blob.Size()
 | 
				
			||||||
		ctx.Data["IsFile"] = true
 | 
							ctx.Data["IsFile"] = true
 | 
				
			||||||
		ctx.Data["FileName"] = blob.Name()
 | 
							ctx.Data["FileName"] = blob.Name()
 | 
				
			||||||
@@ -168,6 +169,7 @@ func Home(ctx *context.Context) {
 | 
				
			|||||||
		default:
 | 
							default:
 | 
				
			||||||
			ctx.Data["FileEditLinkTooltip"] = ctx.Tr("repo.cannot_edit_binary_files")
 | 
								ctx.Data["FileEditLinkTooltip"] = ctx.Tr("repo.cannot_edit_binary_files")
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if ctx.Repo.IsWriter() && ctx.Repo.IsViewBranch {
 | 
							if ctx.Repo.IsWriter() && ctx.Repo.IsViewBranch {
 | 
				
			||||||
			ctx.Data["FileDeleteLink"] = deleteLink + "/" + treename
 | 
								ctx.Data["FileDeleteLink"] = deleteLink + "/" + treename
 | 
				
			||||||
			ctx.Data["FileDeleteLinkTooltip"] = ctx.Tr("repo.delete_this_file")
 | 
								ctx.Data["FileDeleteLinkTooltip"] = ctx.Tr("repo.delete_this_file")
 | 
				
			||||||
@@ -178,7 +180,7 @@ func Home(ctx *context.Context) {
 | 
				
			|||||||
				ctx.Data["FileDeleteLinkTooltip"] = ctx.Tr("repo.must_be_writer")
 | 
									ctx.Data["FileDeleteLinkTooltip"] = ctx.Tr("repo.must_be_writer")
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		}
 | 
					
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		// Directory and file list.
 | 
							// Directory and file list.
 | 
				
			||||||
		tree, err := ctx.Repo.Commit.SubTree(treename)
 | 
							tree, err := ctx.Repo.Commit.SubTree(treename)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -71,9 +71,9 @@
 | 
				
			|||||||
					{{if not $file.IsSubmodule}}
 | 
										{{if not $file.IsSubmodule}}
 | 
				
			||||||
						<div class="ui right">
 | 
											<div class="ui right">
 | 
				
			||||||
							{{if $file.IsDeleted}}
 | 
												{{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}}
 | 
												{{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}}
 | 
												{{end}}
 | 
				
			||||||
						</div>
 | 
											</div>
 | 
				
			||||||
					{{end}}
 | 
										{{end}}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,11 +2,10 @@
 | 
				
			|||||||
<div class="repository file edit">
 | 
					<div class="repository file edit">
 | 
				
			||||||
	{{template "repo/header" .}}
 | 
						{{template "repo/header" .}}
 | 
				
			||||||
	<div class="ui container">
 | 
						<div class="ui container">
 | 
				
			||||||
		{{.branchName}}
 | 
					 | 
				
			||||||
		{{template "base/alert" .}}
 | 
							{{template "base/alert" .}}
 | 
				
			||||||
		<form class="ui edit form" action="{{EscapePound $.Link}}" method="post">
 | 
							<form class="ui edit form" action="{{EscapePound $.Link}}" method="post">
 | 
				
			||||||
			{{.CsrfTokenHtml}}
 | 
								{{.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="ui secondary menu">
 | 
				
			||||||
				<div class="item fitted" style="width:100%;">
 | 
									<div class="item fitted" style="width:100%;">
 | 
				
			||||||
					<div class="ui breadcrumb field{{if .Err_Filename}} error{{end}}">
 | 
										<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">
 | 
									<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="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="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>
 | 
				
			||||||
				<div class="ui bottom attached active tab segment" data-tab="write">
 | 
									<div class="ui bottom attached active tab segment" data-tab="write">
 | 
				
			||||||
					<textarea id="edit_area" name="content" data-id="repo-{{.Repository.Name}}-{{.TreeName}}"
 | 
										<textarea id="edit_area" name="content" data-id="repo-{{.Repository.Name}}-{{.TreeName}}"
 | 
				
			||||||
@@ -53,26 +52,26 @@
 | 
				
			|||||||
				<div class="commit-form">
 | 
									<div class="commit-form">
 | 
				
			||||||
					<h3>{{.i18n.Tr "repo.commit_changes"}}</h3>
 | 
										<h3>{{.i18n.Tr "repo.commit_changes"}}</h3>
 | 
				
			||||||
					<div class="field">
 | 
										<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>
 | 
				
			||||||
					<div class="field">
 | 
										<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>
 | 
				
			||||||
					<div class="quick-pull-choice js-quick-pull-choice">
 | 
										<div class="quick-pull-choice js-quick-pull-choice">
 | 
				
			||||||
						<dl class="form-group">
 | 
											<dl class="form-group">
 | 
				
			||||||
							<dd>
 | 
												<dd>
 | 
				
			||||||
						 		<div class="form-checkbox">
 | 
											 		<div class="form-checkbox">
 | 
				
			||||||
									<label>
 | 
														<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>
 | 
															<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>
 | 
														</label>
 | 
				
			||||||
								</div>
 | 
													</div>
 | 
				
			||||||
								<div class="form-checkbox">
 | 
													<div class="form-checkbox">
 | 
				
			||||||
									<label>
 | 
														<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>
 | 
															<i class="octicon octicon-git-pull-request" height="16" width="12"></i>
 | 
				
			||||||
										{{.CreateNewBranch | Safe}}
 | 
															{{.i18n.Tr "repo.editor.create_new_branch" | Safe}}
 | 
				
			||||||
									</label>
 | 
														</label>
 | 
				
			||||||
								</div>
 | 
													</div>
 | 
				
			||||||
							</dd>
 | 
												</dd>
 | 
				
			||||||
@@ -80,7 +79,7 @@
 | 
				
			|||||||
						<div class="quick-pull-branch-name">
 | 
											<div class="quick-pull-branch-name">
 | 
				
			||||||
							<div class="new-branch-name-input{{if .Err_Branchname}} error{{end}}">
 | 
												<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>
 | 
													<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>
 | 
													<span class="text-muted js-quick-pull-normalization-info"></span>
 | 
				
			||||||
							</div>
 | 
												</div>
 | 
				
			||||||
						</div>
 | 
											</div>
 | 
				
			||||||
		Reference in New Issue
	
	Block a user