src-d / go-git

Project has been moved to: https://github.com/go-git/go-git
https://github.com/go-git/go-git
Apache License 2.0
4.91k stars 541 forks source link

Tag Checkout and/or Reset not working as expected #1249

Open petergardfjall opened 4 years ago

petergardfjall commented 4 years ago

Hi, using go-git (v4.13.1) I'm trying to accomplish the equivalent of

git clone https://github.com/hamcrest/JavaHamcrest.git
cd JavaHamcrest
git checkout hamcrest-java-1.3

That is, checkout a certain repository tag.

However, I cannot seem to get this to work. I'm not sure if its an error on my part or an error of the library. Here is the code I'm running:

package main

import (
    "log"

    "gopkg.in/src-d/go-git.v4"
    "gopkg.in/src-d/go-git.v4/plumbing"
)

func main() {
    remoteURL := "https://github.com/hamcrest/JavaHamcrest.git"
    localPath := "/tmp/hamcrest.git"
    tag := "hamcrest-java-1.3"

    repo, err := git.PlainClone(localPath, false /* isBare */, &git.CloneOptions{
        URL:               remoteURL,
        RecurseSubmodules: git.DefaultSubmoduleRecursionDepth,
        Tags:              git.AllTags,
    })
    if err != nil {
        log.Fatalf("clone of repo failed: %s", err)
    }

    tree, err := repo.Worktree()
    if err != nil {
        log.Fatalf("failed to get worktree: %s", err)
    }

    // check out the tag of interest. this will put us in a detached state
    err = tree.Checkout(&git.CheckoutOptions{
        Branch: plumbing.ReferenceName("refs/tags/" + tag),
        // if branch is changed, throw away any local changes
        Force: true,
    })
    if err != nil {
        log.Fatalf("failed to checkout repo tag %s: %s", tag, err)
    }
    tagHead, err := repo.Head()
    if err != nil {
        log.Fatalf("failed to get HEAD: %s", err)
    }

    if err := tree.Reset(&git.ResetOptions{Commit: tagHead.Hash(), Mode: git.HardReset}); err != nil {
        log.Fatalf("failed to reset repo to commit %s: %s", tagHead.Hash(), tag)
    }

    log.Printf("successfully checked out tag!")
}

After running the above code, I get

$ cd /tmp/hamcrest.git
$ git status
Not currently on any branch.
Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    deleted:    .idea/workspace.xml

no changes added to commit (use "git add" and/or "git commit -a")

So the work tree contains changes, even though I ran a hard reset.

Have I found a bug?

sbourlon commented 4 years ago

I am facing the same issue when resetting to a commit.