فصل(نقل) دليل فرعي إلى مستودع Git منفصل



git-subtree git-filter-branch (15)

الطريق الأسهل

  1. تثبيت git splits . لقد قمت بإنشائه كملحق git ، استناداً إلى حل jkeating .
  2. تقسيم الأدلة إلى فرع محلي #change into your repo's directory cd /path/to/repo #checkout the branch git checkout XYZ
    #split multiple directories into new branch XYZ git splits -b XYZ XY1 XY2
    #change into your repo's directory cd /path/to/repo #checkout the branch git checkout XYZ
    #split multiple directories into new branch XYZ git splits -b XYZ XY1 XY2

  3. إنشاء ريبو فارغة في مكان ما. سنفترض أننا أنشأنا ريبو فارغًا اسمه xyz على GitHub يحتوي على المسار: [email protected]:simpliwp/xyz.git

  4. ادفع إلى الريبو الجديد. #add a new remote origin for the empty repo so we can push to the empty repo on GitHub git remote add origin_xyz [email protected]:simpliwp/xyz.git #push the branch to the empty repo's master branch git push origin_xyz XYZ:master

  5. استنساخ ريبو عن بعد تم إنشاؤه حديثا في دليل محلي جديد
    #change current directory out of the old repo cd /path/to/where/you/want/the/new/local/repo #clone the remote repo you just pushed to git clone [email protected]:simpliwp/xyz.git

https://src-bin.com

لدي مستودع Git الذي يحتوي على عدد من الدلائل الفرعية. الآن لقد وجدت أن أحد الأدلة الفرعية لا علاقة لها بالآخر ويجب فصله إلى مستودع منفصل.

كيف يمكنني القيام بذلك مع الاحتفاظ بتاريخ الملفات ضمن الدليل الفرعي؟

أعتقد أن بإمكاني استنساخ وإزالة الأجزاء غير المرغوب فيها من كل نسخة ، لكنني أعتقد أن هذا سيعطيني الشجرة الكاملة عند التحقق من مراجعة قديمة إلخ. قد يكون هذا مقبولًا ، لكنني أفضل أن أكون قادرًا على التظاهر بأن لا يملك مستودعان محفوظات مشتركة.

فقط لجعلها واضحة ، لدي الهيكل التالي:

XYZ/
    .git/
    XY1/
    ABC/
    XY2/

لكني أود ذلك بدلاً من ذلك:

XYZ/
    .git/
    XY1/
    XY2/
ABC/
    .git/
    ABC/

Answer #1

الطريق السهل ™

لقد تبين أن هذه ممارسة شائعة ومفيدة جعلت كبار أمراء git من السهل فعلاً ، لكن يجب أن يكون لديك إصدار أحدث من git (> = 1.7.11 May 2012). انظر الملحق لمعرفة كيفية تثبيت أحدث git. أيضًا ، هناك مثال حقيقي في جولة التفصيل أدناه.

  1. قم بتحضير الريبو القديم

    pushd <big-repo>
    git subtree split -P <name-of-folder> -b <name-of-new-branch>
    popd
    

    ملاحظة: يجب ألا يحتوي <name-of-folder> على أحرف بادئة أو لاحقة. على سبيل المثال ، يجب أن يتم تمرير المجلد المسمى subproject كمشروع subproject ، NOT ./subproject/

    ملاحظة لمستخدمي windows: عندما يكون عمق المجلد الخاص بك هو> 1 ، <name-of-folder> يجب أن يكون لديك فاصل مجلد * نمط nix (/). على سبيل المثال ، يجب أن يتم تمرير المجلد المسمى path1\path2\subproject مثل path1/path2/subproject

  2. إنشاء الريبو الجديد

    mkdir <new-repo>
    pushd <new-repo>
    
    git init
    git pull </path/to/big-repo> <name-of-new-branch>
    
  3. ربط الريبو الجديد لجيثوب أو في أي مكان

    git remote add origin <[email protected]:my-user/new-repo.git>
    git push origin -u master
    
  4. تنظيف ، إذا رغبت في ذلك

    popd # get out of <new-repo>
    pushd <big-repo>
    
    git rm -rf <name-of-folder>
    

    ملاحظة : هذا يترك كل المراجع التاريخية في مستودع التخزين.راجع الملحق أدناه إذا كنت قلقًا بالفعل بشأن التزامك بكلمة مرور أو تحتاج إلى تقليل حجم ملف مجلدك .git .

...

تجول

هذه هي نفس الخطوات المذكورة أعلاه ، ولكن باتباع الخطوات الدقيقة لمستودعي بدلاً من استخدام <meta-named-things> .

في ما يلي مشروع لدي لتنفيذ وحدات متصفح JavaScript في العقدة:

tree ~/Code/node-browser-compat

node-browser-compat
├── ArrayBuffer
├── Audio
├── Blob
├── FormData
├── atob
├── btoa
├── location
└── navigator

أريد تقسيم مجلد واحد ، btoa ، إلى مستودع git منفصل

pushd ~/Code/node-browser-compat/
git subtree split -P btoa -b btoa-only
popd

لدي الآن فرع جديد ، btoa-only ، الذي لم يلتزم إلا بـ btoa وأريد إنشاء مستودع جديد.

mkdir ~/Code/btoa/
pushd ~/Code/btoa/
git init
git pull ~/Code/node-browser-compat btoa-only

بعد ذلك ، أقوم بإنشاء نسخة repo جديدة على Github أو Bitbucket ، أو أيا كان وأضفها هو origin (btw ، "origin" هو مجرد اتفاقية ، وليس جزءًا من الأمر - يمكنك أن تسميها "الخادم البعيد" أو ما تريده)

git remote add origin [email protected]:node-browser-compat/btoa.git
git push origin -u master

يوم سعيد!

ملاحظة: إذا قمت بإنشاء repo باستخدام README.md و README.md و LICENSE ، فستحتاج إلى السحب أولاً:

git pull origin -u master
git push origin -u master

وأخيرًا ، سأرغب في إزالة المجلد من النسخة السابقة الأكبر

git rm -rf btoa

...

الملحق

أحدث بوابة على OS X

للحصول على أحدث إصدار من git:

brew install git

للحصول على مشروب لنظام التشغيل X:

http://brew.sh

آخر بوابة على أوبونتو

sudo apt-get update
sudo apt-get install git
git --version

إذا كان هذا لا يعمل (لديك نسخة قديمة جدا من أوبونتو) ، حاول

sudo add-apt-repository ppa:git-core/ppa
sudo apt-get update
sudo apt-get install git

إذا لم يفلح ذلك ، حاول

sudo chmod +x /usr/share/doc/git/contrib/subtree/git-subtree.sh
sudo ln -s \
/usr/share/doc/git/contrib/subtree/git-subtree.sh \
/usr/lib/git-core/git-subtree

بفضل rui.araujo من التعليقات.

مسح السجل الخاص بك

افتراضيًا ، لا تؤدي إزالة الملفات من git إلى إزالتها من بوابة git ، ولكنها تلتزم بأنها لم تعد موجودة بعد الآن. إذا كنت تريد إزالة المراجع التاريخية فعليًا (على سبيل المثال ، لديك كلمة مرور ملتزمة) ، فعليك القيام بذلك:

git filter-branch --prune-empty --tree-filter 'rm -rf <name-of-folder>' HEAD

بعد ذلك يمكنك التحقق من أن الملف أو المجلد الخاص بك لم يعد يظهر في تاريخ بوابة على الإطلاق

git log -- <name-of-folder> # should show nothing

ومع ذلك ، لا يمكنك "دفع" حذف github وما شابه ذلك. إذا حاولت أن تحصل على خطأ git pull إلى git pull قبل أن تتمكن من git push - ثم تعود إلى وجود كل شيء في تاريخك.

لذا إذا كنت تريد حذف السجل من "الأصل" - يعني حذفه من github ، bitbucket ، الخ - ستحتاج إلى حذف الريبو وإعادة دفع نسخة مجردة من الريبو. لكن انتظر - هناك المزيد ! - إذا كنت مهتمًا حقًا بالتخلص من كلمة مرور أو شيء من هذا القبيل ، فسيلزمك تقليم النسخة الاحتياطية (انظر أدناه).

جعل أصغر

لا يزال أمر سجل الحذف السابق ذكره يترك وراءه مجموعة من ملفات النسخ الاحتياطي - لأن git كل شيء لطيف للغاية في مساعدتك على عدم تدمير الريبو الخاص بك عن طريق الصدفة. سيؤدي ذلك في النهاية إلى حذف الملفات المعزولة على مدار الأيام والأشهر ، لكنه يتركها هناك لفترة من الوقت في حال أدركت أنك حذفت عن طريق الخطأ شيئًا لا تريده.

لذا إذا كنت تريد حقاً إفراغ سلة المهملات لتقليل حجم نسخ ريبو على الفور ، فعليك القيام بكل هذه الأشياء الغريبة:

rm -rf .git/refs/original/ && \
git reflog expire --all && \
git gc --aggressive --prune=now

git reflog expire --all --expire-unreachable=0
git repack -A -d
git prune

ومع ذلك ، فإنني أوصيك بعدم القيام بهذه الخطوات إلا إذا كنت على دراية بأنك تحتاج إلى ذلك - فقط في حالة قيامك بتخفيض الدليل الفرعي الخطأ ، هل أنت متأكد؟ لا يجب نسخ ملفات النسخ الاحتياطية عند دفع الريبو ، ستكون فقط في نسختك المحلية.

ائتمان


Answer #2

أوصي دليل GitHub لتقسيم المجلدات الفرعية إلى مستودع جديد . الخطوات مشابهة لإجابة بولس ، لكنني وجدت أن تعليماتهم أسهل للفهم.

لقد قمت بتعديل التعليمات بحيث تنطبق على مستودع محلي ، بدلاً من واحدة مستضافة على جيثب.

تقسيم مجلد فرعي إلى مستودع جديد

  1. فتح جيت باش.

  2. Change the current working directory to the location where you want to create your new repository.

  3. Clone the repository that contains the subfolder.

git clone OLD-REPOSITORY-FOLDER NEW-REPOSITORY-FOLDER
  1. Change the current working directory to your cloned repository.

cd REPOSITORY-NAME
  1. To filter out the subfolder from the rest of the files in the repository, run git filter-branch , supplying this information:
    • FOLDER-NAME : The folder within your project that you'd like to create a separate repository from.
      • Tip: Windows users should use / to delimit folders.
    • BRANCH-NAME : The default branch for your current project, for example, master or gh-pages .

git filter-branch --prune-empty --subdirectory-filter FOLDER-NAME  BRANCH-NAME 
# Filter the specified branch in your directory and remove empty commits
Rewrite 48dc599c80e20527ed902928085e7861e6b3cbe6 (89/89)
Ref 'refs/heads/BRANCH-NAME' was rewritten

Answer #3

استخدم أمر التصفية هذا لإزالة دليل فرعي ، مع الاحتفاظ بعلاماتك وفروعك:

git filter-branch --index-filter \
"git rm -r -f --cached --ignore-unmatch DIR" --prune-empty \
--tag-name-filter cat -- --all

Answer #4

الطريق الصحيح الآن هو ما يلي:

git filter-branch --prune-empty --subdirectory-filter FOLDER_NAME [first_branch] [another_branch]

جيثب الآن حتى يكون مقال صغير حول مثل هذه الحالات.

ولكن تأكد من استنساخ الريبو الأصلي لفصل الدليل أولاً (لأنه سيحذف جميع الملفات والدلائل الأخرى وستحتاج إلى العمل معهم).

لذلك يجب أن تكون الخوارزمية الخاصة بك:

  1. استنساخ الريبو الخاص بك عن بعد إلى دليل آخر
  2. باستخدام git filter-branch ترك الملفات فقط تحت بعض الدليل الفرعي ، ودفع إلى جهاز التحكم عن بعد جديد
  3. إنشاء الالتزام لإزالة هذا الدليل الفرعي من الريبو عن بعد الأصلي الخاص بك

Answer #5

تحقق من مشروع git_split على https://github.com/vangorra/git_split

تحويل الدلائل بوابة إلى مستودعات الخاصة بهم في موقع خاص بهم. لا الشجرة التجارية مضحك. سيأخذ هذا البرنامج النصي دليلًا موجودًا في مستودع git الخاص بك ويحول هذا الدليل إلى مستودع مستقل خاص به. على طول الطريق ، سيتم نسخ سجل التغيير بأكمله للدليل الذي قدمته.

./git_split.sh <src_repo> <src_branch> <relative_dir_path> <dest_repo>
        src_repo  - The source repo to pull from.
        src_branch - The branch of the source repo to pull from. (usually master)
        relative_dir_path   - Relative path of the directory in the source repo to split.
        dest_repo - The repo to push to.

Answer #6

ضع هذا في gitconfig الخاص بك:

reduce-to-subfolder = !sh -c 'git filter-branch --tag-name-filter cat --prune-empty --subdirectory-filter cookbooks/unicorn HEAD && git reset --hard && git for-each-ref refs/original/ | cut -f 2 | xargs -n 1 git update-ref -d && git reflog expire --expire=now --all && git gc --aggressive --prune=now && git remote rm origin'

Answer #7

على ما يستحق ، إليك كيفية استخدام GitHub على جهاز يعمل بنظام Windows. لنفترض أن لديك repo مستنسخ في المقيمين في C:\dir1 . يبدو بنية الدليل مثل هذا: C:\dir1\dir2\dir3 . دليل dir3 هو واحد أريد أن أكون ريبو منفصلة جديدة.

جيثب:

  1. إنشاء مستودع جديد: MyTeam/mynewrepo

Bash Prompt:

  1. $ cd c:/Dir1
  2. $ git filter-branch --prune-empty --subdirectory-filter dir2/dir3 HEAD
    Returned: Ref 'refs/heads/master' was rewritten (fyi: dir2 / dir3 حساس لحالة الأحرف).

  3. $ git remote add some_name [email protected]:MyTeam/mynewrepo.git
    git remote add origin etc . لم يعمل ، عاد " remote origin already exists "

  4. $ git push --progress some_name master


Answer #8

قد تحتاج إلى شيء مثل "git reflog expire --expire = now --all" قبل جمع البيانات المهملة لتنظيف الملفات بالفعل. git filter-branch فقط يزيل المراجع في السجل ، لكنه لا يزيل إدخالات سجل البيانات التي تحمل البيانات. بالطبع ، اختبر هذا أولاً.

انخفض استخدام القرص الخاص بي بشكل كبير في القيام بذلك ، على الرغم من أن ظروفي الأولية كانت مختلفة بعض الشيء. ربما -subdirectory-filter ينفي هذه الحاجة ، ولكن أشك في ذلك.


Answer #9

كان لي بالضبط هذه المشكلة ولكن كانت جميع الحلول القياسية القائمة على فرع تصفية غيت بطيئة للغاية. إذا كان لديك مستودع صغير ، فهذا قد لا يمثل مشكلة ، كان ذلك بالنسبة لي. لقد قمت بتأليف برنامج آخر لفلتر git يعتمد على libgit2 والذي يقوم ، كخطوة أولى ، بإنشاء فروع لكل عملية ترشيح للمستودع الأساسي ، ثم يدفعها لتنظيف المستودعات كخطوة تالية. في مستودعاتي (500Mb 100000 الالتزام) استغرقت أساليب git-filter الفرعية أيامًا. يستغرق برنامجي دقائق لإجراء التصفية نفسها.

لديها اسم رائع git_filter ويعيش هنا:

https://github.com/slobobaby/git_filter

على جيثب.

آمل أن يكون مفيدا لشخص ما.


Answer #10

لقد وجدت أنه من أجل حذف التاريخ القديم من المستودع الجديد بشكل صحيح ، عليك القيام بعمل أكثر بعد خطوة filter-branch .

  1. هل الاستنساخ والفلتر:

    git clone --no-hardlinks foo bar; cd bar
    git filter-branch --subdirectory-filter subdir/you/want
    
  2. أزل كل مرجع إلى التاريخ القديم. كان "الأصل" يتتبع استنساخك ، و "الأصلي" هو المكان الذي يوفر فيه عامل التصفية-الفرع الأشياء القديمة:

    git remote rm origin
    git update-ref -d refs/original/refs/heads/master
    git reflog expire --expire=now --all
    
  3. حتى الآن ، قد يتم تعليق السجل الخاص بك في ملف تعبئة لن يتمكن fsck من لمسه. تمزيقه إلى أشلاء ، وإنشاء ملف تعبئة جديد وحذف الكائنات غير المستخدمة:

    git repack -ad
    

هناك تفسير لهذا في دليل لفلتر-فرع .


Answer #11

للإضافة إلى إجابة بول ، وجدت أنه لاستعادة المساحة في النهاية ، يجب أن أدفع HEAD إلى مستودع نظيف وأن يقلص حجم دليل .git / objects / pack.

أي

$ mkdir ...ABC.git
$ cd ...ABC.git
$ git init --bare

بعد gc prune ، أيضًا:

$ git push ...ABC.git HEAD

ثم يمكنك القيام به

$ git clone ...ABC.git

ويتم تقليل حجم ABC / .git

في الواقع ، ليست هناك حاجة إلى بعض الخطوات المستهلكة للوقت (مثل git gc) مع الدفع لتنظيف المستودع ، أي:

$ git clone --no-hardlinks /XYZ /ABC
$ git filter-branch --subdirectory-filter ABC HEAD
$ git reset --hard
$ git push ...ABC.git HEAD

Answer #12

يبدو أن معظم الإجابات (كلها؟) هنا تعتمد على شكل من أشكال git filter-branch --subdirectory-filter وأمثاله. قد يعمل هذا "في معظم الأحيان" في بعض الحالات ، على سبيل المثال في حالة إعادة تسمية المجلد ، على سبيل المثال:

 ABC/
    /move_this_dir # did some work here, then renamed it to

ABC/
    /move_this_dir_renamed

إذا قمت بعمل نمط git filter عادي لاستخراج "move_me_renamed" فسوف تفقد سجل تغيير الملف الذي حدث من الخلف عندما كان في البداية move_this_dir ( ref ).

وهكذا يبدو أن الطريقة الوحيدة للحفاظ على كل تاريخ التغيير (إذا كانت حالتك مثل هذا) ، هي ، في جوهرها ، لنسخ المستودع (إنشاء ريبو جديد ، تعيين ذلك ليكون الأصل) ، ثم حشر كل شيء آخر وإعادة تسمية الدليل الفرعي إلى الأصل مثل هذا:

  1. استنساخ المشروع متعدد الوحدات محليًا
  2. الفروع - تحقق من ما يوجد: git branch -a
  3. قم بإجراء عملية دفع لكل فرع ليتم تضمينها في القسم للحصول على نسخة محلية على محطة العمل الخاصة بك: git checkout --track origin/branchABC
  4. جعل نسخة في دليل جديد: cp -r oldmultimod simple
  5. الذهاب إلى نسخة المشروع الجديد: cd simple
  6. تخلص من الوحدات الأخرى غير المطلوبة في هذا المشروع:
  7. git rm otherModule1 other2 other3
  8. الآن يبقى فقط subdir من الوحدة النمطية الهدف
  9. تخلص من الوحدة النمطية للوحدة النمطية بحيث يصبح جذر الوحدة الجذر الجديد للمشروع
  10. git mv moduleSubdir1/* .
  11. حذف rmdir moduleSubdir1 relic: rmdir moduleSubdir1
  12. تحقق من التغييرات في أي نقطة: git status
  13. قم بإنشاء git repo جديد وقم بنسخ عنوان URL الخاص به لتوجيه هذا المشروع إليه:
  14. git remote set-url origin http://mygithost:8080/git/our-splitted-module-repo
  15. تحقق من هذا جيد: git remote -v
  16. دفع التغييرات تصل إلى الريبو عن بعد: git push
  17. انتقل إلى الريبو عن بعد والتحقق من كل شيء هناك
  18. كرر ذلك لأي فرع آخر مطلوب: git checkout branch2

يتبع هذا المستند جيثب "تقسيم المجلد الفرعي إلى مستودع جديد" الخطوات 6-11 لدفع الوحدة إلى ريبو جديد.

لن يوفر لك هذا أي مساحة في مجلد .git الخاص بك ، ولكنه سيحافظ على كل محفوظات التغيير الخاصة بهذه الملفات حتى عبر إعادة التسمية. وهذا قد لا يكون يستحق العناء إذا لم يكن هناك "الكثير" من التاريخ المفقود ، إلخ. ولكن على الأقل أنت مكفول بعدم فقدان الالتزامات القديمة!


Answer #13

تحرير: وأضاف باش النصي.

الإجابات التي قدمت هنا عملت بشكل جزئي بالنسبة لي. بقي الكثير من الملفات الكبيرة في ذاكرة التخزين المؤقت. ما نجح أخيراً (بعد ساعات في #git على freenode):

git clone --no-hardlinks file:///SOURCE /tmp/blubb
cd blubb
git filter-branch --subdirectory-filter ./PATH_TO_EXTRACT  --prune-empty --tag-name-filter cat -- --all
git clone file:///tmp/blubb/ /tmp/blooh
cd /tmp/blooh
git reflog expire --expire=now --all
git repack -ad
git gc --prune=now

مع الحلول السابقة ، كان حجم المستودع حوالي 100 ميغابايت. هذا واحد أسقطته إلى 1.7 ميغابايت. ربما يساعد شخص ما :)

يقوم البرنامج النصي bash التالي بأتمتة المهمة:

!/bin/bash

if (( $# < 3 ))
then
    echo "Usage:   $0 </path/to/repo/> <directory/to/extract/> <newName>"
    echo
    echo "Example: $0 /Projects/42.git first/answer/ firstAnswer"
    exit 1
fi


clone=/tmp/${3}Clone
newN=/tmp/${3}

git clone --no-hardlinks file://$1 ${clone}
cd ${clone}

git filter-branch --subdirectory-filter $2  --prune-empty --tag-name-filter cat -- --all

git clone file://${clone} ${newN}
cd ${newN}

git reflog expire --expire=now --all
git repack -ad
git gc --prune=now

Answer #14

تحديث : هذه العملية شائعة جدًا ، بحيث جعلها فريق git أكثر بساطة باستخدام أداة جديدة ، git subtree . انظر هنا: فصل (نقل) دليل فرعي إلى مستودع Git منفصل

تريد استنساخ المستودع الخاص بك ، ثم استخدام git filter-branch لوضع علامة على كل شيء ما عدا الدليل الفرعي الذي تريده في repo الجديد الخاص بك لجمع البيانات المهملة.

  1. لاستنساخ المستودع المحلي:

    git clone /XYZ /ABC
    

    (ملاحظة: سيتم نسخ المستودع باستخدام الروابط الثابتة ، ولكن هذه ليست مشكلة نظرًا لأنه لن يتم تعديل الملفات المرتبطة في حد ذاتها - سيتم إنشاء ملفات جديدة.)

  2. الآن ، دعونا نحافظ على الفروع المثيرة للاهتمام التي نرغب في إعادة كتابتها أيضًا ، ثم نزيل الأصل لتجنب دفعها إلى هناك وللتأكد من عدم الإشارة إلى الالتزام القديم بالمصدر:

    cd /ABC
    for i in branch1 br2 br3; do git branch -t $i origin/$i; done
    git remote rm origin
    

    أو لجميع الفروع البعيدة:

    cd /ABC
    for i in $(git branch -r | sed "s/.*origin\///"); do git branch -t $i origin/$i; done
    git remote rm origin
    
  3. الآن قد ترغب أيضًا في إزالة العلامات التي ليس لها علاقة بالمشروع الفرعي ؛ يمكنك أيضا القيام بذلك لاحقا ، ولكن قد تحتاج إلى تقليم الريبو الخاص بك مرة أخرى. لم أفعل ذلك وحصلت على WARNING: Ref 'refs/tags/v0.1' is unchanged بالنسبة لجميع العلامات (لأنها كانت جميعها غير مرتبطة WARNING: Ref 'refs/tags/v0.1' is unchanged الفرعي) ؛ بالإضافة إلى ذلك ، بعد إزالة مثل هذه العلامات سيتم استرداد مساحة أكبر. على ما يبدو يجب أن يكون git filter-branch قادراً على إعادة كتابة علامات أخرى ، ولكن لم أتمكن من التحقق من ذلك. إذا كنت تريد إزالة جميع العلامات ، فاستخدم git tag -l | xargs git tag -d git tag -l | xargs git tag -d .

  4. ثم استخدم filter-branch وقم بإعادة التعيين لاستبعاد الملفات الأخرى ، بحيث يمكن تشذيبها. دعنا نضيف أيضًا --tag-name-filter cat --prune-empty لإزالة --tag-name-filter cat --prune-empty كتابة العلامات (لاحظ أن هذا سيضطر إلى تجريد توقيعهم):

    git filter-branch --tag-name-filter cat --prune-empty --subdirectory-filter ABC -- --all
    

    أو بدلاً من ذلك ، فقط لإعادة كتابة الفرع الرئيسي وتجاهل العلامات والفروع الأخرى:

    git filter-branch --tag-name-filter cat --prune-empty --subdirectory-filter ABC HEAD
    
  5. ثم قم بحذف ملفات إعادة النشر الاحتياطية بحيث يمكن استرجاع المساحة بالفعل (على الرغم من أن العملية الآن مدمرة)

    git reset --hard
    git for-each-ref --format="%(refname)" refs/original/ | xargs -n 1 git update-ref -d
    git reflog expire --expire=now --all
    git gc --aggressive --prune=now
    

    والآن لديك مستودع git المحلي للدليل الفرعي ABC مع الحفاظ على كل تاريخها.

ملاحظة: بالنسبة لمعظم الاستخدامات ، يجب أن يكون git filter-branch بالفعل المعلمة المضافة -- --all . نعم هذا حقا اندفاعة داش الفضاء داش داش all . هذا يجب أن يكون المعلمات الأخيرة للأمر. كما اكتشفت Matli ، وهذا يبقي فروع المشروع والعلامات المدرجة في الريبو الجديد.

تحرير: تم دمج الاقتراحات المختلفة من التعليقات أدناه للتأكد ، على سبيل المثال ، من أن المخزون يتقلص في الواقع (والذي لم يكن دائمًا هو الحال من قبل).





git-filter-branch