diff --git a/GitTfs.Vs2010/GitTfs.Vs2010.csproj b/GitTfs.Vs2010/GitTfs.Vs2010.csproj
index 7ea88d51..7250ae0b 100644
--- a/GitTfs.Vs2010/GitTfs.Vs2010.csproj
+++ b/GitTfs.Vs2010/GitTfs.Vs2010.csproj
@@ -1,4 +1,4 @@
-
+
Debug
@@ -72,6 +72,7 @@
+
False
@@ -154,4 +155,4 @@
xcopy /y "$(TargetDir)*.dll" "$(SolutionDir)GitTfs\$(OutDir)"
-
\ No newline at end of file
+
diff --git a/GitTfs.VsCommon/Wrappers.cs b/GitTfs.VsCommon/Wrappers.cs
index 50c1455e..1f56d0a0 100644
--- a/GitTfs.VsCommon/Wrappers.cs
+++ b/GitTfs.VsCommon/Wrappers.cs
@@ -479,5 +479,19 @@ namespace Sep.Git.Tfs.VsCommon
{
get { return _workspace.OwnerName; }
}
+
+ public void Merge(string sourceTfsPath, string targetTfsPath)
+ {
+ var status = _workspace.Merge(sourceTfsPath, targetTfsPath, null, null, LockLevel.None, RecursionType.Full,
+ MergeOptions.AlwaysAcceptMine);
+ Trace.WriteLine(status.NumOperations);
+ var conflicts = _workspace.QueryConflicts(null, true);
+ foreach (var conflict in conflicts)
+ {
+ conflict.Resolution = Resolution.AcceptYours;
+ _workspace.ResolveConflict(conflict);
+ }
+ //_stdout.WriteLine("merge status:" + status.NumOperations);
+ }
}
}
\ No newline at end of file
diff --git a/GitTfs.VsFake/TfsHelper.VsFake.cs b/GitTfs.VsFake/TfsHelper.VsFake.cs
index 6d011ef6..7f9a10e5 100644
--- a/GitTfs.VsFake/TfsHelper.VsFake.cs
+++ b/GitTfs.VsFake/TfsHelper.VsFake.cs
@@ -233,6 +233,11 @@ namespace Sep.Git.Tfs.VsFake
#region unimplemented
+ public void Merge(string sourceTfsPath, string tfsRepositoryPath)
+ {
+ throw new NotImplementedException();
+ }
+
public IPendingChange[] GetPendingChanges()
{
throw new NotImplementedException();
diff --git a/GitTfs/Commands/Rcheckin.cs b/GitTfs/Commands/Rcheckin.cs
index 4ba4fc52..834c2a46 100644
--- a/GitTfs/Commands/Rcheckin.cs
+++ b/GitTfs/Commands/Rcheckin.cs
@@ -106,13 +106,14 @@ namespace Sep.Git.Tfs.Commands
rc.ExtractCommit(commitWithParents, currentParent);
rc.BuildCommitMessage(!_checkinOptions.NoGenerateCheckinComment, currentParent);
string target = rc.Sha;
+ string tfsRepositoryPathOfMergedBranch = FindTfsRepositoryPathOfMergedBranch(repo, rc.Parents);
var commitSpecificCheckinOptions = _checkinOptionsFactory.BuildCommitSpecificCheckinOptions(_checkinOptions, rc.Message, rc.Commit);
_stdout.WriteLine("Starting checkin of {0} '{1}'", target.Substring(0, 8), commitSpecificCheckinOptions.CheckinComment);
try
{
- newChangesetId = tfsRemote.Checkin(target, currentParent, parentChangeset, commitSpecificCheckinOptions);
+ newChangesetId = tfsRemote.Checkin(target, currentParent, parentChangeset, commitSpecificCheckinOptions, tfsRepositoryPathOfMergedBranch);
tfsRemote.FetchWithMerge(newChangesetId, rc.Parents);
if (tfsRemote.MaxChangesetId != newChangesetId)
{
@@ -177,11 +178,12 @@ namespace Sep.Git.Tfs.Commands
rc.ExtractCommit(revList, tfsLatest);
rc.BuildCommitMessage(!_checkinOptions.NoGenerateCheckinComment, tfsLatest);
string target = rc.Sha;
+ string tfsRepositoryPathOfMergedBranch = FindTfsRepositoryPathOfMergedBranch(repo, rc.Parents);
var commitSpecificCheckinOptions = _checkinOptionsFactory.BuildCommitSpecificCheckinOptions(_checkinOptions, rc.Message, rc.Commit);
_stdout.WriteLine("Starting checkin of {0} '{1}'", target.Substring(0, 8), commitSpecificCheckinOptions.CheckinComment);
- long newChangesetId = tfsRemote.Checkin(rc.Sha, parentChangeset, commitSpecificCheckinOptions);
+ long newChangesetId = tfsRemote.Checkin(rc.Sha, parentChangeset, commitSpecificCheckinOptions, tfsRepositoryPathOfMergedBranch);
tfsRemote.FetchWithMerge(newChangesetId, rc.Parents);
if (tfsRemote.MaxChangesetId != newChangesetId)
throw new GitTfsException("error: New TFS changesets were found. Rcheckin was not finished.");
@@ -230,6 +232,26 @@ namespace Sep.Git.Tfs.Commands
}
}
+ private string FindTfsRepositoryPathOfMergedBranch(IGitRepository repo, string[] gitParents)
+ {
+ if (gitParents.Length != 0)
+ {
+ if (gitParents.Length > 1)
+ _stdout.WriteLine("warning: only 1 parent is supported by TFS for a merge changeset. The other parents won't be materialized on the TFS merge!");
+ foreach (var gitParent in gitParents)
+ {
+ var tfsCommit = repo.GetTfsCommit(gitParent);
+ if (tfsCommit != null)
+ return tfsCommit.Remote.TfsRepositoryPath;
+ _stdout.WriteLine("warning: the parent " + gitParent + " of the merge commit was not checked in TFS and will be ignored!");
+ }
+ //Local merge where didn't found a checked in commit (strange!)
+ //TODO (IMO) Find if that's TFS branches that are not completely checked in
+ //If that's the case, we should fail and ask for rcheckin the merged branch before
+ }
+ return null;
+ }
+
public void RebaseOnto(IGitRepository repository, string tfsLatest, string target)
{
repository.CommandNoisy("rebase", "--preserve-merges", "--onto", tfsLatest, target);
diff --git a/GitTfs/Core/DerivedGitTfsRemote.cs b/GitTfs/Core/DerivedGitTfsRemote.cs
index ef5b9df8..821fee15 100644
--- a/GitTfs/Core/DerivedGitTfsRemote.cs
+++ b/GitTfs/Core/DerivedGitTfsRemote.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using Sep.Git.Tfs.Core.TfsInterop;
using Sep.Git.Tfs.Commands;
@@ -192,12 +192,12 @@ namespace Sep.Git.Tfs.Core
throw new NotImplementedException();
}
- public long Checkin(string treeish, TfsChangesetInfo parentChangeset, CheckinOptions options)
+ public long Checkin(string treeish, TfsChangesetInfo parentChangeset, CheckinOptions options, string sourceTfsPath = null)
{
throw new NotImplementedException();
}
- public long Checkin(string head, string parent, TfsChangesetInfo parentChangeset, CheckinOptions options)
+ public long Checkin(string head, string parent, TfsChangesetInfo parentChangeset, CheckinOptions options, string sourceTfsPath = null)
{
throw new NotImplementedException();
}
@@ -232,12 +232,16 @@ namespace Sep.Git.Tfs.Core
throw new NotImplementedException();
}
- #endregion
-
public RemoteInfo RemoteInfo
{
get { throw new NotImplementedException(); }
}
+
+ public void Merge(string sourceTfsPath, string targetTfsPath)
+ {
+ throw new NotImplementedException();
+ }
+ #endregion
}
}
diff --git a/GitTfs/Core/GitRepository.cs b/GitTfs/Core/GitRepository.cs
index 96ea8cff..662ba025 100644
--- a/GitTfs/Core/GitRepository.cs
+++ b/GitTfs/Core/GitRepository.cs
@@ -270,6 +270,11 @@ namespace Sep.Git.Tfs.Core
return TryParseChangesetInfo(currentCommit.Message, currentCommit.Sha, false);
}
+ public TfsChangesetInfo GetTfsCommit(string sha)
+ {
+ return TryParseChangesetInfo(GetCommitMessage(sha), sha, false);
+ }
+
private void FindTfsCommits(TextReader stdout, ICollection tfsCommits, bool includeStubRemotes)
{
string currentCommit = null;
diff --git a/GitTfs/Core/GitTfsRemote.cs b/GitTfs/Core/GitTfsRemote.cs
index d75ac5fc..596a2327 100644
--- a/GitTfs/Core/GitTfsRemote.cs
+++ b/GitTfs/Core/GitTfsRemote.cs
@@ -533,17 +533,17 @@ namespace Sep.Git.Tfs.Core
}
}
- public long Checkin(string head, TfsChangesetInfo parentChangeset, CheckinOptions options)
+ public long Checkin(string head, TfsChangesetInfo parentChangeset, CheckinOptions options, string sourceTfsPath = null)
{
var changeset = 0L;
- WithWorkspace(parentChangeset, workspace => changeset = Checkin(head, parentChangeset.GitCommit, workspace, options));
+ WithWorkspace(parentChangeset, workspace => changeset = Checkin(head, parentChangeset.GitCommit, workspace, options, sourceTfsPath));
return changeset;
}
- public long Checkin(string head, string parent, TfsChangesetInfo parentChangeset, CheckinOptions options)
+ public long Checkin(string head, string parent, TfsChangesetInfo parentChangeset, CheckinOptions options, string sourceTfsPath = null)
{
var changeset = 0L;
- WithWorkspace(parentChangeset, workspace => changeset = Checkin(head, parent, workspace, options));
+ WithWorkspace(parentChangeset, workspace => changeset = Checkin(head, parent, workspace, options, sourceTfsPath));
return changeset;
}
@@ -558,9 +558,11 @@ namespace Sep.Git.Tfs.Core
Tfs.WithWorkspace(WorkingDirectory, this, parentChangeset, action);
}
- private long Checkin(string head, string parent, ITfsWorkspace workspace, CheckinOptions options)
+ private long Checkin(string head, string parent, ITfsWorkspace workspace, CheckinOptions options, string sourceTfsPath)
{
PendChangesToWorkspace(head, parent, workspace);
+ if (!string.IsNullOrWhiteSpace(sourceTfsPath))
+ workspace.Merge(sourceTfsPath, TfsRepositoryPath);
return workspace.Checkin(options);
}
diff --git a/GitTfs/Core/IGitRepository.cs b/GitTfs/Core/IGitRepository.cs
index 35e8e962..66655cad 100644
--- a/GitTfs/Core/IGitRepository.cs
+++ b/GitTfs/Core/IGitRepository.cs
@@ -21,6 +21,7 @@ namespace Sep.Git.Tfs.Core
void MoveTfsRefForwardIfNeeded(IGitTfsRemote remote);
IEnumerable GetLastParentTfsCommits(string head);
IEnumerable GetLastParentTfsCommits(string head, bool includeStubRemotes);
+ TfsChangesetInfo GetTfsCommit(string sha);
TfsChangesetInfo GetCurrentTfsCommit();
IDictionary GetObjects(string commit);
string HashAndInsertObject(string filename);
diff --git a/GitTfs/Core/IGitTfsRemote.cs b/GitTfs/Core/IGitTfsRemote.cs
index 942c6cea..37a98d88 100644
--- a/GitTfs/Core/IGitTfsRemote.cs
+++ b/GitTfs/Core/IGitTfsRemote.cs
@@ -32,12 +32,12 @@ namespace Sep.Git.Tfs.Core
void Shelve(string shelvesetName, string treeish, TfsChangesetInfo parentChangeset, bool evaluateCheckinPolicies);
bool HasShelveset(string shelvesetName);
long CheckinTool(string head, TfsChangesetInfo parentChangeset);
- long Checkin(string treeish, TfsChangesetInfo parentChangeset, CheckinOptions options);
+ long Checkin(string treeish, TfsChangesetInfo parentChangeset, CheckinOptions options, string sourceTfsPath = null);
///
/// Checks in to TFS set of changes from git repository between given commits (parent..head) onto given TFS changeset. Returns ID of the new changeset.
///
- long Checkin(string head, string parent, TfsChangesetInfo parentChangeset, CheckinOptions options);
+ long Checkin(string head, string parent, TfsChangesetInfo parentChangeset, CheckinOptions options, string sourceTfsPath = null);
void CleanupWorkspace();
void CleanupWorkspaceDirectory();
ITfsChangeset GetChangeset(long changesetId);
diff --git a/GitTfs/Core/ITfsWorkspace.cs b/GitTfs/Core/ITfsWorkspace.cs
index 749f093b..bc318fc3 100644
--- a/GitTfs/Core/ITfsWorkspace.cs
+++ b/GitTfs/Core/ITfsWorkspace.cs
@@ -39,5 +39,6 @@ namespace Sep.Git.Tfs.Core
void Get(IChangeset changeset);
long CheckinTool(Func generateCheckinComment);
+ void Merge(string sourceTfsPath, string tfsRepositoryPath);
}
}
\ No newline at end of file
diff --git a/GitTfs/Core/TfsInterop/IWorkspace.cs b/GitTfs/Core/TfsInterop/IWorkspace.cs
index 87580c8d..92f8a059 100644
--- a/GitTfs/Core/TfsInterop/IWorkspace.cs
+++ b/GitTfs/Core/TfsInterop/IWorkspace.cs
@@ -17,5 +17,6 @@ namespace Sep.Git.Tfs.Core.TfsInterop
void GetSpecificVersion(IChangeset changeset);
string GetLocalItemForServerItem(string serverItem);
string OwnerName { get; }
+ void Merge(string sourceTfsPath, string tfsRepositoryPath);
}
}
\ No newline at end of file
diff --git a/GitTfs/Core/TfsWorkspace.cs b/GitTfs/Core/TfsWorkspace.cs
index b199eae7..54c7f094 100644
--- a/GitTfs/Core/TfsWorkspace.cs
+++ b/GitTfs/Core/TfsWorkspace.cs
@@ -67,6 +67,11 @@ namespace Sep.Git.Tfs.Core
return newChangesetId;
}
+ public void Merge(string sourceTfsPath, string tfsRepositoryPath)
+ {
+ _workspace.Merge(sourceTfsPath, tfsRepositoryPath);
+ }
+
public long Checkin(CheckinOptions options)
{
if (options == null) options = _checkinOptions;