git вставляет подкаталог в другой главный репозиторий - PullRequest
4 голосов
/ 10 августа 2011

У меня большой основной проект с несколькими каталогами в виде поддеревьев .

Я хочу отправить изменения в одном конкретном поддереве к его источнику, которое является отдельным репозиторием.

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

Макет большого проекта, где important_subtree - это то, о чем я беспокоюсь.

~/devel/bigproject
  .git/
  some_subtree/
  other_subtree/
  important_subtree/
    abc.txt
    efg.txt   <--- new version
    hij.txt

И important_subtree «сильно связан» с этим репо:

~/devel/important
   .git/
    abc.txt
    efg.txt   <--- old version
    hij.txt

Теперь ~/devel/bigproject/important_subtree/efg.txt изменилось, и я хочу вставить важные_субтрея в репо ~/devel/important. Так что потом ~/devel/important/efg.txt также имеет изменения.

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

Ответы [ 3 ]

3 голосов
/ 18 января 2012

Я бы рекомендовал git-subtree дополнение к git.Он добавляет команду git subtree split, которая делает то, что вы хотите.

git subtree split --prefix=important_subtree --branch=backport <subtree merge SHA1>^.. --onto=<imported SHA1> --rejoin
git push ~/devel/important backport:master

Эта команда выбирает изменения в bigproject после объединения important как поддерево, принимая только те, которые изменили important_subtree/,Затем он применяет их как новые коммиты поверх коммита, импортированного вами из ~/devel/important, и создает ветку backport, которую вы можете отодвинуть обычным способом.Кроме того, --rejoin делает это таким образом, что вам не нужно будет использовать идентификаторы коммитов в будущем, если вы хотите повторить процесс при большем количестве изменений.

Более подробное объяснение содержится в блоге автора .

3 голосов
/ 20 августа 2014

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

git clone <ORIG_REPO_DIR> <NEW_REPO_DIR>
cd <NEW_REPO_DIR>
git filter-branch --prune-empty --subdirectory-filter <THE_SUBDIR_TO_MAKE_NEW_ROOTDIR> master
git push <MY_NEW_REMOTE_ORIGIN_URL> -f .
1 голос
/ 10 августа 2011

Нажатие на разные ветви может быть очень сложной вещью.

Возможно, самый простой способ был бы:

  1. Еще раз клонируйте свое "важное" хранилище с сервера.
  2. В вашем "большом проекте" производят патчи, которые содержат именно те изменения, которые вы намеревались в первую очередь push (например, git format-patch) (вам может понадобиться сначала сделать «меньшие» коммиты в боковой ветке, если ваши исходные коммиты смешивают файлы, которые должны быть выдвинуты, и такие файлы, которые не должны)
  3. В вашем новом клоне "важных" примените патчи (git am)
  4. подтолкнуть новый клон "важный" к своему удаленному мастеру по умолчанию. Теперь толчок - это просто быстрая перемотка вперед, и он не должен вызывать проблем.
...