diff --git a/models/repo.go b/models/repo.go index ac3443f89..7945cb309 100644 --- a/models/repo.go +++ b/models/repo.go @@ -2810,3 +2810,19 @@ func (repo *Repository) GetOriginalURLHostname() string { return u.Host } + +// GetTreePathLock returns LSF lock for the treePath +func (repo *Repository) GetTreePathLock(treePath string) (*LFSLock, error) { + if setting.LFS.StartServer { + locks, err := GetLFSLockByRepoID(repo.ID) + if err != nil { + return nil, err + } + for _, lock := range locks { + if lock.Path == treePath { + return lock, nil + } + } + } + return nil, nil +} diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 4210ed121..4d1af69db 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -703,6 +703,7 @@ editor.preview_changes = Preview Changes editor.cannot_edit_lfs_files = LFS files cannot be edited in the web interface. editor.cannot_edit_non_text_files = Binary files cannot be edited in the web interface. editor.edit_this_file = Edit File +editor.this_file_locked = File is locked editor.must_be_on_a_branch = You must be on a branch to make or propose changes to this file. editor.fork_before_edit = You must fork this repository to make or propose changes to this file. editor.delete_this_file = Delete File diff --git a/routers/repo/blame.go b/routers/repo/blame.go index 5578942a9..f5a2a548e 100644 --- a/routers/repo/blame.go +++ b/routers/repo/blame.go @@ -119,8 +119,19 @@ func RefBlame(ctx *context.Context) { ctx.Data["IsBlame"] = true if ctx.Repo.CanEnableEditor() { - ctx.Data["CanDeleteFile"] = true - ctx.Data["DeleteFileTooltip"] = ctx.Tr("repo.editor.delete_this_file") + // Check LFS Lock + lfsLock, err := ctx.Repo.Repository.GetTreePathLock(ctx.Repo.TreePath) + if err != nil { + ctx.ServerError("GetTreePathLock", err) + return + } + if lfsLock != nil && lfsLock.OwnerID != ctx.User.ID { + ctx.Data["CanDeleteFile"] = false + ctx.Data["DeleteFileTooltip"] = ctx.Tr("repo.editor.this_file_locked") + } else { + ctx.Data["CanDeleteFile"] = true + ctx.Data["DeleteFileTooltip"] = ctx.Tr("repo.editor.delete_this_file") + } } else if !ctx.Repo.IsViewBranch { ctx.Data["DeleteFileTooltip"] = ctx.Tr("repo.editor.must_be_on_a_branch") } else if !ctx.Repo.CanWrite(models.UnitTypeCode) { diff --git a/routers/repo/view.go b/routers/repo/view.go index da6d426de..8730523d8 100644 --- a/routers/repo/view.go +++ b/routers/repo/view.go @@ -265,6 +265,17 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st ctx.Data["RawFileLink"] = fmt.Sprintf("%s%s.git/info/lfs/objects/%s/%s", setting.AppURL, ctx.Repo.Repository.FullName(), meta.Oid, filenameBase64) } } + // Check LFS Lock + lfsLock, err := ctx.Repo.Repository.GetTreePathLock(ctx.Repo.TreePath) + ctx.Data["LFSLock"] = lfsLock + if err != nil { + ctx.ServerError("GetTreePathLock", err) + return + } + if lfsLock != nil { + ctx.Data["LFSLockOwner"] = lfsLock.Owner.DisplayName() + ctx.Data["LFSLockHint"] = ctx.Tr("repo.editor.this_file_locked") + } // Assume file is not editable first. if isLFSFile { @@ -334,8 +345,13 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st } if !isLFSFile { if ctx.Repo.CanEnableEditor() { - ctx.Data["CanEditFile"] = true - ctx.Data["EditFileTooltip"] = ctx.Tr("repo.editor.edit_this_file") + if lfsLock != nil && lfsLock.OwnerID != ctx.User.ID { + ctx.Data["CanEditFile"] = false + ctx.Data["EditFileTooltip"] = ctx.Tr("repo.editor.this_file_locked") + } else { + ctx.Data["CanEditFile"] = true + ctx.Data["EditFileTooltip"] = ctx.Tr("repo.editor.edit_this_file") + } } else if !ctx.Repo.IsViewBranch { ctx.Data["EditFileTooltip"] = ctx.Tr("repo.editor.must_be_on_a_branch") } else if !ctx.Repo.CanWrite(models.UnitTypeCode) { @@ -368,8 +384,13 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st } if ctx.Repo.CanEnableEditor() { - ctx.Data["CanDeleteFile"] = true - ctx.Data["DeleteFileTooltip"] = ctx.Tr("repo.editor.delete_this_file") + if lfsLock != nil && lfsLock.OwnerID != ctx.User.ID { + ctx.Data["CanDeleteFile"] = false + ctx.Data["DeleteFileTooltip"] = ctx.Tr("repo.editor.this_file_locked") + } else { + ctx.Data["CanDeleteFile"] = true + ctx.Data["DeleteFileTooltip"] = ctx.Tr("repo.editor.delete_this_file") + } } else if !ctx.Repo.IsViewBranch { ctx.Data["DeleteFileTooltip"] = ctx.Tr("repo.editor.must_be_on_a_branch") } else if !ctx.Repo.CanWrite(models.UnitTypeCode) { diff --git a/templates/repo/view_file.tmpl b/templates/repo/view_file.tmpl index 616ca2565..f95076272 100644 --- a/templates/repo/view_file.tmpl +++ b/templates/repo/view_file.tmpl @@ -16,6 +16,12 @@ {{FileSize .FileSize}}{{if .IsLFSFile}} ({{.i18n.Tr "repo.stored_lfs"}}){{end}} {{end}} + {{if .LFSLock}} +