git-tfs / git-tfs

A Git/TFS bridge, similar to git-svn
http://git-tfs.com/
Apache License 2.0
1.93k stars 718 forks source link

How to teach git-tfs to ignore certain branches/changesets? #1033

Open larsxschneider opened 7 years ago

larsxschneider commented 7 years ago

Hi,

I am importing a large TFS repo to Git and I would like to carry over as much history as possible. A git tfs clone --branches=none works but with auto or all I run into a legitimate permission error:

The name of the local branch will be : XXX
error: a problem occurred when trying to clone the repository. Try to solve the problem described below.
In any case, after, try to continue using command `git tfs fetch`

TF14098: Access Denied: User Lars Schneider needs Read permission(s) for at least one item in changeset 123.
TF14098: Access Denied: User Lars Schneider needs Read permission(s) for at least one item in changeset 123.

Is there a way to tell git tfs to import all branches except for branch XXX? Or is there a way to tell it to ignore certain changesets (I don't want these changes in my Git repo anyways).

Thanks for this great tool!

Cheers, Lars

C:\>git tfs version
git-tfs version 0.25.1.0 (TFS client library 14.0.0.0 (MS)) (64-bit)
pmiossec commented 7 years ago

Is there a way to tell git tfs to import all branches except for branch XXX?

No, there is not. I already thought about such a feature but didn't had real need for that myself and no time to implement it...

I think it should not be very difficult to add it. If you want to add it, I could tell you how to do it...

larsxschneider commented 7 years ago

I don't want to promise anything but I would like to try it. Can you give me a few pointers how you would like to see the feature implemented?

pmiossec commented 7 years ago

I see 3 things that should be done:

I think it will work with that...

GoatHunter commented 7 years ago

@pmiossec Hi, I'm working with @larsxschneider, and am migrating a huge tfs repo with git-tfs. I've implemented a branch ignore feature based on your suggestions, and indeed some of the problematic branches into which I didn't have access were ignored successfully and I managed to advance more in the migration process. However, I stumbled upon another error down the road: "warning: git-tfs was unable to find the root changeset (ie the last common commit) between the brach '$/A' and its parent branch '$/B'.

Do you happen to know where in the code can I make it ignore such branches of type '$/A'?

Thanks beforehand!

Scudroe commented 7 years ago

Can you share the code you are working on? I am looking at a similar issue - I need to ignore certain folders and sub folders in an old and poorly maintained TFVC repo

GoatHunter commented 7 years ago

@Scudroe , sure - https://github.com/GoatHunter/git-tfs/tree/feature/v0.25.1_with_ignore_branches It's currently an imperfect hack, but it works for some of the use cases. Use skip-branches-file= where is a text file with the names to the branches delimited by '|'

anrichter commented 7 years ago

Need that feature too. Are the changes from @GoatHunter a PR candidate? So the feature would be part of the official next release?

GoatHunter commented 7 years ago

@anrichter hey, it's a bit hackish, not sure if it qualifies as a PR candidate if suggested

anrichter commented 7 years ago

Give it a try. :-)

ShoshanaTzi commented 3 years ago

Hi, I have a huge repository in tfs, and need to clone to git but exclude some branches. this tool will really help me, but I don't understand how to use this from git-tfs? do I need any installation to get the option of 'skip-branches-file'? can you give me an example? (I use Visual Studio 2019)

pmiossec commented 3 years ago

Hi, I have a huge repository in tfs, and need to clone to git but exclude some branches. this tool will really help me, but I don't understand how to use this from git-tfs? do I need any installation to get the option of 'skip-branches-file'? can you give me an example? (I use Visual Studio 2019)

This commit introduce the possibility to exclude some branches using a regex with the parameter --ignore-branches-regex=. See clone command doc

Because it is a regular expression, it could be more or less convenient to specify your branches... You could use this tool to help you write the regex: https://regex101.com/

For example to ignore these 2 branches: $/test/of/path, $/another/path You could write something like: (\$\/test\/of\/path|\$\/another\/path)

pmiossec commented 3 years ago

@ShoshanaTzi The other solution is to build your own version with a port of @GoatHunter solution ( https://github.com/GoatHunter/git-tfs/commits/feature/v0.25.1_with_ignore_branches ) looking at what have been done in #1194 to ignore a list of branches imported from of file.

It should not be that difficult if you know C# a little...

ShoshanaTzi commented 3 years ago

Hi, Thanks for you quick response! I tried this: git tfs clone http://XXX:8080/tfs/YYYY/ $/Development--ignore-branches-regex='\$\/Development\/FOO' but it's still clone the FOO What I missed?

pmiossec commented 3 years ago

I never used the feature but for me it should have worked.

Just to be sure... Do you use simple quote? Could you try with double quote?

Otherwise, perhaps we could ask @Laibalion that contribute the feature (long ago) if he remember how it works...

Perhaps we should have required some documentation at the time ;)

If nothing works, you may have to debug the source code and see what is the result of the regex match: https://github.com/git-tfs/git-tfs/blob/master/src/GitTfs/Core/GitTfsRemote.cs#L653

ShoshanaTzi commented 3 years ago

I never used the feature but for me it should have worked.

Just to be sure... Do you use simple quote? Could you try with double quote?

Otherwise, perhaps we could ask @Laibalion that contribute the feature (long ago) if he remember how it works...

Perhaps we should have required some documentation at the time ;)

If nothing works, you may have to debug the source code and see what is the result of the regex match: https://github.com/git-tfs/git-tfs/blob/master/src/GitTfs/Core/GitTfsRemote.cs#L653

I tried with double quote also, but It's still doesn't work

siprbaum commented 3 years ago

In a git bash on windows, the following command worked for me. The important parts are the MSYS_NO_PATHCONV=1 and that I didn't need to quote the slash ('/').

MSYS_NO_PATHCONV=1 git-tfs clone -ignore-branches-regex='\$/Development/Branches/SomeBranch' --branches=auto https://some.server.com/tfs/Projects  $/Development/Main

Another thing which looks supsicious in your example command: You are trying to clone the top level structure $/Development and under that you want to ignore a branch FOO (at $/Development/FOO). What I would expect is that you would clone some real branch, e.g. $/Development/Main and ignore $/Development/FOO. As far as I know branches can't be nested in TFVC, so if $/Development is a branch $/Development/Foo can't be a branch. And if $/Development is not a branch, then your command makes no sense

ShoshanaTzi commented 3 years ago

In a git bash on windows, the following command worked for me. The important parts are the MSYS_NO_PATHCONV=1 and that I didn't need to quote the slash ('/').

MSYS_NO_PATHCONV=1 git-tfs clone -ignore-branches-regex='\$/Development/Branches/SomeBranch' --branches=auto https://some.server.com/tfs/Projects  $/Development/Main

Another thing which looks supsicious in your example command: You are trying to clone the top level structure $/Development and under that you want to ignore a branch FOO (at $/Development/FOO). What I would expect is that you would clone some real branch, e.g. $/Development/Main and ignore $/Development/FOO. As far as I know branches can't be nested in TFVC, so if $/Development is a branch $/Development/Foo can't be a branch. And if $/Development is not a branch, then your command makes no sense

Thanks for your reply, I will try this. The $/Development is the whole tfs repository, what the meaning of -ignoe-branches-regex if I use him from branch? I need to clone all the repository except some branches.

siprbaum commented 3 years ago

You usually have a structure of

$/Development/Main/<here are your sources>
$/Development/Branches/BranchA/<here are the sources for your branchA version>
$/Development/Branches/BranchB/<here are the sources for your branchB version, e.g. branched from $/Development/Main sometimes in the past>
...

When you now clone, you need to clone the Main branch $/Development/Main, not the whole repository. git-tfs will automatically detect that BranchA and BranchB are branched from e.g. Main and will fetch them, if they are not ignored.

pmiossec commented 3 years ago

@ShoshanaTzi This command could help you find the branch you want to clone: https://github.com/git-tfs/git-tfs/blob/master/doc/commands/list-remote-branches.md

Then you could clone the branches marked with [*]

ShoshanaTzi commented 3 years ago

@ShoshanaTzi The other solution is to build your own version with a port of @GoatHunter solution ( https://github.com/GoatHunter/git-tfs/commits/feature/v0.25.1_with_ignore_branches ) looking at what have been done in #1194 to ignore a list of branches imported from of file.

It should not be that difficult if you know C# a little...

Hi, Thanks for your advice, I edited the code for me, and it's work nice!

siprbaum commented 3 years ago

@ShoshanaTzi From what you wrote above, you needed to edit the code and it looks like the --ignore-branches-regex wasn't fullfilling your needs. Care to explain what is missing, so we might have a chance to improve here?

ShoshanaTzi commented 3 years ago

@ShoshanaTzi From what you wrote above, you needed to edit the code and it looks like the --ignore-branches-regex wasn't fullfilling your needs. Care to explain what is missing, so we might have a chance to improve here?

Hi, I have no time to deep in the code too much, so what I did is to filter the files in the code in two places:

  1. TfsChanges.GetFullTree
  2. ChangeSieve.IsIgnorable