Be more strict with git arguments (#7715)

* Be more strict with git arguments
* fix-up commit test
* use bindings for branch name
This commit is contained in:
zeripath 2019-08-05 21:39:39 +01:00 committed by GitHub
parent 1d8915ad5d
commit 7ad67109d7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 41 additions and 20 deletions

View file

@ -169,6 +169,7 @@ func AddChanges(repoPath string, all bool, files ...string) error {
if all { if all {
cmd.AddArguments("--all") cmd.AddArguments("--all")
} }
cmd.AddArguments("--")
_, err := cmd.AddArguments(files...).RunInDir(repoPath) _, err := cmd.AddArguments(files...).RunInDir(repoPath)
return err return err
} }
@ -304,6 +305,7 @@ func (c *Commit) GetFilesChangedSinceCommit(pastCommit string) ([]string, error)
} }
// FileChangedSinceCommit Returns true if the file given has changed since the the past commit // FileChangedSinceCommit Returns true if the file given has changed since the the past commit
// YOU MUST ENSURE THAT pastCommit is a valid commit ID.
func (c *Commit) FileChangedSinceCommit(filename, pastCommit string) (bool, error) { func (c *Commit) FileChangedSinceCommit(filename, pastCommit string) (bool, error) {
return c.repo.FileChangedBetweenCommits(filename, pastCommit, c.ID.String()) return c.repo.FileChangedBetweenCommits(filename, pastCommit, c.ID.String())
} }

View file

@ -187,8 +187,7 @@ func Pull(repoPath string, opts PullRemoteOptions) error {
if opts.All { if opts.All {
cmd.AddArguments("--all") cmd.AddArguments("--all")
} else { } else {
cmd.AddArguments(opts.Remote) cmd.AddArguments("--", opts.Remote, opts.Branch)
cmd.AddArguments(opts.Branch)
} }
if opts.Timeout <= 0 { if opts.Timeout <= 0 {
@ -213,7 +212,7 @@ func Push(repoPath string, opts PushOptions) error {
if opts.Force { if opts.Force {
cmd.AddArguments("-f") cmd.AddArguments("-f")
} }
cmd.AddArguments(opts.Remote, opts.Branch) cmd.AddArguments("--", opts.Remote, opts.Branch)
_, err := cmd.RunInDirWithEnv(repoPath, opts.Env) _, err := cmd.RunInDirWithEnv(repoPath, opts.Env)
return err return err
} }

View file

@ -135,7 +135,7 @@ func (repo *Repository) DeleteBranch(name string, opts DeleteBranchOptions) erro
cmd.AddArguments("-d") cmd.AddArguments("-d")
} }
cmd.AddArguments(name) cmd.AddArguments("--", name)
_, err := cmd.RunInDir(repo.Path) _, err := cmd.RunInDir(repo.Path)
return err return err

View file

@ -117,20 +117,26 @@ func (repo *Repository) getCommit(id SHA1) (*Commit, error) {
return commit, nil return commit, nil
} }
// GetCommit returns commit object of by ID string. // ConvertToSHA1 returns a Hash object from a potential ID string
func (repo *Repository) GetCommit(commitID string) (*Commit, error) { func (repo *Repository) ConvertToSHA1(commitID string) (SHA1, error) {
if len(commitID) != 40 { if len(commitID) != 40 {
var err error var err error
actualCommitID, err := NewCommand("rev-parse", commitID).RunInDir(repo.Path) actualCommitID, err := NewCommand("rev-parse", "--verify", commitID).RunInDir(repo.Path)
if err != nil { if err != nil {
if strings.Contains(err.Error(), "unknown revision or path") { if strings.Contains(err.Error(), "unknown revision or path") ||
return nil, ErrNotExist{commitID, ""} strings.Contains(err.Error(), "fatal: Needed a single revision") {
return SHA1{}, ErrNotExist{commitID, ""}
} }
return nil, err return SHA1{}, err
} }
commitID = actualCommitID commitID = actualCommitID
} }
id, err := NewIDFromString(commitID) return NewIDFromString(commitID)
}
// GetCommit returns commit object of by ID string.
func (repo *Repository) GetCommit(commitID string) (*Commit, error) {
id, err := repo.ConvertToSHA1(commitID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -243,6 +249,7 @@ func (repo *Repository) getFilesChanged(id1, id2 string) ([]string, error) {
} }
// FileChangedBetweenCommits Returns true if the file changed between commit IDs id1 and id2 // FileChangedBetweenCommits Returns true if the file changed between commit IDs id1 and id2
// You must ensure that id1 and id2 are valid commit ids.
func (repo *Repository) FileChangedBetweenCommits(filename, id1, id2 string) (bool, error) { func (repo *Repository) FileChangedBetweenCommits(filename, id1, id2 string) (bool, error) {
stdout, err := NewCommand("diff", "--name-only", "-z", id1, id2, "--", filename).RunInDirBytes(repo.Path) stdout, err := NewCommand("diff", "--name-only", "-z", id1, id2, "--", filename).RunInDirBytes(repo.Path)
if err != nil { if err != nil {

View file

@ -58,5 +58,5 @@ func TestGetCommitWithBadCommitID(t *testing.T) {
commit, err := bareRepo1.GetCommit("bad_branch") commit, err := bareRepo1.GetCommit("bad_branch")
assert.Nil(t, commit) assert.Nil(t, commit)
assert.Error(t, err) assert.Error(t, err)
assert.EqualError(t, err, "object does not exist [id: bad_branch, rel_path: ]") assert.True(t, IsErrNotExist(err))
} }

View file

@ -39,7 +39,7 @@ func (repo *Repository) GetMergeBase(tmpRemote string, base, head string) (strin
} }
} }
stdout, err := NewCommand("merge-base", base, head).RunInDir(repo.Path) stdout, err := NewCommand("merge-base", "--", base, head).RunInDir(repo.Path)
return strings.TrimSpace(stdout), base, err return strings.TrimSpace(stdout), base, err
} }

View file

@ -12,7 +12,7 @@ import (
// ReadTreeToIndex reads a treeish to the index // ReadTreeToIndex reads a treeish to the index
func (repo *Repository) ReadTreeToIndex(treeish string) error { func (repo *Repository) ReadTreeToIndex(treeish string) error {
if len(treeish) != 40 { if len(treeish) != 40 {
res, err := NewCommand("rev-parse", treeish).RunInDir(repo.Path) res, err := NewCommand("rev-parse", "--verify", treeish).RunInDir(repo.Path)
if err != nil { if err != nil {
return err return err
} }

View file

@ -29,13 +29,13 @@ func (repo *Repository) IsTagExist(name string) bool {
// CreateTag create one tag in the repository // CreateTag create one tag in the repository
func (repo *Repository) CreateTag(name, revision string) error { func (repo *Repository) CreateTag(name, revision string) error {
_, err := NewCommand("tag", name, revision).RunInDir(repo.Path) _, err := NewCommand("tag", "--", name, revision).RunInDir(repo.Path)
return err return err
} }
// CreateAnnotatedTag create one annotated tag in the repository // CreateAnnotatedTag create one annotated tag in the repository
func (repo *Repository) CreateAnnotatedTag(name, message, revision string) error { func (repo *Repository) CreateAnnotatedTag(name, message, revision string) error {
_, err := NewCommand("tag", "-a", "-m", message, name, revision).RunInDir(repo.Path) _, err := NewCommand("tag", "-a", "-m", message, "--", name, revision).RunInDir(repo.Path)
return err return err
} }
@ -153,7 +153,7 @@ func (repo *Repository) GetTagNameBySHA(sha string) (string, error) {
// GetTagID returns the object ID for a tag (annotated tags have both an object SHA AND a commit SHA) // GetTagID returns the object ID for a tag (annotated tags have both an object SHA AND a commit SHA)
func (repo *Repository) GetTagID(name string) (string, error) { func (repo *Repository) GetTagID(name string) (string, error) {
stdout, err := NewCommand("show-ref", name).RunInDir(repo.Path) stdout, err := NewCommand("show-ref", "--", name).RunInDir(repo.Path)
if err != nil { if err != nil {
return "", err return "", err
} }

View file

@ -26,7 +26,7 @@ func (repo *Repository) getTree(id SHA1) (*Tree, error) {
// GetTree find the tree object in the repository. // GetTree find the tree object in the repository.
func (repo *Repository) GetTree(idStr string) (*Tree, error) { func (repo *Repository) GetTree(idStr string) (*Tree, error) {
if len(idStr) != 40 { if len(idStr) != 40 {
res, err := NewCommand("rev-parse", idStr).RunInDir(repo.Path) res, err := NewCommand("rev-parse", "--verify", idStr).RunInDir(repo.Path)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View file

@ -92,6 +92,12 @@ func DeleteRepoFile(repo *models.Repository, doer *models.User, opts *DeleteRepo
// Assigned LastCommitID in opts if it hasn't been set // Assigned LastCommitID in opts if it hasn't been set
if opts.LastCommitID == "" { if opts.LastCommitID == "" {
opts.LastCommitID = commit.ID.String() opts.LastCommitID = commit.ID.String()
} else {
lastCommitID, err := t.gitRepo.ConvertToSHA1(opts.LastCommitID)
if err != nil {
return nil, fmt.Errorf("DeleteRepoFile: Invalid last commit ID: %v", err)
}
opts.LastCommitID = lastCommitID.String()
} }
// Get the files in the index // Get the files in the index

View file

@ -190,6 +190,13 @@ func CreateOrUpdateRepoFile(repo *models.Repository, doer *models.User, opts *Up
// Assigned LastCommitID in opts if it hasn't been set // Assigned LastCommitID in opts if it hasn't been set
if opts.LastCommitID == "" { if opts.LastCommitID == "" {
opts.LastCommitID = commit.ID.String() opts.LastCommitID = commit.ID.String()
} else {
lastCommitID, err := t.gitRepo.ConvertToSHA1(opts.LastCommitID)
if err != nil {
return nil, fmt.Errorf("DeleteRepoFile: Invalid last commit ID: %v", err)
}
opts.LastCommitID = lastCommitID.String()
} }
encoding := "UTF-8" encoding := "UTF-8"

View file

@ -10,9 +10,9 @@ type FileOptions struct {
// message (optional) for the commit of this file. if not supplied, a default message will be used // message (optional) for the commit of this file. if not supplied, a default message will be used
Message string `json:"message"` Message string `json:"message"`
// branch (optional) to base this file from. if not given, the default branch is used // branch (optional) to base this file from. if not given, the default branch is used
BranchName string `json:"branch"` BranchName string `json:"branch" binding:"GitRefName;MaxSize(100)"`
// new_branch (optional) will make a new branch from `branch` before creating the file // new_branch (optional) will make a new branch from `branch` before creating the file
NewBranchName string `json:"new_branch"` NewBranchName string `json:"new_branch" binding:"GitRefName;MaxSize(100)"`
// `author` and `committer` are optional (if only one is given, it will be used for the other, otherwise the authenticated user will be used) // `author` and `committer` are optional (if only one is given, it will be used for the other, otherwise the authenticated user will be used)
Author Identity `json:"author"` Author Identity `json:"author"`
Committer Identity `json:"committer"` Committer Identity `json:"committer"`