rcheckin merge commit as a merge changeset

- find the tfs repository path of the parent commit
- create changeset of type merge with the previously found tfs repository path
- Resolve conflicts found by TFS by "AlwaysAcceptMine" because merge have already been done with git
This commit is contained in:
Philippe Miossec
2013-01-13 19:24:29 +01:00
parent 0432bc0ebb
commit bdf3c67ab9
12 changed files with 77 additions and 16 deletions
+3 -2
View File
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -72,6 +72,7 @@
<Reference Include="Microsoft.TeamFoundation.Common, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
<Reference Include="Microsoft.TeamFoundation.Common.Library, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
<Reference Include="Microsoft.TeamFoundation.VersionControl.Client, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
<Reference Include="Microsoft.TeamFoundation.VersionControl.Common, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
<Reference Include="Microsoft.TeamFoundation.WorkItemTracking.Client, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
<Reference Include="StructureMap, Version=2.5.3.0, Culture=neutral, PublicKeyToken=e60ad81abae3c223, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
@@ -154,4 +155,4 @@
<PostBuildEvent>xcopy /y "$(TargetDir)*.dll" "$(SolutionDir)GitTfs\$(OutDir)"</PostBuildEvent>
</PropertyGroup>
<Import Project="$(SolutionDir)\.nuget\nuget.targets" />
</Project>
</Project>
+14
View File
@@ -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);
}
}
}
+5
View File
@@ -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();
+24 -2
View File
@@ -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);
+9 -5
View File
@@ -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
}
}
+5
View File
@@ -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<TfsChangesetInfo> tfsCommits, bool includeStubRemotes)
{
string currentCommit = null;
+7 -5
View File
@@ -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);
}
+1
View File
@@ -21,6 +21,7 @@ namespace Sep.Git.Tfs.Core
void MoveTfsRefForwardIfNeeded(IGitTfsRemote remote);
IEnumerable<TfsChangesetInfo> GetLastParentTfsCommits(string head);
IEnumerable<TfsChangesetInfo> GetLastParentTfsCommits(string head, bool includeStubRemotes);
TfsChangesetInfo GetTfsCommit(string sha);
TfsChangesetInfo GetCurrentTfsCommit();
IDictionary<string, GitObject> GetObjects(string commit);
string HashAndInsertObject(string filename);
+2 -2
View File
@@ -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);
/// <summary>
/// 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.
/// </summary>
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);
+1
View File
@@ -39,5 +39,6 @@ namespace Sep.Git.Tfs.Core
void Get(IChangeset changeset);
long CheckinTool(Func<string> generateCheckinComment);
void Merge(string sourceTfsPath, string tfsRepositoryPath);
}
}
+1
View File
@@ -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);
}
}
+5
View File
@@ -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;