RemoveReference should clean up empty directories
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 68/100
Research direction
Start with the filesystem storage implementations of SetReference and RemoveReference, then use the provided TestConflictWithDeletedRef reproduction as the first test to run. Done means removing a nested reference also removes empty parent directories, allowing a later reference named bugfix to be created successfully.
Written by the indexing model from the issue text.
Description
Bug Description
When SetReference is called to create a reference with / in the name, it creates subdirectories for each part of the name separated by a slash. For example, when creating the ref bugfix/issue-1 SetReference would create it at the path <repo>/refs/bugfix/issue-1, creating the file issue-1 and the parent directory bugfix/.
When RemoveReference is called on the same reference, it deletes the reference but not the parent directories, even though they may be empty. In the example above, it would delete issue-1, but the refs/heads/bugfix/ directory would still exist.
Since the parent directories are not cleaned up, it becomes impossible to create any new references that share the same name. In the example above, it is now not possible to use SetReference to create a ref with the name bugfix, since it conflicts with the leftover directory refs/heads/bugfix/.
The Git implementation does cleanup parent directories when a branch is deleted.
go-git Version
v5.16.4
Steps to Reproduce
func TestConflictWithDeletedRef(t *testing.T) {
repoPath := t.TempDir()
fs := filesystem.NewStorage(osfs.New(repoPath), cache.NewObjectLRUDefault())
if _, err := git.Init(fs, nil); err != nil {
t.Fatalf("Failed to init git: %v", err)
}
// Create a new branch named bugfix/1.
nestedRef := plumbing.NewReferenceFromStrings("refs/heads/bugfix/1", "target1")
if err := fs.SetReference(nestedRef); err != nil {
t.Fatalf("Failed to set reference: %v", err)
}
if err := fs.RemoveReference(nestedRef.Name()); err != nil {
t.Fatalf("Failed to remove reference: %v", err)
}
// Now we try to create a ref named 'bugfix' but it fails, since the directory refs/heads/bugfix/ exists.
// Error:
// Failed to set reference: open /tmp/TestConflictWithDeletedRef4236784409/001/refs/heads/bugfix: is a directory
conflictingRef := plumbing.NewReferenceFromStrings("refs/heads/bugfix", "target2")
if err := fs.SetReference(conflictingRef); err != nil {
t.Fatalf("Failed to set reference: %v", err)
}
}
Additional Information
No response
- Dominant language
- Go
- Stars
- 7.7k
- Forks
- 1k
- Avg merge
- 1d 1h
- Merged PRs (30d)
- 21
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from go-git/go-git
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
Similar issues
-
Difficulty 1/5 Under an hour Newbie friendliness 84/100
-
enhancement needs triage
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
-
kind/cleanup
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
kubernetes-sigs/kueue#15947 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
sympozium-ai/sympozium#627 ·
-
priority: p3
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
googleapis/librarian#7636 ·