git - добавить несколько подкаталогов в локальный репозиторий, но не в удаленный? - PullRequest
1 голос
/ 15 сентября 2011

Есть ли (относительно) простой способ добавить некоторые части дерева в локальный репозиторий, но НЕ в удаленный репозиторий? Например, предположим, что у меня есть что-то вроде

project_root/
-- src/ <- in local and remote
-- test/ <- in local and remote
-- my_dev_ideas/ <- currently untracked, want in local but not remote

Я хотел бы добавить my_dev_ideas/, чтобы я мог отслеживать его в локальном репо, но не включать его при удалении. Я мог бы создать ветку и my_dev_ideas/ в ветке, но есть пара зависаний:

  • Когда я пытаюсь объединиться с (например) мастером, я не хочу, чтобы он создавал my_dev_ideas/
  • Это упрощенный пример - на самом деле это довольно большой проект, и у меня есть несколько таких каталогов, разбросанных по всему дереву.
  • ИМО, это разрушает абстракцию того, что такое "ветвь". Я все еще хочу иметь возможность создавать локальные ветви, такие как add-feature, в которых все еще находятся эти каталоги.

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

Я надеюсь, что следующее может работать в мою пользу.

  1. Каталоги еще не находятся в репо (локальном или удаленном).
  2. Мне не обязательно выбирать определенные файлы - просто части дерева каталогов.

Я понимаю, почему это может быть очень сложно или даже невозможно (предположим, я изменяю src/foo.cpp и my_dev_ideas/bananas.h в одном и том же коммите ...), но я хотел посмотреть, есть ли у кого-нибудь какие-либо предложения ...

Ответы [ 2 ]

0 голосов
/ 16 октября 2012

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

Ну, вы можете это сделать.Есть несколько подходов, но все они сложны.Но я думаю, что это окажется самым простым:

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

Во-первых, вы захотите найти самый ранний коммит, в который вы добавили материал, который вы не хотите публиковать.Допустим, это 1abcdef.Нам очень нужен родитель этого коммита, поэтому давайте создадим ветку для ссылки на него:

git branch before_publish 1abcdef^

Внимательно обратите внимание на ^ в конце строки.Если вы используете windows и cmd.exe, вам придется заключить его в кавычки со вторым символом ^, то есть ^^, поскольку cmd.exe использует ^ в качестве символа продолжения строки ....

ДалееДавайте создадим и извлечем ветку для публикации (при условии, что мы уже извлекли ветку, из которой мы хотим публиковать):

git checkout -b publish

Теперь самое интересное.Мы хотим избавиться от этой ветки от поврежденных файлов.

git filter-branch -f --index-filter 'git rm -r -f --quiet --cached --ignore-unmatch <your list of files and directories here>' before_publish..publish

ОК, это даст вам ветку без дополнений, которые вы не хотите публиковать.Затем вы можете объединить или перебазировать эти изменения поверх основной ветви, с которой вы начали, и протолкнуть их, как обычно, в соответствии с вашим рабочим процессом.

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

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

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

Вы не сможете напрямую использовать «git merge» - вам придется использовать:

git checkout publish
git branch -f before_publish
git cherry-pick last_published..my-main-branch
git filter-branch ... before_publish..publish
git checkout my-main-branch
git branch -f last_published

Это немного сложнее, но избавляет вас от необходимостинеоднократно создавать новые коммиты для всей истории ваших дополнительных файлов.Это, вероятно, не стоит делать, если вы делаете что-то недолгое.

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

git filter-branch -f --index-filter 'git reset --quiet before_publish -- <paths to restore>' before_publish..publish

Конечно, вы можете (и должны) объединить оба в одной операции 'git filter-branch', есливам нужны оба.

0 голосов
/ 15 сентября 2011

это звучит как работа для подмодулей git , чтобы вы могли отслеживать их отдельно. хотя это означает, что вам нужно связать два проекта, которые могут вызвать у вас проблемы другого рода. возможно это поможет?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...