Submitter | Angel Ezquerra |
---|---|
Date | March 6, 2014, 7:59 a.m. |
Message ID | <CAMefLFHcrVbMoNN592WxYpRcKuQw69q0k4hNFZLqkkafFM+dcg@mail.gmail.com> |
Download | mbox | patch |
Permalink | /patch/3870/ |
State | Rejected |
Headers | show |
Comments
On 03/06/2014 08:59 AM, Angel Ezquerra wrote:
> I'm trying to create a mercurial-TFS bridge
Have you considered implementing convert source and sink for TFS?
/Mads
On Thu, Mar 6, 2014 at 11:42 AM, Mads Kiilerich <mads@kiilerich.com> wrote: > On 03/06/2014 08:59 AM, Angel Ezquerra wrote: >> >> I'm trying to create a mercurial-TFS bridge > > > Have you considered implementing convert source and sink for TFS? > > /Mads That is something that could be done (and I may do it). However, I don't think that lets you have a bidirectional bridge, does it? I haven't used convert much so please correct me if I am wrong... I think what I'm trying to make is something similar to hggit or hgsubversion (although I have not actually used those myself, so the similarity may only be superficial). It is not ready yet (I will share it when it is) but what I am doing is adding 3 new commands that let you link a mercurial repo to a TFS workspace and pull from / push to that TFS workspace: - tflink: Link an existing mercurial repository to an existing TFS branch workspace. This simply stores a TFS "branch_name" to local TFS folder relationship on a config file). - tfpull: Gets new TFS changesets from a linked TFS branch into a mercurial repository. These are converted into mercurial revisions that are made on a particular branch (called TFS.TFS_BRANCH_NAME by default). - tfpush: take the mercurial revisions that descend from the latest imported TFS revision and convert them into TFS changesets. This is tricky because TFS history must be purely linear (as in SVN). This means that we need abort if there are multiple heads for example. We also need to detect when the history is not linear, and in that case choose which revisions to "push" (either always taking one of the parents or by asking the user what to do). Currently these commands are executed by running a stand alone "hgtf.py" script, but I may create a proper mercurial extension and convert them into mercurial commands instead. To "mark" imported revisions I had planned to embed the unique TFS changeset ID in extra.user.tfs. Perhaps a better strategy is to just add tags. I would want to avoid creating two revisions per TFS changeset (1 regular revision + 1 tag revision) so perhaps I will try to create all the tags on a single commit (by tagging at the end and folding the tag commits or by automatically updating the .hgtags file in a single go). I have also considered adding a new type of subrepo (tfsubrepo). This should be pretty simple I think, and very similar to the existing svnsubrepo. The main issue I see is that this is not something that can be easily tested with mercurial's test suite, since it requires access to a proprietary Team Foundation Server. Cheers, Angel
On 03/06/2014 12:20 PM, Angel Ezquerra wrote: > On Thu, Mar 6, 2014 at 11:42 AM, Mads Kiilerich <mads@kiilerich.com> wrote: >> On 03/06/2014 08:59 AM, Angel Ezquerra wrote: >>> I'm trying to create a mercurial-TFS bridge >> >> Have you considered implementing convert source and sink for TFS? >> >> /Mads > That is something that could be done (and I may do it). However, I > don't think that lets you have a bidirectional bridge, does it? It does. http://selenic.com/hg/rev/2147a734dcf9 and http://selenic.com/hg/rev/77872b002e73 . /Mads
On Thu, Mar 6, 2014 at 11:20 AM, Angel Ezquerra <angel.ezquerra@gmail.com> wrote: > On Thu, Mar 6, 2014 at 11:42 AM, Mads Kiilerich <mads@kiilerich.com> wrote: >> On 03/06/2014 08:59 AM, Angel Ezquerra wrote: >>> >>> I'm trying to create a mercurial-TFS bridge >> >> >> Have you considered implementing convert source and sink for TFS? >> >> /Mads > > That is something that could be done (and I may do it). However, I > don't think that lets you have a bidirectional bridge, does it? I > haven't used convert much so please correct me if I am wrong... > > I think what I'm trying to make is something similar to hggit or > hgsubversion (although I have not actually used those myself, so the > similarity may only be superficial). > > It is not ready yet (I will share it when it is) but what I am doing > is adding 3 new commands that let you link a mercurial repo to a TFS > workspace and pull from / push to that TFS workspace: > > - tflink: Link an existing mercurial repository to an existing TFS > branch workspace. This simply stores a TFS "branch_name" to local TFS > folder relationship on a config file). > > - tfpull: Gets new TFS changesets from a linked TFS branch into a > mercurial repository. These are converted into mercurial revisions > that are made on a particular branch (called TFS.TFS_BRANCH_NAME by > default). > > - tfpush: take the mercurial revisions that descend from the latest > imported TFS revision and convert them into TFS changesets. This is > tricky because TFS history must be purely linear (as in SVN). This > means that we need abort if there are multiple heads for example. We > also need to detect when the history is not linear, and in that case > choose which revisions to "push" (either always taking one of the > parents or by asking the user what to do). > > Currently these commands are executed by running a stand alone > "hgtf.py" script, but I may create a proper mercurial extension and > convert them into mercurial commands instead. > > To "mark" imported revisions I had planned to embed the unique TFS > changeset ID in extra.user.tfs. Perhaps a better strategy is to just > add tags. I would want to avoid creating two revisions per TFS > changeset (1 regular revision + 1 tag revision) so perhaps I will try > to create all the tags on a single commit (by tagging at the end and > folding the tag commits or by automatically updating the .hgtags file > in a single go). Could you use local tags to avoid the extra commits? Or just have a separate file that tracks the mapping between TFS and hg changesets? > > I have also considered adding a new type of subrepo (tfsubrepo). This > should be pretty simple I think, and very similar to the existing > svnsubrepo. The main issue I see is that this is not something that > can be easily tested with mercurial's test suite, since it requires > access to a proprietary Team Foundation Server. >
On Thu, Mar 6, 2014 at 12:35 PM, Simon King <simon@simonking.org.uk> wrote: > On Thu, Mar 6, 2014 at 11:20 AM, Angel Ezquerra > <angel.ezquerra@gmail.com> wrote: >> On Thu, Mar 6, 2014 at 11:42 AM, Mads Kiilerich <mads@kiilerich.com> wrote: >>> On 03/06/2014 08:59 AM, Angel Ezquerra wrote: >>>> >>>> I'm trying to create a mercurial-TFS bridge >>> >>> >>> Have you considered implementing convert source and sink for TFS? >>> >>> /Mads >> >> That is something that could be done (and I may do it). However, I >> don't think that lets you have a bidirectional bridge, does it? I >> haven't used convert much so please correct me if I am wrong... >> >> I think what I'm trying to make is something similar to hggit or >> hgsubversion (although I have not actually used those myself, so the >> similarity may only be superficial). >> >> It is not ready yet (I will share it when it is) but what I am doing >> is adding 3 new commands that let you link a mercurial repo to a TFS >> workspace and pull from / push to that TFS workspace: >> >> - tflink: Link an existing mercurial repository to an existing TFS >> branch workspace. This simply stores a TFS "branch_name" to local TFS >> folder relationship on a config file). >> >> - tfpull: Gets new TFS changesets from a linked TFS branch into a >> mercurial repository. These are converted into mercurial revisions >> that are made on a particular branch (called TFS.TFS_BRANCH_NAME by >> default). >> >> - tfpush: take the mercurial revisions that descend from the latest >> imported TFS revision and convert them into TFS changesets. This is >> tricky because TFS history must be purely linear (as in SVN). This >> means that we need abort if there are multiple heads for example. We >> also need to detect when the history is not linear, and in that case >> choose which revisions to "push" (either always taking one of the >> parents or by asking the user what to do). >> >> Currently these commands are executed by running a stand alone >> "hgtf.py" script, but I may create a proper mercurial extension and >> convert them into mercurial commands instead. >> >> To "mark" imported revisions I had planned to embed the unique TFS >> changeset ID in extra.user.tfs. Perhaps a better strategy is to just >> add tags. I would want to avoid creating two revisions per TFS >> changeset (1 regular revision + 1 tag revision) so perhaps I will try >> to create all the tags on a single commit (by tagging at the end and >> folding the tag commits or by automatically updating the .hgtags file >> in a single go). > > Could you use local tags to avoid the extra commits? Or just have a > separate file that tracks the mapping between TFS and hg changesets? Actually I first started using a separate file inside the .hg folder and then I changed it so that the current unfinished implementation uses local tags, not regular tags. However I think that I must record it "in history" so that more than one user can link its local repository clone to their own TF workspace. Angel
On Thu, Mar 6, 2014 at 12:31 PM, Mads Kiilerich <mads@kiilerich.com> wrote: > On 03/06/2014 12:20 PM, Angel Ezquerra wrote: >> >> On Thu, Mar 6, 2014 at 11:42 AM, Mads Kiilerich <mads@kiilerich.com> >> wrote: >>> >>> On 03/06/2014 08:59 AM, Angel Ezquerra wrote: >>>> >>>> I'm trying to create a mercurial-TFS bridge >>> >>> >>> Have you considered implementing convert source and sink for TFS? >>> >>> /Mads >> >> That is something that could be done (and I may do it). However, I >> don't think that lets you have a bidirectional bridge, does it? > > > It does. http://selenic.com/hg/rev/2147a734dcf9 and > http://selenic.com/hg/rev/77872b002e73 . > > /Mads That's interesting. Thanks for the info! I'm not sure how well this can be mapped to the work I already did, but I'll look into it. Thanks, Angel
On Thu, Mar 6, 2014 at 11:43 AM, Angel Ezquerra <angel.ezquerra@gmail.com> wrote: > On Thu, Mar 6, 2014 at 12:35 PM, Simon King <simon@simonking.org.uk> wrote: >> On Thu, Mar 6, 2014 at 11:20 AM, Angel Ezquerra >> <angel.ezquerra@gmail.com> wrote: >>> On Thu, Mar 6, 2014 at 11:42 AM, Mads Kiilerich <mads@kiilerich.com> wrote: >>>> On 03/06/2014 08:59 AM, Angel Ezquerra wrote: >>>>> >>>>> I'm trying to create a mercurial-TFS bridge >>>> >>>> >>>> Have you considered implementing convert source and sink for TFS? >>>> >>>> /Mads >>> >>> That is something that could be done (and I may do it). However, I >>> don't think that lets you have a bidirectional bridge, does it? I >>> haven't used convert much so please correct me if I am wrong... >>> >>> I think what I'm trying to make is something similar to hggit or >>> hgsubversion (although I have not actually used those myself, so the >>> similarity may only be superficial). >>> >>> It is not ready yet (I will share it when it is) but what I am doing >>> is adding 3 new commands that let you link a mercurial repo to a TFS >>> workspace and pull from / push to that TFS workspace: >>> >>> - tflink: Link an existing mercurial repository to an existing TFS >>> branch workspace. This simply stores a TFS "branch_name" to local TFS >>> folder relationship on a config file). >>> >>> - tfpull: Gets new TFS changesets from a linked TFS branch into a >>> mercurial repository. These are converted into mercurial revisions >>> that are made on a particular branch (called TFS.TFS_BRANCH_NAME by >>> default). >>> >>> - tfpush: take the mercurial revisions that descend from the latest >>> imported TFS revision and convert them into TFS changesets. This is >>> tricky because TFS history must be purely linear (as in SVN). This >>> means that we need abort if there are multiple heads for example. We >>> also need to detect when the history is not linear, and in that case >>> choose which revisions to "push" (either always taking one of the >>> parents or by asking the user what to do). >>> >>> Currently these commands are executed by running a stand alone >>> "hgtf.py" script, but I may create a proper mercurial extension and >>> convert them into mercurial commands instead. >>> >>> To "mark" imported revisions I had planned to embed the unique TFS >>> changeset ID in extra.user.tfs. Perhaps a better strategy is to just >>> add tags. I would want to avoid creating two revisions per TFS >>> changeset (1 regular revision + 1 tag revision) so perhaps I will try >>> to create all the tags on a single commit (by tagging at the end and >>> folding the tag commits or by automatically updating the .hgtags file >>> in a single go). >> >> Could you use local tags to avoid the extra commits? Or just have a >> separate file that tracks the mapping between TFS and hg changesets? > > Actually I first started using a separate file inside the .hg folder > and then I changed it so that the current unfinished implementation > uses local tags, not regular tags. However I think that I must record > it "in history" so that more than one user can link its local > repository clone to their own TF workspace. > Fair enough. In answer to one of your earlier questions, about having to rewrite commands.commit, you could avoid that with a very ugly hack, passing the extra data in via the config object. You could even do that from the command line: hg ci --config tfs.changeset=xxx You would then wrap localrepo.commit, get it to pull the data it wants from the config and put it in the extra dict. (As a proper solution this is horrible, but it seems like the least invasive way to get the behaviour you want) Simon
On Thu, Mar 6, 2014 at 12:54 PM, Simon King <simon@simonking.org.uk> wrote: > On Thu, Mar 6, 2014 at 11:43 AM, Angel Ezquerra > <angel.ezquerra@gmail.com> wrote: >> On Thu, Mar 6, 2014 at 12:35 PM, Simon King <simon@simonking.org.uk> wrote: >>> On Thu, Mar 6, 2014 at 11:20 AM, Angel Ezquerra >>> <angel.ezquerra@gmail.com> wrote: >>>> On Thu, Mar 6, 2014 at 11:42 AM, Mads Kiilerich <mads@kiilerich.com> wrote: >>>>> On 03/06/2014 08:59 AM, Angel Ezquerra wrote: >>>>>> >>>>>> I'm trying to create a mercurial-TFS bridge >>>>> >>>>> >>>>> Have you considered implementing convert source and sink for TFS? >>>>> >>>>> /Mads >>>> >>>> That is something that could be done (and I may do it). However, I >>>> don't think that lets you have a bidirectional bridge, does it? I >>>> haven't used convert much so please correct me if I am wrong... >>>> >>>> I think what I'm trying to make is something similar to hggit or >>>> hgsubversion (although I have not actually used those myself, so the >>>> similarity may only be superficial). >>>> >>>> It is not ready yet (I will share it when it is) but what I am doing >>>> is adding 3 new commands that let you link a mercurial repo to a TFS >>>> workspace and pull from / push to that TFS workspace: >>>> >>>> - tflink: Link an existing mercurial repository to an existing TFS >>>> branch workspace. This simply stores a TFS "branch_name" to local TFS >>>> folder relationship on a config file). >>>> >>>> - tfpull: Gets new TFS changesets from a linked TFS branch into a >>>> mercurial repository. These are converted into mercurial revisions >>>> that are made on a particular branch (called TFS.TFS_BRANCH_NAME by >>>> default). >>>> >>>> - tfpush: take the mercurial revisions that descend from the latest >>>> imported TFS revision and convert them into TFS changesets. This is >>>> tricky because TFS history must be purely linear (as in SVN). This >>>> means that we need abort if there are multiple heads for example. We >>>> also need to detect when the history is not linear, and in that case >>>> choose which revisions to "push" (either always taking one of the >>>> parents or by asking the user what to do). >>>> >>>> Currently these commands are executed by running a stand alone >>>> "hgtf.py" script, but I may create a proper mercurial extension and >>>> convert them into mercurial commands instead. >>>> >>>> To "mark" imported revisions I had planned to embed the unique TFS >>>> changeset ID in extra.user.tfs. Perhaps a better strategy is to just >>>> add tags. I would want to avoid creating two revisions per TFS >>>> changeset (1 regular revision + 1 tag revision) so perhaps I will try >>>> to create all the tags on a single commit (by tagging at the end and >>>> folding the tag commits or by automatically updating the .hgtags file >>>> in a single go). >>> >>> Could you use local tags to avoid the extra commits? Or just have a >>> separate file that tracks the mapping between TFS and hg changesets? >> >> Actually I first started using a separate file inside the .hg folder >> and then I changed it so that the current unfinished implementation >> uses local tags, not regular tags. However I think that I must record >> it "in history" so that more than one user can link its local >> repository clone to their own TF workspace. >> > > Fair enough. > > In answer to one of your earlier questions, about having to rewrite > commands.commit, you could avoid that with a very ugly hack, passing > the extra data in via the config object. You could even do that from > the command line: > > hg ci --config tfs.changeset=xxx > > You would then wrap localrepo.commit, get it to pull the data it wants > from the config and put it in the extra dict. > > (As a proper solution this is horrible, but it seems like the least > invasive way to get the behaviour you want) That is neat but as you say also pretty "horrible" (in a kind of awesome way :-) ) Angel
On Thu, 2014-03-06 at 08:59 +0100, Angel Ezquerra wrote: > I'm > trying to create a mercurial-TFS bridge and this seemed a very > convenient way to "link" mercurial revisions with TFS changeset > numbers (for example it would let us look for a particular TFS > changest in the mercurial history). However, if you really think that > this is a terrible idea maybe I need to rethink my approach. I think this is actually a legitimate thing to want to do, but it's also one we've always done via extensions. This naturally creates a nice, high barrier to adding new types of metadata for Mercurial to care about, which I consider to be a good thing. The problem with something like extra is that it's TOO useful. It looks vaguely like a solution to everyone's pet problem, and if we expose it directly, everyone will abuse it. And then everyone will want to extend it with hooks and supplementary commands and special merge behavior and hgweb etc. etc. If we instead say "do it yourself with a .myextrametadata file", they'll say "but that's ugly" and maybe re-evaluate their need. At worst the ugliness will be on their plate and not ours.
Patch
diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -1370,7 +1370,7 @@ branch = repo[None].branch() bheads = repo.branchheads(branch) - extra = {} + extra = opts.get('extra', {}) if opts.get('close_branch'): extra['close'] = 1