mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 16:40:24 +08:00 
			
		
		
		
	Adds side-by-side diff for images (#6784)
* Adds side-by-side diff for images Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com> * Explain blank imports Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com> * Use complete word for width and height labels on image compare Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com> * Update index.css from master Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com> * Moves ImageInfo to git commit file Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com> * Assign ImageInfo function for template and sets correct target for BeforeSourcePath Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com> * Adds missing comment Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com> * Return error if ImageInfo failed Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com> * Avoid template panic when ImageInfo failed for some reason Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com> * Show file size on image diff Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com> * Removes unused helper function Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com> * Reverts copyright year change Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com> * Close file reader Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com> * Update commit.go Sets correct data key * Moves reader.Close() up a few lines * Updates index.css * Updates CSS file Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com> * Transfers adjustments for image compare to compare.go file Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com> * Adjusts variable name Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com> * Apply lesshint recommendations Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com> * Do not show old image on image compare if it is not in index of base commit Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com> * Change file size text Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com>
This commit is contained in:
		
				
					committed by
					
						
						Lunny Xiao
					
				
			
			
				
	
			
			
			
						parent
						
							a5f87feefd
						
					
				
				
					commit
					a37236314c
				
			@@ -10,6 +10,11 @@ import (
 | 
				
			|||||||
	"bytes"
 | 
						"bytes"
 | 
				
			||||||
	"container/list"
 | 
						"container/list"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
 | 
						"image"
 | 
				
			||||||
 | 
						"image/color"
 | 
				
			||||||
 | 
						_ "image/gif"  // for processing gif images
 | 
				
			||||||
 | 
						_ "image/jpeg" // for processing jpeg images
 | 
				
			||||||
 | 
						_ "image/png"  // for processing png images
 | 
				
			||||||
	"io"
 | 
						"io"
 | 
				
			||||||
	"net/http"
 | 
						"net/http"
 | 
				
			||||||
	"strconv"
 | 
						"strconv"
 | 
				
			||||||
@@ -158,6 +163,43 @@ func (c *Commit) IsImageFile(name string) bool {
 | 
				
			|||||||
	return isImage
 | 
						return isImage
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ImageMetaData represents metadata of an image file
 | 
				
			||||||
 | 
					type ImageMetaData struct {
 | 
				
			||||||
 | 
						ColorModel color.Model
 | 
				
			||||||
 | 
						Width      int
 | 
				
			||||||
 | 
						Height     int
 | 
				
			||||||
 | 
						ByteSize   int64
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ImageInfo returns information about the dimensions of an image
 | 
				
			||||||
 | 
					func (c *Commit) ImageInfo(name string) (*ImageMetaData, error) {
 | 
				
			||||||
 | 
						if !c.IsImageFile(name) {
 | 
				
			||||||
 | 
							return nil, nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						blob, err := c.GetBlobByPath(name)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						reader, err := blob.DataAsync()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer reader.Close()
 | 
				
			||||||
 | 
						config, _, err := image.DecodeConfig(reader)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						metadata := ImageMetaData{
 | 
				
			||||||
 | 
							ColorModel: config.ColorModel,
 | 
				
			||||||
 | 
							Width:      config.Width,
 | 
				
			||||||
 | 
							Height:     config.Height,
 | 
				
			||||||
 | 
							ByteSize:   blob.Size(),
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return &metadata, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetCommitByPath return the commit of relative path object.
 | 
					// GetCommitByPath return the commit of relative path object.
 | 
				
			||||||
func (c *Commit) GetCommitByPath(relpath string) (*Commit, error) {
 | 
					func (c *Commit) GetCommitByPath(relpath string) (*Commit, error) {
 | 
				
			||||||
	return c.repo.getCommitByPathWithID(c.ID, relpath)
 | 
						return c.repo.getCommitByPathWithID(c.ID, relpath)
 | 
				
			||||||
@@ -310,6 +352,13 @@ func (c *Commit) FileChangedSinceCommit(filename, pastCommit string) (bool, erro
 | 
				
			|||||||
	return c.repo.FileChangedBetweenCommits(filename, pastCommit, c.ID.String())
 | 
						return c.repo.FileChangedBetweenCommits(filename, pastCommit, c.ID.String())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// HasFile returns true if the file given exists on this commit
 | 
				
			||||||
 | 
					// This does only mean it's there - it does not mean the file was changed during the commit.
 | 
				
			||||||
 | 
					func (c *Commit) HasFile(filename string) (bool, error) {
 | 
				
			||||||
 | 
						result, err := c.repo.LsFiles(filename)
 | 
				
			||||||
 | 
						return result[0] == filename, err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetSubModules get all the sub modules of current revision git tree
 | 
					// GetSubModules get all the sub modules of current revision git tree
 | 
				
			||||||
func (c *Commit) GetSubModules() (*ObjectCache, error) {
 | 
					func (c *Commit) GetSubModules() (*ObjectCache, error) {
 | 
				
			||||||
	if c.submoduleCache != nil {
 | 
						if c.submoduleCache != nil {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1358,6 +1358,11 @@ diff.whitespace_ignore_at_eol = Ignore changes in whitespace at EOL
 | 
				
			|||||||
diff.stats_desc = <strong> %d changed files</strong> with <strong>%d additions</strong> and <strong>%d deletions</strong>
 | 
					diff.stats_desc = <strong> %d changed files</strong> with <strong>%d additions</strong> and <strong>%d deletions</strong>
 | 
				
			||||||
diff.bin = BIN
 | 
					diff.bin = BIN
 | 
				
			||||||
diff.view_file = View File
 | 
					diff.view_file = View File
 | 
				
			||||||
 | 
					diff.file_before = Before
 | 
				
			||||||
 | 
					diff.file_after = After
 | 
				
			||||||
 | 
					diff.file_image_width = Width
 | 
				
			||||||
 | 
					diff.file_image_height = Height
 | 
				
			||||||
 | 
					diff.file_byte_size = Size
 | 
				
			||||||
diff.file_suppressed = File diff suppressed because it is too large
 | 
					diff.file_suppressed = File diff suppressed because it is too large
 | 
				
			||||||
diff.too_many_files = Some files were not shown because too many files changed in this diff
 | 
					diff.too_many_files = Some files were not shown because too many files changed in this diff
 | 
				
			||||||
diff.comment.placeholder = Leave a comment
 | 
					diff.comment.placeholder = Leave a comment
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -140,6 +140,16 @@ a{cursor:pointer}
 | 
				
			|||||||
.ui .migrate{color:#888!important;opacity:.5}
 | 
					.ui .migrate{color:#888!important;opacity:.5}
 | 
				
			||||||
.ui .migrate a{color:#444!important}
 | 
					.ui .migrate a{color:#444!important}
 | 
				
			||||||
.ui .migrate a:hover{color:#000!important}
 | 
					.ui .migrate a:hover{color:#000!important}
 | 
				
			||||||
 | 
					.ui .border{border:1px solid}
 | 
				
			||||||
 | 
					.ui .border.red{border-color:#d95c5c!important}
 | 
				
			||||||
 | 
					.ui .border.blue{border-color:#428bca!important}
 | 
				
			||||||
 | 
					.ui .border.black{border-color:#444}
 | 
				
			||||||
 | 
					.ui .border.grey{border-color:#767676!important}
 | 
				
			||||||
 | 
					.ui .border.light.grey{border-color:#888!important}
 | 
				
			||||||
 | 
					.ui .border.green{border-color:#6cc644!important}
 | 
				
			||||||
 | 
					.ui .border.purple{border-color:#6e5494!important}
 | 
				
			||||||
 | 
					.ui .border.yellow{border-color:#fbbd08!important}
 | 
				
			||||||
 | 
					.ui .border.gold{border-color:#a1882b!important}
 | 
				
			||||||
.ui .branch-tag-choice{line-height:20px}
 | 
					.ui .branch-tag-choice{line-height:20px}
 | 
				
			||||||
@media only screen and (max-width:767px){.ui.pagination.menu .item.navigation span.navigation_label,.ui.pagination.menu .item:not(.active):not(.navigation){display:none}
 | 
					@media only screen and (max-width:767px){.ui.pagination.menu .item.navigation span.navigation_label,.ui.pagination.menu .item:not(.active):not(.navigation){display:none}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -670,6 +680,7 @@ footer .ui.left,footer .ui.right{line-height:40px}
 | 
				
			|||||||
.repository .diff-file-box .code-diff td{padding:0 0 0 10px!important;border-top:0}
 | 
					.repository .diff-file-box .code-diff td{padding:0 0 0 10px!important;border-top:0}
 | 
				
			||||||
.repository .diff-file-box .code-diff .lines-num{border-color:#d4d4d5;border-right-width:1px;border-right-style:solid;padding:0 5px!important}
 | 
					.repository .diff-file-box .code-diff .lines-num{border-color:#d4d4d5;border-right-width:1px;border-right-style:solid;padding:0 5px!important}
 | 
				
			||||||
.repository .diff-file-box .code-diff tbody tr td.halfwidth{width:49%}
 | 
					.repository .diff-file-box .code-diff tbody tr td.halfwidth{width:49%}
 | 
				
			||||||
 | 
					.repository .diff-file-box .code-diff tbody tr td.center{text-align:center}
 | 
				
			||||||
.repository .diff-file-box .code-diff tbody tr .removed-code{background-color:#f99}
 | 
					.repository .diff-file-box .code-diff tbody tr .removed-code{background-color:#f99}
 | 
				
			||||||
.repository .diff-file-box .code-diff tbody tr .added-code{background-color:#9f9}
 | 
					.repository .diff-file-box .code-diff tbody tr .added-code{background-color:#9f9}
 | 
				
			||||||
.repository .diff-file-box .code-diff tbody tr [data-line-num]::before{content:attr(data-line-num);text-align:right}
 | 
					.repository .diff-file-box .code-diff tbody tr [data-line-num]::before{content:attr(data-line-num);text-align:right}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -600,6 +600,45 @@ code,
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .border {
 | 
				
			||||||
 | 
					        border: 1px solid;
 | 
				
			||||||
 | 
					        &.red {
 | 
				
			||||||
 | 
					            border-color: #d95c5c !important;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        &.blue {
 | 
				
			||||||
 | 
					            border-color: #428bca !important;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        &.black {
 | 
				
			||||||
 | 
					            border-color: #444444;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        &.grey {
 | 
				
			||||||
 | 
					            border-color: #767676 !important;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        &.light.grey {
 | 
				
			||||||
 | 
					            border-color: #888888 !important;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        &.green {
 | 
				
			||||||
 | 
					            border-color: #6cc644 !important;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        &.purple {
 | 
				
			||||||
 | 
					            border-color: #6e5494 !important;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        &.yellow {
 | 
				
			||||||
 | 
					            border-color: #fbbd08 !important;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        &.gold {
 | 
				
			||||||
 | 
					            border-color: #a1882b !important;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    .branch-tag-choice {
 | 
					    .branch-tag-choice {
 | 
				
			||||||
        line-height: 20px;
 | 
					        line-height: 20px;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1364,6 +1364,10 @@
 | 
				
			|||||||
                        width: 49%;
 | 
					                        width: 49%;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    td.center {
 | 
				
			||||||
 | 
					                        text-align: center;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    .removed-code {
 | 
					                    .removed-code {
 | 
				
			||||||
                        background-color: #ff9999;
 | 
					                        background-color: #ff9999;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -240,6 +240,23 @@ func Diff(ctx *context.Context) {
 | 
				
			|||||||
	ctx.Data["Username"] = userName
 | 
						ctx.Data["Username"] = userName
 | 
				
			||||||
	ctx.Data["Reponame"] = repoName
 | 
						ctx.Data["Reponame"] = repoName
 | 
				
			||||||
	ctx.Data["IsImageFile"] = commit.IsImageFile
 | 
						ctx.Data["IsImageFile"] = commit.IsImageFile
 | 
				
			||||||
 | 
						ctx.Data["ImageInfo"] = func(name string) *git.ImageMetaData {
 | 
				
			||||||
 | 
							result, err := commit.ImageInfo(name)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								log.Error("ImageInfo failed: %v", err)
 | 
				
			||||||
 | 
								return nil
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return result
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ctx.Data["ImageInfoBase"] = ctx.Data["ImageInfo"]
 | 
				
			||||||
 | 
						if commit.ParentCount() > 0 {
 | 
				
			||||||
 | 
							parentCommit, err := ctx.Repo.GitRepo.GetCommit(parents[0])
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								ctx.NotFound("GetParentCommit", err)
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							ctx.Data["ImageInfo"] = parentCommit.ImageInfo
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	ctx.Data["Title"] = commit.Summary() + " · " + base.ShortSha(commitID)
 | 
						ctx.Data["Title"] = commit.Summary() + " · " + base.ShortSha(commitID)
 | 
				
			||||||
	ctx.Data["Commit"] = commit
 | 
						ctx.Data["Commit"] = commit
 | 
				
			||||||
	ctx.Data["Verification"] = models.ParseCommitWithSignature(commit)
 | 
						ctx.Data["Verification"] = models.ParseCommitWithSignature(commit)
 | 
				
			||||||
@@ -248,6 +265,7 @@ func Diff(ctx *context.Context) {
 | 
				
			|||||||
	ctx.Data["Parents"] = parents
 | 
						ctx.Data["Parents"] = parents
 | 
				
			||||||
	ctx.Data["DiffNotAvailable"] = diff.NumFiles() == 0
 | 
						ctx.Data["DiffNotAvailable"] = diff.NumFiles() == 0
 | 
				
			||||||
	ctx.Data["SourcePath"] = setting.AppSubURL + "/" + path.Join(userName, repoName, "src", "commit", commitID)
 | 
						ctx.Data["SourcePath"] = setting.AppSubURL + "/" + path.Join(userName, repoName, "src", "commit", commitID)
 | 
				
			||||||
 | 
						ctx.Data["RawPath"] = setting.AppSubURL + "/" + path.Join(userName, repoName, "raw", "commit", commitID)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	note := &git.Note{}
 | 
						note := &git.Note{}
 | 
				
			||||||
	err = git.GetNote(ctx.Repo.GitRepo, commitID, note)
 | 
						err = git.GetNote(ctx.Repo.GitRepo, commitID, note)
 | 
				
			||||||
@@ -259,8 +277,8 @@ func Diff(ctx *context.Context) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	if commit.ParentCount() > 0 {
 | 
						if commit.ParentCount() > 0 {
 | 
				
			||||||
		ctx.Data["BeforeSourcePath"] = setting.AppSubURL + "/" + path.Join(userName, repoName, "src", "commit", parents[0])
 | 
							ctx.Data["BeforeSourcePath"] = setting.AppSubURL + "/" + path.Join(userName, repoName, "src", "commit", parents[0])
 | 
				
			||||||
 | 
							ctx.Data["BeforeRawPath"] = setting.AppSubURL + "/" + path.Join(userName, repoName, "raw", "commit", parents[0])
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	ctx.Data["RawPath"] = setting.AppSubURL + "/" + path.Join(userName, repoName, "raw", "commit", commitID)
 | 
					 | 
				
			||||||
	ctx.Data["BranchName"], err = commit.GetBranchName()
 | 
						ctx.Data["BranchName"], err = commit.GetBranchName()
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		ctx.ServerError("commit.GetBranchName", err)
 | 
							ctx.ServerError("commit.GetBranchName", err)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -247,6 +247,26 @@ func PrepareCompareDiff(
 | 
				
			|||||||
		return false
 | 
							return false
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						baseGitRepo := ctx.Repo.GitRepo
 | 
				
			||||||
 | 
						baseCommitID := baseBranch
 | 
				
			||||||
 | 
						if ctx.Data["BaseIsCommit"] == false {
 | 
				
			||||||
 | 
							if ctx.Data["BaseIsTag"] == true {
 | 
				
			||||||
 | 
								baseCommitID, err = baseGitRepo.GetTagCommitID(baseBranch)
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								baseCommitID, err = baseGitRepo.GetBranchCommitID(baseBranch)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								ctx.ServerError("GetRefCommitID", err)
 | 
				
			||||||
 | 
								return false
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						baseCommit, err := baseGitRepo.GetCommit(baseCommitID)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							ctx.ServerError("GetCommit", err)
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	compareInfo.Commits = models.ValidateCommitsWithEmails(compareInfo.Commits)
 | 
						compareInfo.Commits = models.ValidateCommitsWithEmails(compareInfo.Commits)
 | 
				
			||||||
	compareInfo.Commits = models.ParseCommitsWithSignature(compareInfo.Commits)
 | 
						compareInfo.Commits = models.ParseCommitsWithSignature(compareInfo.Commits)
 | 
				
			||||||
	compareInfo.Commits = models.ParseCommitsWithStatus(compareInfo.Commits, headRepo)
 | 
						compareInfo.Commits = models.ParseCommitsWithStatus(compareInfo.Commits, headRepo)
 | 
				
			||||||
@@ -272,11 +292,43 @@ func PrepareCompareDiff(
 | 
				
			|||||||
	ctx.Data["Username"] = headUser.Name
 | 
						ctx.Data["Username"] = headUser.Name
 | 
				
			||||||
	ctx.Data["Reponame"] = headRepo.Name
 | 
						ctx.Data["Reponame"] = headRepo.Name
 | 
				
			||||||
	ctx.Data["IsImageFile"] = headCommit.IsImageFile
 | 
						ctx.Data["IsImageFile"] = headCommit.IsImageFile
 | 
				
			||||||
 | 
						ctx.Data["ImageInfo"] = func(name string) *git.ImageMetaData {
 | 
				
			||||||
 | 
							result, err := headCommit.ImageInfo(name)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								log.Error("ImageInfo failed: %v", err)
 | 
				
			||||||
 | 
								return nil
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return result
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ctx.Data["FileExistsInBaseCommit"] = func(filename string) bool {
 | 
				
			||||||
 | 
							result, err := baseCommit.HasFile(filename)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								log.Error(
 | 
				
			||||||
 | 
									"Error while checking if file \"%s\" exists in base commit \"%s\" (repo: %s): %v",
 | 
				
			||||||
 | 
									filename,
 | 
				
			||||||
 | 
									baseCommit,
 | 
				
			||||||
 | 
									baseGitRepo.Path,
 | 
				
			||||||
 | 
									err)
 | 
				
			||||||
 | 
								return false
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return result
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ctx.Data["ImageInfoBase"] = func(name string) *git.ImageMetaData {
 | 
				
			||||||
 | 
							result, err := baseCommit.ImageInfo(name)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								log.Error("ImageInfo failed: %v", err)
 | 
				
			||||||
 | 
								return nil
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return result
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	headTarget := path.Join(headUser.Name, repo.Name)
 | 
						headTarget := path.Join(headUser.Name, repo.Name)
 | 
				
			||||||
 | 
						baseTarget := path.Join(ctx.Repo.Owner.Name, ctx.Repo.Repository.Name)
 | 
				
			||||||
	ctx.Data["SourcePath"] = setting.AppSubURL + "/" + path.Join(headTarget, "src", "commit", headCommitID)
 | 
						ctx.Data["SourcePath"] = setting.AppSubURL + "/" + path.Join(headTarget, "src", "commit", headCommitID)
 | 
				
			||||||
	ctx.Data["BeforeSourcePath"] = setting.AppSubURL + "/" + path.Join(headTarget, "src", "commit", compareInfo.MergeBase)
 | 
					 | 
				
			||||||
	ctx.Data["RawPath"] = setting.AppSubURL + "/" + path.Join(headTarget, "raw", "commit", headCommitID)
 | 
						ctx.Data["RawPath"] = setting.AppSubURL + "/" + path.Join(headTarget, "raw", "commit", headCommitID)
 | 
				
			||||||
 | 
						ctx.Data["BeforeSourcePath"] = setting.AppSubURL + "/" + path.Join(baseTarget, "src", "commit", baseCommitID)
 | 
				
			||||||
 | 
						ctx.Data["BeforeRawPath"] = setting.AppSubURL + "/" + path.Join(baseTarget, "raw", "commit", baseCommitID)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return false
 | 
						return false
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -535,6 +535,11 @@ func ViewPullFiles(ctx *context.Context) {
 | 
				
			|||||||
	ctx.Data["Diff"] = diff
 | 
						ctx.Data["Diff"] = diff
 | 
				
			||||||
	ctx.Data["DiffNotAvailable"] = diff.NumFiles() == 0
 | 
						ctx.Data["DiffNotAvailable"] = diff.NumFiles() == 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						baseCommit, err := ctx.Repo.GitRepo.GetCommit(startCommitID)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							ctx.ServerError("GetCommit", err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	commit, err := gitRepo.GetCommit(endCommitID)
 | 
						commit, err := gitRepo.GetCommit(endCommitID)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		ctx.ServerError("GetCommit", err)
 | 
							ctx.ServerError("GetCommit", err)
 | 
				
			||||||
@@ -542,9 +547,29 @@ func ViewPullFiles(ctx *context.Context) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ctx.Data["IsImageFile"] = commit.IsImageFile
 | 
						ctx.Data["IsImageFile"] = commit.IsImageFile
 | 
				
			||||||
 | 
						ctx.Data["ImageInfoBase"] = func(name string) *git.ImageMetaData {
 | 
				
			||||||
 | 
							result, err := baseCommit.ImageInfo(name)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								log.Error("ImageInfo failed: %v", err)
 | 
				
			||||||
 | 
								return nil
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return result
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ctx.Data["ImageInfo"] = func(name string) *git.ImageMetaData {
 | 
				
			||||||
 | 
							result, err := commit.ImageInfo(name)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								log.Error("ImageInfo failed: %v", err)
 | 
				
			||||||
 | 
								return nil
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return result
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						baseTarget := path.Join(ctx.Repo.Owner.Name, ctx.Repo.Repository.Name)
 | 
				
			||||||
	ctx.Data["SourcePath"] = setting.AppSubURL + "/" + path.Join(headTarget, "src", "commit", endCommitID)
 | 
						ctx.Data["SourcePath"] = setting.AppSubURL + "/" + path.Join(headTarget, "src", "commit", endCommitID)
 | 
				
			||||||
	ctx.Data["BeforeSourcePath"] = setting.AppSubURL + "/" + path.Join(headTarget, "src", "commit", startCommitID)
 | 
					 | 
				
			||||||
	ctx.Data["RawPath"] = setting.AppSubURL + "/" + path.Join(headTarget, "raw", "commit", endCommitID)
 | 
						ctx.Data["RawPath"] = setting.AppSubURL + "/" + path.Join(headTarget, "raw", "commit", endCommitID)
 | 
				
			||||||
 | 
						ctx.Data["BeforeSourcePath"] = setting.AppSubURL + "/" + path.Join(baseTarget, "src", "commit", startCommitID)
 | 
				
			||||||
 | 
						ctx.Data["BeforeRawPath"] = setting.AppSubURL + "/" + path.Join(baseTarget, "raw", "commit", startCommitID)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ctx.Data["RequireHighlightJS"] = true
 | 
						ctx.Data["RequireHighlightJS"] = true
 | 
				
			||||||
	ctx.Data["RequireTribute"] = true
 | 
						ctx.Data["RequireTribute"] = true
 | 
				
			||||||
	if ctx.Data["Assignees"], err = ctx.Repo.Repository.GetAssignees(); err != nil {
 | 
						if ctx.Data["Assignees"], err = ctx.Repo.Repository.GetAssignees(); err != nil {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -107,14 +107,12 @@
 | 
				
			|||||||
				<div class="ui attached unstackable table segment">
 | 
									<div class="ui attached unstackable table segment">
 | 
				
			||||||
					{{if ne $file.Type 4}}
 | 
										{{if ne $file.Type 4}}
 | 
				
			||||||
						{{$isImage := (call $.IsImageFile $file.Name)}}
 | 
											{{$isImage := (call $.IsImageFile $file.Name)}}
 | 
				
			||||||
						{{if and $isImage}}
 | 
											<div class="file-body file-code code-view code-diff {{if $.IsSplitStyle}}code-diff-split{{else}}code-diff-unified{{end}}">
 | 
				
			||||||
							<div class="center">
 | 
												<table>
 | 
				
			||||||
								<img src="{{$.RawPath}}/{{EscapePound .Name}}">
 | 
													<tbody>
 | 
				
			||||||
							</div>
 | 
														{{if $isImage}}
 | 
				
			||||||
						{{else}}
 | 
															{{template "repo/diff/image_diff" dict "file" . "root" $}}
 | 
				
			||||||
							<div class="file-body file-code code-view code-diff {{if $.IsSplitStyle}}code-diff-split{{else}}code-diff-unified{{end}}">
 | 
														{{else}}
 | 
				
			||||||
								<table>
 | 
					 | 
				
			||||||
									<tbody>
 | 
					 | 
				
			||||||
										{{if $.IsSplitStyle}}
 | 
															{{if $.IsSplitStyle}}
 | 
				
			||||||
											{{$highlightClass := $file.GetHighlightClass}}
 | 
																{{$highlightClass := $file.GetHighlightClass}}
 | 
				
			||||||
											{{range $j, $section := $file.Sections}}
 | 
																{{range $j, $section := $file.Sections}}
 | 
				
			||||||
@@ -164,10 +162,10 @@
 | 
				
			|||||||
										{{else}}
 | 
															{{else}}
 | 
				
			||||||
											{{template "repo/diff/section_unified" dict "file" . "root" $}}
 | 
																{{template "repo/diff/section_unified" dict "file" . "root" $}}
 | 
				
			||||||
										{{end}}
 | 
															{{end}}
 | 
				
			||||||
									</tbody>
 | 
														{{end}}
 | 
				
			||||||
								</table>
 | 
													</tbody>
 | 
				
			||||||
							</div>
 | 
												</table>
 | 
				
			||||||
						{{end}}
 | 
											</div>
 | 
				
			||||||
					{{end}}
 | 
										{{end}}
 | 
				
			||||||
				</div>
 | 
									</div>
 | 
				
			||||||
			</div>
 | 
								</div>
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										46
									
								
								templates/repo/diff/image_diff.tmpl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								templates/repo/diff/image_diff.tmpl
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,46 @@
 | 
				
			|||||||
 | 
					{{ $imagePathOld := printf "%s/%s" .root.BeforeRawPath (EscapePound .file.OldName)  }}
 | 
				
			||||||
 | 
					{{ $imagePathNew := printf "%s/%s" .root.RawPath (EscapePound .file.Name)  }}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<tr>
 | 
				
			||||||
 | 
					 	<th class="halfwidth center">
 | 
				
			||||||
 | 
					 		{{.root.i18n.Tr "repo.diff.file_before"}}
 | 
				
			||||||
 | 
					 	</th>
 | 
				
			||||||
 | 
					 	<th class="halfwidth center">
 | 
				
			||||||
 | 
					 		{{.root.i18n.Tr "repo.diff.file_after"}}
 | 
				
			||||||
 | 
					 	</th>
 | 
				
			||||||
 | 
					</tr>
 | 
				
			||||||
 | 
					<tr>
 | 
				
			||||||
 | 
					 	<td class="halfwidth center">
 | 
				
			||||||
 | 
					 	    {{ $oldImageExists := (call .root.FileExistsInBaseCommit .file.OldName) }}
 | 
				
			||||||
 | 
					 	    {{if $oldImageExists}}
 | 
				
			||||||
 | 
					            <a href="{{$imagePathOld}}" target="_blank">
 | 
				
			||||||
 | 
					                <img src="{{$imagePathOld}}" class="border red" />
 | 
				
			||||||
 | 
					            </a>
 | 
				
			||||||
 | 
					 	    {{end}}
 | 
				
			||||||
 | 
					 	</td>
 | 
				
			||||||
 | 
					 	<td class="halfwidth center">
 | 
				
			||||||
 | 
					 		<a href="{{$imagePathNew}}" target="_blank">
 | 
				
			||||||
 | 
					 			<img src="{{$imagePathNew}}" class="border green" />
 | 
				
			||||||
 | 
					 		</a>
 | 
				
			||||||
 | 
					 	</td>
 | 
				
			||||||
 | 
					</tr>
 | 
				
			||||||
 | 
					{{ $imageInfoBase := (call .root.ImageInfoBase .file.OldName) }}
 | 
				
			||||||
 | 
					{{ $imageInfoHead := (call .root.ImageInfo .file.Name) }}
 | 
				
			||||||
 | 
					{{if and $imageInfoBase $imageInfoHead }}
 | 
				
			||||||
 | 
					<tr>
 | 
				
			||||||
 | 
					 	<td class="halfwidth center">
 | 
				
			||||||
 | 
					 		{{.root.i18n.Tr "repo.diff.file_image_width"}}: <span class="text {{if not (eq $imageInfoBase.Width $imageInfoHead.Width)}}red{{end}}">{{$imageInfoBase.Width}}</span>
 | 
				
			||||||
 | 
					 		 | 
 | 
				
			||||||
 | 
					 	    {{.root.i18n.Tr "repo.diff.file_image_height"}}: <span class="text {{if not (eq $imageInfoBase.Height $imageInfoHead.Height)}}red{{end}}">{{$imageInfoBase.Height}}</span>
 | 
				
			||||||
 | 
					 		 | 
 | 
				
			||||||
 | 
					 	    {{.root.i18n.Tr "repo.diff.file_byte_size"}}: <span class="text {{if not (eq $imageInfoBase.ByteSize $imageInfoHead.ByteSize)}}red{{end}}">{{FileSize $imageInfoBase.ByteSize}}</span>
 | 
				
			||||||
 | 
					 	</td>
 | 
				
			||||||
 | 
					 	<td class="halfwidth center">
 | 
				
			||||||
 | 
					 		{{.root.i18n.Tr "repo.diff.file_image_width"}}: <span class="text {{if not (eq $imageInfoBase.Width $imageInfoHead.Width)}}green{{end}}">{{$imageInfoHead.Width}}</span>
 | 
				
			||||||
 | 
					 		 | 
 | 
				
			||||||
 | 
					 	    {{.root.i18n.Tr "repo.diff.file_image_height"}}: <span class="text {{if not (eq $imageInfoBase.Height $imageInfoHead.Height)}}green{{end}}">{{$imageInfoHead.Height}}</span>
 | 
				
			||||||
 | 
					 		 | 
 | 
				
			||||||
 | 
					 	    {{.root.i18n.Tr "repo.diff.file_byte_size"}}: <span class="text {{if not (eq $imageInfoBase.ByteSize $imageInfoHead.ByteSize)}}green{{end}}">{{FileSize $imageInfoHead.ByteSize}}</span>
 | 
				
			||||||
 | 
					 	</td>
 | 
				
			||||||
 | 
					 </tr>
 | 
				
			||||||
 | 
					{{end}}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user