Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/libgit2sharp.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJameson Miller <jamill@microsoft.com>2014-04-22 17:25:49 +0400
committerJameson Miller <jamill@microsoft.com>2014-05-03 07:03:28 +0400
commit90155789aedd51bc8f2ccb122f48977bc0fccc66 (patch)
tree4ee1020c8e6b75552193894fbaa547d54275efad /LibGit2Sharp
parent81cb7603bd106ab6d9eefda97dbebe56039d35bb (diff)
Update Checkout and Merge options
Checkout methods now use CheckoutOptions Merge now takes several options: - Option to specify what is checked out for file conflicts. - Report CheckoutProgress and CheckoutNotify - Option to specify MergeFileFavor Updates for code review feedback
Diffstat (limited to 'LibGit2Sharp')
-rw-r--r--LibGit2Sharp/Branch.cs30
-rw-r--r--LibGit2Sharp/CheckoutCallbacks.cs2
-rw-r--r--LibGit2Sharp/CheckoutFileConflictStrategy.cs43
-rw-r--r--LibGit2Sharp/CheckoutNotificationOptions.cs1
-rw-r--r--LibGit2Sharp/CheckoutOptions.cs37
-rw-r--r--LibGit2Sharp/CloneOptions.cs29
-rw-r--r--LibGit2Sharp/Core/GitCheckoutOpts.cs21
-rw-r--r--LibGit2Sharp/Core/GitCheckoutOptsWrapper.cs98
-rw-r--r--LibGit2Sharp/Core/GitMergeOpts.cs10
-rw-r--r--LibGit2Sharp/IRepository.cs41
-rw-r--r--LibGit2Sharp/LibGit2Sharp.csproj2
-rw-r--r--LibGit2Sharp/MergeOptions.cs120
-rw-r--r--LibGit2Sharp/Repository.cs230
-rw-r--r--LibGit2Sharp/RepositoryExtensions.cs9
14 files changed, 548 insertions, 125 deletions
diff --git a/LibGit2Sharp/Branch.cs b/LibGit2Sharp/Branch.cs
index e13c5c57..1e64b8b9 100644
--- a/LibGit2Sharp/Branch.cs
+++ b/LibGit2Sharp/Branch.cs
@@ -233,9 +233,37 @@ namespace LibGit2Sharp
/// <param name="checkoutModifiers">Options controlling checkout behavior.</param>
/// <param name="onCheckoutProgress">Callback method to report checkout progress updates through.</param>
/// <param name="checkoutNotificationOptions"><see cref="CheckoutNotificationOptions"/> to manage checkout notifications.</param>
+ [Obsolete("This overload will be removed in the next release. Please use Branch.Checkout(CheckoutOptions, Signature) instead.")]
public virtual void Checkout(CheckoutModifiers checkoutModifiers, CheckoutProgressHandler onCheckoutProgress, CheckoutNotificationOptions checkoutNotificationOptions)
{
- repo.Checkout(this, checkoutModifiers, onCheckoutProgress, checkoutNotificationOptions);
+ var options = new CheckoutOptions
+ {
+ CheckoutModifiers = checkoutModifiers,
+ OnCheckoutProgress = onCheckoutProgress,
+ };
+
+ if (checkoutNotificationOptions != null)
+ {
+ options.OnCheckoutNotify = checkoutNotificationOptions.CheckoutNotifyHandler;
+ options.CheckoutNotifyFlags = checkoutNotificationOptions.NotifyFlags;
+ }
+
+ Checkout(options, null);
+ }
+
+ /// <summary>
+ /// Checkout the tip commit of this <see cref="Branch"/> object with
+ /// <see cref="CheckoutOptions"/> parameter specifying checkout
+ /// behavior. If this commit is the current tip of the branch, will
+ /// checkout the named branch. Otherwise, will checkout the tip
+ /// commit as a detached HEAD.
+ /// </summary>
+ /// <param name="options"><see cref="CheckoutOptions"/> controlling checkout behavior.</param>
+ /// <param name="signature">Identity for use when updating the reflog.</param>
+ public virtual void Checkout(CheckoutOptions options, Signature signature = null)
+ {
+ Ensure.ArgumentNotNull(options, "options");
+ repo.Checkout(this, options, signature);
}
private Branch ResolveTrackedBranch()
diff --git a/LibGit2Sharp/CheckoutCallbacks.cs b/LibGit2Sharp/CheckoutCallbacks.cs
index fa8817b8..dc03846b 100644
--- a/LibGit2Sharp/CheckoutCallbacks.cs
+++ b/LibGit2Sharp/CheckoutCallbacks.cs
@@ -69,7 +69,7 @@ namespace LibGit2Sharp
/// <param name="onCheckoutProgress"><see cref="CheckoutProgressHandler"/> that should be wrapped in the native callback.</param>
/// <param name="onCheckoutNotify"><see cref="CheckoutNotifyHandler"/> delegate to call in response to checkout notification callback.</param>
/// <returns>The delegate with signature matching the expected native callback.</returns>
- internal static CheckoutCallbacks GenerateCheckoutCallbacks(CheckoutProgressHandler onCheckoutProgress, CheckoutNotifyHandler onCheckoutNotify)
+ internal static CheckoutCallbacks From(CheckoutProgressHandler onCheckoutProgress, CheckoutNotifyHandler onCheckoutNotify)
{
return new CheckoutCallbacks(onCheckoutProgress, onCheckoutNotify);
}
diff --git a/LibGit2Sharp/CheckoutFileConflictStrategy.cs b/LibGit2Sharp/CheckoutFileConflictStrategy.cs
new file mode 100644
index 00000000..578ebe03
--- /dev/null
+++ b/LibGit2Sharp/CheckoutFileConflictStrategy.cs
@@ -0,0 +1,43 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace LibGit2Sharp
+{
+ /// <summary>
+ /// Enum specifying what content checkout should write to disk
+ /// for conflicts.
+ /// </summary>
+ public enum CheckoutFileConflictStrategy
+ {
+ /// <summary>
+ /// Use the default behavior for handling file conflicts. This is
+ /// controlled by the merge.conflictstyle config option, and is "Merge"
+ /// if no option is explicitly set.
+ /// </summary>
+ Normal,
+
+ /// <summary>
+ /// For conflicting files, checkout the "ours" (stage 2) version of
+ /// the file from the index.
+ /// </summary>
+ Ours,
+
+ /// <summary>
+ /// For conflicting files, checkout the "theirs" (stage 3) version of
+ /// the file from the index.
+ /// </summary>
+ Theirs,
+
+ /// <summary>
+ /// Write normal merge files for conflicts.
+ /// </summary>
+ Merge,
+
+ /// <summary>
+ /// Write diff3 formated files for conflicts.
+ /// </summary>
+ Diff3
+ }
+}
diff --git a/LibGit2Sharp/CheckoutNotificationOptions.cs b/LibGit2Sharp/CheckoutNotificationOptions.cs
index 97b5012c..c1d0a167 100644
--- a/LibGit2Sharp/CheckoutNotificationOptions.cs
+++ b/LibGit2Sharp/CheckoutNotificationOptions.cs
@@ -45,6 +45,7 @@ namespace LibGit2Sharp
/// <summary>
/// Class to specify options and callback on CheckoutNotifications.
/// </summary>
+ [Obsolete("This class will be removed in the next release. Specify CheckoutNotification options through CheckoutOptions instead.")]
public class CheckoutNotificationOptions
{
/// <summary>
diff --git a/LibGit2Sharp/CheckoutOptions.cs b/LibGit2Sharp/CheckoutOptions.cs
index 69fd0439..9e297cd4 100644
--- a/LibGit2Sharp/CheckoutOptions.cs
+++ b/LibGit2Sharp/CheckoutOptions.cs
@@ -1,11 +1,12 @@
-using LibGit2Sharp.Handlers;
+using LibGit2Sharp.Core;
+using LibGit2Sharp.Handlers;
namespace LibGit2Sharp
{
/// <summary>
/// Collection of parameters controlling Checkout behavior.
/// </summary>
- public sealed class CheckoutOptions
+ public sealed class CheckoutOptions : IConvertableToGitCheckoutOpts
{
/// <summary>
/// Options controlling checkout behavior.
@@ -13,13 +14,39 @@ namespace LibGit2Sharp
public CheckoutModifiers CheckoutModifiers { get; set; }
/// <summary>
- /// Callback method to report checkout progress updates through.
+ /// The flags specifying what conditions are
+ /// reported through the OnCheckoutNotify delegate.
/// </summary>
+ public CheckoutNotifyFlags CheckoutNotifyFlags { get; set; }
+
+ /// <summary>
+ /// Delegate to be called during checkout for files that match
+ /// desired filter specified with the NotifyFlags property.
+ /// </summary>
+ public CheckoutNotifyHandler OnCheckoutNotify { get; set; }
+
+ /// Delegate through which checkout will notify callers of
+ /// certain conditions. The conditions that are reported is
+ /// controlled with the CheckoutNotifyFlags property.
public CheckoutProgressHandler OnCheckoutProgress { get; set; }
+ CheckoutStrategy IConvertableToGitCheckoutOpts.CheckoutStrategy
+ {
+ get
+ {
+ return CheckoutModifiers.HasFlag(CheckoutModifiers.Force) ?
+ CheckoutStrategy.GIT_CHECKOUT_FORCE : CheckoutStrategy.GIT_CHECKOUT_SAFE;
+ }
+ }
+
/// <summary>
- /// Options to manage checkout notifications.
+ /// Generate a <see cref="CheckoutCallbacks"/> object with the delegates
+ /// hooked up to the native callbacks.
/// </summary>
- public CheckoutNotificationOptions CheckoutNotificationOptions { get; set; }
+ /// <returns></returns>
+ CheckoutCallbacks IConvertableToGitCheckoutOpts.GenerateCallbacks()
+ {
+ return CheckoutCallbacks.From(OnCheckoutProgress, OnCheckoutNotify);
+ }
}
}
diff --git a/LibGit2Sharp/CloneOptions.cs b/LibGit2Sharp/CloneOptions.cs
index 09e513f7..65b98bd0 100644
--- a/LibGit2Sharp/CloneOptions.cs
+++ b/LibGit2Sharp/CloneOptions.cs
@@ -1,11 +1,12 @@
-using LibGit2Sharp.Handlers;
+using LibGit2Sharp.Core;
+using LibGit2Sharp.Handlers;
namespace LibGit2Sharp
{
/// <summary>
/// Options to define clone behaviour
/// </summary>
- public sealed class CloneOptions
+ public sealed class CloneOptions : IConvertableToGitCheckoutOpts
{
/// <summary>
/// Creates default <see cref="CloneOptions"/> for a non-bare clone
@@ -40,5 +41,29 @@ namespace LibGit2Sharp
/// Credentials to use for user/pass authentication
/// </summary>
public Credentials Credentials { get; set; }
+
+ #region IConvertableToGitCheckoutOpts
+
+ CheckoutCallbacks IConvertableToGitCheckoutOpts.GenerateCallbacks()
+ {
+ return CheckoutCallbacks.From(OnCheckoutProgress, null);
+ }
+
+ CheckoutStrategy IConvertableToGitCheckoutOpts.CheckoutStrategy
+ {
+ get
+ {
+ return this.Checkout ?
+ CheckoutStrategy.GIT_CHECKOUT_SAFE_CREATE :
+ CheckoutStrategy.GIT_CHECKOUT_NONE;
+ }
+ }
+
+ CheckoutNotifyFlags IConvertableToGitCheckoutOpts.CheckoutNotifyFlags
+ {
+ get { return CheckoutNotifyFlags.None; }
+ }
+
+ #endregion
}
}
diff --git a/LibGit2Sharp/Core/GitCheckoutOpts.cs b/LibGit2Sharp/Core/GitCheckoutOpts.cs
index ca694395..214251d6 100644
--- a/LibGit2Sharp/Core/GitCheckoutOpts.cs
+++ b/LibGit2Sharp/Core/GitCheckoutOpts.cs
@@ -120,7 +120,7 @@ namespace LibGit2Sharp.Core
IntPtr payload);
[StructLayout(LayoutKind.Sequential)]
- internal struct GitCheckoutOpts :IDisposable
+ internal struct GitCheckoutOpts
{
public uint version;
@@ -146,15 +146,18 @@ namespace LibGit2Sharp.Core
public IntPtr ancestor_label;
public IntPtr our_label;
public IntPtr their_label;
+ }
+
+ /// <summary>
+ /// An inteface for objects that specify parameters from which a
+ /// GitCheckoutOpts struct can be populated.
+ /// </summary>
+ internal interface IConvertableToGitCheckoutOpts
+ {
+ CheckoutCallbacks GenerateCallbacks();
- public void Dispose()
- {
- if (paths == null)
- {
- return;
- }
+ CheckoutStrategy CheckoutStrategy { get; }
- paths.Dispose();
- }
+ CheckoutNotifyFlags CheckoutNotifyFlags { get; }
}
}
diff --git a/LibGit2Sharp/Core/GitCheckoutOptsWrapper.cs b/LibGit2Sharp/Core/GitCheckoutOptsWrapper.cs
new file mode 100644
index 00000000..b98a5cd9
--- /dev/null
+++ b/LibGit2Sharp/Core/GitCheckoutOptsWrapper.cs
@@ -0,0 +1,98 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace LibGit2Sharp.Core
+{
+ /// <summary>
+ /// A wrapper around the native GitCheckoutOpts structure. This class is responsible
+ /// for the managed objects that the native code points to.
+ /// </summary>
+ internal class GitCheckoutOptsWrapper : IDisposable
+ {
+ /// <summary>
+ /// Create wrapper around <see cref="GitCheckoutOpts"/> from <see cref="CheckoutOptions"/>.
+ /// </summary>
+ /// <param name="options">Options to create native GitCheckoutOpts structure from.</param>
+ /// <param name="paths">Paths to checkout.</param>
+ public GitCheckoutOptsWrapper(IConvertableToGitCheckoutOpts options, FilePath[] paths = null)
+ {
+ Callbacks = options.GenerateCallbacks();
+
+ if (paths != null)
+ {
+ PathArray = GitStrArrayIn.BuildFrom(paths);
+ }
+
+ Options = new GitCheckoutOpts
+ {
+ version = 1,
+ checkout_strategy = options.CheckoutStrategy,
+ progress_cb = Callbacks.CheckoutProgressCallback,
+ notify_cb = Callbacks.CheckoutNotifyCallback,
+ notify_flags = options.CheckoutNotifyFlags,
+ paths = PathArray,
+ };
+ }
+
+ /// <summary>
+ /// Native struct to pass to libgit.
+ /// </summary>
+ public GitCheckoutOpts Options { get; set; }
+
+ /// <summary>
+ /// The managed class mapping native callbacks into the
+ /// corresponding managed delegate.
+ /// </summary>
+ public CheckoutCallbacks Callbacks { get; private set; }
+
+ /// <summary>
+ /// Keep the paths around so we can dispose them.
+ /// </summary>
+ private GitStrArrayIn PathArray;
+
+ public void Dispose()
+ {
+ Dispose(true);
+ }
+
+ private void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ if (PathArray != null)
+ {
+ PathArray.Dispose();
+ PathArray = null;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Method to translate from <see cref="CheckoutFileConflictStrategy"/> to <see cref="CheckoutStrategy"/> flags.
+ /// </summary>
+ internal static CheckoutStrategy CheckoutStrategyFromFileConflictStrategy(CheckoutFileConflictStrategy fileConflictStrategy)
+ {
+ CheckoutStrategy flags = default(CheckoutStrategy);
+
+ switch (fileConflictStrategy)
+ {
+ case CheckoutFileConflictStrategy.Ours:
+ flags = CheckoutStrategy.GIT_CHECKOUT_USE_OURS;
+ break;
+ case CheckoutFileConflictStrategy.Theirs:
+ flags = CheckoutStrategy.GIT_CHECKOUT_USE_THEIRS;
+ break;
+ case CheckoutFileConflictStrategy.Merge:
+ flags = CheckoutStrategy.GIT_CHECKOUT_CONFLICT_STYLE_MERGE;
+ break;
+ case CheckoutFileConflictStrategy.Diff3:
+ flags = CheckoutStrategy.GIT_CHECKOUT_CONFLICT_STYLE_DIFF3;
+ break;
+ }
+
+ return flags;
+ }
+ }
+}
diff --git a/LibGit2Sharp/Core/GitMergeOpts.cs b/LibGit2Sharp/Core/GitMergeOpts.cs
index 36ccd45f..0c677817 100644
--- a/LibGit2Sharp/Core/GitMergeOpts.cs
+++ b/LibGit2Sharp/Core/GitMergeOpts.cs
@@ -30,7 +30,7 @@ namespace LibGit2Sharp.Core
/// <summary>
/// Flags for automerging content.
/// </summary>
- public GitMergeFileFavorFlags MergeFileFavorFlags;
+ public MergeFileFavor MergeFileFavorFlags;
}
/// <summary>
@@ -84,12 +84,4 @@ namespace LibGit2Sharp.Core
/// </summary>
GIT_MERGE_TREE_FIND_RENAMES = (1 << 0),
}
-
- internal enum GitMergeFileFavorFlags
- {
- GIT_MERGE_FILE_FAVOR_NORMAL = 0,
- GIT_MERGE_FILE_FAVOR_OURS = 1,
- GIT_MERGE_FILE_FAVOR_THEIRS = 2,
- GIT_MERGE_FILE_FAVOR_UNION = 3,
- }
}
diff --git a/LibGit2Sharp/IRepository.cs b/LibGit2Sharp/IRepository.cs
index 44e40d2a..28ce2989 100644
--- a/LibGit2Sharp/IRepository.cs
+++ b/LibGit2Sharp/IRepository.cs
@@ -83,6 +83,7 @@ namespace LibGit2Sharp
/// <param name="checkoutNotificationOptions"><see cref="CheckoutNotificationOptions"/> to manage checkout notifications.</param>
/// <param name="signature">Identity for use when updating the reflog.</param>
/// <returns>The <see cref="Branch"/> that was checked out.</returns>
+ [Obsolete("This overload will be removed in the next release. Please use Repository.Checkout(Branch, CheckoutOptions, Signature) instead.")]
Branch Checkout(Branch branch, CheckoutModifiers checkoutModifiers, CheckoutProgressHandler onCheckoutProgress, CheckoutNotificationOptions checkoutNotificationOptions, Signature signature = null);
/// <summary>
@@ -98,6 +99,7 @@ namespace LibGit2Sharp
/// <param name="checkoutNotificationOptions"><see cref="CheckoutNotificationOptions"/> to manage checkout notifications.</param>
/// <param name="signature">Identity for use when updating the reflog.</param>
/// <returns>The <see cref="Branch"/> that was checked out.</returns>
+ [Obsolete("This overload will be removed in the next release. Please use Repository.Checkout(string, CheckoutOptions, Signature) instead.")]
Branch Checkout(string committishOrBranchSpec, CheckoutModifiers checkoutModifiers, CheckoutProgressHandler onCheckoutProgress, CheckoutNotificationOptions checkoutNotificationOptions, Signature signature = null);
/// <summary>
@@ -112,9 +114,48 @@ namespace LibGit2Sharp
/// <param name="checkoutNotificationOptions"><see cref="CheckoutNotificationOptions"/> to manage checkout notifications.</param>
/// <param name="signature">Identity for use when updating the reflog.</param>
/// <returns>The <see cref="Branch"/> that was checked out.</returns>
+ [Obsolete("This overload will be removed in the next release. Please use Repository.Checkout(Commit, CheckoutOptions, Signature) instead.")]
Branch Checkout(Commit commit, CheckoutModifiers checkoutModifiers, CheckoutProgressHandler onCheckoutProgress, CheckoutNotificationOptions checkoutNotificationOptions, Signature signature = null);
/// <summary>
+ /// Checkout the commit pointed at by the tip of the specified <see cref="Branch"/>.
+ /// <para>
+ /// If this commit is the current tip of the branch as it exists in the repository, the HEAD
+ /// will point to this branch. Otherwise, the HEAD will be detached, pointing at the commit sha.
+ /// </para>
+ /// </summary>
+ /// <param name="branch">The <see cref="Branch"/> to check out.</param>
+ /// <param name="options"><see cref="CheckoutOptions"/> controlling checkout behavior.</param>
+ /// <param name="signature">Identity for use when updating the reflog.</param>
+ /// <returns>The <see cref="Branch"/> that was checked out.</returns>
+ Branch Checkout(Branch branch, CheckoutOptions options, Signature signature = null);
+
+ /// <summary>
+ /// Checkout the specified branch, reference or SHA.
+ /// <para>
+ /// If the committishOrBranchSpec parameter resolves to a branch name, then the checked out HEAD will
+ /// will point to the branch. Otherwise, the HEAD will be detached, pointing at the commit sha.
+ /// </para>
+ /// </summary>
+ /// <param name="committishOrBranchSpec">A revparse spec for the commit or branch to checkout.</param>
+ /// <param name="options"><see cref="CheckoutOptions"/> controlling checkout behavior.</param>
+ /// <param name="signature">Identity for use when updating the reflog.</param>
+ /// <returns>The <see cref="Branch"/> that was checked out.</returns>
+ Branch Checkout(string committishOrBranchSpec, CheckoutOptions options, Signature signature = null);
+
+ /// <summary>
+ /// Checkout the specified <see cref="LibGit2Sharp.Commit"/>.
+ /// <para>
+ /// Will detach the HEAD and make it point to this commit sha.
+ /// </para>
+ /// </summary>
+ /// <param name="commit">The <see cref="LibGit2Sharp.Commit"/> to check out.</param>
+ /// <param name="options"><see cref="CheckoutOptions"/> controlling checkout behavior.</param>
+ /// <param name="signature">Identity for use when updating the reflog.</param>
+ /// <returns>The <see cref="Branch"/> that was checked out.</returns>
+ Branch Checkout(Commit commit, CheckoutOptions options, Signature signature = null);
+
+ /// <summary>
/// Updates specifed paths in the index and working directory with the versions from the specified branch, reference, or SHA.
/// <para>
/// This method does not switch branches or update the current repository HEAD.
diff --git a/LibGit2Sharp/LibGit2Sharp.csproj b/LibGit2Sharp/LibGit2Sharp.csproj
index 566e4005..e8261962 100644
--- a/LibGit2Sharp/LibGit2Sharp.csproj
+++ b/LibGit2Sharp/LibGit2Sharp.csproj
@@ -69,6 +69,7 @@
<Compile Include="BranchTrackingDetails.cs" />
<Compile Include="BranchUpdater.cs" />
<Compile Include="CheckoutCallbacks.cs" />
+ <Compile Include="CheckoutFileConflictStrategy.cs" />
<Compile Include="CheckoutModifiers.cs" />
<Compile Include="CheckoutNotificationOptions.cs" />
<Compile Include="CheckoutOptions.cs" />
@@ -79,6 +80,7 @@
<Compile Include="CompareOptions.cs" />
<Compile Include="ContentChangeStats.cs" />
<Compile Include="Core\GitBuiltInFeatures.cs" />
+ <Compile Include="Core\GitCheckoutOptsWrapper.cs" />
<Compile Include="Core\GitCredentialType.cs" />
<Compile Include="Core\Handles\PatchSafeHandle.cs" />
<Compile Include="Core\IntPtrExtensions.cs" />
diff --git a/LibGit2Sharp/MergeOptions.cs b/LibGit2Sharp/MergeOptions.cs
index 06eb13ce..be25665e 100644
--- a/LibGit2Sharp/MergeOptions.cs
+++ b/LibGit2Sharp/MergeOptions.cs
@@ -1,22 +1,40 @@
-
+using LibGit2Sharp.Core;
+using LibGit2Sharp.Handlers;
+
namespace LibGit2Sharp
{
/// <summary>
/// Options controlling Merge behavior.
/// </summary>
- public sealed class MergeOptions
+ public sealed class MergeOptions : IConvertableToGitCheckoutOpts
{
/// <summary>
/// Initializes a new instance of the <see cref="MergeOptions"/> class.
- /// By default, a fast-forward merge will be performed if possible, and
- /// if a merge commit is created, then it will be commited.
+ /// <para>
+ /// Default behavior:
+ /// A fast-forward merge will be performed if possible.
+ /// A merge commit will be committed, if one was created.
+ /// Merge will attempt to find renames.
+ /// </para>
/// </summary>
public MergeOptions()
{
CommitOnSuccess = true;
+
+ FindRenames = true;
+ // TODO: libgit2 should provide reasonable defaults for these
+ // values, but it currently does not.
+ RenameThreshold = 50;
+ TargetLimit = 200;
}
/// <summary>
+ /// The Flags specifying what conditions are
+ /// reported through the OnCheckoutNotify delegate.
+ /// </summary>
+ public CheckoutNotifyFlags CheckoutNotifyFlags { get; set; }
+
+ /// <summary>
/// Commit the merge if the merge is successful and this is a non-fast-forward merge.
/// If this is a fast-forward merge, then there is no merge commit and this option
/// will not affect the merge.
@@ -27,6 +45,63 @@ namespace LibGit2Sharp
/// The type of merge to perform.
/// </summary>
public FastForwardStrategy FastForwardStrategy { get; set; }
+
+ /// <summary>
+ /// How conflicting index entries should be written out during checkout.
+ /// </summary>
+ public CheckoutFileConflictStrategy FileConflictStrategy { get; set; }
+
+ /// <summary>
+ /// Find renames. Default is true.
+ /// </summary>
+ public bool FindRenames { get; set; }
+
+ /// <summary>
+ /// Similarity to consider a file renamed.
+ /// </summary>
+ public int RenameThreshold;
+
+ /// <summary>
+ /// Maximum similarity sources to examine (overrides
+ /// 'merge.renameLimit' config (default 200)
+ /// </summary>
+ public int TargetLimit;
+
+ /// <summary>
+ /// How to handle conflicts encountered during a merge.
+ /// </summary>
+ public MergeFileFavor MergeFileFavor { get; set; }
+
+ /// <summary>
+ /// Delegate that the checkout will report progress through.
+ /// </summary>
+ public CheckoutProgressHandler OnCheckoutProgress { get; set; }
+
+ /// <summary>
+ /// Delegate that checkout will notify callers of
+ /// certain conditions. The conditions that are reported is
+ /// controlled with the CheckoutNotifyFlags property.
+ /// </summary>
+ public CheckoutNotifyHandler OnCheckoutNotify { get; set; }
+
+ #region IConvertableToGitCheckoutOpts
+
+ CheckoutCallbacks IConvertableToGitCheckoutOpts.GenerateCallbacks()
+ {
+ return CheckoutCallbacks.From(OnCheckoutProgress, OnCheckoutNotify);
+ }
+
+ CheckoutStrategy IConvertableToGitCheckoutOpts.CheckoutStrategy
+ {
+ get
+ {
+ return CheckoutStrategy.GIT_CHECKOUT_SAFE|
+ CheckoutStrategy.GIT_CHECKOUT_ALLOW_CONFLICTS |
+ GitCheckoutOptsWrapper.CheckoutStrategyFromFileConflictStrategy(FileConflictStrategy);
+ }
+ }
+
+ #endregion
}
/// <summary>
@@ -51,4 +126,41 @@ namespace LibGit2Sharp
/// </summary>
FastForwardOnly = 2, /* GIT_MERGE_FASTFORWARD_ONLY */
}
+
+ /// <summary>
+ /// Enum specifying how merge should deal with conflicting regions
+ /// of the files.
+ /// </summary>
+ public enum MergeFileFavor
+ {
+ /// <summary>
+ /// When a region of a file is changed in both branches, a conflict
+ /// will be recorded in the index so that the checkout operation can produce
+ /// a merge file with conflict markers in the working directory.
+ /// This is the default.
+ /// </summary>
+ Normal = 0,
+
+ /// <summary>
+ /// When a region of a file is changed in both branches, the file
+ /// created in the index will contain the "ours" side of any conflicting
+ /// region. The index will not record a conflict.
+ /// </summary>
+ Ours = 1,
+
+ /// <summary>
+ /// When a region of a file is changed in both branches, the file
+ /// created in the index will contain the "theirs" side of any conflicting
+ /// region. The index will not record a conflict.
+ /// </summary>
+ Theirs = 2,
+
+ /// <summary>
+ /// When a region of a file is changed in both branches, the file
+ /// created in the index will contain each unique line from each side,
+ /// which has the result of combining both files. The index will not
+ /// record a conflict.
+ /// </summary>
+ Union = 3,
+ }
}
diff --git a/LibGit2Sharp/Repository.cs b/LibGit2Sharp/Repository.cs
index ce99a25e..36ffc279 100644
--- a/LibGit2Sharp/Repository.cs
+++ b/LibGit2Sharp/Repository.cs
@@ -549,36 +549,29 @@ namespace LibGit2Sharp
{
options = options ?? new CloneOptions();
- CheckoutCallbacks checkoutCallbacks = CheckoutCallbacks.GenerateCheckoutCallbacks(
- options.OnCheckoutProgress, null);
+ using (GitCheckoutOptsWrapper checkoutOptionsWrapper = new GitCheckoutOptsWrapper(options))
+ {
+ var gitCheckoutOptions = checkoutOptionsWrapper.Options;
- var callbacks = new RemoteCallbacks(null, options.OnTransferProgress, null,
- options.Credentials);
- GitRemoteCallbacks gitCallbacks = callbacks.GenerateCallbacks();
+ var remoteCallbacks = new RemoteCallbacks(null, options.OnTransferProgress, null, options.Credentials);
+ var gitRemoteCallbacks = remoteCallbacks.GenerateCallbacks();
- var cloneOpts = new GitCloneOptions
- {
- Version = 1,
- Bare = options.IsBare ? 1 : 0,
- CheckoutOpts =
+ var cloneOpts = new GitCloneOptions
{
- version = 1,
- progress_cb =
- checkoutCallbacks.CheckoutProgressCallback,
- checkout_strategy = options.Checkout
- ? CheckoutStrategy.GIT_CHECKOUT_SAFE_CREATE
- : CheckoutStrategy.GIT_CHECKOUT_NONE
- },
- RemoteCallbacks = gitCallbacks,
- };
+ Version = 1,
+ Bare = options.IsBare ? 1 : 0,
+ CheckoutOpts = gitCheckoutOptions,
+ RemoteCallbacks = gitRemoteCallbacks,
+ };
- FilePath repoPath;
- using (RepositorySafeHandle repo = Proxy.git_clone(sourceUrl, workdirPath, ref cloneOpts))
- {
- repoPath = Proxy.git_repository_path(repo);
- }
+ FilePath repoPath;
+ using (RepositorySafeHandle repo = Proxy.git_clone(sourceUrl, workdirPath, ref cloneOpts))
+ {
+ repoPath = Proxy.git_repository_path(repo);
+ }
- return repoPath.Native;
+ return repoPath.Native;
+ }
}
/// <summary>
@@ -605,9 +598,39 @@ namespace LibGit2Sharp
/// <param name="checkoutNotifications"><see cref="CheckoutNotificationOptions"/> to manage checkout notifications.</param>
/// <param name="signature">Identity for use when updating the reflog.</param>
/// <returns>The <see cref="Branch"/> that was checked out.</returns>
+ [Obsolete("This overload will be removed in the next release. Please use Repository.Checkout(string, CheckoutOptions, Signature) instead.")]
public Branch Checkout(string committishOrBranchSpec, CheckoutModifiers checkoutModifiers, CheckoutProgressHandler onCheckoutProgress, CheckoutNotificationOptions checkoutNotifications, Signature signature = null)
{
+ var options = new CheckoutOptions()
+ {
+ CheckoutModifiers = checkoutModifiers,
+ OnCheckoutProgress = onCheckoutProgress
+ };
+
+ if (checkoutNotifications != null)
+ {
+ options.OnCheckoutNotify = checkoutNotifications.CheckoutNotifyHandler;
+ options.CheckoutNotifyFlags = checkoutNotifications.NotifyFlags;
+ }
+
+ return Checkout(committishOrBranchSpec, options, signature);
+ }
+
+ /// <summary>
+ /// Checkout the specified <see cref="Branch"/>, reference or SHA.
+ /// <para>
+ /// If the committishOrBranchSpec parameter resolves to a branch name, then the checked out HEAD will
+ /// will point to the branch. Otherwise, the HEAD will be detached, pointing at the commit sha.
+ /// </para>
+ /// </summary>
+ /// <param name="committishOrBranchSpec">A revparse spec for the commit or branch to checkout.</param>
+ /// <param name="options"><see cref="CheckoutOptions"/> controlling checkout behavior.</param>
+ /// <param name="signature">Identity for use when updating the reflog.</param>
+ /// <returns>The <see cref="Branch"/> that was checked out.</returns>
+ public Branch Checkout(string committishOrBranchSpec, CheckoutOptions options, Signature signature = null)
+ {
Ensure.ArgumentNotNullOrEmptyString(committishOrBranchSpec, "committishOrBranchSpec");
+ Ensure.ArgumentNotNull(options, "options");
var handles = Proxy.git_revparse_ext(Handle, committishOrBranchSpec);
if (handles == null)
@@ -626,7 +649,7 @@ namespace LibGit2Sharp
if (reference.IsLocalBranch())
{
Branch branch = Branches[reference.CanonicalName];
- return Checkout(branch, checkoutModifiers, onCheckoutProgress, checkoutNotifications);
+ return Checkout(branch, options, signature);
}
}
@@ -640,7 +663,7 @@ namespace LibGit2Sharp
}
Commit commit = obj.DereferenceToCommit(true);
- Checkout(commit.Tree, checkoutModifiers, onCheckoutProgress, checkoutNotifications, commit.Id.Sha, committishOrBranchSpec, signature);
+ Checkout(commit.Tree, options, commit.Id.Sha, committishOrBranchSpec, signature);
return Head;
}
@@ -656,10 +679,40 @@ namespace LibGit2Sharp
/// <param name="checkoutNotificationOptions"><see cref="CheckoutNotificationOptions"/> to manage checkout notifications.</param>
/// <param name="signature">Identity for use when updating the reflog.</param>
/// <returns>The <see cref="Branch"/> that was checked out.</returns>
+ [Obsolete("This overload will be removed in the next release. Please use Repository.Checkout(Branch, CheckoutOptions, Signature) instead.")]
public Branch Checkout(Branch branch, CheckoutModifiers checkoutModifiers, CheckoutProgressHandler onCheckoutProgress, CheckoutNotificationOptions checkoutNotificationOptions, Signature signature = null)
{
Ensure.ArgumentNotNull(branch, "branch");
+ var options = new CheckoutOptions
+ {
+ CheckoutModifiers = checkoutModifiers,
+ OnCheckoutProgress = onCheckoutProgress,
+ };
+
+ if (checkoutNotificationOptions != null)
+ {
+ options.OnCheckoutNotify = checkoutNotificationOptions.CheckoutNotifyHandler;
+ options.CheckoutNotifyFlags = checkoutNotificationOptions.NotifyFlags;
+ }
+
+ return Checkout(branch, options, signature);
+ }
+
+ /// <summary>
+ /// Checkout the tip commit of the specified <see cref="Branch"/> object. If this commit is the
+ /// current tip of the branch, will checkout the named branch. Otherwise, will checkout the tip commit
+ /// as a detached HEAD.
+ /// </summary>
+ /// <param name="branch">The <see cref="Branch"/> to check out.</param>
+ /// <param name="options"><see cref="CheckoutOptions"/> controlling checkout behavior.</param>
+ /// <param name="signature">Identity for use when updating the reflog.</param>
+ /// <returns>The <see cref="Branch"/> that was checked out.</returns>
+ public Branch Checkout(Branch branch, CheckoutOptions options, Signature signature = null)
+ {
+ Ensure.ArgumentNotNull(branch, "branch");
+ Ensure.ArgumentNotNull(options, "options");
+
// Make sure this is not an unborn branch.
if (branch.Tip == null)
{
@@ -672,11 +725,11 @@ namespace LibGit2Sharp
string.Equals(Refs[branch.CanonicalName].TargetIdentifier, branch.Tip.Id.Sha,
StringComparison.OrdinalIgnoreCase))
{
- Checkout(branch.Tip.Tree, checkoutModifiers, onCheckoutProgress, checkoutNotificationOptions, branch.CanonicalName, branch.Name, signature);
+ Checkout(branch.Tip.Tree, options, branch.CanonicalName, branch.Name, signature);
}
else
{
- Checkout(branch.Tip.Tree, checkoutModifiers, onCheckoutProgress, checkoutNotificationOptions, branch.Tip.Id.Sha, branch.Name, signature);
+ Checkout(branch.Tip.Tree, options, branch.Tip.Id.Sha, branch.Name, signature);
}
return Head;
@@ -694,9 +747,43 @@ namespace LibGit2Sharp
/// <param name="checkoutNotificationOptions"><see cref="CheckoutNotificationOptions"/> to manage checkout notifications.</param>
/// <param name="signature">Identity for use when updating the reflog.</param>
/// <returns>The <see cref="Branch"/> that was checked out.</returns>
+ [Obsolete("This overload will be removed in the next release. Please use Repository.Checkout(Commit, CheckoutOptions, Signature) instead.")]
public Branch Checkout(Commit commit, CheckoutModifiers checkoutModifiers, CheckoutProgressHandler onCheckoutProgress, CheckoutNotificationOptions checkoutNotificationOptions, Signature signature = null)
{
- Checkout(commit.Tree, checkoutModifiers, onCheckoutProgress, checkoutNotificationOptions, commit.Id.Sha, commit.Id.Sha, signature);
+
+ var options = new CheckoutOptions
+ {
+ CheckoutModifiers = checkoutModifiers,
+ OnCheckoutProgress = onCheckoutProgress,
+ };
+
+ if (checkoutNotificationOptions != null)
+ {
+ options.OnCheckoutNotify = checkoutNotificationOptions.CheckoutNotifyHandler;
+ options.CheckoutNotifyFlags = checkoutNotificationOptions.NotifyFlags;
+ }
+
+ Checkout(commit.Tree, options, commit.Id.Sha, commit.Id.Sha, signature);
+
+ return Head;
+ }
+
+ /// <summary>
+ /// Checkout the specified <see cref="LibGit2Sharp.Commit"/>.
+ /// <para>
+ /// Will detach the HEAD and make it point to this commit sha.
+ /// </para>
+ /// </summary>
+ /// <param name="commit">The <see cref="LibGit2Sharp.Commit"/> to check out.</param>
+ /// <param name="options"><see cref="CheckoutOptions"/> controlling checkout behavior.</param>
+ /// <param name="signature">Identity for use when updating the reflog.</param>
+ /// <returns>The <see cref="Branch"/> that was checked out.</returns>
+ public Branch Checkout(Commit commit, CheckoutOptions options, Signature signature = null)
+ {
+ Ensure.ArgumentNotNull(commit, "commit");
+ Ensure.ArgumentNotNull(options, "options");
+
+ Checkout(commit.Tree, options, commit.Id.Sha, commit.Id.Sha, signature);
return Head;
}
@@ -706,29 +793,18 @@ namespace LibGit2Sharp
/// to already be in the form of a canonical branch name or a commit ID.
/// </summary>
/// <param name="tree">The <see cref="Tree"/> to checkout.</param>
- /// <param name="checkoutModifiers"><see cref="CheckoutModifiers"/> controlling checkout behavior.</param>
- /// <param name="onCheckoutProgress"><see cref="CheckoutProgressHandler"/> that checkout progress is reported through.</param>
- /// <param name="checkoutNotificationOptions"><see cref="CheckoutNotificationOptions"/> to manage checkout notifications.</param>
+ /// <param name="checkoutOptions"><see cref="CheckoutOptions"/> controlling checkout behavior.</param>
/// <param name="headTarget">Target for the new HEAD.</param>
/// <param name="refLogHeadSpec">The spec which will be written as target in the reflog.</param>
/// <param name="signature">Identity for use when updating the reflog.</param>
private void Checkout(
Tree tree,
- CheckoutModifiers checkoutModifiers,
- CheckoutProgressHandler onCheckoutProgress,
- CheckoutNotificationOptions checkoutNotificationOptions,
+ CheckoutOptions checkoutOptions,
string headTarget, string refLogHeadSpec, Signature signature)
{
var previousHeadName = Info.IsHeadDetached ? Head.Tip.Sha : Head.Name;
- var opts = new CheckoutOptions
- {
- CheckoutModifiers = checkoutModifiers,
- OnCheckoutProgress = onCheckoutProgress,
- CheckoutNotificationOptions = checkoutNotificationOptions
- };
-
- CheckoutTree(tree, null, opts);
+ CheckoutTree(tree, null, checkoutOptions);
Refs.UpdateTarget("HEAD", headTarget, signature,
string.Format(
@@ -745,37 +821,14 @@ namespace LibGit2Sharp
private void CheckoutTree(
Tree tree,
IList<string> paths,
- CheckoutOptions opts)
+ IConvertableToGitCheckoutOpts opts)
{
- CheckoutNotifyHandler onCheckoutNotify = opts.CheckoutNotificationOptions != null ? opts.CheckoutNotificationOptions.CheckoutNotifyHandler : null;
- CheckoutNotifyFlags checkoutNotifyFlags = opts.CheckoutNotificationOptions != null ? opts.CheckoutNotificationOptions.NotifyFlags : default(CheckoutNotifyFlags);
- CheckoutCallbacks checkoutCallbacks = CheckoutCallbacks.GenerateCheckoutCallbacks(opts.OnCheckoutProgress, onCheckoutNotify);
-
- GitStrArrayIn strArray = (paths != null && paths.Count > 0) ? GitStrArrayIn.BuildFrom(ToFilePaths(paths)) : null;
-
- var options = new GitCheckoutOpts
- {
- version = 1,
- checkout_strategy = CheckoutStrategy.GIT_CHECKOUT_SAFE,
- progress_cb = checkoutCallbacks.CheckoutProgressCallback,
- notify_cb = checkoutCallbacks.CheckoutNotifyCallback,
- notify_flags = checkoutNotifyFlags,
- paths = strArray
- };
- try
+ using(GitCheckoutOptsWrapper checkoutOptionsWrapper = new GitCheckoutOptsWrapper(opts, ToFilePaths(paths)))
{
- if (opts.CheckoutModifiers.HasFlag(CheckoutModifiers.Force))
- {
- options.checkout_strategy = CheckoutStrategy.GIT_CHECKOUT_FORCE;
- }
-
+ var options = checkoutOptionsWrapper.Options;
Proxy.git_checkout_tree(Handle, tree.Id, ref options);
}
- finally
- {
- options.Dispose();
- }
}
/// <summary>
@@ -977,14 +1030,7 @@ namespace LibGit2Sharp
| CheckoutStrategy.GIT_CHECKOUT_ALLOW_CONFLICTS,
};
- try
- {
- Proxy.git_checkout_index(Handle, new NullGitObjectSafeHandle(), ref options);
- }
- finally
- {
- options.Dispose();
- }
+ Proxy.git_checkout_index(Handle, new NullGitObjectSafeHandle(), ref options);
}
private void CleanupDisposableDependencies()
@@ -1168,7 +1214,7 @@ namespace LibGit2Sharp
throw new LibGit2SharpException("Unable to perform Fast-Forward merge with mith multiple merge heads.");
}
- mergeResult = FastForwardMerge(mergeHeads[0], merger);
+ mergeResult = FastForwardMerge(mergeHeads[0], merger, options);
}
else if (mergeAnalysis.HasFlag(GitMergeAnalysis.GIT_MERGE_ANALYSIS_NORMAL))
{
@@ -1184,7 +1230,7 @@ namespace LibGit2Sharp
throw new LibGit2SharpException("Unable to perform Fast-Forward merge with mith multiple merge heads.");
}
- mergeResult = FastForwardMerge(mergeHeads[0], merger);
+ mergeResult = FastForwardMerge(mergeHeads[0], merger, options);
}
else
{
@@ -1226,15 +1272,20 @@ namespace LibGit2Sharp
var mergeOptions = new GitMergeOpts
{
- Version = 1
+ Version = 1,
+ MergeFileFavorFlags = options.MergeFileFavor,
+ MergeTreeFlags = options.FindRenames ? GitMergeTreeFlags.GIT_MERGE_TREE_FIND_RENAMES :
+ GitMergeTreeFlags.GIT_MERGE_TREE_NORMAL,
+ RenameThreshold = (uint) options.RenameThreshold,
+ TargetLimit = (uint) options.TargetLimit,
};
- var checkoutOpts = new GitCheckoutOpts
+ using (GitCheckoutOptsWrapper checkoutOptionsWrapper = new GitCheckoutOptsWrapper(options))
{
- version = 1
- };
+ var checkoutOpts = checkoutOptionsWrapper.Options;
- Proxy.git_merge(Handle, mergeHeads, mergeOptions, checkoutOpts);
+ Proxy.git_merge(Handle, mergeHeads, mergeOptions, checkoutOpts);
+ }
if (Index.IsFullyMerged)
{
@@ -1260,18 +1311,15 @@ namespace LibGit2Sharp
/// </summary>
/// <param name="mergeHead">The merge head handle to fast-forward merge.</param>
/// <param name="merger">The <see cref="Signature"/> of who is performing the merge.</param>
+ /// <param name="options">Options controlling merge behavior.</param>
/// <returns>The <see cref="MergeResult"/> of the merge.</returns>
- private MergeResult FastForwardMerge(GitMergeHeadHandle mergeHead, Signature merger)
+ private MergeResult FastForwardMerge(GitMergeHeadHandle mergeHead, Signature merger, MergeOptions options)
{
ObjectId id = Proxy.git_merge_head_id(mergeHead);
Commit fastForwardCommit = (Commit) Lookup(id, ObjectType.Commit);
Ensure.GitObjectIsNotNull(fastForwardCommit, id.Sha);
- var checkoutOpts = new CheckoutOptions
- {
- CheckoutModifiers = CheckoutModifiers.None,
- };
- CheckoutTree(fastForwardCommit.Tree, null, checkoutOpts);
+ CheckoutTree(fastForwardCommit.Tree, null, options);
var reference = Refs.Head.ResolveToDirectReference();
diff --git a/LibGit2Sharp/RepositoryExtensions.cs b/LibGit2Sharp/RepositoryExtensions.cs
index 8e859072..43907b76 100644
--- a/LibGit2Sharp/RepositoryExtensions.cs
+++ b/LibGit2Sharp/RepositoryExtensions.cs
@@ -254,7 +254,8 @@ namespace LibGit2Sharp
/// <returns>The <see cref="Branch"/> that was checked out.</returns>
public static Branch Checkout(this IRepository repository, string commitOrBranchSpec, Signature signature = null)
{
- return repository.Checkout(commitOrBranchSpec, CheckoutModifiers.None, null, null, signature);
+ CheckoutOptions options = new CheckoutOptions();
+ return repository.Checkout(commitOrBranchSpec, options, signature);
}
/// <summary>
@@ -270,7 +271,8 @@ namespace LibGit2Sharp
/// <returns>The <see cref="Branch"/> that was checked out.</returns>
public static Branch Checkout(this IRepository repository, Branch branch, Signature signature = null)
{
- return repository.Checkout(branch, CheckoutModifiers.None, null, null, signature);
+ CheckoutOptions options = new CheckoutOptions();
+ return repository.Checkout(branch, options, signature);
}
/// <summary>
@@ -285,7 +287,8 @@ namespace LibGit2Sharp
/// <returns>The <see cref="Branch"/> that was checked out.</returns>
public static Branch Checkout(this IRepository repository, Commit commit, Signature signature = null)
{
- return repository.Checkout(commit, CheckoutModifiers.None, null, null, signature);
+ CheckoutOptions options = new CheckoutOptions();
+ return repository.Checkout(commit, options, signature);
}
internal static string BuildRelativePathFrom(this Repository repo, string path)