تقسيم الدليل الفرعي مع العارض الفرعي إلى مستودع GIT منفصل

StackOverflow https://stackoverflow.com/questions/3411364

  •  25-09-2019
  •  | 
  •  

سؤال

كمجموعة فرعية من السؤال detach-subdirectory تم تقديمه بالفعل من قبل وبالنظر إلى حقيقة أنه على الرغم من أن الكثير من الأسئلة قد تم طرحها حول عملية تقسيم ودمج مستودعات GIT ، إلا أنني لم أتمكن من العثور على موضوع يمس موضوع الانقسام عند وجود علامات فرعية.

لذلك في السيناريو التالي:

.git/
.gitmodules
folder/
    data/
    content/
        other_data/
        submoduleA/
        submoduleB/

أود الحصول على مستودعين مع الهيكل التالي:

.git/
data/

و

.git/
.gitmodules
content/
    other_data/
    submoduleA/
    submoduleB/

الحالة الأولى ليست مشكلة ويمكن حلها بسهولة مع الطريقة الموضحة في detach-subdirectory.

الثاني ليس كثيرا. وجود عروض فرعية وحقيقة أن .gitmodules يحتوي على المسار الكامل ل folder/content/submoduleA و folder/content/submoduleB يسبب جزء من التاريخ غير متناسق لأن .gitmodules يشير إلى بنية دليل غير موجودة (بمجرد استخدام فرع المرشح).

لذلك أود أن أعرف ما إذا كانت هناك طريقة للقيام بذلك دون التسبب في تاريخ غير متناسق.

هل كانت مفيدة؟

المحلول

أظن (لم يختبر) أن ثانية git filter-branch سيكون لديك الفرصة لتعديل .gitmodules محتوى لكل ارتباط من الريبو الجديد.

ولكن في الواقع أ git submodule split كان الأمر في المناقشة في أوائل عام 2009.

الاستخدام المقترح:

git submodule split [--url submodule_repo_url] submodule_dir \
    [alternate_dir...]

يحل محل submodule_dir مع وحدة فرعية تم إنشاؤها حديثًا ، مع الحفاظ على كل تاريخ submodule_dir.
يعيد هذا الأمر أيضًا كتابة كل التزام في تاريخ المستودع الحالي لتضمين المراجعة الصحيحة لـ sumodule_dir والمناسبة .gitmodules إدخالات.

ومع ذلك ، لا أراه في أحدث ما يطبخ.
يمكن أن يمنحك البرنامج النصي في التصحيح المقترح فكرة عن نوع إعادة كتابة الأشجار اللازمة لتحديث .gitmodules ملف رغم ذلك.

نصائح أخرى

لقد واجهت نفس المشكلة بالضبط التي تمكنت من حلها وتمكنت من حلها مع الإجراء التالي:

git clone git@github.com:kdeldycke/kev-code.git
cd kev-code
git filter-branch --tree-filter "test -f ./.gitmodules && mv ./.gitmodules ./cool-cavemen/gitmodules || echo 'No .gitmodules file found'" -- --all
git filter-branch --force --prune-empty --subdirectory-filter cool-cavemen --tag-name-filter cat -- --all init..HEAD
git filter-branch --force --tree-filter "test -f ./gitmodules && mv ./gitmodules ./.gitmodules || echo 'No gitmodules file found'" -- --all
git filter-branch --force --tree-filter "test -f ./.gitmodules && sed -i 's/cool-cavemen\///g' ./.gitmodules || echo 'No .gitmodules file found'" -- --all
git remote rm origin
rm -rf .git/refs/original/
git reflog expire --all
git gc --aggressive --prune
git remote add origin git@github.com:kdeldycke/cool-cavemen.git
git push -u origin master --force --tags

كما ترى ، فإن الحيلة هي إعادة تسمية مؤقتًا .gitmodules الملف والاستخدام sed لإعادة كتابة محتواها. يمكنك الحصول على كل التفاصيل و سياق هذا الإجراء على مدونتي.

لتوضيح إجابة كيفن: على افتراض أنه لم تكن هناك أي منها فرعي في الخارج cool/cavemen - المجلد الذي يتم فصله (وإلا سيكون هناك حاجة إلى تحرير أكثر تفصيلاً لـ .gitmodules لإزالة تلك الأقسام الإضافية) ، ويمكن تحقيق ذلك كثير أسرع وفي خطوة واحدة باستخدام index-filter:

$ git filter-branch --subdirectory-filter cool/cavemen --index-filter $'
hash=$(git rev-parse --verify $GIT_COMMIT:.gitmodules 2>/dev/null) &&
 git update-index --add --cacheinfo 100644 $(git cat-file -p $hash |
 sed \'s/cool\\/cavemen\\///g\' | git hash-object -w --stdin) .gitmodules ||
true' --tag-name-filter cat --prune-empty -- --all

كميزة إضافية ، إذا cool/cavemen لم تكن موجودة في كل مراجعة أو فرع فقط تلك المراجعات أو الفروع التي تحتوي cool/cavemen سيتم النظر إليه.

إذا كان هذا هو الحال ، فقد ترغب في تشغيل ما يلي لإزالة المراجع التي لم تتغير:

$ git for-each-ref --format='%(refname)' | 
 grep -vF "$(git for-each-ref --format='%(refname)' refs/original |
 sed 's/refs\/original\///g')" | xargs -n 1 git update-ref -d
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top