Skip to content

Commit

Permalink
Use git binary to reset project after checking out reference
Browse files Browse the repository at this point in the history
This is required since go-git's reset implementation ignores files in
.gitignore even if the files in question are committed to the repo.

Signed-off-by: Angel Misevski <amisevsk@redhat.com>
  • Loading branch information
amisevsk committed Jul 13, 2021
1 parent 8f96431 commit 7e6a6f5
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 2 deletions.
12 changes: 10 additions & 2 deletions project-clone/internal/git/operations.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ func CheckoutReference(repo *git.Repository, project *dw.Project) error {
continue
}
if ref.Name().IsBranch() {
return checkoutRemoteBranch(repo, defaultRemoteName, ref)
return checkoutRemoteBranch(internal.GetClonePath(project), repo, defaultRemoteName, ref)
} else if ref.Name().IsTag() {
return checkoutTag(repo, defaultRemoteName, ref)
}
Expand All @@ -139,7 +139,7 @@ func CheckoutReference(repo *git.Repository, project *dw.Project) error {
return checkoutCommit(repo, hash)
}

func checkoutRemoteBranch(repo *git.Repository, remote string, branchRef *plumbing.Reference) error {
func checkoutRemoteBranch(projectPath string, repo *git.Repository, remote string, branchRef *plumbing.Reference) error {
// Implement logic of `git checkout <remote-branch-name>`:
// 1. Create tracking info in .git/config to properly track remote branch
// 2. Create local branch to match name of remote branch with hash matching remote branch
Expand Down Expand Up @@ -171,6 +171,14 @@ func checkoutRemoteBranch(repo *git.Repository, remote string, branchRef *plumbi
return fmt.Errorf("failed to checkout branch %s: %s", branchName, err)
}

// Need to also reset git repo due to how go-git handles some untracked files (https://github.com/go-git/go-git/issues/99)
// NOTE: using reset in go-git will not work in some cases, as that implementation of reset respects gitignore, so e.g.
// a .gitignored file that is checked in will never be reset.
err = shell.GitResetProject(path.Join(internal.ProjectsRoot, projectPath))
if err != nil {
return fmt.Errorf("failed to git reset: %s", err)
}

return nil
}

Expand Down
21 changes: 21 additions & 0 deletions project-clone/internal/shell/execute.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
package shell

import (
"fmt"
"log"
"os"
"os/exec"
)
Expand All @@ -30,6 +32,25 @@ func GitCloneProject(repoUrl, defaultRemoteName, destPath string) error {
return executeCommand("git", args...)
}

// GitResetProject runs `git reset --hard` in the project specified by projectPath
func GitResetProject(projectPath string) error {
currDir, err := os.Getwd()
if err != nil {
return fmt.Errorf("failed to get current working directory: %s", err)
}
defer func() {
if err := os.Chdir(currDir); err != nil {
log.Printf("failed to return to original working directory: %s", err)
}
}()

err = os.Chdir(projectPath)
if err != nil {
return fmt.Errorf("failed to move to project directory %s: %s", projectPath, err)
}
return executeCommand("git", "reset", "--hard")
}

func executeCommand(name string, args ...string) error {
cmd := exec.Command(name, args...)
cmd.Stderr = os.Stderr
Expand Down

0 comments on commit 7e6a6f5

Please sign in to comment.