2013-11-15 4 views
2

У меня есть 2 репозитория, синхронизирующихся через общий сервер.Git + Python Virtualenvs: уникальный каталог в репозиториях

Repository 1 -- Server -- Repository 2 

В каждом хранилище, есть каталог под названием «уникальный», который может содержать данные о настройке базы данных используется в virtualenv.

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

Примите во внимание вашу помощь.

+1

Хотелось бы узнать больше об этом несколько уникальном случае использования ... вы посмотрели на подмодули Git? – RyPeck

+0

Это действительно миграционный каталог юга в Django. Он отслеживает изменения структуры базы данных, и каждая ветка соответствует другой базе данных. Это, вероятно, преувеличенный подход, с которым я мог бы обойтись без него, или я могу найти обходные пути вне git. Тем не менее, я хотел бы знать, есть ли способ сделать это, используя настройки конфигурации git. Я пробовал подмодули git в прошлом, я нахожу их громоздкими и трудными в обслуживании. Если это единственное решение, я бы предпочел изменить структуру моей установки разработки. – raratiru

+1

Есть ли причина, по которой двум репозиториям нужны свои «уникальные» каталоги с тем же именем? Если у вас есть другой способ отличить (например, от имени вашей базы данных или от хоста, на котором он запущен,), вы можете использовать это, чтобы выбрать соответствующий каталог. Если у них разные имена, ваша проблема уходит. – engineerC

ответ

1

Наконец, решение было предоставлено virtualenvs.

Очень хорошее сообщение, объясняющее, как и почему нужно использовать разные виртуальные языки в разработке django: Marina Mele's.

уникальных файлов соответствуют одному virtualenv и у них есть символическая ссылка на каталог .local/path/to/unique/file, который обновляется каждый раз, когда среда активируется.

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

В ~/.virtualenvs/<myvirtualenv>/bin/activate я бы добавить команды :

cd /path/to/git/repository/of/my/project && manage_migrations <myvirtualenv> 
for item in $(find ./ ! -type f -name "migrations" ! -path "./.git/*" ! -path "./.local/*"); do touch "$item"/__init__.py; done 

Где manage_migrations:

(скрипт, который при активации virtualenv, он обновляет й e символической ссылки для каждой папки migrations. например

./app/migrations -> .local/<myvirtualenv>/app/migrations

#!/bin/bash 
# vim: filetype=sh 

virtualenv_name=$1 
repository_root=$(git rev-parse --show-toplevel) 
local_environment="$repository_root"/.local/"$virtualenv_name" 

mkdir -p "$local_environment" 
cd "$repository_root" 
for item in $(find ./ ! -type f -name "migrations" ! -path "./.git/*" ! -path "./.local/*") 
do 
    if [ -f $item ] 
    then 
     echo "$item is a file, this is a plain burdain." 
     exit 
    elif [ ! -L $item ] 
    then 
     rsync -vaR --delete "$item" "$local_environment"/ 
     rm -Rf $item 
    fi 
    rm "$item" > /dev/null 2>&1 
    mkdir -p "$local_environment"/"${item#./}" 
    ln -s "$local_environment"/"${item#./}" "$item" 
done 

Я отправил подход, основанный ГИТ-крюки к этому вопросу в следующем хранилище:

Disabled Link

Однако, это делает не представляется жизнеспособным решением.

Использование symlinks, Merge Strategies или local config files для переопределения значений по умолчанию было бы рекомендуемым способом.

Обратите внимание на this issue, прежде чем доверять стратегиям объединения.

1

EDIT: Ниже следует наивный «первый подход», который не может считаться жизнеспособным решением.

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


Путь я собираюсь заняться этим вопросом является мягким связывающим «уникальным» файл или каталога в файл или каталог в .local папки.

Структура этой папки должна быть создана впервые -На мастер филиала перед созданием другого branches- с помощью следующей команды:

cd ./$(git rev-parse --show-cdup) && mkdir -p .local/$(echo "$USER")/$(git symbolic-ref --short -q HEAD) 

Эта команда создаст -в корне repository- дерево:

.local/<username>/<git branch>. 

в «уникальные» файлы в хранилище должны быть перемещены в соответствующий каталог под этим деревом и должны быть мягкими связаны между собой.

Например:

Уникальный файл

./path/to/file/<my_file> 

будет вручную переместить в:

./.local/<username>/<git branch>/path/to/file/<my_file> 

в то время как символическая будет создан вручную в старом положении ссылки на новую ,

"./path/to/file/<my_file>" -> "./.local/<username>/<git branch>/path/to/file/<my_file>" 

Символическая ссылка может быть также добавлена ​​в файле .gitignore:

path/to/file/<my_file> 

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

Теперь на двух сценариях, вызванных пост-слияния и пост-контроль в:

.git/hooks/post-merge 
.git/hooks/post-checkout 

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

Во время первый pull/merge будет создавать локальную среду, в которой все «уникальные» файлы из исходного хранилища будут скопированы и символически связаны.

Пользователь должен удалить или упорядочить соответствующие подпапки .local, а затем ссылки будут автоматически обновлены - при необходимости - скриптом, написанным в bash, который в основном использует sed.

Я не тщательно протестировал сценарий из-за ограничений по времени. Кажется, он работает в моей среде fedora 19, и я буду обновлять сообщение, если изменения будут сделаны.

Я более git-ориентированное решение по-прежнему будет очень желанным.

после слияния:

#! /bin/sh 

# "origin": Refers to the existing merged files (soft links) information that will be overriden. 
# "local": Refers to the local system information that will replace origin information. 

#Get local user name to define the repository directory. 
local_user=$(echo "$USER") 

#Get local branch name to define the branch directory. 
local_branch=$(git symbolic-ref --short -q HEAD) 

#Go to the root of the repository 
cd ./$(git rev-parse --show-cdup) 

#Create local environment 
local_environment=$(echo './.local/'"$local_user"'/'"$local_branch"'/') 
mkdir -p $local_environment 


#Grub and manipulate all soft links. 
symlink_no=0 
for link in $(find -L ./ -xtype l); 
do 
    symlink_no=$[symlink_no+1] 
    # Grub information from each symlink 
    source_file=$(ls -la $link | sed -n 's/^.*[0-9]\+:[0-9]\+\s\(.*\)\s->.*$/\1/p') 
    origin_target_file=$(ls -la $link | sed -n 's/.*>\s\+\(.*\)$/\1/p') 
    relative_to_root_origin_target_file=$(ls -la $link | sed -n 's/.*>\s.*\(.\/.local.*\)$/\1/p') 

    find_origin_user='s/.*local\/\([a-zA-Z0-9._-]\+\).*/\1/p' 
    origin_user=$(echo $origin_target_file | sed -n "$find_origin_user") 
    find_origin_branch='s/.*local\/'"$origin_user"'\/\([a-zA-Z0-9._-]\+\).*/\1/p' 
    origin_branch=$(echo $origin_target_file | sed -n "$find_origin_branch") 

    local_target_file=$(echo $origin_target_file | sed -n 's/local\/'"$origin_user"'\/'"$origin_branch"'/local\/'"$local_user"'\/'"$local_branch"'/p') 
    relative_to_root_local_target_file=$(echo $relative_to_root_origin_target_file | sed -n 's/local\/'"$origin_user"'\/'"$origin_branch"'/local\/'"$local_user"'\/'"$local_branch"'/p') 

    remove_file_from_target_path='s/\(.*\)\/.*$/\1/p' 
    find_local_target_layout=$(echo $relative_to_root_origin_target_file | sed -n "$remove_file_from_target_path" | sed -n 's/.*'"$origin_branch"'\/\(.*$\)/\1/p') 
    local_environment_path=$(echo "$local_environment""$find_local_target_layout") 

    #Wording header. 
    echo '' 
    echo '' 
    echo 'Checking for symlink [' "$symlink_no"' ]:' "$source_file" 
    echo '------------------------------------------------------' 
    echo '' 

    # ------------------- Target File Manipulation --------------------------------- 
    #Check if target file does not exist in local environment. 
    if [ ! -f "$relative_to_root_local_target_file" ]; 
    then 
     #If true, verify that the source file exists and copy it. 
     if [ -f "$relative_to_root_origin_target_file" ]; 
     then 
      mkdir -p "$local_environment_path" 
      rsync -va "$relative_to_root_origin_target_file" "$relative_to_root_local_target_file" 
      echo '' 
      origin_target_file_exists=1 
      local_target_file_exists=1 
      echo 'The source file has been created: ' "$relative_to_root_local_target_file" 
     else 
      echo 'The source file does not exist: ' "$relative_to_root_origin_target_file" 
      origin_target_file_exists=0 
      local_target_file_exists=0 
     fi 
    else 
     local_target_file_exists=1 
     echo 'The local file "'"$relative_to_root_local_target_file" '" already exists.' 
    fi 
    source_path=$(echo $source_file | sed -n "$remove_file_from_target_path") 
    source_check_target=$(echo "$source_path"'/'"$local_target_file") 
    #-------------------- Source File Manipulation --------------------------------- 
    # If target file exists: 
    if [[ $local_target_file_exists -eq 1 ]]; 
    then 
     #Check the source file if it is already linked. 
     if [ "$local_target_file" == "$origin_target_file" ]; 
     then 
      #Is it a correct link? 
      if [ -f $source_check_target ]; 
      then 
       echo 'symlink "' "$source_file" '->' "$local_target_file" '" already exists and it is correct.' 
      else 
       echo '*********** This is a broken link: ' "$source_file" 
       echo '   **********************' 
      fi 
     else 
      #Delete existing symlink 
      rm "$source_file" 

      #Create new symlink according to local environment 
      ln -s "$local_target_file" "$source_file" 
      echo 'symlink "' "$source_file" '->' "$local_target_file" '" has been created.' 
     fi 
    else 
     echo '*********** This is a broken link: ' "$source_file" 
     echo '   **********************' 
    fi 
done 

пост-фотографии:

#! /bin/sh 

# Start from the repository root. 
cd ./$(git rev-parse --show-cdup) 

# Delete .pyc files and empty directories. 
find . -name "*.pyc" -delete 
#find . -type d -empty -delete 

#----------------Symlink manipulation--------------------------------------- 
#Get local user name to define the repository directory. 
local_user=$(echo "$USER") 

#Get local branch name to define the branch directory. 
local_branch=$(git symbolic-ref --short -q HEAD) 

#Go to the root of the repository 
cd ./$(git rev-parse --show-cdup) 

#Grub and manipulate all soft links. 
symlink_no=0 
for link in $(find -L ./ -xtype l); 
do 
    symlink_no=$[symlink_no+1] 
    # Grub information from each symlink 
    source_file=$(ls -la $link | sed -n 's/^.*[0-9]\+:[0-9]\+\s\(.*\)\s->.*$/\1/p') 
    origin_target_file=$(ls -la $link | sed -n 's/.*>\s\+\(.*\)$/\1/p') 
    relative_to_root_origin_target_file=$(ls -la $link | sed -n 's/.*>\s.*\(.\/.local.*\)$/\1/p') 

    find_origin_user='s/.*local\/\([a-zA-Z0-9._-]\+\).*/\1/p' 
    origin_user=$(echo $origin_target_file | sed -n "$find_origin_user") 
    find_origin_branch='s/.*local\/'"$origin_user"'\/\([a-zA-Z0-9._-]\+\).*/\1/p' 
    origin_branch=$(echo $origin_target_file | sed -n "$find_origin_branch") 

    local_target_file=$(echo $origin_target_file | sed -n 's/local\/'"$origin_user"'\/'"$origin_branch"'/local\/'"$local_user"'\/'"$local_branch"'/p') 
    relative_to_root_local_target_file=$(echo $relative_to_root_origin_target_file | sed -n 's/local\/'"$origin_user"'\/'"$origin_branch"'/local\/'"$local_user"'\/'"$local_branch"'/p') 

    remove_file_from_target_path='s/\(.*\)\/.*$/\1/p' 
    find_local_target_layout=$(echo $relative_to_root_origin_target_file | sed -n "$remove_file_from_target_path" | sed -n 's/.*'"$origin_branch"'\/\(.*$\)/\1/p') 
    local_environment_path=$(echo "$local_environment""$find_local_target_layout") 

    source_path=$(echo $source_file | sed -n "$remove_file_from_target_path") 
    source_check_target=$(echo "$source_path"'/'"$local_target_file") 

    #Wording header. 
    echo '' 
    echo '' 
    echo 'Checking for symlink [' "$symlink_no"' ]:' "$source_file" 
    echo '------------------------------------------------------' 
    echo '' 

    # ------------------- Target File Manipulation --------------------------------- 
    #Check if target file does not exist in local environment. 
    if [ -f "$relative_to_root_local_target_file" ]; 
    then 
     #Check the source file if it is already linked. 
     if [ "$local_target_file" == "$origin_target_file" ]; 
     then 
      #Is it a correct link? 
      if [ -f $source_check_target ]; 
      then 
       echo 'symlink "' "$source_file" '->' "$local_target_file" '" already exists and it is correct.' 
      else 
       echo '*********** This is a broken link: ' "$source_file" 
       echo '   **********************' 
      fi 
     else 
      #Delete existing symlink 
      rm "$source_file" 

      #Create new symlink according to local environment 
      ln -s "$local_target_file" "$source_file" 
      echo 'symlink "' "$source_file" '->' "$local_target_file" '" has been created.' 
     fi 
    else 
     echo 'The source file does not exist: ' "$relative_to_root_local_target_file" 
    fi 
done 
Смежные вопросы