Skip to content
This repository has been archived by the owner on Sep 11, 2020. It is now read-only.

Worktree.Checkout:Force bug? #435

Closed
snail007 opened this issue Jun 18, 2017 · 3 comments
Closed

Worktree.Checkout:Force bug? #435

snail007 opened this issue Jun 18, 2017 · 3 comments
Labels

Comments

@snail007
Copy link

snail007 commented Jun 18, 2017

1.I clone a test Repository to /Users/snail/codes/gotest (current branch is master)
2.I delete a file "/Users/snail/codes/gotest/index.php"
3.use git command,git checkout master -f
4. nothing error showed and index.php returned back,i hope so.
but if is use go-git do step 3 ,i got an error :remove /Users/snail/codes/gotest/index.php: no such file or directory
code snippet:
err = w.Checkout(&git.CheckoutOptions{
Branch: plumbing.ReferenceName("refs/heads/master"),
Force: true,
})
fmt.Println(err)
is it a bug? I confused .

@snail007 snail007 changed the title Worktree.Checkout:Force error? Worktree.Checkout:Force bug? Jun 20, 2017
@azuenko
Copy link

azuenko commented Jul 18, 2017

I confirm the bug, force checkout doesn't work properly. How to reproduce it:

  • create Makefile
reproduce: clean

	git init --bare repo.git

	mkdir native
	echo hello > native/hello

	git --git-dir=repo.git --work-tree=native add -A
	git --git-dir=repo.git --work-tree=native commit -m init

	rm -rf native
	mkdir native

	git --git-dir=repo.git --work-tree=native checkout -f
	ls native

	mkdir gogit
	go run bug.go repo.git gogit
	ls gogit

clean:
	-rm -rf repo.git gogit native

  • create bug.go:
package main

import (
	"log"
	"os"

	"gopkg.in/src-d/go-billy.v3/osfs"
	gogit "gopkg.in/src-d/go-git.v4"
	"gopkg.in/src-d/go-git.v4/storage/filesystem"
)

func main() {

	gitDirFs := osfs.New(os.Args[1])
	workDirFs := osfs.New(os.Args[2])

	storer, err := filesystem.NewStorage(gitDirFs)
	if err != nil {
		log.Fatal(err)
	}

	repository, err := gogit.Open(storer, workDirFs)
	if err != nil {
		log.Fatal(err)
	}

	worktree, err := repository.Worktree()
	if err != nil {
		log.Fatal(err)
	}

	err = worktree.Checkout(&gogit.CheckoutOptions{Force: true})
	if err != nil {
		log.Fatal(err)
	}

}
  • run make reproduce

Expected: both ls native and ls gogit return the same result -- file hello
Got: ls native returns hello, but ls gogit returns nothing.

I suspect it's due to the fact that worktree.Reset only compares commit with index, and never index with working tree:

https://github.com/src-d/go-git/blob/v4/worktree.go#L130

Actually, worktree.Reset makes no distinction on opts.Mode.

@skyflyer
Copy link

/cc @mcuadros @smola

I'd be interested in functioning worktree.Reset as well (which I assume is the same as force checkout?). The way I see it, we need to cover following scenarios:

  • staged modifications (add/delete/modify)
  • missing files
  • modified files
  • working tree pointing to a different commit than the one requested

I looked at the code in the worktree.Reset, but I'm not sure I grok everything with the Merkle trees.

So far, I've tested that the following scenarios don't work:

  • missing files are not re-created
  • modified files are not reverted
  • working tree is not reset to the commit requested and stays (in my example HEAD remains detached

If you could provide some support in terms of guidance, I'd be interested in preparing a pull request to solve those issues.

@mcuadros
Copy link
Contributor

@skyflyer I am working in he fix since some days ago, will implement all the reset modes properly. Thanks

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

4 participants