Skip to content

Commit 5fd810d

Browse files
authored
Merge pull request #2099 from enriqueraso/bug/Repositoy.Worktrees.Add_creates_an_empty_folder_for_the_worktree
Fix empty folder issue in Repositoy.Worktrees.Add
2 parents 0961ea7 + 704a25b commit 5fd810d

File tree

3 files changed

+117
-19
lines changed

3 files changed

+117
-19
lines changed

LibGit2Sharp.Tests/WorktreeFixture.cs

+103-6
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
1-
using LibGit2Sharp.Tests.TestHelpers;
2-
using System;
1+
using System;
32
using System.Collections.Generic;
43
using System.IO;
54
using System.Linq;
6-
using System.Text;
7-
using System.Threading.Tasks;
5+
using LibGit2Sharp.Tests.TestHelpers;
86
using Xunit;
97

108
namespace LibGit2Sharp.Tests
@@ -238,7 +236,7 @@ public void CanForcePruneLockedWorktree()
238236
}
239237

240238
[Fact]
241-
public void CanAddWorktree()
239+
public void CanAddWorktree_WithUncommitedChanges()
242240
{
243241
var repoPath = SandboxWorktreeTestRepo();
244242
using (var repo = new Repository(repoPath))
@@ -252,11 +250,54 @@ public void CanAddWorktree()
252250
Assert.False(worktree.IsLocked);
253251

254252
Assert.Equal(3, repo.Worktrees.Count());
253+
254+
// Check that branch contains same number of files and folders
255+
Assert.True(repo.RetrieveStatus().IsDirty);
256+
var filesInMain = GetFilesOfRepo(repoPath);
257+
var filesInBranch = GetFilesOfRepo(path);
258+
Assert.NotEqual(filesInMain, filesInBranch);
259+
260+
repo.Reset(ResetMode.Hard);
261+
repo.RemoveUntrackedFiles();
262+
263+
Assert.False(repo.RetrieveStatus().IsDirty);
264+
filesInMain = GetFilesOfRepo(repoPath);
265+
filesInBranch = GetFilesOfRepo(path);
266+
Assert.Equal(filesInMain, filesInBranch);
255267
}
256268
}
257269

258270
[Fact]
259-
public void CanAddLockedWorktree()
271+
public void CanAddWorktree_WithCommitedChanges()
272+
{
273+
var repoPath = SandboxWorktreeTestRepo();
274+
using (var repo = new Repository(repoPath))
275+
{
276+
// stage all changes
277+
Commands.Stage(repo, "*");
278+
repo.Commit("Apply all changes", Constants.Signature, Constants.Signature);
279+
280+
Assert.Equal(2, repo.Worktrees.Count());
281+
282+
var name = "blah";
283+
var path = Path.Combine(repo.Info.WorkingDirectory, "..", "worktrees", name);
284+
var worktree = repo.Worktrees.Add(name, path, false);
285+
Assert.Equal(name, worktree.Name);
286+
Assert.False(worktree.IsLocked);
287+
288+
Assert.Equal(3, repo.Worktrees.Count());
289+
290+
// Check that branch contains same number of files and folders
291+
Assert.False(repo.RetrieveStatus().IsDirty);
292+
var filesInMain = GetFilesOfRepo(repoPath);
293+
var filesInBranch = GetFilesOfRepo(path);
294+
295+
Assert.Equal(filesInMain, filesInBranch);
296+
}
297+
}
298+
299+
[Fact]
300+
public void CanAddLockedWorktree_WithUncommitedChanges()
260301
{
261302
var repoPath = SandboxWorktreeTestRepo();
262303
using (var repo = new Repository(repoPath))
@@ -270,6 +311,48 @@ public void CanAddLockedWorktree()
270311
Assert.True(worktree.IsLocked);
271312

272313
Assert.Equal(3, repo.Worktrees.Count());
314+
315+
// Check that branch contains same number of files and folders
316+
Assert.True(repo.RetrieveStatus().IsDirty);
317+
var filesInMain = GetFilesOfRepo(repoPath);
318+
var filesInBranch = GetFilesOfRepo(path);
319+
Assert.NotEqual(filesInMain, filesInBranch);
320+
321+
repo.Reset(ResetMode.Hard);
322+
repo.RemoveUntrackedFiles();
323+
324+
Assert.False(repo.RetrieveStatus().IsDirty);
325+
filesInMain = GetFilesOfRepo(repoPath);
326+
filesInBranch = GetFilesOfRepo(path);
327+
Assert.Equal(filesInMain, filesInBranch);
328+
}
329+
}
330+
331+
[Fact]
332+
public void CanAddLockedWorktree_WithCommitedChanges()
333+
{
334+
var repoPath = SandboxWorktreeTestRepo();
335+
using (var repo = new Repository(repoPath))
336+
{
337+
// stage all changes
338+
Commands.Stage(repo, "*");
339+
repo.Commit("Apply all changes", Constants.Signature, Constants.Signature);
340+
341+
Assert.Equal(2, repo.Worktrees.Count());
342+
343+
var name = "blah";
344+
var path = Path.Combine(repo.Info.WorkingDirectory, "..", "worktrees", name);
345+
var worktree = repo.Worktrees.Add(name, path, true);
346+
Assert.Equal(name, worktree.Name);
347+
Assert.True(worktree.IsLocked);
348+
349+
Assert.Equal(3, repo.Worktrees.Count());
350+
351+
// Check that branch contains same number of files and folders
352+
Assert.False(repo.RetrieveStatus().IsDirty);
353+
var filesInMain = GetFilesOfRepo(repoPath);
354+
var filesInBranch = GetFilesOfRepo(path);
355+
Assert.Equal(filesInMain, filesInBranch);
273356
}
274357
}
275358

@@ -292,7 +375,21 @@ public void CanAddWorktreeForCommittish()
292375
Assert.Equal(committish, repository.Head.FriendlyName);
293376
}
294377
Assert.Equal(3, repo.Worktrees.Count());
378+
379+
// Check that branch contains same number of files and folders
380+
var filesInCommittish = new string[] { "numbers.txt", "super-file.txt" };
381+
var filesInBranch = GetFilesOfRepo(path);
382+
Assert.Equal(filesInCommittish, filesInBranch);
295383
}
296384
}
385+
386+
private static IEnumerable<string> GetFilesOfRepo(string repoPath)
387+
{
388+
return Directory.GetFiles(repoPath, "*", SearchOption.AllDirectories)
389+
.Where(fileName => !fileName.StartsWith(Path.Combine(repoPath, ".git")))
390+
.Select(fileName => fileName.Replace($"{repoPath}{Path.DirectorySeparatorChar}", ""))
391+
.OrderBy(fileName => fileName)
392+
.ToList();
393+
}
297394
}
298395
}

LibGit2Sharp/Core/GitWorktree.cs

+5-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,11 @@ internal class git_worktree_add_options
3838

3939
public IntPtr @ref = IntPtr.Zero;
4040

41-
public GitCheckoutOpts checkoutOpts = new GitCheckoutOpts { version = 1 };
41+
public GitCheckoutOpts checkoutOpts = new GitCheckoutOpts
42+
{
43+
version = 1,
44+
checkout_strategy = CheckoutStrategy.GIT_CHECKOUT_SAFE
45+
};
4246
}
4347

4448
[StructLayout(LayoutKind.Sequential)]

LibGit2Sharp/WorktreeCollection.cs

+9-12
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,12 @@ public virtual Worktree this[string name]
4646
}
4747

4848
/// <summary>
49-
///
49+
/// Creates a worktree.
5050
/// </summary>
51-
/// <param name="committishOrBranchSpec"></param>
52-
/// <param name="name"></param>
53-
/// <param name="path"></param>
51+
/// <param name="committishOrBranchSpec">The committish to checkout into the new worktree.</param>
52+
/// <param name="name">Name of the worktree.</param>
53+
/// <param name="path">Location of the worktree.</param>
5454
/// <param name="isLocked"></param>
55-
/// <returns></returns>
5655
public virtual Worktree Add(string committishOrBranchSpec, string name, string path, bool isLocked)
5756
{
5857
if (string.Equals(committishOrBranchSpec, name))
@@ -61,7 +60,7 @@ public virtual Worktree Add(string committishOrBranchSpec, string name, string p
6160
return null;
6261
}
6362

64-
git_worktree_add_options options = new git_worktree_add_options
63+
var options = new git_worktree_add_options
6564
{
6665
version = 1,
6766
locked = Convert.ToInt32(isLocked)
@@ -81,20 +80,18 @@ public virtual Worktree Add(string committishOrBranchSpec, string name, string p
8180
}
8281
}
8382

84-
85-
8683
return this[name];
8784
}
8885

8986
/// <summary>
90-
///
87+
/// Creates a worktree.
9188
/// </summary>
92-
/// <param name="name"></param>
93-
/// <param name="path"></param>
89+
/// <param name="name">Name of the worktree.</param>
90+
/// <param name="path">Location of the worktree.</param>
9491
/// <param name="isLocked"></param>
9592
public virtual Worktree Add(string name, string path, bool isLocked)
9693
{
97-
git_worktree_add_options options = new git_worktree_add_options
94+
var options = new git_worktree_add_options
9895
{
9996
version = 1,
10097
locked = Convert.ToInt32(isLocked)

0 commit comments

Comments
 (0)