Hatred's Log Place

DON'T PANIC!

SubGit

May 28, 2018 - 3 minute read

Разные советы и рекомендации. Хорошие практики.

Слияния (git merge)

Выключить в git репозитории Fast Forward Merge: git config merge.ff false

Это упредит от ошибки вида:

remote: The following ref update is disallowed:
remote:   refs/heads/master: leads to replacement of SVN branch 'trunk'
remote: 
remote: If changes were forcefully pushed to Git repository, try to merge them with the upstream instead;
remote: If changes were result of fast-forward merge, retry merge with --no-ff option.

Подробнее: https://stackoverflow.com/questions/38926427/jira-subversion-mirror-subgit-remote-error-on-push

git pull

Согласно ответу одного из разработчиков SubGit, при обновлении репозитория рекомендуют делать: git pull –rebase

вместо просто git pull

Что бы сделать это поведение поведением по умолчанию для репозитория: git config pull.rebase true

Или глобально: git config –global pull.rebase true

Имена пользователей

Немного странного в SubGit.

SubGit может установить правильное имя автора коммита в SVN двумя путями:

  1. залогиниться как этот пользователь. Для этого пароль пользователя должен быть прописан в subgit/passwords или быть захешированным в $HOME/.subversion. В обоих случаях, скорее всего (можно мутить с gpg-agent для второго варианта), он должен там храниться открытым текстом, что не есть хорошо. Для этого не нужно действий со стороны администратора SVN.
  2. разрешить на стороне svn хук pre-revprop-change, который просто будет возвращать 0, тем самым будет разрешено установка свойства svn:author. Но тут нужно вмешательство со стороны администратора SVN. Плюс, возможно, нужно создать отдельного пользователя, которому это разрешено и его прописать в настройках SubGit. И один фиг, его нужно будет хранить открытым текстом.

А странность заключается в том, что если пользователь не задан или если для этого пользователя нет пароля (в случае первого варианта), то коммит будет втихаря сделан от… произвольного пользователя, от которого получилось залогиниться!

Соответственно, нужно создать git hook user-pre-receive на стороне git-зеркала, что бы он давал отлуп таким коммитам. Примерное исполнение:

#!/bin/bash

process_stdin()
{
    svn_url=$(cat ${GIT_DIR}/subgit/config | sed 's/^[ <br/>t]<br/>+//' | grep -v '^#' | grep '^url[ <br/>t]*=' | sed 's/=/ /' | awk '{print $2}')
    local ret=0
    while read line
    do
        from=$(echo $line | awk '{print $1}')
        to=$(echo $line | awk '{print $2}')

        cd "${GIT_DIR}"
        git log --format="%an <%ae>" ${from}..${to} | while read user
        do
            item=$(cat ${GIT_DIR}/subgit/authors.txt | grep "${user}<br/>$")
            svn_user=$(echo ${item} | awk -F= '{print $1}' | awk '{print $1}')
            #svn_user=123
            echo "mapping: $item, '$svn_user'" >&2
            if [ -z "$svn_user" ]; then
                svn_user=$(echo "${user}" | awk '{print $1}')
            fi

            svn ls --username="$svn_user" "$svn_url" > /dev/null
            ret=$?
            if [ $ret -ne 0 ]; then
                echo "error during access to the SVN repo for user '$svn_user' (git credentionals: '$user'). Try to make login before." >&2
                exit 1
            else
                echo "valid SVN user, continue..." >&2
            fi
        done; ret=$?

        # to bypass to the next hook
        #echo "$line"
    done

    return $ret
}

#set -x
process_stdin
ret=$?

echo "User ret status: " $ret

#exit 1
exit $ret

SubGit использует свой хук pre-receive, но он предварительно пробует вызвать пользовательский, если он существует.

Ещё, для склонированного репозитория имеет смысл выполнить такие команды, что бы использовать автоматический меппинг:

git config user.name svnUserName
git config user.email svnUserName@localhost

Подробности:

Заметки

comments powered by Disqus