Как отслеживать только локальные изменения / наборы изменений с помощью git-svn?

Я хочу, чтобы файлы, которые я отслеживаю в моем локальном репозитории git, не регистрируются в центральном репозитории svn, когда я запускаю git-svn dcommit. У меня часто есть долгоживущие локальные изменения файлов, отслеживаемых в репозитории. Иногда для отладки кода. У меня также есть файлы IDE проекта, которые я хотел бы отслеживать. Используя старый добрый svn, я бы просто поместил эти файлы в список изменений с надписью «XYZ: DO NOT CHECK IN», а затем просто вручную решил проблему, когда у меня действительно есть изменения, которые мне нужно зафиксировать.

В идеале я хотел бы проверить свои изменения в своей основной ветке, но установить что-то, что предотвращает распространение этих конкретных изменений в репозиторий svn. Я бы использовал git и git-svn обычным способом, но некоторые коммиты никогда не подталкиваются. Очевидно, я могу делать это вручную каждый раз, когда совершаю коммит, но это больно.

Я рассмотрел и отбросил пару вещей. Я не хочу исключать эти файлы, потому что иногда мне нужно внести изменения, которые ДОЛЖНЫ быть зафиксированы. Кроме того, я бы хотел, чтобы эти файлы отображались во всех создаваемых мной ветвях, предназначенных только для локальных пользователей, как в случае с файлами IDE. Однако я не могу изолировать эти изменения в одной ветке, потому что мне нужно, чтобы они были в каждой ветке, как и в файлах IDE. Похоже, что-то вроде вины или stgit может делать то, что я хочу, но это не очевидно, поскольку они добавляют свой собственный уровень сложности поверх git, который я все еще изучаю.


person normal    schedule 11.03.2009    source источник


Ответы (5)


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

Добавляйте свои "не SVN" файлы только в рабочую ветку. Как правило, все изменения кода вносите в рабочую ветку. При изменении файлов, не относящихся к SVN, добавьте те, которые используют уникальную фиксацию, и установите префикс сообщения фиксации (например, «local:» или «private:»). Когда вы будете готовы к использованию SVN, выполните следующие действия:

  1. Показать журнал коммитов для добавления в SVN:

    git co working
    git cherry master
    
  2. Добавьте все вышестоящие коммиты в основную ветку, игнорируя «частные» коммиты. Повторяйте этот шаг, пока все вышестоящие коммиты не будут в мастере.

    git co master
    git cherry-pick <SHA1>
    
  3. Отправка коммитов в репозиторий SVN:

    git svn rebase
    git svn dcommit
    
person cmcginty    schedule 11.03.2009
comment
Спасибо за предложение. Возможно, мне придется прибегнуть к этому, но недостаток в том, что мне каждый раз придется выполнять дополнительную работу. - person normal; 12.03.2009

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

stg pop # naming the patches that should not be commited
stg commit # the rest of the patches to commit
git svn dcommit
stg push # naming the patches that are used locally

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

stg push local-mods-derby
ant tests
stg pop

или если я хочу протестировать PostgreSQL, я запускаю

stg push local-mods-test-postgresql
ant tests
stg pop

Здесь «local-mods-derby» и «local-mods-test-postgresql» - названия патчей.

Таким образом, поддерживать отдельные патчи работы с помощью stg очень просто.

person Blair Zajac    schedule 24.03.2009

Вы не думали работать в главной ветке?

Если вы сохраняете свои изменения в локальной ветке git, вы можете периодически объединять или выбирать только желаемые изменения в своей ветке отслеживания svn. Переключитесь на ветку отслеживания, запустите dcommit. Затем вернитесь в свою локальную ветку и переустановите ее.

Если вы хотите, чтобы изменения происходили в нескольких ветвях, базируйте их все на одной и той же точке ветвления. Сохраните эту ветку как master + изменения через ребазинг. Затем для всех остальных веток просто переустановите эту базовую ветку.

person Ryan Graham    schedule 27.03.2009

Возможно, вы захотите использовать для этого тайник.

git-stash - Stash the changes in a dirty working directory away

Однако он может быть недостаточно мощным для того, что вы описываете.

person Kent Fredric    schedule 11.03.2009
comment
stash может только временно хранить незафиксированные изменения в дереве. В конце концов OP хочет проверить изменения в файлах, но не допустить их фиксации в репозитории SVN. - person cmcginty; 12.03.2009
comment
Собственно, некоторые изменения я никогда не захочу фиксировать. Может быть, это плохая практика, но это было удобно. - person normal; 12.03.2009

Я провел небольшое исследование и обнаружил возможность, которая могла бы это сделать: 2 репозитория git, указывающих на один и тот же каталог. Переменная среды GIT_DIR хранит имя каталога локального репозитория. Если не задано, по умолчанию git принимает значение .git, но это может быть что угодно.

Тогда я мог бы создать один репозиторий в .git, который сопоставляется с моим репозиторием Subversion. Это обычный случай. Тогда у меня мог бы быть другой репозиторий в .localgit. Каждый репозиторий должен быть настроен так, чтобы игнорировать файлы, управляемые другим репозиторием. Это просто с! для отрицания паттернов.

Когда я вношу изменения только в локальные файлы, которые хочу зарегистрировать, я либо изменяю свою переменную среды GIT_DIR, либо использую аргумент командной строки --git-dir. Если мои исключения / игнорирования настроены правильно, мне не придется беспокоиться о коллизиях. Очевидно, есть некоторые накладные расходы, чтобы поддерживать это в актуальном состоянии, но я могу написать сценарий оболочки, который добавляет файл в исключение одного репо, когда файл добавляется к другому. Кроме того, эти накладные расходы возникают только один раз для каждого файла, а не при каждой фиксации, как в случае предложения с несколькими ветвями.

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

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

person normal    schedule 16.03.2009