Как указать ветвь git во время выполнения? [Дубликат]

Мы решили это с помощью класса ниже. Просто вызовите метод аутентификации:

import java.text.MessageFormat;
import java.util.*;    
import javax.naming.*;    
import org.apache.log4j.Level;

public class LdapGroupAuthenticator {
    public static final String DISTINGUISHED_NAME = "distinguishedName";
    public static final String CN = "cn";
    public static final String MEMBER = "member";
    public static final String MEMBER_OF = "memberOf";
    public static final String SEARCH_BY_SAM_ACCOUNT_NAME = "(SAMAccountName={0})";
    public static final String SEARCH_GROUP_BY_GROUP_CN = "(&(objectCategory=group)(cn={0}))";

    /*
     * Prepares and returns CN that can be used for AD query
     * e.g. Converts "CN=**Dev - Test Group" to "**Dev - Test Group"
     * Converts CN=**Dev - Test Group,OU=Distribution Lists,DC=DOMAIN,DC=com to "**Dev - Test Group"
     */
    public static String getCN(String cnName) {
        if (cnName != null && cnName.toUpperCase().startsWith("CN=")) {
            cnName = cnName.substring(3);
        }
        int position = cnName.indexOf(',');
        if (position == -1) {
            return cnName;
        } else {
            return cnName.substring(0, position);
        }
    }
    public static boolean isSame(String target, String candidate) {
        if (target != null && target.equalsIgnoreCase(candidate)) {
            return true;
        }
        return false;
    }

    public static boolean authenticate(String domain, String username, String password) {
        Hashtable env = new Hashtable();
        env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory");
        env.put(Context.PROVIDER_URL, "ldap://1.2.3.4:389");
        env.put(Context.SECURITY_AUTHENTICATION, "simple");
        env.put(Context.SECURITY_PRINCIPAL, domain + "\\" + username);
        env.put(Context.SECURITY_CREDENTIALS, password);
        DirContext ctx = null;
        String defaultSearchBase = "DC=DOMAIN,DC=com";
        String groupDistinguishedName = "DN=CN=DLS-APP-MyAdmin-C,OU=DLS File Permissions,DC=DOMAIN,DC=com";

        try {
            ctx = new InitialDirContext(env);

            // userName is SAMAccountName
            SearchResult sr = executeSearchSingleResult(ctx, SearchControls.SUBTREE_SCOPE, defaultSearchBase,
                    MessageFormat.format( SEARCH_BY_SAM_ACCOUNT_NAME, new Object[] {username}),
                    new String[] {DISTINGUISHED_NAME, CN, MEMBER_OF}
                    );

            String groupCN = getCN(groupDistinguishedName);
            HashMap processedUserGroups = new HashMap();
            HashMap unProcessedUserGroups = new HashMap();

            // Look for and process memberOf
            Attribute memberOf = sr.getAttributes().get(MEMBER_OF);
            if (memberOf != null) {
                for ( Enumeration e1 = memberOf.getAll() ; e1.hasMoreElements() ; ) {
                    String unprocessedGroupDN = e1.nextElement().toString();
                    String unprocessedGroupCN = getCN(unprocessedGroupDN);
                    // Quick check for direct membership
                    if (isSame (groupCN, unprocessedGroupCN) && isSame (groupDistinguishedName, unprocessedGroupDN)) {
                        Log.info(username + " is authorized.");
                        return true;
                    } else {
                        unProcessedUserGroups.put(unprocessedGroupDN, unprocessedGroupCN);
                    }
                }
                if (userMemberOf(ctx, defaultSearchBase, processedUserGroups, unProcessedUserGroups, groupCN, groupDistinguishedName)) {
                    Log.info(username + " is authorized.");
                    return true;
                }
            }

            Log.info(username + " is NOT authorized.");
            return false;
        } catch (AuthenticationException e) {
            Log.info(username + " is NOT authenticated");
            return false;
        } catch (NamingException e) {
            throw new SystemException(e);
        } finally {
            if (ctx != null) {
                try {
                    ctx.close();
                } catch (NamingException e) {
                    throw new SystemException(e);
                }
            }
        }
    }

    public static boolean userMemberOf(DirContext ctx, String searchBase, HashMap processedUserGroups, HashMap unProcessedUserGroups, String groupCN, String groupDistinguishedName) throws NamingException {
        HashMap newUnProcessedGroups = new HashMap();
        for (Iterator entry = unProcessedUserGroups.keySet().iterator(); entry.hasNext();) {
            String  unprocessedGroupDistinguishedName = (String) entry.next();
            String unprocessedGroupCN = (String)unProcessedUserGroups.get(unprocessedGroupDistinguishedName);
            if ( processedUserGroups.get(unprocessedGroupDistinguishedName) != null) {
                Log.info("Found  : " + unprocessedGroupDistinguishedName +" in processedGroups. skipping further processing of it..." );
                // We already traversed this.
                continue;
            }
            if (isSame (groupCN, unprocessedGroupCN) && isSame (groupDistinguishedName, unprocessedGroupDistinguishedName)) {
                Log.info("Found Match DistinguishedName : " + unprocessedGroupDistinguishedName +", CN : " + unprocessedGroupCN );
                return true;
            }
        }

        for (Iterator entry = unProcessedUserGroups.keySet().iterator(); entry.hasNext();) {
            String  unprocessedGroupDistinguishedName = (String) entry.next();
            String unprocessedGroupCN = (String)unProcessedUserGroups.get(unprocessedGroupDistinguishedName);

            processedUserGroups.put(unprocessedGroupDistinguishedName, unprocessedGroupCN);

            // Fetch Groups in unprocessedGroupCN and put them in newUnProcessedGroups
            NamingEnumeration ns = executeSearch(ctx, SearchControls.SUBTREE_SCOPE, searchBase,
                    MessageFormat.format( SEARCH_GROUP_BY_GROUP_CN, new Object[] {unprocessedGroupCN}),
                    new String[] {CN, DISTINGUISHED_NAME, MEMBER_OF});

            // Loop through the search results
            while (ns.hasMoreElements()) {
                SearchResult sr = (SearchResult) ns.next();

                // Make sure we're looking at correct distinguishedName, because we're querying by CN
                String userDistinguishedName = sr.getAttributes().get(DISTINGUISHED_NAME).get().toString();
                if (!isSame(unprocessedGroupDistinguishedName, userDistinguishedName)) {
                    Log.info("Processing CN : " + unprocessedGroupCN + ", DN : " + unprocessedGroupDistinguishedName +", Got DN : " + userDistinguishedName +", Ignoring...");
                    continue;
                }

                Log.info("Processing for memberOf CN : " + unprocessedGroupCN + ", DN : " + unprocessedGroupDistinguishedName);
                // Look for and process memberOf
                Attribute memberOf = sr.getAttributes().get(MEMBER_OF);
                if (memberOf != null) {
                    for ( Enumeration e1 = memberOf.getAll() ; e1.hasMoreElements() ; ) {
                        String unprocessedChildGroupDN = e1.nextElement().toString();
                        String unprocessedChildGroupCN = getCN(unprocessedChildGroupDN);
                        Log.info("Adding to List of un-processed groups : " + unprocessedChildGroupDN +", CN : " + unprocessedChildGroupCN);
                        newUnProcessedGroups.put(unprocessedChildGroupDN, unprocessedChildGroupCN);
                    }
                }
            }
        }
        if (newUnProcessedGroups.size() == 0) {
            Log.info("newUnProcessedGroups.size() is 0. returning false...");
            return false;
        }

        //  process unProcessedUserGroups
        return userMemberOf(ctx, searchBase, processedUserGroups, newUnProcessedGroups, groupCN, groupDistinguishedName);
    }

    private static NamingEnumeration executeSearch(DirContext ctx, int searchScope,  String searchBase, String searchFilter, String[] attributes) throws NamingException {
        // Create the search controls
        SearchControls searchCtls = new SearchControls();

        // Specify the attributes to return
        if (attributes != null) {
            searchCtls.setReturningAttributes(attributes);
        }

        // Specify the search scope
        searchCtls.setSearchScope(searchScope);

        // Search for objects using the filter
        NamingEnumeration result = ctx.search(searchBase, searchFilter,searchCtls);
        return result;
    }

    private static SearchResult executeSearchSingleResult(DirContext ctx, int searchScope,  String searchBase, String searchFilter, String[] attributes) throws NamingException {
        NamingEnumeration result = executeSearch(ctx, searchScope,  searchBase, searchFilter, attributes);

        SearchResult sr = null;
        // Loop through the search results
        while (result.hasMoreElements()) {
            sr = (SearchResult) result.next();
            break;
        }
        return sr;
    }
}
120
задан Nick Volynkin 14 July 2016 в 10:46
поделиться

8 ответов

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

Проблема в том, что системы сборки Linux и Windows врезаются друг в друга при использовании в одном каталоге; есть несколько сложных этапов сборки для загрузки библиотек и т. д., которые используют одни и те же имена каталогов. Windows-версия системы сборки загружает библиотеки, специфичные для Windows, и Linux-версия системы сборки загружает библиотеки, специфичные для Linux.

В идеальном мире система сборки будет изменена так, чтобы Windows & амп; Linux может сосуществовать внутри каталога, но на данный момент проблема решается с помощью рабочих деревьев. Папка «Linux» может генерировать артефакты сборки для Linux, а папка «Windows» может генерировать артефакты сборки Windows. Хотя это вряд ли идеальное решение, он делает приятную остановку, ожидая, когда будут исправлены ошибки системы сборки.

По общему признанию, worktree не был предназначен для этого; Я должен держать версию Windows и версию Linux в отдельных ветвях, хотя я бы предпочел, чтобы они были в одной ветке. Тем не менее, он выполняет свою работу, и это несколько нетрадиционный случай смены рабочего дня.

2
ответ дан AHelps 15 August 2018 в 19:33
поделиться
  • 1
    +1 Это похоже на очень эффективный обходной путь для того, чтобы не делать каталоги вывода сборки для каждой конфигурации. У меня есть аналогичная настройка рабочей станции VMware с пользователями Ubuntu и macOS. – Tanz87 22 January 2017 в 04:31

Одно очевидное использование - одновременное сравнение поведения (не источника) разных версий - например, различных версий веб-сайта или просто веб-страницы.

Я попытался это сделать локально.

  • создать каталог page1.
  • внутри создать каталог src и git init it.
  • в src создать page1.html с
  • $ git worktree add ../V0 ver0
  • в src мастер добавляет больше текста в page1.html и фиксирует его.
  • $ git branch sty1
  • отредактируйте page1.html в ветке sty1 (добавьте некоторый отличительный стиль CSS) и добавьте commit it.
  • $ git worktree add ../S1 sty1

Теперь вы можете использовать веб-браузер для одновременного открытия и просмотра этих трех версий:

  • ..\page1\src\page1.html // любой git имеет текущий
  • ..\page1\V0\page1.html // начальная версия
  • ..\page1\S1\page1.html // версия в экспериментальном стиле
49
ответ дан aldoWan 15 August 2018 в 19:33
поделиться
  1. Есть законные причины, по которым вам может понадобиться несколько рабочих деревьев в файловой системе сразу. манипулирование проверенными файлами , в то время как , требующие внести изменения в другое место (например, компиляция / тестирование), отличает файлы с помощью обычных инструментов diff во время конфликтов слияния, я часто хочу перемещаться по исходному коду, поскольку он включен исходная сторона , в то время как разрешает конфликты в файлах. Если вам нужно много раз переключаться вперед и назад, вы теряете время и проверяете, что вам не нужно делать с несколькими рабочими. ментальная стоимость ментального контекста, переходящая между ветвями через git stashing, на самом деле не измерима. Некоторые люди находят, что существует ментальная стоимость, которая не существует, просто открывая файлы из другого каталога.
  2. Некоторые люди спрашивают «почему бы не сделать несколько локальных клонов». Это правда, что с флагом «--local» вам не нужно беспокоиться об использовании дополнительного дискового пространства. Это (или подобные идеи) - это то, что я сделал до этого момента. Функциональные преимущества для связанных рабочих мест над локальными клонами: с локальными клонами ваши дополнительные рабочие деревья (которые находятся в локальных клонах) просто не имеют доступа к источникам происхождения или вверх по течению. «Начало» в клоне не будет таким же, как «происхождение» в первом клоне. Запуск git log @{u}.. или git diff origin/feature/other-feature может быть очень полезным, и это невозможно или более сложно. Эти идеи технически возможны с локальными клонами через ассортимент трудовых ресурсов, но каждое обходное решение, которое вы можете сделать, выполняется лучше и / или проще с помощью связанных рабочих деревьев. Вы можете делиться ссылками между рабочими. Если вы хотите сравнить или заимствовать изменения из другого локального филиала, теперь вы можете.
51
ответ дан Alexander Bird 15 August 2018 в 19:33
поделиться
  • 1
    Не будет ли git clone работать так же хорошо для всех этих? – jthill 11 August 2015 в 08:23
  • 2
    Было бы, но клонирование большого хранилища с пульта может занять много времени. Я работаю против одного репозитория, который занимает несколько минут, чтобы клонировать. Я думаю, вы могли бы сделать это с помощью git clone --reference. Кроме того, управление всеми другими филиалами будет выполняться только один раз, а не один раз за рабочий каталог. – Andreas Wederbrand 11 August 2015 в 10:53
  • 3
    Не клонируйте с удаленного, клонируйте с вашего местного. Я не понимаю проблему управления филиалами, вы можете уточнить? – jthill 11 August 2015 в 14:48
  • 4
    Я пытался использовать клоны, и на самом деле проблема управления. Вместо одного набора ветвей у меня есть набор клонов, которые я не вижу в одном пользовательском интерфейсе. Если мне нужно вишни, выберите некоторые изменения, которые я должен получить или направить на них. Он добавляет дополнительные шаги ко всем действиям. Все выполнимо, но всегда есть трение. – max630 13 October 2015 в 05:04
  • 5
    И когда дело доходит до создания резервной копии, один репозиторий намного проще. – max630 13 October 2015 в 05:04
  • 6
    Кроме того, вы можете перечислить все рабочие группы с помощью одной команды, с клонами вам нужно будет следить за ними самостоятельно. – Ian Ringrose 28 January 2016 в 11:23
  • 7
    хмм. Что касается git 2.7.0, то, похоже, это так. Приятно знать. – Alexander Bird 28 January 2016 в 16:18

В новом проекте для меня я создал функцию. Но некоторые спецификации не удались. Чтобы сравнить результаты с master, я создал репозиторий work-tree. Я сравнивал результаты шаг за шагом в коде запуска, пока не понял, что пошло не так.

1
ответ дан itsnikolay 15 August 2018 в 19:33
поделиться

tl; dr: В любой момент, когда вы хотите, чтобы два рабочих дерева проверялись одновременно, по какой-либо причине, git-worktree - это быстрый и экономичный способ сделать это.

Если вы создайте другую рабочую строку, большинство разделов репо (т.е. .git) будут разделены, то есть если вы создадите ветвь или извлечете данные, когда находитесь в одном дереве работ, она также будет доступна из любых других рабочих деревьев, которые у вас есть. Предположим, вы хотите запустить свой тестовый пакет на ветке foo, не нажимая его где-нибудь, чтобы клонировать его, и вы хотите избежать проблем с клонированием своего репо локально, используя git-worktree, это отличный способ создать только новую проверку некоторых в отдельном месте, временно или постоянно. Точно так же, как с клоном, все, что вам нужно сделать, когда вы закончите с ним, - это удалить его, и ссылка на него будет собираться через некоторое время.

8
ответ дан jsageryd 15 August 2018 в 19:33
поделиться
  • 1
    Документы говорят, что вы не можете иметь одну и ту же ветку в обеих рабочих копиях, что является серьезным ограничением. С Mercurial он работал только с небольшими проблемами. – hypersw 11 February 2016 в 21:11
  • 2
    Что вы можете. На странице руководства написано, как; найдите --force. Но неудобно, если вы обновите ветку в одном месте и ожидаете работать над ней в другом, так как worktree не обновляется. – jsageryd 27 February 2016 в 01:59
  • 3
    Да, ветви в Mercurial - более прозрачная концепция в этом аспекте. Как ветки из одной рабочей строки появляются в другой? Точно так же, как несколько восходящих линий? Мои первые эксперименты с рабочими деревьями, с запуском извлечения в обоих, закончились двумя (!) Разными (!) Указателями с именем origin/master. – hypersw 29 February 2016 в 18:48
  • 4
    Трудная работа (как следует из названия) - просто worktree, с некоторыми дополнительными добавленными функциями; репозиторий разделяется между всеми рабочими. Единственное различие между двумя рабочими строками заключается в том, что вырезанная ветка может быть (и для нормальных рабочих процессов, есть) различной. Это можно сделать в отдельной рабочей книге, так что у нее также есть свой собственный индекс (промежуточная область a.k.a.), чтобы сделать эту работу. Файл .git в отдельной рабочей папке представляет собой текстовый файл, содержащий путь к его конфигурации, который находится в исходном репозитории. – jsageryd 27 March 2016 в 10:41
  • 5
    @WilsonF: git checkout --ignore-other-worktrees <branch> git-scm.com/docs/git-checkout/… – jsageryd 4 April 2017 в 13:38

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

Я работаю над довольно большой базой кода, которая занимает довольно много времени для компиляции. Обычно у меня есть текущая ветвь развития на моей машине вместе с ветвью функций, в которой я сейчас работаю, плюс ведущая ветвь, представляющая текущее состояние живой системы.

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

4
ответ дан rethab 15 August 2018 в 19:33
поделиться

Для меня, git worktree - самое большое улучшение с давних времен. Я работаю над разработкой корпоративного программного обеспечения. Там очень часто приходится поддерживать старые версии, как то, что вы выпустили 3 года назад. Конечно, у вас есть ветка для каждой версии, чтобы вы могли легко переключиться на нее и исправить ошибку. Однако переключение дорого, потому что пока вы полностью реорганизовали хранилище и, возможно, создали систему. Если вы переключитесь, ваша среда IDE будет безумной, пытаясь адаптировать настройки проекта.

С помощью worktree вы можете избежать этой постоянной реконфигурации. Оформить эти ветви в отдельных папках с помощью рабочей таблицы. Для каждой ветви у вас есть независимый проект IDE.

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

Теперь единственной недостающей частью является официальная версия git 2.5 для Windows, но есть надежда, что новый git для окон скоро выйдет: -)

86
ответ дан Sebi 15 August 2018 в 19:33
поделиться
  • 1
    Вам не приходилось приносить одни и те же изменения из репо несколько раз. Возможно, вы просто скопировали каталог .git первого клона. – misiu_mp 15 March 2017 в 15:35
  • 2
    но это все равно будет потреблять больше дискового пространства? – mxttie 8 May 2017 в 14:05
  • 3
    @mxttie Не использует жесткие ссылки для клонирования с места на диске? (Не знаю, как это работает в Windows ...) – jdk1.0 5 July 2017 в 03:49
  • 4
    @ jdk1.0 извините за путаницу, комментарий был направлен на misiu_mp – mxttie 6 July 2017 в 12:55
  • 5
    Как кто-то, кто использовал 2-3 сильно реплицированных репозитория, поэтому я могу построить одну ветвь функции при разработке на другой, у меня было каждое локальное репо в качестве пультов других, и я полностью согласен с характеристиками суффиксами Себи (много выборки и толкания! ) Кроме того, как только я переключаюсь на worktree, я понимаю, что мне больше не придется беспокоиться о том, что локальные ветви с одинаковым именем расходятся (что происходит примерно раз в 6-10 месяцев, так как меня прерывают несколько раз в течение нескольких дней и заканчивают работая с одной и той же функциональной ветвью из нескольких репозиториев, но забывайте синхронизировать их с резервным копированием ...) – sage 31 July 2017 в 21:26
51
ответ дан Alexander Bird 5 September 2018 в 18:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: