Удаление ветвящихся отношений в TFS 2010

У меня есть проект Team TFS 2010, который я только что принял. Инициатива ветвления - Dev - это дочерний элемент Test, Test - дочерний элемент Main, например.

Main

----Test

--------Dev

Однако в какой-то момент в прошлом кто-то сделал необоснованное слияние между Dev и Main. это вызывает много путаницы, так как разработчики теперь случайно объединяют код непосредственно с Dev на Main.

Это вызывает боль при непредвиденных конфликтах слияния, когда код следует правильному процессу и объединяется с Test to Main, а также потенциально создает сценарий, в котором непроверенный код продвигается к главному ветки.

Есть ли способ удалить ветвящиеся отношения между Dev и Main без удаления ветки? Я хотел бы сохранить ветку Dev и ее отношения с Test. Просто удалите отношения с Main.

Я попытался преобразовать ветку в папку, чтобы удалить отношения, но это не работает. Я могу отследить ветку, но, похоже, нет очевидного способа полностью удалить отношения. Я мог бы преобразовать ветвь в папку, а затем удалить ее и перекрутить из Test, но это будет означать, что кодовая база синхронизирована, что может быть трудно достичь.

Ответ 1

TFS не обязательно создает кандидаты слияния на основе объектов ветвей для обратной совместимости (объекты ветвления были новыми в TFS 2010) и для поддержки необоснованных слияний (как только вы выполняете необоснованное слияние между двумя путями, они будут сохранены с объединением отношения для будущих слияний.)

Я бы предложил использовать специальную политику регистрации, которая предусматривает, что слияния идут из Dev → Test или Test → Dev и не пропускают промежуточный уровень. Это также позволяет сохранить Dev как объект ветвления, поэтому вы все равно получите все приятные функции, такие как визуализация ветвей.

Я могу привести очень грубый, очень псевдокодиальный пример того, что я имел в виду. (Это грубо и потому, что я ленив, и потому, что я трачу свое время в Java SDK, а не на .NET SDK, и понимаю, что большинство людей хотят проводить политику регистрации .NET. Но в основном потому, что я ленив.)

/*
 * Create a dictionary of merge targets to allowable merge sources.
 * For an item in this list, the allowable merge sources are a whitelist.
 */
private readonly Dictionary<String, List<String>> restrictedMergeTargets =
    new Dictionary<String, List<String>>();

public static MergeWhitelistPolicy
{
    /* Only allowed merges to $/Main from $/Test. */
    List<String> mainWhitelist = new List<String>();
    mainWhitelist.add("$/Test");
    allowedMerges.put("$/Main", mainWhitelist);

    /* Only allow merges to $/Test from $/Dev. */
    List<String> testWhitelist = new List<String>();
    testWhitelist.add("$/Dev");
    allowedMerges.put("$/Test", testWhitelist);
}

public PolicyFailure[] evaluate(PolicyContext context)
{
    PendingChange[] pendingChanges = GetPendingCheckin().GetCheckedPendingChanges();

    foreach(PendingChange change : pendingChanges)
    {
        if(! change.IsMerge())
        {
            continue;
        }

        foreach(KeyValuePair<String, List<String>> restrictedTarget : restrictedMergeTargets)
        {
            if(VersionControlPath.IsChild(restrictedTarget.GetKey(), change.GetServerItem())
            {
                /* Whitelisted merge path - investigate. */
                foreach(String allowedSource : restrictedTarget.GetValue())
                {
                    foreach(MergeSource mergeSource : change.GetMergeSources())
                    {
                        if(! VersionControlPath.IsChild(allowedSource, mergeSource.GetServerItem()))
                        {
                            return new PolicyFailure("Merge from " +
                                mergeSource.GetServerItem() + " to " +
                                change.GetServerItem() + " is disallowed.");
                        }
                    }
                }
            }
        }
    }

    return null;
}

Конечно, есть несколько проблем. Вы, конечно же, не хотели бы жестко кодировать список приемлемых отношений слияния в политике - вы могли бы экрнализировать его в файл конфигурации или вы могли бы запрашивать отношения слияния на сервере и кэшировать их, если бы у вас были определенные правила, такие как только прямые потомки слияния. (Кэширование это важно, поскольку проверка политики проверки выполняется часто и, как ожидается, будет быстрой. Иногда она может запускаться в потоке пользовательского интерфейса (хотя я сомневаюсь), поэтому ваш пробег может отличаться.)

Кроме того, мой код тестирования пути довольно неряшлив, в основном просто для сохранения некоторого пробела в моем комментарии. (И также, вышеупомянутая лень с моей стороны.)

Надеюсь, это хорошее начало.

Ответ 2

Отличный вопрос! У меня нет прямого ответа, но у меня есть предложение снизить риск возникновения в будущем:

Строго ограничьте, кто имеет права сливаться с родительскими веткими, особенно в Главном филиале. Я назначаю одного Dev Lead или Sr. Dev как владельца ветки, который отвечает за объединение RI в эту ветвь. (Админы могут также охватывать, не требуя дополнительных привилегий.)

Это не поможет вам, как только необоснованное слияние создаст новые отношения, но это должно уменьшить риск непреднамеренного повторения в будущем. Также может быть допустимый случай, когда вам понадобится прыгать в тестовую ветку, но я не могу придумать никаких оснований для этого.