Как автоматически разделить git коммиты на отдельные изменения в одном файле - PullRequest
2 голосов
/ 25 марта 2010

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

Я установил две ветви кодовой базы. Один из них "мастер", а другой "Prod". HEAD of prod - это всегда новейший код для развертывания в рабочей среде, а master - это основная ветка разработки.

Но вот проблема: клиент конвертируется из CVS, и большинство разработчиков все еще привыкли к git. Их рабочий процесс CVS включал тегирование версий отдельных файлов для производства, а затем обновление серверов с использованием тега. К сожалению, это привело к неаккуратным практикам, таким как совместное внесение несвязанных изменений и последующая маркировка файлов по факту, сохранение большого количества ненужных файлов в их главном рабочем дереве и т. Д., И разработчики хотят знать, как они могут это сделать следующее:

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

Я знаю, как разделить коммиты с помощью git rebase --interactive, но я понятия не имею, как вообще автоматизировать разбиение коммитов, не говоря уже о том, как я хочу.

Я понимаю, что самым простым было бы просто сказать им переключать свои ветки prod, извлекать файлы из их главных ветвей в рабочее дерево и затем выполнять prod. Моя проблема с этим - потерять историю их коммитов за день.

Кто-нибудь еще занимался этим с помощью сценария или чего-то в этом роде, или я должен просто побудить разработчиков к лучшему поведению - и рискнуть тем, что они полностью отвергнут Git?


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

#!/bin/sh
set -e
dest_branch=$1
file=$2
current_branch=$(git branch | sed 's/^\* //;/^\s/d')
( 
    set -e 
    git format-patch --stdout --full-index -M -C -B --ignore-if-in-upstream $dest_branch -- $file
    git checkout $dest_branch 
) | git am
git checkout $current_branch

1 Ответ

2 голосов
/ 25 марта 2010

У этих разработчиков все еще очень "файлово-ориентированное" видение, а не "хранилище-ориентированный" подход (основанный на ревизии для SVN или коммитах для Git)!
Им нужно прочитать « Какие основные концепции VCS должен знать каждый разработчик? »;)
(изначально речь идет о ClearCase, но все еще актуальна для пользователей CVS, сталкивающихся с DVCS)

Тем не менее, одним из способов преодоления разрыва в конкретном сценарии было бы:

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

Таким образом, история этих файлов сохраняется.

...