2019-05-11 18:29:17 +03:00
// Copyright 2019 The Gitea 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 git
import (
"bytes"
2021-09-09 23:13:36 +03:00
"context"
"os"
2021-11-17 23:37:00 +03:00
"path/filepath"
2019-05-11 18:29:17 +03:00
"strings"
2021-09-09 23:13:36 +03:00
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/util"
2019-05-11 18:29:17 +03:00
)
// ReadTreeToIndex reads a treeish to the index
2021-09-09 23:13:36 +03:00
func ( repo * Repository ) ReadTreeToIndex ( treeish string , indexFilename ... string ) error {
2019-05-11 18:29:17 +03:00
if len ( treeish ) != 40 {
2022-04-01 05:55:30 +03:00
res , _ , err := NewCommand ( repo . Ctx , "rev-parse" , "--verify" , treeish ) . RunStdString ( & RunOpts { Dir : repo . Path } )
2019-05-11 18:29:17 +03:00
if err != nil {
return err
}
if len ( res ) > 0 {
treeish = res [ : len ( res ) - 1 ]
}
}
id , err := NewIDFromString ( treeish )
if err != nil {
return err
}
2021-09-09 23:13:36 +03:00
return repo . readTreeToIndex ( id , indexFilename ... )
2019-05-11 18:29:17 +03:00
}
2021-09-09 23:13:36 +03:00
func ( repo * Repository ) readTreeToIndex ( id SHA1 , indexFilename ... string ) error {
var env [ ] string
if len ( indexFilename ) > 0 {
env = append ( os . Environ ( ) , "GIT_INDEX_FILE=" + indexFilename [ 0 ] )
}
2022-04-01 05:55:30 +03:00
_ , _ , err := NewCommand ( repo . Ctx , "read-tree" , id . String ( ) ) . RunStdString ( & RunOpts { Dir : repo . Path , Env : env } )
2019-05-11 18:29:17 +03:00
if err != nil {
return err
}
return nil
}
2021-09-09 23:13:36 +03:00
// ReadTreeToTemporaryIndex reads a treeish to a temporary index file
2021-11-17 23:37:00 +03:00
func ( repo * Repository ) ReadTreeToTemporaryIndex ( treeish string ) ( filename , tmpDir string , cancel context . CancelFunc , err error ) {
tmpDir , err = os . MkdirTemp ( "" , "index" )
2021-09-09 23:13:36 +03:00
if err != nil {
return
}
2021-11-17 23:37:00 +03:00
filename = filepath . Join ( tmpDir , ".tmp-index" )
2021-09-09 23:13:36 +03:00
cancel = func ( ) {
2021-11-17 23:37:00 +03:00
err := util . RemoveAll ( tmpDir )
2021-09-09 23:13:36 +03:00
if err != nil {
log . Error ( "failed to remove tmp index file: %v" , err )
}
}
err = repo . ReadTreeToIndex ( treeish , filename )
if err != nil {
defer cancel ( )
2021-11-17 23:37:00 +03:00
return "" , "" , func ( ) { } , err
2021-09-09 23:13:36 +03:00
}
return
}
2019-05-11 18:29:17 +03:00
// EmptyIndex empties the index
func ( repo * Repository ) EmptyIndex ( ) error {
2022-04-01 05:55:30 +03:00
_ , _ , err := NewCommand ( repo . Ctx , "read-tree" , "--empty" ) . RunStdString ( & RunOpts { Dir : repo . Path } )
2019-05-11 18:29:17 +03:00
return err
}
// LsFiles checks if the given filenames are in the index
func ( repo * Repository ) LsFiles ( filenames ... string ) ( [ ] string , error ) {
2022-02-06 22:01:47 +03:00
cmd := NewCommand ( repo . Ctx , "ls-files" , "-z" , "--" )
2019-05-11 18:29:17 +03:00
for _ , arg := range filenames {
if arg != "" {
cmd . AddArguments ( arg )
}
}
2022-04-01 05:55:30 +03:00
res , _ , err := cmd . RunStdBytes ( & RunOpts { Dir : repo . Path } )
2019-05-11 18:29:17 +03:00
if err != nil {
return nil , err
}
filelist := make ( [ ] string , 0 , len ( filenames ) )
for _ , line := range bytes . Split ( res , [ ] byte { '\000' } ) {
filelist = append ( filelist , string ( line ) )
}
return filelist , err
}
// RemoveFilesFromIndex removes given filenames from the index - it does not check whether they are present.
func ( repo * Repository ) RemoveFilesFromIndex ( filenames ... string ) error {
2022-02-06 22:01:47 +03:00
cmd := NewCommand ( repo . Ctx , "update-index" , "--remove" , "-z" , "--index-info" )
2019-05-11 18:29:17 +03:00
stdout := new ( bytes . Buffer )
stderr := new ( bytes . Buffer )
buffer := new ( bytes . Buffer )
for _ , file := range filenames {
if file != "" {
buffer . WriteString ( "0 0000000000000000000000000000000000000000\t" )
buffer . WriteString ( file )
buffer . WriteByte ( '\000' )
}
}
2022-04-01 05:55:30 +03:00
return cmd . Run ( & RunOpts {
Dir : repo . Path ,
Stdin : bytes . NewReader ( buffer . Bytes ( ) ) ,
Stdout : stdout ,
Stderr : stderr ,
2022-02-11 15:47:22 +03:00
} )
2019-05-11 18:29:17 +03:00
}
// AddObjectToIndex adds the provided object hash to the index at the provided filename
func ( repo * Repository ) AddObjectToIndex ( mode string , object SHA1 , filename string ) error {
2022-02-06 22:01:47 +03:00
cmd := NewCommand ( repo . Ctx , "update-index" , "--add" , "--replace" , "--cacheinfo" , mode , object . String ( ) , filename )
2022-04-01 05:55:30 +03:00
_ , _ , err := cmd . RunStdString ( & RunOpts { Dir : repo . Path } )
2019-05-11 18:29:17 +03:00
return err
}
// WriteTree writes the current index as a tree to the object db and returns its hash
func ( repo * Repository ) WriteTree ( ) ( * Tree , error ) {
2022-04-01 05:55:30 +03:00
stdout , _ , runErr := NewCommand ( repo . Ctx , "write-tree" ) . RunStdString ( & RunOpts { Dir : repo . Path } )
if runErr != nil {
return nil , runErr
2019-05-11 18:29:17 +03:00
}
2022-04-01 05:55:30 +03:00
id , err := NewIDFromString ( strings . TrimSpace ( stdout ) )
2019-05-11 18:29:17 +03:00
if err != nil {
return nil , err
}
return NewTree ( repo , id ) , nil
}