Skip to content

Commit d522310

Browse files
committed
rebase with submodules fixed.
1 parent 5e36970 commit d522310

File tree

3 files changed

+71
-11
lines changed

3 files changed

+71
-11
lines changed

LibGit2Sharp/LibGit2Sharp.csproj

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
<AssemblyOriginatorKeyFile>..\libgit2sharp.snk</AssemblyOriginatorKeyFile>
1919
<PackageIcon>square-logo.png</PackageIcon>
2020
<PackageLicenseFile>App_Readme/LICENSE.md</PackageLicenseFile>
21+
<DelaySign>false</DelaySign>
2122
</PropertyGroup>
2223

2324
<ItemGroup>

LibGit2Sharp/Rebase.cs

+63-11
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,56 @@ unsafe AnnotatedCommitHandle AnnotatedCommitHandleFromRefHandle(ReferenceHandle
6969
Proxy.git_annotated_commit_from_ref(this.repository.Handle, refHandle);
7070
}
7171

72+
ReferenceHandle RefHandleFrom(Branch b) =>
73+
(b == null) ? null : this.repository.Refs.RetrieveReferencePtr(b.CanonicalName);
74+
75+
ReferenceHandle RefHandleFrom(string name) =>
76+
(name == null) ? null : this.repository.Refs.RetrieveReferencePtr(name);
77+
78+
class RebaseReferenceGuard : IDisposable
79+
{
80+
Reference rf;
81+
Action<Reference> disposeFn;
82+
83+
public RebaseReferenceGuard(Reference rf_, Action<Reference> disposeFn_)
84+
{
85+
rf = rf_;
86+
disposeFn = disposeFn_;
87+
}
88+
89+
public string CanonicalName => rf.CanonicalName;
90+
91+
public void Dispose()
92+
{
93+
disposeFn(rf);
94+
}
95+
}
96+
97+
RebaseReferenceGuard ReferenceFrom(Commit c)
98+
{
99+
if (c == null)
100+
return null;
101+
102+
var rfname = $"refs/rebase/{c.Sha}";
103+
var rf = this.repository.Refs.Resolve<Reference>(rfname);
104+
rf = rf ?? this.repository.Refs.Add(rfname, c.Id);
105+
106+
return new RebaseReferenceGuard(rf, r => { try { this.repository.Refs.Remove(r); } catch { }});
107+
}
108+
109+
public virtual RebaseResult Start(Commit annotated, Commit upstream, Commit onto, Identity committer, RebaseOptions options)
110+
{
111+
Ensure.ArgumentNotNull(upstream, "upstream");
112+
113+
// TODO: Rebase does not work with just references, is that a bug or design feature?
114+
using (var annotatedRef = ReferenceFrom(annotated))
115+
using (var upstreamRef = ReferenceFrom(upstream))
116+
using (var ontoRef = ReferenceFrom(onto))
117+
using (ReferenceHandle annotatedRefPtr = RefHandleFrom(annotatedRef?.CanonicalName))
118+
using (ReferenceHandle upstreamRefPtr = RefHandleFrom(upstreamRef?.CanonicalName))
119+
using (ReferenceHandle ontoRefPtr = RefHandleFrom(ontoRef?.CanonicalName))
120+
return Start(annotatedRefPtr, upstreamRefPtr, ontoRefPtr, committer, options);
121+
}
72122
/// <summary>
73123
/// Start a rebase operation.
74124
/// </summary>
@@ -82,6 +132,16 @@ public virtual RebaseResult Start(Branch branch, Branch upstream, Branch onto, I
82132
{
83133
Ensure.ArgumentNotNull(upstream, "upstream");
84134

135+
using (ReferenceHandle branchRefPtr = RefHandleFrom(branch))
136+
using (ReferenceHandle upstreamRefPtr = RefHandleFrom(upstream))
137+
using (ReferenceHandle ontoRefPtr = RefHandleFrom(onto))
138+
return Start(branchRefPtr, upstreamRefPtr, ontoRefPtr, committer, options);
139+
}
140+
141+
internal virtual RebaseResult Start(ReferenceHandle annotatedRefPtr, ReferenceHandle upstreamRefPtr, ReferenceHandle ontoRefPtr, Identity committer, RebaseOptions options)
142+
{
143+
Ensure.ArgumentNotNull(upstreamRefPtr, "upstream");
144+
85145
options = options ?? new RebaseOptions();
86146

87147
EnsureNonBareRepo();
@@ -92,13 +152,6 @@ public virtual RebaseResult Start(Branch branch, Branch upstream, Branch onto, I
92152
this.repository.Info.CurrentOperation);
93153
}
94154

95-
Func<Branch, ReferenceHandle> RefHandleFromBranch = (Branch b) =>
96-
{
97-
return (b == null) ?
98-
null :
99-
this.repository.Refs.RetrieveReferencePtr(b.CanonicalName);
100-
};
101-
102155
using (GitCheckoutOptsWrapper checkoutOptionsWrapper = new GitCheckoutOptsWrapper(options))
103156
{
104157
GitRebaseOptions gitRebaseOptions = new GitRebaseOptions()
@@ -107,10 +160,7 @@ public virtual RebaseResult Start(Branch branch, Branch upstream, Branch onto, I
107160
checkout_options = checkoutOptionsWrapper.Options,
108161
};
109162

110-
using (ReferenceHandle branchRefPtr = RefHandleFromBranch(branch))
111-
using (ReferenceHandle upstreamRefPtr = RefHandleFromBranch(upstream))
112-
using (ReferenceHandle ontoRefPtr = RefHandleFromBranch(onto))
113-
using (AnnotatedCommitHandle annotatedBranchCommitHandle = AnnotatedCommitHandleFromRefHandle(branchRefPtr))
163+
using (AnnotatedCommitHandle annotatedBranchCommitHandle = AnnotatedCommitHandleFromRefHandle(annotatedRefPtr))
114164
using (AnnotatedCommitHandle upstreamRefAnnotatedCommitHandle = AnnotatedCommitHandleFromRefHandle(upstreamRefPtr))
115165
using (AnnotatedCommitHandle ontoRefAnnotatedCommitHandle = AnnotatedCommitHandleFromRefHandle(ontoRefPtr))
116166
using (RebaseHandle rebaseOperationHandle = Proxy.git_rebase_init(this.repository.Handle,
@@ -119,6 +169,8 @@ public virtual RebaseResult Start(Branch branch, Branch upstream, Branch onto, I
119169
ontoRefAnnotatedCommitHandle,
120170
gitRebaseOptions))
121171
{
172+
this.repository.Submodules.UpdateAll(new SubmoduleUpdateOptions());
173+
122174
RebaseResult rebaseResult = RebaseOperationImpl.Run(rebaseOperationHandle,
123175
this.repository,
124176
committer,

LibGit2Sharp/SubmoduleCollection.cs

+7
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,13 @@ public virtual void Init(string name, bool overwrite)
7070
}
7171
}
7272

73+
74+
public virtual void UpdateAll(SubmoduleUpdateOptions options)
75+
{
76+
foreach (var sm in this)
77+
Update(sm.Name, options);
78+
}
79+
7380
/// <summary>
7481
/// Update specified submodule.
7582
/// <para>

0 commit comments

Comments
 (0)