Skip to content

Commit 08fafd5

Browse files
Enrique Raso Barberobording
Enrique Raso Barbero
authored andcommitted
Set GIT_CHECKOUT_FORCE as checkout strategy when creating a worktree
1 parent 0961ea7 commit 08fafd5

File tree

3 files changed

+118
-16
lines changed

3 files changed

+118
-16
lines changed

LibGit2Sharp.Tests/WorktreeFixture.cs

+105-4
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
using System.Collections.Generic;
44
using System.IO;
55
using System.Linq;
6-
using System.Text;
7-
using System.Threading.Tasks;
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,15 +250,96 @@ 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+
// NOTE: There is an open bug - [Repository.Worktrees.Add leaves now worktree empty](https://github.com/libgit2/libgit2sharp/issues/2037)
256+
Assert.True(repo.RetrieveStatus().IsDirty);
257+
var filesInMain = GetFilesOfRepo(repoPath);
258+
var filesInBranch = GetFilesOfRepo(path);
259+
Assert.NotEqual(filesInMain, filesInBranch);
260+
261+
repo.Reset(ResetMode.Hard);
262+
repo.RemoveUntrackedFiles();
263+
264+
Assert.False(repo.RetrieveStatus().IsDirty);
265+
filesInMain = GetFilesOfRepo(repoPath);
266+
filesInBranch = GetFilesOfRepo(path);
267+
Assert.Equal(filesInMain, filesInBranch);
268+
}
269+
}
270+
271+
[Fact]
272+
public void CanAddWorktree_WithCommitedChanges()
273+
{
274+
var repoPath = SandboxWorktreeTestRepo();
275+
using (var repo = new Repository(repoPath))
276+
{
277+
// stage all changes
278+
Commands.Stage(repo, "*");
279+
repo.Commit("Apply all changes", Constants.Signature, Constants.Signature);
280+
281+
Assert.Equal(2, repo.Worktrees.Count());
282+
283+
var name = "blah";
284+
var path = Path.Combine(repo.Info.WorkingDirectory, "..", "worktrees", name);
285+
var worktree = repo.Worktrees.Add(name, path, false);
286+
Assert.Equal(name, worktree.Name);
287+
Assert.False(worktree.IsLocked);
288+
289+
Assert.Equal(3, repo.Worktrees.Count());
290+
291+
// Check that branch contains same number of files and folders
292+
// NOTE: There is an open bug - [Repository.Worktrees.Add leaves now worktree empty](https://github.com/libgit2/libgit2sharp/issues/2037)
293+
Assert.False(repo.RetrieveStatus().IsDirty);
294+
var filesInMain = GetFilesOfRepo(repoPath);
295+
var filesInBranch = GetFilesOfRepo(path);
296+
Assert.Equal(filesInMain, filesInBranch);
297+
}
298+
}
299+
300+
[Fact]
301+
public void CanAddLockedWorktree_WithUncommitedChanges()
302+
{
303+
var repoPath = SandboxWorktreeTestRepo();
304+
using (var repo = new Repository(repoPath))
305+
{
306+
Assert.Equal(2, repo.Worktrees.Count());
307+
308+
var name = "blah";
309+
var path = Path.Combine(repo.Info.WorkingDirectory, "..", "worktrees", name);
310+
var worktree = repo.Worktrees.Add(name, path, true);
311+
Assert.Equal(name, worktree.Name);
312+
Assert.True(worktree.IsLocked);
313+
314+
Assert.Equal(3, repo.Worktrees.Count());
315+
316+
// Check that branch contains same number of files and folders
317+
// NOTE: There is an open bug - [Repository.Worktrees.Add leaves now worktree empty](https://github.com/libgit2/libgit2sharp/issues/2037)
318+
Assert.True(repo.RetrieveStatus().IsDirty);
319+
var filesInMain = GetFilesOfRepo(repoPath);
320+
var filesInBranch = GetFilesOfRepo(path);
321+
Assert.NotEqual(filesInMain, filesInBranch);
322+
323+
repo.Reset(ResetMode.Hard);
324+
repo.RemoveUntrackedFiles();
325+
326+
Assert.False(repo.RetrieveStatus().IsDirty);
327+
filesInMain = GetFilesOfRepo(repoPath);
328+
filesInBranch = GetFilesOfRepo(path);
329+
Assert.Equal(filesInMain, filesInBranch);
255330
}
256331
}
257332

258333
[Fact]
259-
public void CanAddLockedWorktree()
334+
public void CanAddLockedWorktree_WithCommitedChanges()
260335
{
261336
var repoPath = SandboxWorktreeTestRepo();
262337
using (var repo = new Repository(repoPath))
263338
{
339+
// stage all changes
340+
Commands.Stage(repo, "*");
341+
repo.Commit("Apply all changes", Constants.Signature, Constants.Signature);
342+
264343
Assert.Equal(2, repo.Worktrees.Count());
265344

266345
var name = "blah";
@@ -270,6 +349,13 @@ public void CanAddLockedWorktree()
270349
Assert.True(worktree.IsLocked);
271350

272351
Assert.Equal(3, repo.Worktrees.Count());
352+
353+
// Check that branch contains same number of files and folders
354+
// NOTE: There is an open bug - [Repository.Worktrees.Add leaves now worktree empty](https://github.com/libgit2/libgit2sharp/issues/2037)
355+
Assert.False(repo.RetrieveStatus().IsDirty);
356+
var filesInMain = GetFilesOfRepo(repoPath);
357+
var filesInBranch = GetFilesOfRepo(path);
358+
Assert.Equal(filesInMain, filesInBranch);
273359
}
274360
}
275361

@@ -292,7 +378,22 @@ public void CanAddWorktreeForCommittish()
292378
Assert.Equal(committish, repository.Head.FriendlyName);
293379
}
294380
Assert.Equal(3, repo.Worktrees.Count());
381+
382+
// Check that branch contains same number of files and folders
383+
// NOTE: There is an open bug - [Repository.Worktrees.Add leaves now worktree empty](https://github.com/libgit2/libgit2sharp/issues/2037)
384+
var filesInCommittish = new string[] { "numbers.txt", "super-file.txt" };
385+
var filesInBranch = GetFilesOfRepo(path);
386+
Assert.Equal(filesInCommittish, filesInBranch);
295387
}
296388
}
389+
390+
private static IEnumerable<string> GetFilesOfRepo(string repoPath)
391+
{
392+
return Directory.GetFiles(repoPath, "*", SearchOption.AllDirectories)
393+
.Where(fileName => !fileName.StartsWith($"{repoPath}\\.git", StringComparison.InvariantCultureIgnoreCase))
394+
.Select(fileName => fileName.Replace($"{repoPath}\\", "", StringComparison.InvariantCultureIgnoreCase))
395+
.OrderBy(fileName => fileName, StringComparer.InvariantCultureIgnoreCase)
396+
.ToList();
397+
}
297398
}
298399
}

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_FORCE
45+
};
4246
}
4347

4448
[StructLayout(LayoutKind.Sequential)]

LibGit2Sharp/WorktreeCollection.cs

+8-11
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,10 @@ public virtual Worktree this[string name]
4848
/// <summary>
4949
///
5050
/// </summary>
51-
/// <param name="committishOrBranchSpec"></param>
52-
/// <param name="name"></param>
53-
/// <param name="path"></param>
51+
/// <param name="committishOrBranchSpec">A committish or branch name./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>
9087
///
9188
/// </summary>
92-
/// <param name="name"></param>
93-
/// <param name="path"></param>
94-
/// <param name="isLocked"></param>
89+
/// <param name="committishOrBranchSpec">A committish or branch name./param>
90+
/// <param name="name">Name of the worktree.</param>
91+
/// <param name="path">Location of the worktree.</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)