Skip to content

Commit 0541390

Browse files
Enrique Raso BarberoEnrique Raso Barbero
Enrique Raso Barbero
authored and
Enrique Raso Barbero
committed
Set GIT_CHECKOUT_FORCE as checkout strategy when creating a worktree
1 parent 5085a0c commit 0541390

File tree

3 files changed

+122
-24
lines changed

3 files changed

+122
-24
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-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
using System;
2-
using System.Collections.Generic;
32
using System.Runtime.InteropServices;
4-
using System.Text;
53

64
namespace LibGit2Sharp.Core
75
{
@@ -38,7 +36,11 @@ internal class git_worktree_add_options
3836

3937
public IntPtr @ref = IntPtr.Zero;
4038

41-
public GitCheckoutOpts checkoutOpts = new GitCheckoutOpts { version = 1 };
39+
public GitCheckoutOpts checkoutOpts = new GitCheckoutOpts
40+
{
41+
version = 1,
42+
checkout_strategy = CheckoutStrategy.GIT_CHECKOUT_FORCE
43+
};
4244
}
4345

4446
[StructLayout(LayoutKind.Sequential)]

LibGit2Sharp/WorktreeCollection.cs

+12-17
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,7 @@
44
using System.Collections;
55
using System.Collections.Generic;
66
using System.Globalization;
7-
using System.IO;
87
using System.Linq;
9-
using System.Text;
108

119
namespace LibGit2Sharp
1210
{
@@ -48,22 +46,21 @@ public virtual Worktree this[string name]
4846
}
4947

5048
/// <summary>
51-
///
49+
/// Creates a worktree from a committish or branch.
5250
/// </summary>
53-
/// <param name="committishOrBranchSpec"></param>
54-
/// <param name="name"></param>
55-
/// <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>
5654
/// <param name="isLocked"></param>
57-
/// <returns></returns>
5855
public virtual Worktree Add(string committishOrBranchSpec, string name, string path, bool isLocked)
5956
{
60-
if(string.Equals(committishOrBranchSpec, name))
57+
if (string.Equals(committishOrBranchSpec, name))
6158
{
6259
// Proxy.git_worktree_add() creates a new branch of name = name, so if we want to checkout a given branch then the 'name' cannot be the same as the target branch
6360
return null;
6461
}
6562

66-
git_worktree_add_options options = new git_worktree_add_options
63+
var options = new git_worktree_add_options
6764
{
6865
version = 1,
6966
locked = Convert.ToInt32(isLocked)
@@ -83,20 +80,18 @@ public virtual Worktree Add(string committishOrBranchSpec, string name, string p
8380
}
8481
}
8582

86-
87-
88-
return this[name];
83+
return this[name];
8984
}
9085

9186
/// <summary>
92-
///
87+
/// Creates a worktree from a committish or branch.
9388
/// </summary>
94-
/// <param name="name"></param>
95-
/// <param name="path"></param>
96-
/// <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>
9792
public virtual Worktree Add(string name, string path, bool isLocked)
9893
{
99-
git_worktree_add_options options = new git_worktree_add_options
94+
var options = new git_worktree_add_options
10095
{
10196
version = 1,
10297
locked = Convert.ToInt32(isLocked)

0 commit comments

Comments
 (0)