Filter by tag: Science
  • Удаление паролей из истории Git by Ast

    Great Scott!

    Почему это важно?

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

    Плохие новости состоят в том, что не существует волшебной пилюли, которая просто всё исправит и не потребует от вас никаких лишний действий или головной боли после. Хорошие новости в том, что решение всё таки существует, хотя оно и изменит каждый коммит, начиная с момента «изъятия» важной информации из хранилища — а значит, вы получите совсем другую ветку кода, с совсем другими хешами коммитов.

    git filter-branch --tree-filter 'git ls-files -z "*" |xargs -0 perl -p -i -e "s#(PASSWORD1|PASSWORD2|PASSWORD3)#NOT_A_PASSWORD_ACTUALLY#g"' -- --all
    git reset --hard
    git gc --aggressive --prune
    

    Вся магия — в первой команде, которая пройдет по всем коммитам текущей веткеи и заменит PASSWORD1, PASSWORD2, PASSWORD3 на безопасный плейсхолдер — NOT_A_PASSWORD_ACTUALLY.

  • Миграция с Mercurial на Git by Ast

    migration

    Иногда возникает необходимость продолжать работу над старыми проектами, в которых могут использоваться устаревшие системы версий — например, mercurial или, боже упаси, svn. К счастью, для перехода с mecurial на git не требуется начинать проект с чистого листа и терять историю изменений, есть утилита, которая всё сделает для нас сама.

    cd
    git clone git://repo.or.cz/fast-export.git
    git init git_repo
    cd ~/git_repo
    ~/fast-export/hg-fast-export.sh -r ~/mercurial-repo
    git checkout HEAD
    

    В итоге, в текущей папке мы получим самый настоящий git.

  • Ветка git в командной строке by Ast

    Если активная работа над проектом идет над несколькими ветками сразу, всегда полезно знать, на какой ветке в текущий момент находится указатель HEAD репозитария. Чтобы не полагаться на память, можно добавить отображение названия ветки в приглашение командной строки. Для этого откроем на редактирование ~/.bashrc

    export PS1='\u@\h: \w\[\033[01;33m\]$(__git_ps1) \$\[\033[00m\] '
    

    Любуемся результатом:

    Но, по хорошему, лучше просто поставьте zsh — оно того стоит.

  • Как вежливо попросить git напомнить о миграциях by Ast

    Иногда важно помнить о том, что вместе с апдейтом кода появилась и новая миграция, которую нужно бы не забыть запустить. Первый вариант — git merge-base и еще несколько полезных команд. Задачу это решает, но требует множества действий — есть простор для фантазии и автоматизации. Пускай git сам напоминает нам о новых миграциях!

    #!/bin/bash
    
    HAS_NEW_MIGRATIONS=0
    git diff HEAD@{1} HEAD@{0} --name-only --diff-filter=A | grep 'migration' | while read FILENAME; do
      if [ "$HAS_NEW_MIGRATIONS" == 0 ] ; then
        echo -en "\033[32mМиграции добавлены: \033[0m \n"
        HAS_NEW_MIGRATIONS=1
      fi
    
      echo -en "\033[32m — " $FILENAME "\033[0m \n"
    done
    
    HAS_MODIFIED_MIGRATIONS=0
    git diff HEAD@{1} HEAD@{0} --name-only --diff-filter=M | grep 'migration' | while read FILENAME; do
      if [ "$HAS_MODIFIED_MIGRATIONS" == 0 ] ; then
        echo -en "\033[31mМиграции изменены: \033[0m \n"
        HAS_MODIFIED_MIGRATIONS=1
      fi
    
      echo -en "\033[31m — " $FILENAME "\033[0m \n"
    done
    
    exit 0
    
    ~/project/.git/hooks/post-checkout
    ~/project/.git/hooks/post-merge
    ~/project/.git/hooks/post-rewrite
    

    Миссия выполнена. Теперь при обновлении мы будем получать зеленый список новых миграций и красный список измененных миграций (но лучше такого вовсе не допускать). Не забудьте поставить файлу права на выполнение.

    На самом деле, лучше используйте какое-нибудь готовое решение для учета миграций, которое, в том числе, умеет их откатывать. А еще лучше — делайте это автоматически, используя Continious Delivery.

  • Первичная настройка git by Ast

    Алиасы

    Получение статуса

    git config --global alias.st status
    git st
    

    Наглядный лог

    git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"
    git lg
    git lg -p
    

    Настройка пользователя

    git config --global user.name "Username"
    git config --global user.email "foo@bar.com"
    

    Добавим цвета

    git config --global color.branch auto
    git config --global color.diff auto
    git config --global color.interactive auto
    git config --global color.status auto
    
  • Как привести в порядок репозитарий by Ast

    Всегда приятно начинать проект с нуля, самому создавать под него репозитарий, определять принятый в нём стиль кодирования, да и многое другое. Но иногда нам достаются «трудные дети» с тяжелым прошлым, включающим мешанину табуляции и пробелов, разных способов обрыва строки, кодировок. Понятное дело, что все это приводит систему контроля версий к истерике. Но не беда. Linux to the rescue!

    Форматирование

    Нам пригодится утилита expand.

    find ./ -type f -name "*.php" -exec sh -c 'expand -t 4 {} > _tmp_ && mv _tmp_ {}' \;
    

    Данная команда заменит в каждом *.php файле табуляцию на 4 пробела. В обратную сторону работает команда unexpand.

    Завершение строки

    Исторически так сложилось, что способов завершить строку в текстовом файле довольно много. Самые распространенные: версия Windows (CR+LF) и Unix (LF). В репозитарии же следует выбрать что-то одно. Нам придет на выручку другая замечательная утилита dos2unix (еще более замечательная тем, что нет необходимости париться с временными файлами!)

    find ./ -type f -name "*.php" -exec sh -c 'dos2unix {}' \;
    

    Еще одно решение: hook для git`а

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

    nano repository_path/.git/hooks/pre-commit
    
    ALLOWED_EXTENSIONS=('php' 'phtml' 'js' 'css' 'html' 'htm' )
    git diff --cached --name-only --diff-filter=ACM | while read FILENAME; do
      FILENAME_EXTENSION=${FILENAME#*.}
      for ALLOWED_EXTENSION in "${ALLOWED_EXTENSIONS[@]}"
      do
        if [ "$ALLOWED_EXTENSION" == "$FILENAME_EXTENSION" ] ; then
          # fixing line endings
          dos2unix --quiet $FILENAME
          # converting tabs into spaces
          expand -t 4 $FILENAME > _tmp_ && mv _tmp_ $FILENAME
          git add $FILENAME
        fi
      done
    done
    exit 0
    
  • Актуальная версия Git на Ubuntu by Ast

    Добавляем репозиторий

    add-apt-repository ppa:git-core/ppa
    apt-get update
    apt-get install git-core
    

    Если в системе нет add-apt-repository, необходимо перед этим поставить еще один пакет

    sudo apt-get install python-software-properties
    

    Ура, у нас современная версия git!