-
Notifications
You must be signed in to change notification settings - Fork 0
Git history preservation (full clone) #83
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -31,17 +31,29 @@ func setupTestRepo(t *testing.T) (repoPath string) { | |
| defer os.RemoveAll(clonePath) | ||
|
|
||
| runCmd(t, clonePath, "git", "clone", bareRepoPath, ".") | ||
| runCmd(t, clonePath, "git", "config", "user.email", "test@example.com") | ||
| runCmd(t, clonePath, "git", "config", "user.name", "Test User") | ||
|
|
||
| // Create a file and commit it. | ||
| filePath := filepath.Join(clonePath, "foo.txt") | ||
| if err := os.WriteFile(filePath, []byte("foo"), 0644); err != nil { | ||
| t.Fatalf("Failed to write file: %v", err) | ||
| } | ||
| runCmd(t, clonePath, "git", "add", "foo.txt") | ||
| runCmd(t, clonePath, "git", "config", "user.email", "test@example.com") | ||
| runCmd(t, clonePath, "git", "config", "user.name", "Test User") | ||
| runCmd(t, clonePath, "git", "commit", "-m", "Initial commit") | ||
| runCmd(t, clonePath, "git", "push", "origin", "master") | ||
| runCmd(t, clonePath, "git", "tag", "v1.0") | ||
|
|
||
| // Create a new branch and commit to it | ||
| runCmd(t, clonePath, "git", "checkout", "-b", "dev") | ||
| filePath2 := filepath.Join(clonePath, "bar.txt") | ||
| if err := os.WriteFile(filePath2, []byte("bar"), 0644); err != nil { | ||
| t.Fatalf("Failed to write file: %v", err) | ||
| } | ||
| runCmd(t, clonePath, "git", "add", "bar.txt") | ||
| runCmd(t, clonePath, "git", "commit", "-m", "Dev commit") | ||
|
|
||
| runCmd(t, clonePath, "git", "push", "origin", "master", "dev") | ||
| runCmd(t, clonePath, "git", "push", "origin", "--tags") | ||
|
|
||
| return bareRepoPath | ||
| } | ||
|
|
@@ -66,7 +78,101 @@ func TestCloneGitRepository_Good(t *testing.T) { | |
|
|
||
| cloner := NewGitCloner() | ||
| var out bytes.Buffer | ||
| dn, err := cloner.CloneGitRepository("file://"+repoPath, &out) | ||
| options := GitCloneOptions{FullHistory: false} | ||
| dn, err := cloner.CloneGitRepository("file://"+repoPath, options, &out) | ||
| if err != nil { | ||
| t.Fatalf("CloneGitRepository failed: %v\nOutput: %s", err, out.String()) | ||
| } | ||
|
|
||
| // Verify the DataNode contains the correct file. | ||
| exists, err := dn.Exists("foo.txt") | ||
| if err != nil { | ||
| t.Fatalf("Exists failed: %v", err) | ||
| } | ||
| if !exists { | ||
| t.Errorf("Expected to find file foo.txt in DataNode, but it was not found") | ||
| } | ||
|
|
||
| // Verify the .git directory is NOT present. | ||
| exists, err = dn.Exists(".git/config") | ||
| if err != nil { | ||
| t.Fatalf("Exists failed for git config: %v", err) | ||
| } | ||
| if exists { | ||
| t.Errorf("Expected NOT to find file .git/config in DataNode for shallow clone, but it was found") | ||
| } | ||
| } | ||
|
|
||
| func TestCloneGitRepository_FullHistory(t *testing.T) { | ||
| repoPath := setupTestRepo(t) | ||
| defer os.RemoveAll(repoPath) | ||
|
|
||
| cloner := NewGitCloner() | ||
| var out bytes.Buffer | ||
| options := GitCloneOptions{FullHistory: true} | ||
| dn, err := cloner.CloneGitRepository("file://"+repoPath, options, &out) | ||
| if err != nil { | ||
| t.Fatalf("CloneGitRepository failed: %v\nOutput: %s", err, out.String()) | ||
| } | ||
|
|
||
| // Verify the DataNode contains the correct file. | ||
| exists, err := dn.Exists("foo.txt") | ||
| if err != nil { | ||
| t.Fatalf("Exists failed: %v", err) | ||
| } | ||
| if !exists { | ||
| t.Errorf("Expected to find file foo.txt in DataNode, but it was not found") | ||
| } | ||
|
|
||
| // Verify the .git directory IS present. | ||
| exists, err = dn.Exists(".git/config") | ||
| if err != nil { | ||
| t.Fatalf("Exists failed for git config: %v", err) | ||
| } | ||
| if !exists { | ||
| t.Errorf("Expected to find file .git/config in DataNode for full history clone, but it was not found") | ||
| } | ||
|
|
||
| // Verify the dev branch file is NOT present | ||
| exists, err = dn.Exists("bar.txt") | ||
| if err != nil { | ||
| t.Fatalf("Exists failed for bar.txt: %v", err) | ||
| } | ||
| if exists { | ||
| t.Errorf("Expected NOT to find file bar.txt in DataNode for default clone, but it was found") | ||
| } | ||
| } | ||
|
|
||
| func TestCloneGitRepository_AllBranches(t *testing.T) { | ||
| repoPath := setupTestRepo(t) | ||
| defer os.RemoveAll(repoPath) | ||
|
|
||
| cloner := NewGitCloner() | ||
| var out bytes.Buffer | ||
| options := GitCloneOptions{FullHistory: true, AllBranches: true} | ||
| dn, err := cloner.CloneGitRepository("file://"+repoPath, options, &out) | ||
| if err != nil { | ||
| t.Fatalf("CloneGitRepository failed: %v\nOutput: %s", err, out.String()) | ||
| } | ||
|
|
||
| // Verify the .git directory IS present. | ||
| exists, err := dn.Exists(".git/config") | ||
| if err != nil { | ||
| t.Fatalf("Exists failed for git config: %v", err) | ||
| } | ||
| if !exists { | ||
| t.Errorf("Expected to find file .git/config in DataNode for all branches clone, but it was not found") | ||
| } | ||
| } | ||
|
Comment on lines
+146
to
+166
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The test for To make this test more robust, you should verify that references for other branches (like the func TestCloneGitRepository_AllBranches(t *testing.T) {
repoPath := setupTestRepo(t)
defer os.RemoveAll(repoPath)
cloner := NewGitCloner()
var out bytes.Buffer
options := GitCloneOptions{FullHistory: true, AllBranches: true}
dn, err := cloner.CloneGitRepository("file://"+repoPath, options, &out)
if err != nil {
t.Fatalf("CloneGitRepository failed: %v\nOutput: %s", err, out.String())
}
// Verify the .git directory IS present.
exists, err := dn.Exists(".git/config")
if err != nil {
t.Fatalf("Exists failed for git config: %v", err)
}
if !exists {
t.Errorf("Expected to find file .git/config in DataNode for all branches clone, but it was not found")
}
// Verify the dev branch reference exists
exists, err = dn.Exists(".git/refs/remotes/origin/dev")
if err != nil {
t.Fatalf("Exists failed for dev branch ref: %v", err)
}
if !exists {
t.Errorf("Expected to find ref for dev branch, but it was not found")
}
} |
||
|
|
||
| func TestCloneGitRepository_Depth(t *testing.T) { | ||
| repoPath := setupTestRepo(t) | ||
| defer os.RemoveAll(repoPath) | ||
|
|
||
| cloner := NewGitCloner() | ||
| var out bytes.Buffer | ||
| options := GitCloneOptions{Depth: 1} | ||
| dn, err := cloner.CloneGitRepository("file://"+repoPath, options, &out) | ||
| if err != nil { | ||
| t.Fatalf("CloneGitRepository failed: %v\nOutput: %s", err, out.String()) | ||
| } | ||
|
|
@@ -79,12 +185,21 @@ func TestCloneGitRepository_Good(t *testing.T) { | |
| if !exists { | ||
| t.Errorf("Expected to find file foo.txt in DataNode, but it was not found") | ||
| } | ||
|
|
||
| // Verify the .git directory is NOT present. | ||
| exists, err = dn.Exists(".git/config") | ||
| if err != nil { | ||
| t.Fatalf("Exists failed for git config: %v", err) | ||
| } | ||
| if exists { | ||
| t.Errorf("Expected NOT to find file .git/config in DataNode for shallow clone, but it was found") | ||
| } | ||
| } | ||
|
|
||
| func TestCloneGitRepository_Bad(t *testing.T) { | ||
| t.Run("Non-existent repository", func(t *testing.T) { | ||
| cloner := NewGitCloner() | ||
| _, err := cloner.CloneGitRepository("file:///non-existent-repo", io.Discard) | ||
| _, err := cloner.CloneGitRepository("file:///non-existent-repo", GitCloneOptions{}, io.Discard) | ||
| if err == nil { | ||
| t.Fatal("Expected an error for a non-existent repository, but got nil") | ||
| } | ||
|
|
@@ -95,7 +210,7 @@ func TestCloneGitRepository_Bad(t *testing.T) { | |
|
|
||
| t.Run("Invalid URL", func(t *testing.T) { | ||
| cloner := NewGitCloner() | ||
| _, err := cloner.CloneGitRepository("not-a-valid-url", io.Discard) | ||
| _, err := cloner.CloneGitRepository("not-a-valid-url", GitCloneOptions{}, io.Discard) | ||
| if err == nil { | ||
| t.Fatal("Expected an error for an invalid URL, but got nil") | ||
| } | ||
|
|
@@ -112,7 +227,7 @@ func TestCloneGitRepository_Ugly(t *testing.T) { | |
| runCmd(t, bareRepoPath, "git", "init", "--bare") | ||
|
|
||
| cloner := NewGitCloner() | ||
| dn, err := cloner.CloneGitRepository("file://"+bareRepoPath, io.Discard) | ||
| dn, err := cloner.CloneGitRepository("file://"+bareRepoPath, GitCloneOptions{}, io.Discard) | ||
| if err != nil { | ||
| t.Fatalf("CloneGitRepository failed on empty repo: %v", err) | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new git clone options are not exposed as flags for the
allcommand.FullHistoryis hardcoded totrue, which might not always be the desired behavior for users ofall. Consider adding flags like--full-history,--depth, etc., to theallcommand, similar to how they were added to thecollect github repocommand, to provide more granular control over the cloning process.