github.com/dolthub/dolt/go@v0.40.5-0.20240520175717-68db7794bea6/performance/utils/dolt_builder/git.go (about)

     1  // Copyright 2019-2022 Dolthub, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package dolt_builder
    16  
    17  import (
    18  	"context"
    19  	"fmt"
    20  	"os"
    21  	"strings"
    22  )
    23  
    24  // GitVersion runs git version
    25  func GitVersion(ctx context.Context) error {
    26  	checkGit := ExecCommand(ctx, "git", "version")
    27  	err := checkGit.Run()
    28  	if err != nil {
    29  		helpStr := "dolt-builder requires git.\n" +
    30  			"Make sure git is installed and on your PATH.\n" +
    31  			"git version: %v\n"
    32  		return fmt.Errorf(helpStr, err)
    33  	}
    34  	return nil
    35  }
    36  
    37  // GitCloneBare clones a repo
    38  func GitCloneBare(ctx context.Context, dir, url string) error {
    39  	clone := ExecCommand(ctx, "git", "clone", "--bare", url)
    40  	clone.Dir = dir
    41  	return clone.Run()
    42  }
    43  
    44  func CommitArg(c string) string {
    45  	if IsCommit(c) {
    46  		return c
    47  	}
    48  	if strings.HasPrefix(c, "v") {
    49  		return "tags/" + c
    50  	}
    51  	return "tags/v" + c
    52  }
    53  
    54  // GitCheckoutTree checks out `commit` from the Git repo at
    55  // `repoDir` into `toDir`. It does it without copying the entire
    56  // git repository. First we run `git read-tree` with a GIT_INDEX_FILE set to
    57  // `$toDir/.buildindex`, which gets an index for the commit fully populated
    58  // into the file. Then we run `git checkout-index -a` referencing the same
    59  // INDEX_FILE, which populates the current working directory (`toDir`) with the
    60  // contents of the index file.
    61  func GitCheckoutTree(ctx context.Context, repoDir string, toDir string, commit string) error {
    62  	env := os.Environ()
    63  	env = append(env, "GIT_DIR="+repoDir)
    64  	env = append(env, "GIT_INDEX_FILE=.buildindex")
    65  	env = append(env, "GIT_WORK_TREE=.")
    66  
    67  	read := ExecCommand(ctx, "git", "read-tree", CommitArg(commit))
    68  	read.Dir = toDir
    69  	read.Env = env
    70  	if err := read.Run(); err != nil {
    71  		return err
    72  	}
    73  
    74  	checkout := ExecCommand(ctx, "git", "checkout-index", "-a")
    75  	checkout.Dir = toDir
    76  	checkout.Env = env
    77  	return checkout.Run()
    78  }
    79  
    80  // IsCommit returns true if a commit is not a tag
    81  func IsCommit(commit string) bool {
    82  	return strings.IndexByte(commit, '.') == -1
    83  }