Skip to content

Commit

Permalink
Set GIT_CHECKOUT_FORCE as checkout strategy when creating a worktree
Browse files Browse the repository at this point in the history
  • Loading branch information
Enrique Raso Barbero authored and bording committed Nov 24, 2024
1 parent 0961ea7 commit 08fafd5
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 16 deletions.
109 changes: 105 additions & 4 deletions LibGit2Sharp.Tests/WorktreeFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xunit;

namespace LibGit2Sharp.Tests
Expand Down Expand Up @@ -238,7 +236,7 @@ public void CanForcePruneLockedWorktree()
}

[Fact]
public void CanAddWorktree()
public void CanAddWorktree_WithUncommitedChanges()
{
var repoPath = SandboxWorktreeTestRepo();
using (var repo = new Repository(repoPath))
Expand All @@ -252,15 +250,96 @@ public void CanAddWorktree()
Assert.False(worktree.IsLocked);

Assert.Equal(3, repo.Worktrees.Count());

// Check that branch contains same number of files and folders
// NOTE: There is an open bug - [Repository.Worktrees.Add leaves now worktree empty](https://github.com/libgit2/libgit2sharp/issues/2037)
Assert.True(repo.RetrieveStatus().IsDirty);
var filesInMain = GetFilesOfRepo(repoPath);
var filesInBranch = GetFilesOfRepo(path);
Assert.NotEqual(filesInMain, filesInBranch);

repo.Reset(ResetMode.Hard);
repo.RemoveUntrackedFiles();

Assert.False(repo.RetrieveStatus().IsDirty);
filesInMain = GetFilesOfRepo(repoPath);
filesInBranch = GetFilesOfRepo(path);
Assert.Equal(filesInMain, filesInBranch);
}
}

[Fact]
public void CanAddWorktree_WithCommitedChanges()
{
var repoPath = SandboxWorktreeTestRepo();
using (var repo = new Repository(repoPath))
{
// stage all changes
Commands.Stage(repo, "*");
repo.Commit("Apply all changes", Constants.Signature, Constants.Signature);

Assert.Equal(2, repo.Worktrees.Count());

var name = "blah";
var path = Path.Combine(repo.Info.WorkingDirectory, "..", "worktrees", name);
var worktree = repo.Worktrees.Add(name, path, false);
Assert.Equal(name, worktree.Name);
Assert.False(worktree.IsLocked);

Assert.Equal(3, repo.Worktrees.Count());

// Check that branch contains same number of files and folders
// NOTE: There is an open bug - [Repository.Worktrees.Add leaves now worktree empty](https://github.com/libgit2/libgit2sharp/issues/2037)
Assert.False(repo.RetrieveStatus().IsDirty);
var filesInMain = GetFilesOfRepo(repoPath);
var filesInBranch = GetFilesOfRepo(path);
Assert.Equal(filesInMain, filesInBranch);
}
}

[Fact]
public void CanAddLockedWorktree_WithUncommitedChanges()
{
var repoPath = SandboxWorktreeTestRepo();
using (var repo = new Repository(repoPath))
{
Assert.Equal(2, repo.Worktrees.Count());

var name = "blah";
var path = Path.Combine(repo.Info.WorkingDirectory, "..", "worktrees", name);
var worktree = repo.Worktrees.Add(name, path, true);
Assert.Equal(name, worktree.Name);
Assert.True(worktree.IsLocked);

Assert.Equal(3, repo.Worktrees.Count());

// Check that branch contains same number of files and folders
// NOTE: There is an open bug - [Repository.Worktrees.Add leaves now worktree empty](https://github.com/libgit2/libgit2sharp/issues/2037)
Assert.True(repo.RetrieveStatus().IsDirty);
var filesInMain = GetFilesOfRepo(repoPath);
var filesInBranch = GetFilesOfRepo(path);
Assert.NotEqual(filesInMain, filesInBranch);

repo.Reset(ResetMode.Hard);
repo.RemoveUntrackedFiles();

Assert.False(repo.RetrieveStatus().IsDirty);
filesInMain = GetFilesOfRepo(repoPath);
filesInBranch = GetFilesOfRepo(path);
Assert.Equal(filesInMain, filesInBranch);
}
}

[Fact]
public void CanAddLockedWorktree()
public void CanAddLockedWorktree_WithCommitedChanges()
{
var repoPath = SandboxWorktreeTestRepo();
using (var repo = new Repository(repoPath))
{
// stage all changes
Commands.Stage(repo, "*");
repo.Commit("Apply all changes", Constants.Signature, Constants.Signature);

Assert.Equal(2, repo.Worktrees.Count());

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

Assert.Equal(3, repo.Worktrees.Count());

// Check that branch contains same number of files and folders
// NOTE: There is an open bug - [Repository.Worktrees.Add leaves now worktree empty](https://github.com/libgit2/libgit2sharp/issues/2037)
Assert.False(repo.RetrieveStatus().IsDirty);
var filesInMain = GetFilesOfRepo(repoPath);
var filesInBranch = GetFilesOfRepo(path);
Assert.Equal(filesInMain, filesInBranch);
}
}

Expand All @@ -292,7 +378,22 @@ public void CanAddWorktreeForCommittish()
Assert.Equal(committish, repository.Head.FriendlyName);
}
Assert.Equal(3, repo.Worktrees.Count());

// Check that branch contains same number of files and folders
// NOTE: There is an open bug - [Repository.Worktrees.Add leaves now worktree empty](https://github.com/libgit2/libgit2sharp/issues/2037)
var filesInCommittish = new string[] { "numbers.txt", "super-file.txt" };
var filesInBranch = GetFilesOfRepo(path);
Assert.Equal(filesInCommittish, filesInBranch);
}
}

private static IEnumerable<string> GetFilesOfRepo(string repoPath)
{
return Directory.GetFiles(repoPath, "*", SearchOption.AllDirectories)
.Where(fileName => !fileName.StartsWith($"{repoPath}\\.git", StringComparison.InvariantCultureIgnoreCase))
.Select(fileName => fileName.Replace($"{repoPath}\\", "", StringComparison.InvariantCultureIgnoreCase))
.OrderBy(fileName => fileName, StringComparer.InvariantCultureIgnoreCase)
.ToList();
}
}
}
6 changes: 5 additions & 1 deletion LibGit2Sharp/Core/GitWorktree.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,11 @@ internal class git_worktree_add_options

public IntPtr @ref = IntPtr.Zero;

public GitCheckoutOpts checkoutOpts = new GitCheckoutOpts { version = 1 };
public GitCheckoutOpts checkoutOpts = new GitCheckoutOpts
{
version = 1,
checkout_strategy = CheckoutStrategy.GIT_CHECKOUT_FORCE
};
}

[StructLayout(LayoutKind.Sequential)]
Expand Down
19 changes: 8 additions & 11 deletions LibGit2Sharp/WorktreeCollection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,10 @@ public virtual Worktree this[string name]
/// <summary>
///
/// </summary>
/// <param name="committishOrBranchSpec"></param>
/// <param name="name"></param>
/// <param name="path"></param>
/// <param name="committishOrBranchSpec">A committish or branch name./param>
/// <param name="name">Name of the worktree.</param>
/// <param name="path">Location of the worktree.</param>
/// <param name="isLocked"></param>
/// <returns></returns>
public virtual Worktree Add(string committishOrBranchSpec, string name, string path, bool isLocked)
{
if (string.Equals(committishOrBranchSpec, name))
Expand All @@ -61,7 +60,7 @@ public virtual Worktree Add(string committishOrBranchSpec, string name, string p
return null;
}

git_worktree_add_options options = new git_worktree_add_options
var options = new git_worktree_add_options
{
version = 1,
locked = Convert.ToInt32(isLocked)
Expand All @@ -81,20 +80,18 @@ public virtual Worktree Add(string committishOrBranchSpec, string name, string p
}
}



return this[name];
}

/// <summary>
///
/// </summary>
/// <param name="name"></param>
/// <param name="path"></param>
/// <param name="isLocked"></param>
/// <param name="committishOrBranchSpec">A committish or branch name./param>
/// <param name="name">Name of the worktree.</param>
/// <param name="path">Location of the worktree.</param>
public virtual Worktree Add(string name, string path, bool isLocked)
{
git_worktree_add_options options = new git_worktree_add_options
var options = new git_worktree_add_options
{
version = 1,
locked = Convert.ToInt32(isLocked)
Expand Down

0 comments on commit 08fafd5

Please sign in to comment.