-
Notifications
You must be signed in to change notification settings - Fork 892
/
Copy pathWorktreeCollection.cs
191 lines (169 loc) · 6.26 KB
/
WorktreeCollection.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using LibGit2Sharp.Core;
using LibGit2Sharp.Core.Handles;
namespace LibGit2Sharp
{
/// <summary>
/// The collection of worktrees in a <see cref="Repository"/>
/// </summary>
public class WorktreeCollection : IEnumerable<Worktree>
{
internal readonly Repository repo;
/// <summary>
/// Needed for mocking purposes.
/// </summary>
protected WorktreeCollection()
{ }
/// <summary>
/// Initializes a new instance of the <see cref="LibGit2Sharp.WorktreeCollection"/> class.
/// </summary>
/// <param name="repo">The repo.</param>
internal WorktreeCollection(Repository repo)
{
this.repo = repo;
}
/// <summary>
/// Gets the <see cref="LibGit2Sharp.Submodule"/> with the specified name.
/// </summary>
public virtual Worktree this[string name]
{
get
{
Ensure.ArgumentNotNullOrEmptyString(name, "name");
return Lookup(name, handle => new Worktree(repo,
name,
Proxy.git_worktree_is_locked(handle)));
}
}
/// <summary>
/// Creates a worktree.
/// </summary>
/// <param name="committishOrBranchSpec">The committish to checkout into the new worktree.</param>
/// <param name="name">Name of the worktree.</param>
/// <param name="path">Location of the worktree.</param>
/// <param name="isLocked"></param>
public virtual Worktree Add(string committishOrBranchSpec, string name, string path, bool isLocked)
{
if (string.Equals(committishOrBranchSpec, name))
{
// 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
return null;
}
var options = new git_worktree_add_options
{
version = 1,
locked = Convert.ToInt32(isLocked)
};
using (var handle = Proxy.git_worktree_add(repo.Handle, name, path, options))
{
var worktree = new Worktree(
repo,
name,
Proxy.git_worktree_is_locked(handle));
// switch the worktree to the target branch
using (var repository = worktree.WorktreeRepository)
{
Commands.Checkout(repository, committishOrBranchSpec);
}
}
return this[name];
}
/// <summary>
/// Creates a worktree.
/// </summary>
/// <param name="name">Name of the worktree.</param>
/// <param name="path">Location of the worktree.</param>
/// <param name="isLocked"></param>
public virtual Worktree Add(string name, string path, bool isLocked)
{
var options = new git_worktree_add_options
{
version = 1,
locked = Convert.ToInt32(isLocked)
};
using (var handle = Proxy.git_worktree_add(repo.Handle, name, path, options))
{
return new Worktree(
repo,
name,
Proxy.git_worktree_is_locked(handle));
}
}
/// <summary>
///
/// </summary>
/// <param name="worktree"></param>
/// <returns></returns>
public virtual bool Prune(Worktree worktree)
{
return Prune(worktree, false);
}
/// <summary>
///
/// </summary>
/// <param name="worktree"></param>
/// <param name="ifLocked"></param>
/// <returns></returns>
public virtual bool Prune(Worktree worktree, bool ifLocked)
{
using (var handle = worktree.GetWorktreeHandle())
{
git_worktree_prune_options options = new git_worktree_prune_options
{
version = 1,
// default
flags = GitWorktreePruneOptionFlags.GIT_WORKTREE_PRUNE_WORKING_TREE | GitWorktreePruneOptionFlags.GIT_WORKTREE_PRUNE_VALID
};
if (ifLocked)
{
options.flags |= GitWorktreePruneOptionFlags.GIT_WORKTREE_PRUNE_LOCKED;
}
return Proxy.git_worktree_prune(handle, options);
}
}
internal T Lookup<T>(string name, Func<WorktreeHandle, T> selector, bool throwIfNotFound = false)
{
using (var handle = Proxy.git_worktree_lookup(repo.Handle, name))
{
if (handle != null && Proxy.git_worktree_validate(handle))
{
return selector(handle);
}
if (throwIfNotFound)
{
throw new LibGit2SharpException("Worktree lookup failed for '{0}'.", name);
}
return default(T);
}
}
/// <summary>
/// Returns an enumerator that iterates through the collection.
/// </summary>
/// <returns>An <see cref="IEnumerator{T}"/> object that can be used to iterate through the collection.</returns>
public virtual IEnumerator<Worktree> GetEnumerator()
{
return Proxy.git_worktree_list(repo.Handle)
.Select(n => Lookup(n, handle => new Worktree(repo, n, Proxy.git_worktree_is_locked(handle))))
.GetEnumerator();
}
/// <summary>
/// Returns an enumerator that iterates through the collection.
/// </summary>
/// <returns>An <see cref="IEnumerator"/> object that can be used to iterate through the collection.</returns>
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
private string DebuggerDisplay
{
get
{
return string.Format(CultureInfo.InvariantCulture, "Count = {0}", this.Count());
}
}
}
}