උප බහලුම වෙනම Git නිධියකට වෙන් කරන්න


1760

මා සතුව Git ගබඩාවක් ඇත, එහි උප බහලුම් ගණනාවක් අඩංගු වේ. දැන් මම සොයාගෙන ඇත්තේ එක් උප බහලුමක් අනෙකට සම්බන්ධ නැති බවත් වෙනම ගබඩාවකට වෙන් කළ යුතු බවත්ය.

ලිපිගොනු වල ඉතිහාසය උප බහලුම තුළ තබා ගනිමින් මෙය කරන්නේ කෙසේද?

මම හිතන්නේ මට ක්ලෝනයක් සාදා එක් එක් ක්ලෝනයේ අනවශ්‍ය කොටස් ඉවත් කළ හැකි නමුත් පැරණි සංශෝධනයක් පරීක්ෂා කිරීමේදී මෙය සම්පූර්ණ ගසක් ලබා දෙනු ඇතැයි මම සිතමි. මෙය පිළිගත හැකි නමුත් මම එය මවාපෑමට කැමැත්තෙමි ගබඩාවන් දෙකකට හවුල් ඉතිහාසයක් නොමැත.

එය පැහැදිලි කිරීම සඳහා, මට පහත ව්‍යුහය ඇත:

XYZ/
    .git/
    XY1/
    ABC/
    XY2/

නමුත් මම ඒ වෙනුවට කැමතියි:

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

7
මේ සමග දැන් නොවැදගත් git filter-branchපහත මගේ පිළිතුර බලන්න.
jeremyjjbrown

8
ejeremyjjbrown හරි. මෙය තවදුරටත් කිරීමට අපහසු නමුත් ගූගල් හි නිවැරදි පිළිතුර සොයා ගැනීම දුෂ්කර බැවින් පැරණි පිළිතුරු සියල්ලම ප්‍රති .ලවල ආධිපත්‍යය දරයි.
ඇග්නෙල් කුරියන්

Answers:


1232

යාවත්කාලීන කිරීම : මෙම ක්‍රියාවලිය කොතරම් සුලභද යත්, git කණ්ඩායම නව මෙවලමක් සමඟ එය වඩාත් සරල කළේය git subtree. මෙහි බලන්න: උප බහලුම වෙනම Git නිධියකට වෙන් කරන්න


ඔබට අවශ්‍ය වන්නේ ඔබේ ගබඩාව ක්ලෝන කර පසුව git filter-branchසියල්ල සලකුණු කිරීමට භාවිතා කිරීමයි, නමුත් ඔබේ නව ගබඩාවේ ඔබට අවශ්‍ය උප බහලුම කසළ එකතු කිරීමට ය.

  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සියලු ටැග් සඳහා ලබා ගත්තා (ඒවා සියල්ලම උප ව්‍යාපෘතියට සම්බන්ධ නැති නිසා); මීට අමතරව, එවැනි ටැග් ඉවත් කිරීමෙන් පසු වැඩි ඉඩක් නැවත ලබා ගනු ඇත. පෙනෙන විදිහට git filter-branchවෙනත් ටැග් නැවත ලිවීමට හැකි විය යුතුය, නමුත් මට මෙය සත්‍යාපනය කිරීමට නොහැකි විය. ඔබට සියලු ටැග් ඉවත් කිරීමට අවශ්‍ය නම් භාවිතා කරන්න git tag -l | xargs git tag -d.

  4. ඉන්පසු පෙරහන් ශාඛාව භාවිතා කර අනෙක් ගොනු බැහැර කිරීම සඳහා යළි පිහිටුවන්න, එවිට ඒවා කප්පාදු කළ හැකිය. --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
    

    දැන් ඔබට ABC උප බහලුමේ දේශීය ජිට් ගබඩාවක් ඇත.

සටහන: බොහෝ භාවිතයන් සඳහා, git filter-branchඇත්ත වශයෙන්ම එකතු කළ පරාමිතිය තිබිය යුතුය -- --all. ඔව් ඒක ඇත්තටම --space-- all. මෙය විධානය සඳහා අවසාන පරාමිතීන් විය යුතුය. මැට්ලි සොයාගත් පරිදි, මෙය නව ගබඩාවට ඇතුළත් කර ඇති ව්‍යාපෘති ශාඛා සහ ටැග් තබා ගනී.

සංස්කරණය කරන්න: නිදසුනක් ලෙස, නිධිය සැබවින්ම හැකිලී ඇති බව තහවුරු කර ගැනීම සඳහා පහත දැක්වෙන අදහස් වලින් විවිධ යෝජනා ඇතුළත් කරන ලදි (එය මීට පෙර සෑම විටම එසේ නොවීය).


29
ඉතා හොඳ පිළිතුරක්. ස්තූතියි! මට අවශ්‍ය දේ හරියටම ලබා ගැනීම සඳහා මම පෙරහන් ශාඛා විධානයට "- --all" එකතු කළෙමි.
matli

12
ඔබට අවශ්‍ය --no-hardlinksඇයි? එක් දෘඩ සබැඳියක් ඉවත් කිරීම අනෙක් ගොනුවට බලපාන්නේ නැත. Git වස්තූන් ද වෙනස් නොවේ. ඔබට අවශ්‍ය හිමිකරු / ගොනු අවසරයන් වෙනස් කරන්නේ නම් පමණි --no-hardlinks.
vdboor

67
මම නිර්දේශ කරන අතිරේක පියවරක් වනුයේ "git remote rm සම්භවය" යන්නයි. මා වරදවා වටහා නොගත්තොත් මෙය මුල් ගබඩාවට ආපසු යාම වළක්වයි.
ටොම්

13
එකතු කළ යුතු තවත් විධානයක් filter-branchනම් --prune-empty, දැන් හිස් වූ කොමිස් ඉවත් කිරීමයි.
සෙත් ජොන්සන්

8
පෝල් මෙන්, මගේ නව ගබඩාවේ ව්‍යාපෘති ටැග් අවශ්‍ය නොවූ නිසා මම භාවිතා නොකළෙමි -- --all. මම ද දිව ගියෙමි git remote rm origin, අණට git tag -l | xargs git tag -dපෙර git filter-branch. මෙය මගේ .gitනාමාවලිය 60M සිට K 300K දක්වා හැකිලී ගියේය. ප්‍රමාණය අඩු කර ගැනීම සඳහා මෙම විධාන දෙකම ක්‍රියාත්මක කිරීමට මට අවශ්‍ය බව සලකන්න.
saltycrane

1330

පහසු මාර්ගය

මෙය එතරම් පොදු සහ ප්‍රයෝජනවත් ක්‍රියාවක් බව පෙනේ, Git හි අධිපතීන් එය සැබවින්ම පහසු කර ඇත, නමුත් ඔබට Git හි නවතම අනුවාදයක් තිබිය යුතුය (> = 1.7.11 මැයි 2012). නවතම Git ස්ථාපනය කරන්නේ කෙසේද යන්න සඳහා උපග්‍රන්ථය බලන්න . එසේම, පහත ඇවිදීමේ දී සැබෑ ලෝක උදාහරණයක් තිබේ .

  1. පැරණි repo සූදානම් කරන්න

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

    සටහන: <name-of-folder> ප්‍රමුඛ හෝ පසුපස අක්ෂර අඩංගු නොවිය යුතුය. උදාහරණයක් ලෙස, subprojectMUST නම් ෆෝල්ඩරය සම්මත subprojectනොකළ යුතුය./subproject/

    වින්ඩෝස් භාවිතා කරන්නන් සඳහා සටහන: ඔබේ ෆෝල්ඩරයේ ගැඹුර> 1 වන විට, <name-of-folder>* නික්ස් ස්ටයිල් ෆෝල්ඩර බෙදුම්කරු (/) තිබිය යුතුය. උදාහරණයක් ලෙස, path1\path2\subprojectMUST නම් ෆෝල්ඩරය ලෙස සම්මත කළ යුතුයpath1/path2/subproject

  2. නව repo එක සාදන්න

    mkdir ~/<new-repo> && cd ~/<new-repo>
    git init
    git pull </path/to/big-repo> <name-of-new-branch>
    
  3. නව repo එක GitHub හෝ ඕනෑම තැනකට සම්බන්ධ කරන්න

    git remote add origin <git@github.com:user/new-repo.git>
    git push -u origin master
    
  4. පිරිසිදු කිරීමේ තුළ <big-repo>, අවශ්ය නම්

    git rm -rf <name-of-folder>
    

    සටහන : මෙය ගබඩාවේ ඇති සියලුම reference තිහාසික යොමු කිරීම් අතහැර දමයි. මුරපදයක් සිදු කිරීම ගැන ඔබ සැබවින්ම සැලකිලිමත් වන්නේ නම් හෝ ඔබේ ෆෝල්ඩරයේ ගොනු ප්‍රමාණය අඩු කිරීමට අවශ්‍ය නම් පහත උපග්‍රන්ථය බලන්න .git.

...

පාගමන

මේවා ඉහත පියවරයන්ම වේ , නමුත් භාවිතා කිරීම වෙනුවට මගේ ගබඩාව සඳහා මගේ නිශ්චිත පියවර අනුගමනය කරන්න <meta-named-things>.

ජාවාස්ක්‍රිප්ට් බ්‍රව්සර් මොඩියුල නෝඩ් තුළ ක්‍රියාත්මක කිරීම සඳහා මා සතුව ඇති ව්‍යාපෘතියක් මෙන්න:

tree ~/node-browser-compat

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

මට තනි ෆෝල්ඩරයක් btoaවෙනම Git ගබඩාවකට බෙදීමට අවශ්‍යයි

cd ~/node-browser-compat/
git subtree split -P btoa -b btoa-only

මට දැන් නව ශාඛාවක් ඇත, btoa-onlyඒ සඳහා කැපවීම් පමණක් ඇති btoaඅතර මට නව ගබඩාවක් නිර්මාණය කිරීමට අවශ්‍යය.

mkdir ~/btoa/ && cd ~/btoa/
git init
git pull ~/node-browser-compat btoa-only

ඊළඟට මම GitHub හෝ Bitbucket හෝ වෙනත් ඕනෑම දෙයක් මත නව repo එකක් නිර්මාණය කර එය ලෙස එකතු කරමි origin

git remote add origin git@github.com:node-browser-compat/btoa.git
git push -u origin master

සුබ දවසක්!

සටහන: ඔබ a සමඟ repo එකක් නිර්මාණය කළේ නම් README.md, .gitignoreසහ LICENSE, ඔබට පළමුව ඇද ගැනීමට අවශ්‍ය වනු ඇත:

git pull origin master
git push origin master

අවසාන වශයෙන්, මට විශාල repo වෙතින් ෆෝල්ඩරය ඉවත් කිරීමට අවශ්‍ය වනු ඇත

git rm -rf btoa

...

උපග්රන්ථය

මැකෝස් හි නවතම Git

භාවිතා Git නවතම අනුවාදය ලබා ගැනීමට බරපැනක් :

brew install git

උබුන්ටු හි නවතම Git

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 වෙතින් ලිපිගොනු ඉවත් කිරීම ඇත්ත වශයෙන්ම ඒවා ඉවත් නොකරයි, එයින් කියවෙන්නේ ඒවා තවදුරටත් එහි නොමැති බවයි. ඔබට historical තිහාසික යොමු ඉවත් කිරීමට අවශ්‍ය නම් (එනම් ඔබට මුරපදයක් තිබේ නම්), ඔබ මෙය කළ යුතුය:

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

ඊට පසු ඔබගේ ගොනුව හෝ ෆෝල්ඩරය Git ඉතිහාසයේ කිසිසේත් නොපෙන්වන බව ඔබට පරීක්ෂා කළ හැකිය

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

කෙසේ වෙතත්, ඔබට GitHub සහ ඒ හා සමාන මකාදැමීම් "තල්ලු" කළ නොහැක . ඔබ උත්සාහ කළහොත් ඔබට දෝෂයක් ඇති වන අතර ඔබට එය කිරීමට git pullපෙර ඔබට සිදුවනු ඇත git push- ඉන්පසු ඔබ ඉතිහාසයේ සෑම දෙයක්ම ලබා ගැනීමට නැවත පැමිණේ.

එබැවින් ඔබට "සම්භවය" වෙතින් ඉතිහාසය මකා දැමීමට අවශ්‍ය නම් - එය GitHub, Bitbucket යනාදියෙන් මකාදැමීමට අදහස් කරයි - ඔබට repo මකා දමා repo හි කප්පාදු කළ පිටපතක් නැවත තල්ලු කළ යුතුය. නමුත් රැඳී සිටින්න - තවත් බොහෝ දේ ඇත ! - මුරපදයක් හෝ ඒ හා සමාන දෙයක් ඉවත් කිරීම ගැන ඔබ සැබවින්ම සැලකිලිමත් වන්නේ නම් ඔබට උපස්ථය කප්පාදු කිරීමට අවශ්‍ය වේ (පහත බලන්න).

කිරීම .gitකුඩා

ඉහත සඳහන් මකාදැමීමේ ඉතිහාස විධානය තවමත් උපස්ථ ලිපිගොනු රාශියක් අතහැර දමා ඇත - මන්ද යත්, ඔබේ ගබඩාව අහම්බෙන් විනාශ නොකිරීමට 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

එයින් කියැවුණේ, ඔබට අවශ්‍ය බව ඔබ දන්නේ නැත්නම් මෙම පියවරයන් නොකිරීමට මම නිර්දේශ කරමි - ඔබ වැරදි උප බහලුම කප්පාදු කළහොත් පමණක් ද? ඔබ repo තල්ලු කරන විට උපස්ථ ලිපිගොනු ක්ලෝන නොවිය යුතුය, ඒවා ඔබගේ දේශීය පිටපතෙහි ඇත.

ණය


16
git subtreeතවමත් 'දායක' ෆෝල්ඩරයේ කොටසක් වන අතර එය පෙරනිමියෙන් සියලුම ඩිස්ට්‍රෝ වල ස්ථාපනය කර නොමැත. github.com/git/git/blob/master/contrib/subtree
onionjake

11
rkrlmlr 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 උබුන්ටු 13.04 හි ක්‍රියාත්මක කිරීමට
rui.araujo

42
ඔබ මුරපදයක් පොදු ගබඩාවකට තල්ලු කර ඇත්නම්, ඔබ මුරපදය වෙනස් කළ යුතුය, එය මහජන ගබඩාවෙන් ඉවත් කිරීමට උත්සාහ නොකරන්න, කිසිවෙකු එය දුටුවේ නැතැයි සිතමු.
සැතපුම් මාර්ගය

8
මෙම විසඳුම ඉතිහාසය ආරක්ෂා නොකරයි.
Cœur

18
මෙම popdසහ pushdවිධානය එය කිරීමට අදහස් කරන අදහසත් මට මේ වෙනුවට ගම්ය කිරීමට හා අමාරු ...
jones77

133

පෝල්ගේ පිළිතුර / ABC අඩංගු නව ගබඩාවක් නිර්මාණය කරයි, නමුත් / XYZ තුළ / ABC ඉවත් නොකරයි. පහත දැක්වෙන විධානය මඟින් / ABC / XYZ තුළ සිට ඉවත් කරනු ඇත:

git filter-branch --tree-filter "rm -rf ABC" --prune-empty HEAD

ඇත්ත වශයෙන්ම, පළමුවෙන්ම එය 'ක්ලෝන - නො-හාඩ්ලින්ක්ස්' ගබඩාවක පරීක්ෂා කර, නැවත සකස් කිරීම, ජීසී සහ කප්පාදු විධානයන් සමඟ එය අනුගමනය කරන්න.


53
එය සාදන්න git filter-branch --index-filter "git rm -r -f --cached --ignore-unmatch ABC" --prune-empty HEAD, එය වඩා වේගවත් වනු ඇත . දර්ශක-පෙරණය දර්ශකයේ ක්‍රියාත්මක වන අතර ගස්-පෙරණය සෑම කැපවීමක් සඳහාම සියල්ල පරීක්ෂා කර බැලිය යුතුය .
fmarc

51
සමහර අවස්ථාවලදී XYZ නිධියේ ඉතිහාසය අවුල් කිරීම අතිරික්තය ... සරල "rm -rf ABC; git rm -r ABC; git commit -m'extracted ABC its repo '" බොහෝ මිනිසුන්ට වඩා හොඳ වනු ඇත.
එව්ගනි

2
ඔබ මෙම විධානය එක් වරකට වඩා කළහොත් -f (force) භාවිතා කිරීමට ඔබ බොහෝ විට කැමති වනු ඇත, උදා: ඩිරෙක්ටරි දෙකක් වෙන් වූ පසු ඒවා ඉවත් කිරීම. එසේ නොමැතිනම් ඔබට "නව උපස්ථයක් සෑදිය නොහැක."
බ්‍රයන් කාල්ටන්

4
ඔබ --index-filterක්‍රමවේදය කරන්නේ නම් , ඔබට git rm -q -r -fඑය සෑදීමටද අවශ්‍ය වනු ඇත , එවිට එක් එක් ආයාචනය එය මකාදමන සෑම ගොනුවක් සඳහාම පේළියක් මුද්‍රණය නොකරනු ඇත.
එරික් නසෙත්

1
පාවුල්ගේ පිළිතුර සංස්කරණය කිරීමට මම යෝජනා කරමි.
එරික් ඇරොනෙස්ටි

96

නව ගබඩාවෙන් පැරණි ඉතිහාසය නිසියාකාරව මකා දැමීමට නම්, 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
    

නැත මේ කරුණු පැහැදිලි කිරීමක් තුළ පෙරහන-ශාඛා සඳහා අත්පොත .


3
මම හිතන්නේ යම්කිසි දෙයක් git gc --aggressive --prune=nowතවමත් අතුරුදහන් වී ඇත, එසේ නොවේ ද?
ඇල්බට්

1
L ඇල්බට් නැවත සැකසුම් විධානය ඒ ගැන සැලකිලිමත් වන අතර කිසිදු ලිහිල් වස්තුවක් නොතිබෙනු ඇත.
ජොෂ් ලී

ඔව්, git gc --aggressive --prune=nowනව
රෙපෝ

සරල හා අලංකාරයි. ස්තූතියි!
මාකෝ පෙලෙග්‍රිනි

40

සංස්කරණය කරන්න: Bash ස්ක්‍රිප්ට් එකතු කරන ලදි.

මෙහි දී ඇති පිළිතුරු මා වෙනුවෙන් අර්ධ වශයෙන් ක්‍රියාත්මක විය; විශාල ලිපිගොනු විශාල ප්‍රමාණයක් හැඹිලියේ ඉතිරිව තිබේ. අවසාන වශයෙන් ක්‍රියා කළ දේ (ෆ්‍රීනෝඩ් හි #git පැය ගණනකට පසු):

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 MB පමණ විය. මෙය එය 1.7 MB දක්වා පහතට ගෙන එන ලදි. සමහර විට එය යමෙකුට උපකාරී වේ :)


පහත දැක්වෙන 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

26

මෙය තවදුරටත් එතරම් සංකීර්ණ නොවන අතර ඔබට අවශ්‍ය නොවන උප බහලුම් ඉවත් කර නව දුරස්ථයට තල්ලු කිරීම සඳහා ඔබේ රෙපෝ හි ක්ලෝනයක ඇති git filter-branch විධානය භාවිතා කළ හැකිය .

git filter-branch --prune-empty --subdirectory-filter <YOUR_SUBDIR_TO_KEEP> master
git push <MY_NEW_REMOTE_URL> -f .

3
මෙය චාම් එකක් මෙන් වැඩ කළේය. ඉහත උදාහරණයේ ඇති YOUR_SUBDIR යනු ඔබට KEEP කිරීමට අවශ්‍ය උප බහලුමයි, අනෙක් සියල්ල ඉවත් කරනු ලැබේ
JT ටේලර්

1
ඔබගේ අදහස් මත පදනම් වූ යාවත්කාලීන කිරීම්.
jeremyjjbrown

2
මෙය ප්‍රශ්නයට පිළිතුරු සපයන්නේ නැත. ලියකියවිලි වලින් එය පවසන The result will contain that directory (and only that) as its project root.අතර ඇත්ත වශයෙන්ම මෙය ඔබට ලැබෙනු ඇත, එනම් මුල් ව්‍යාපෘති ව්‍යුහය ආරක්ෂා නොවේ.
නික්බ්‍රයිට්

2
IcNicBright ප්‍රශ්නයේ දී මෙන් XYZ සහ ABC සමඟ ඇති ඔබේ ගැටලුව නිදර්ශනය කළ හැකිද?
ඇඩම්

ejeremyjjbrown විසින් ක්ලෝන කරන ලද repo නැවත භාවිතා කළ හැකි අතර නව repo එකක් භාවිතා නොකෙරේ, එනම් මගේ ප්‍රශ්නය මෙහි stackoverflow.com/questions/49269602/…
Qiulang

19

යාවත්කාලීන කිරීම : git-subtree මොඩියුලය කොතරම් ප්‍රයෝජනවත්ද යත්, git කණ්ඩායම එය හරයට ඇද එය සාදන ලදී git subtree. මෙහි බලන්න: උප බහලුම වෙනම Git නිධියකට වෙන් කරන්න

git-subtree මේ සඳහා ප්‍රයෝජනවත් විය හැකිය

http://github.com/apenwarr/git-subtree/blob/master/git-subtree.txt (අවලංගු කරන ලදි)

http://psionides.jogger.pl/2010/02/04/sharing-code-between-projects-with-git-subtree/


1
git-subtree දැන් දායකත්වයේ ගසෙහි වුවද Git හි කොටසකි, එබැවින් සෑම විටම පෙරනිමියෙන් ස්ථාපනය කර නොමැත. එය ස්ථාපනය කර ඇත්තේ හෝම්බ rew git සූත්‍රයෙන් බව මම දනිමි, නමුත් එහි පිටුවක් නොමැතිව. මේ අනුව apenwarr ඔහුගේ අනුවාදය යල් පැන ගිය එකක් ලෙස හැඳින්වේ.
echristopherson

19

බහුවිධ උප ෆෝල්ඩර (අපි කියමු සහ ) නව git ගබඩාවක් ලෙස බෙදීම සඳහා CoolAJ86 හි “පහසු මාර්ගය answer” පිළිතුරට කුඩා වෙනස් කිරීමක් මෙන්න .sub1sub2

පහසු මාර්ගය ™ (බහු උප ෆෝල්ඩර)

  1. පැරණි repo සූදානම් කරන්න

    pushd <big-repo>
    git filter-branch --tree-filter "mkdir <name-of-folder>; mv <sub1> <sub2> <name-of-folder>/" HEAD
    git subtree split -P <name-of-folder> -b <name-of-new-branch>
    popd
    

    සටහන: <name-of-folder> ප්‍රමුඛ හෝ පසුපස අක්ෂර අඩංගු නොවිය යුතුය. උදාහරණයක් ලෙස, subprojectMUST නම් ෆෝල්ඩරය සම්මත subprojectනොකළ යුතුය./subproject/

    වින්ඩෝස් භාවිතා කරන්නන් සඳහා සටහන: ඔබේ ෆෝල්ඩරයේ ගැඹුර> 1 වන විට, <name-of-folder>* නික්ස් ස්ටයිල් ෆෝල්ඩර බෙදුම්කරු (/) තිබිය යුතුය. උදාහරණයක් ලෙස, path1\path2\subprojectMUST නම් ෆෝල්ඩරය ලෙස සම්මත කළ යුතුය path1/path2/subproject. තවද mvවිධානය භාවිතා නොකරන්න move.

    අවසාන සටහන: මූලික පිළිතුර සමඟ අද්විතීය හා විශාල වෙනස වන්නේ පිටපතෙහි දෙවන පේළියයි " git filter-branch..."

  2. නව repo එක සාදන්න

    mkdir <new-repo>
    pushd <new-repo>
    
    git init
    git pull </path/to/big-repo> <name-of-new-branch>
    
  3. නව ගබඩාව ගිතූබ් හෝ ඕනෑම තැනකට සම්බන්ධ කරන්න

    git remote add origin <git@github.com: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>
    

    සටහන : මෙය ගබඩාවේ ඇති සියලුම reference තිහාසික යොමු කිරීම් අතහැර දමයි. මුරපදයක් සිදු කිරීම ගැන ඔබ සැබවින්ම සැලකිලිමත් වන්නේ නම් හෝ ඔබේ ෆෝල්ඩරයේ ගොනු ප්‍රමාණය අඩු කිරීමට අවශ්‍ය නම් මුල් පිළිතුරේ උපග්‍රන්ථය බලන්න .git.


1
මෙය සුළු වෙනස් කිරීමකින් මට වැඩ කළේය. ආරම්භක අනුවාදය සමඟ මගේ sub1සහ sub2ෆෝල්ඩර නොතිබූ නිසා, මගේ --tree-filterපිටපත පහත පරිදි වෙනස් කිරීමට මට සිදු විය : "mkdir <name-of-folder>; if [ -d sub1 ]; then mv <sub1> <name-of-folder>/; fi". දෙවන filter-branchවිධානය සඳහා මම <sub1> වෙනුවට <sub2>, <name-of-folder> නිර්මාණය කිරීම අතහැර දමා, පවතින උපස්ථයක අනතුරු ඇඟවීම ඉක්මවා -fයාමෙන් පසුව ඇතුළත් කළෙමි filter-branch.
pglezen

Git හි ඉතිහාසය තුළ කිසියම් උප උපසිරැසි වෙනස් වී ඇත්නම් මෙය ක්‍රියා නොකරයි. මෙය විසඳන්නේ කෙසේද?
nietras

ietnietras රොජර්ඩ්පැක්ගේ පිළිතුර බලන්න. මෙම අනෙක් පිළිතුරු වල ඇති සියලුම තොරතුරු කියවා අවශෝෂණය කර ගැනීමෙන් පසුව එය සොයා ගැනීමට මට ටික වේලාවක් ගත විය.
ඇඩම්

12

මුල් ප්‍රශ්නයට අවශ්‍ය වන්නේ XYZ / ABC / (* ගොනු) ABC / ABC / (* ගොනු) බවට පත්වීමයි. මගේම කේතය සඳහා පිළිගත් පිළිතුර ක්‍රියාත්මක කිරීමෙන් පසුව, එය ඇත්ත වශයෙන්ම XYZ / ABC / (* ගොනු) ABC / (* ගොනු) බවට වෙනස් කරන බව මම දුටුවෙමි. පෙරහන් ශාඛා මෑන් පිටුව පවා පවසන්නේ,

ප්‍රති result ලය එහි ව්‍යාපෘති මූල ලෙස එම නාමාවලිය (සහ එය පමණක්) අඩංගු වේ .

වෙනත් වචන වලින් කිවහොත්, එය ඉහළ මට්ටමේ ෆෝල්ඩරය “ඉහළට” එක් මට්ටමකට ප්‍රවර්ධනය කරයි. එය වැදගත් වෙනසක් නිසා, උදාහරණයක් ලෙස, මගේ ඉතිහාසයේ මම ඉහළ මට්ටමේ ෆෝල්ඩරයක් නම් කර ඇත්තෙමි. ෆෝල්ඩර එක් මට්ටමකට “ඉහළට” ප්‍රවර්ධනය කිරීමෙන්, මම නැවත නම් කළ ස්ථානයේ දී අඛණ්ඩතාව නැති වී යයි.

පෙරහන් ශාඛාවෙන් පසු මට සහසම්බන්ධය නැති විය

එවිට මගේ ප්‍රශ්නයට පිළිතුර නම් නිධියෙහි පිටපත් 2 ක් සාදා ඔබට ඒවා තබා ගැනීමට අවශ්‍ය ෆෝල්ඩරය අතින් මකා දැමීමයි. මෑන් පිටුව මට මේ සමඟ පිටුබලය දෙයි:

[...] ඔබේ ගැටළුව විසඳීම සඳහා සරල තනි කැපවීමක් ප්‍රමාණවත් නම් [මෙම විධානය] භාවිතා කිරීමෙන් වළකින්න


1
මම ඒ ප්‍රස්ථාරයේ ශෛලියට කැමතියි. ඔබ භාවිතා කරන මෙවලම කුමක්දැයි මට විමසිය හැකිද?
ස්ලිප් ඩී. තොම්සන්

3
මැක් සඳහා කුළුණ. මම ඇත්තටම එයට කැමතියි. මැක් වෙත මාරුවීම වටී.
එම්.එම්.

2
ඔව්, මගේ නඩුවේදී, මගේ උප ෆෝල්ඩරය යම් අවස්ථාවක දී නැවත නම්targetdir කර ඇති අතර එය දිනකට සරලව නම් කර ඇත. කම්පනය, එවැනි දේ සොයා ගැනීමට Git කොතරම් දක්ෂද යන්න සහ තනි අන්තර්ගත කොටස් සංක්‍රමණය කිරීම පවා සලකා බලයි! git filter-branch
ජේ ඇලන්

1
ඔහ්, යමෙක් එකම බෝට්ටුවක සිටියහොත්, මෙන්න මම භාවිතා කළ විධානය. git rmබහුවිධ ආග්ස් අවශ්‍ය බව අමතක නොකරන්න , එබැවින් සෑම ගොනුවක් / ෆෝල්ඩරයක් සඳහාම එය ක්‍රියාත්මක කිරීමට හේතුවක් නැත: BYEBYE="dir/subdir2 dir2 file1 dir/file2"; git filter-branch -f --index-filter "git rm -q -r -f --cached --ignore-unmatch $BYEBYE" --prune-empty -- --all
ජේ ඇලන්

7

පාවුල්ගේ පිළිතුරට එකතු කිරීම සඳහා , අවසානයේදී අවකාශය යථා තත්වයට පත් කිරීම සඳහා, මට හෙඩ් පිරිසිදු ගබඩාවකට තල්ලු කළ යුතු බවත්, එය .git / object / pack නාමාවලියෙහි ප්‍රමාණය අඩු කරන බවත් මට පෙනී ගියේය.

එනම්

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

Gc කප්පාදු කිරීමෙන් පසුවද කරන්න:

$ git push ... ABC.git HEAD

එවිට ඔබට කළ හැකිය

it git clone ... ABC.git

ABC / .git හි ප්‍රමාණය අඩු වේ

ඇත්ත වශයෙන්ම, නිධිය පිරිසිදු කිරීම සඳහා තල්ලුව සමඟ සමහර කාලය ගතවන පියවර (උදා: git gc) අවශ්‍ය නොවේ, එනම්:

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

6

දැන් නිසි ක්‍රමය පහත දැක්වේ:

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

GitHub හි දැන් එවැනි අවස්ථා පිළිබඳ කුඩා ලිපියක් පවා තිබේ .

නමුත් පළමුවෙන්ම ඩිරෙක්ටරිය වෙන් කිරීම සඳහා ඔබේ මුල් ගබඩාව ක්ලෝන කිරීමට වග බලා ගන්න (එය සියලු ලිපිගොනු සහ අනෙකුත් නාමාවලි මකා දැමිය හැකි බැවින් ඒවා සමඟ වැඩ කිරීමට ඔබට අවශ්‍ය වනු ඇත).

එබැවින් ඔබේ ඇල්ගොරිතම විය යුත්තේ:

  1. ඔබගේ දුරස්ථ ගබඩාව වෙනත් නාමාවලියකට ක්ලෝන කරන්න
  2. git filter-branchසමහර උප බහලුම් යටතේ වම් පමණක් ගොනු භාවිතා කරමින් නව දුරස්ථයට තල්ලු කරන්න
  3. ඔබගේ මුල් දුරස්ථ ගබඩාවෙන් මෙම උප බහලුම ඉවත් කිරීමට කැපවීමක් සාදන්න

6

උප ෆෝල්ඩර නව ගබඩාවකට බෙදීමට GitHub හි මාර්ගෝපදේශය මම නිර්දේශ කරමි . පියවර පාවුල්ගේ පිළිතුරට සමාන ය , නමුත් ඔවුන්ගේ උපදෙස් තේරුම් ගැනීමට පහසු බව මට පෙනී ගියේය.

මම උපදෙස් වෙනස් කර ඇති අතර ඒවා GitHub හි සත්කාරකත්වයට වඩා දේශීය ගබඩාවක් සඳහා ඉල්ලුම් කරයි.


උප ෆෝල්ඩරයක් නව ගබඩාවකට බෙදීම

  1. Git Bash විවෘත කරන්න.

  2. ඔබගේ නව ගබඩාව නිර්මාණය කිරීමට අවශ්‍ය ස්ථානයට වත්මන් වැඩ නාමාවලිය වෙනස් කරන්න.

  3. උප ෆෝල්ඩරය අඩංගු නිධිය ක්ලෝන කරන්න.

git clone OLD-REPOSITORY-FOLDER NEW-REPOSITORY-FOLDER
  1. වත්මන් වැඩ කරන නාමාවලිය ඔබේ ක්ලෝන ගබඩාවට වෙනස් කරන්න.

cd REPOSITORY-NAME
  1. ගබඩාවේ ඉතිරි ලිපිගොනු වලින් උප ෆෝල්ඩරය පෙරීමට git filter-branch, මෙම තොරතුරු සැපයීම , ධාවනය කරන්න :
    • FOLDER-NAME: ඔබේ ව්‍යාපෘතිය තුළ ඇති වෙනම ගබඩාවක් සෑදීමට කැමති ෆෝල්ඩරය.
      • ඉඟිය: වින්ඩෝස් භාවිතා කරන්නන් /ෆෝල්ඩර සීමා කිරීමට භාවිතා කළ යුතුය .
    • BRANCH-NAME: ඔබගේ වර්තමාන ව්‍යාපෘතිය සඳහා පෙරනිමි ශාඛාව, උදාහරණයක් ලෙස, masterහෝ 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

ලස්සන පෝස්ට් එකක්, නමුත් ඔබ සම්බන්ධ කළ ලේඛනයේ පළමු ඡේදය පවසන බව මම දනිමි. If you create a new clone of the repository, you won't lose any of your Git history or changes when you split a folder into a separate repository.එහෙත් මෙහි ඇති සියලුම පිළිතුරු සඳහා වන විවරණවලට අනුව filter-branchසහ subtreeපිටපතෙහි ප්‍රති result ලයක් ලෙස උප බහලුමක් නම් කර ඇති සෑම තැනකම ඉතිහාසය නැති වී යයි. මෙය විසඳීම සඳහා කළ හැකි යමක් තිබේද?
ඇඩම්

නාමාවලි නැවත නම් කිරීම / චලනයන් ඇතුළුව සියලු කොමිස් සංරක්ෂණය සඳහා විසඳුම සොයා ගන්නා ලදි - මෙම ප්‍රශ්නයට රොජර්ඩ්පැක්ගේ පිළිතුරයි.
ඇඩම්

එකම ගැටළුව නම් මට තවදුරටත් ක්ලෝන කරන ලද repo භාවිතා කළ නොහැකි වීමයි
Qiulang

6

මෙහි ඇති පිළිතුරු වලින් බොහොමයක් (සියල්ලම?) යම් ආකාරයක git filter-branch --subdirectory-filterසහ එහි ඉල්ක් මත රඳා පවතින බව පෙනේ . කෙසේ වෙතත් සමහර අවස්ථාවල මෙය "බොහෝ වාරයක්" වැඩ කළ හැකිය, උදාහරණයක් ලෙස ඔබ ෆෝල්ඩරය නැවත නම් කළ විට, උදා:

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

ABC/
    /move_this_dir_renamed

"Move_me_renamed" උපුටා ගැනීම සඳහා ඔබ සාමාන්‍ය git පෙරහන් ශෛලියක් කළහොත්, එය මුලින් 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. දැන් ඉතිරිව ඇත්තේ ඉලක්ක මොඩියුලයේ උප කුලකය පමණි
  9. මොඩියුලය root නව ව්‍යාපෘති මූල බවට පත්වන පරිදි මොඩියුලය උප ඩිර් ඉවත් කරන්න
  10. git mv moduleSubdir1/* .
  11. ධාතු උප කුලකය මකන්න: 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. වෙනස්කම් දුරස්ථ repo වෙත තල්ලු කරන්න: git push
  17. දුරස්ථ repo වෙත ගොස් ඒ සියල්ල තිබේදැයි පරීක්ෂා කරන්න
  18. අවශ්‍ය ඕනෑම ශාඛාවක් සඳහා එය නැවත කරන්න: git checkout branch2

මොඩියුලය නව ගබඩාවකට තල්ලු කිරීම සඳහා 6-11 පියවර "නව උප ගබඩාවක් තුළට උප ෆෝල්ඩරයක් බෙදීම" යන ගිතුබ් ලේඛනය මෙය අනුගමනය කරයි .

මෙය ඔබගේ .git ෆෝල්ඩරයේ කිසිදු ඉඩක් ඉතිරි නොකරනු ඇත, නමුත් එය නැවත නම් කිරීම හරහා වුවද එම ලිපිගොනු සඳහා ඔබගේ සියලු වෙනස්වීම් ඉතිහාසය සුරකිනු ඇත. "නැතිවූ" ඉතිහාසයක් නැතිනම් මෙය වටින්නේ නැත. එහෙත් අවම වශයෙන් ඔබට පැරණි කොමිස් අහිමි නොවන බවට සහතික විය හැකිය!


1
Git පිදුරු මල්ලේ ඉඳිකටුවක් හමු විය! දැන් මම තබා ගත හැකි සියලූම ඉතිහාසය සිදු මගේ.
ඇඩම්

5

( සමහර විට?) git filter-branchහි නවතම අනුවාදයක් භාවිතා කරමින් ධාවනය වන විට , එය පවසන්නේ මෙම නව මෙවලම git-filter-repo භාවිතා කරන ලෙසයිgit2.22+ . මෙම මෙවලම නිසැකවම මා සඳහා දේවල් සරල කළේය.

පෙරහන්-රෙපෝ සමඟ පෙරීම

XYZමුල් ප්‍රශ්නයෙන් repo නිර්මාණය කිරීමට විධාන :

# create local clone of original repo in directory XYZ
tmp $ git clone git@github.com:user/original.git XYZ

# switch to working in XYZ
tmp $ cd XYZ

# keep subdirectories XY1 and XY2 (dropping ABC)
XYZ $ git filter-repo --path XY1 --path XY2

# note: original remote origin was dropped
# (protecting against accidental pushes overwriting original repo data)

# XYZ $ ls -1
# XY1
# XY2

# XYZ $ git log --oneline
# last commit modifying ./XY1 or ./XY2
# first commit modifying ./XY1 or ./XY2

# point at new hosted, dedicated repo
XYZ $ git remote add origin git@github.com:user/XYZ.git

# push (and track) remote master
XYZ $ git push -u origin master

උපකල්පන: * දුරස්ථ XYZ repo තල්ලු කිරීමට පෙර අළුත් හා හිස් විය

පෙරීම සහ චලනය

මගේ නඩුවේදී, වඩාත් ස්ථාවර ව්‍යුහයක් සඳහා නාමාවලි කිහිපයක් ගෙනයාමට මට අවශ්‍ය විය. මුලදී, මම එම සරල filter-repoවිධානය අනුගමනය git mv dir-to-renameකළෙමි, නමුත් --path-renameවිකල්පය භාවිතා කර මට තරමක් හොඳ ඉතිහාසයක් ලබා ගත හැකි බව මට පෙනී ගියේය . 5 hours agoමා දැන් දකින නව ගබඩාවේ ගෙන ගිය ලිපිගොනු වල අවසන් වරට වෙනස් කරන ලද ඒවා දැකීම වෙනුවටlast year (GitHub UI හි), එය මුල් ගබඩාවේ වෙනස් කළ කාලයට ගැලපේ.

වෙනුවට...

git filter-repo --path XY1 --path XY2 --path inconsistent
git mv inconsistent XY3  # which updates last modification time

මම අවසානයේ දිව්වා ...

git filter-repo --path XY1 --path XY2 --path inconsistent --path-rename inconsistent:XY3
සටහන්:
  • මම හිතුවේ Git Rev News බ්ලොග් සටහනතවත් රෙපෝ-ෆිල්ටරින් මෙවලමක් නිර්මාණය කිරීමට හොඳින් පැහැදිලි කර .
  • මම මුලින් උත්සාහ කළේ මුල් ගබඩාවේ ඉලක්කගත රෙපෝ නාමයට ගැලපෙන උප ඩිරෙක්ටරියක් නිර්මාණය කර පසුව පෙරීම (භාවිතා කිරීම git filter-repo --subdirectory-filter dir-matching-new-repo-name). එම විධානය මඟින් එම උප බහලුම පිටපත් කරන ලද දේශීය රෙපෝවේ මූලයට නිවැරදිව පරිවර්තනය කළ නමුත් එහි ප්‍රති ulted ලය වූයේ උප බහලුම නිර්මාණය කිරීම සඳහා කළ කැපවීම් තුනක ඉතිහාසය පමණි. ( --pathඑය කිහිප වතාවක් නියම කළ හැකි බව මා දැන සිටියේ නැත ; එමඟින්, මූලාශ්‍ර ගබඩාවේ උප බහලුමක් නිර්මාණය කිරීමේ අවශ්‍යතාවය මග හැරේ.) යමෙකු මූලාශ්‍ර ගබඩාවට කැපවී සිටි හෙයින්, මා ඉදිරියට යන විට මා ඉදිරියට යාමට අපොහොසත් වූ බව මා දුටුවෙමි. ඉතිහාසය, මම භාවිතා git reset commit-before-subdir-move --hardපසු cloneවිධාන, සහ එකතු --forceකිරීමට filter-repoඑය සුළු වශයෙන් වෙනස් කොට දේශීය පරිගණක ක්රිඩාවට සමාන මත ක්රියාත්මක කිරීමට ලබා ගැනීමට අණ.
git clone ...
git reset HEAD~7 --hard      # roll back before mistake
git filter-repo ... --force  # tell filter-repo the alterations are expected
  • විස්තාරණ රටාව ගැන මා නොදැන සිටි හෙයින් මම ස්ථාපනය මත පැටලී සිටියෙමි git, නමුත් අවසානයේ මම git-filter-repo ක්ලෝන කර එය සමමුහුර්ත කළෙමි $(git --exec-path):
ln -s ~/github/newren/git-filter-repo/git-filter-repo $(git --exec-path)

1
නව filter-repoමෙවලම නිර්දේශ කිරීම සඳහා ඉහළට (මම පසුගිය මාසයේ stackoverflow.com/a/58251653/6309 හි ඉදිරිපත් කළෙමි )
VonC

git-filter-repoමෙම අවස්ථාවේදී භාවිතා කිරීම අනිවාර්යයෙන්ම කැමතිම ප්‍රවේශය විය යුතුය. එය වඩා වේගවත් හා ආරක්ෂිත git-filter-branchවන අතර කෙනෙකුගේ ඉතිහාසය නැවත ලිවීමේදී කෙනෙකුට ලබා ගත හැකි ගොචා රාශියකින් ආරක්ෂා වේ. ආමන්ත්‍රණය කළ යුතු බැවින් මෙම පිළිතුරට තවත් අවධානයක් ලැබෙනු ඇතැයි අපේක්‍ෂා කරමු git-filter-repo.
ජෙරමි කැනී

4

මට හරියටම මෙම ගැටළුව ඇති නමුත් git filter-branch මත පදනම් වූ සියලුම සම්මත විසඳුම් අතිශයින් මන්දගාමී විය. ඔබට කුඩා ගබඩාවක් තිබේ නම් මෙය ගැටළුවක් නොවිය හැකිය, එය මට විය. මම libgit2 මත පදනම්ව තවත් git filtering වැඩසටහනක් ලිවූ අතර එය පළමු පියවර ලෙස ප්‍රාථමික ගබඩාවේ සෑම පෙරනයක් සඳහාම ශාඛා නිර්මාණය කර ඊළඟ පියවර ලෙස මේවා පිරිසිදු ගබඩාවලට තල්ලු කරයි. මගේ ගබඩාවේ (500Mb 100000 කොමිස්) සම්මත git පෙරහන්-ශාඛා ක්‍රම සඳහා දින ගණනාවක් ගත විය. මගේ වැඩසටහන එකම පෙරනයක් කිරීමට මිනිත්තු කිහිපයක් ගතවේ.

එයට git_filter යන අපූරු නම ඇති අතර මෙහි ජීවත් වේ:

https://github.com/slobobaby/git_filter

GitHub හි.

එය කෙනෙකුට ප්‍රයෝජනවත් වේ යැයි මම බලාපොරොත්තු වෙමි.


4

ඔබේ ටැග් සහ ශාඛා සංරක්ෂණය කරන අතරතුර උප බහලුමක් ඉවත් කිරීමට මෙම පෙරහන් විධානය භාවිතා කරන්න:

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

බළලා මොකක්ද?
rogerdpack

4

එය වටින දේ සඳහා, මෙන්න වින්ඩෝස් යන්ත්‍රයක GitHub භාවිතා කරන ආකාරය. අපි ඔබට වාසය කිරීමේදී ක්ලෝන කරන ලද ගබඩාවක් ඇති බව කියමු 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
    ආපසු: Ref 'refs/heads/master' was rewritten(fyi: dir2 / dir3 සිද්ධි සංවේදී වේ.)

  3. $ git remote add some_name git@github.com:MyTeam/mynewrepo.git
    git remote add origin etc. වැඩ කළේ නැත, ආපසු " remote origin already exists"

  4. $ git push --progress some_name master


3

මා ඉහත සඳහන් කළ පරිදි , මට ප්‍රතිලෝම විසඳුම භාවිතා කිරීමට සිදු විය (මගේ ස්පර්ශයට නොපැමිණෙන සියලුම කොමිස් මකා දැමීම dir/subdir/targetdir) එය හොඳින් ක්‍රියාත්මක වන බව පෙනේ. කෙසේ වෙතත්, කුඩා ගැටළු දෙකක් ඉතිරිව ඇත.

FIRST , filter-branchකේතය හඳුන්වා දෙන හෝ වෙනස් කරන කොමිස් ඉවත් කිරීමේ වේගවත් කාර්යයක් කළ නමුත් පෙනෙන පරිදි, ඒකාබද්ධ කිරීමේ කොමිස් එහි ස්ථානයට යටින් Gitiverse හි ඇත.

මෙය රූපලාවණ්‍ය ගැටළුවක් වන අතර එය මට බොහෝ විට ජීවත් විය හැකිය (ඔහු පවසයි ... ඇස්වලින් වැළකී සෙමෙන් පසුබසිනු ඇත) .

තත්පරයකම පවතිනු ඇති අනාචාරයේ කිහිපයක් එච්චරමයි ඇත සියලූම දෙබිඩි! ව්‍යාපෘතියේ සමස්ත ඉතිහාසය පුරාම විහිදෙන දෙවන අතිරික්ත කාලරාමුවක් මා ලබාගෙන ඇති බව පෙනේ. සිත්ගන්නා කරුණ නම් (පහත පින්තූරයෙන් ඔබට දැකිය හැකි), මගේ දේශීය ශාඛා තුන එකම කාලරාමුවක නොතිබීමයි (එනම්, නිසැකවම එය පවතින්නේ ඇයි සහ කුණු එකතු නොකෙරේ).

මට සිතාගත හැකි එකම දෙය නම්, මකාදැමූ එක් කොමිස් එකක්, සමහර විට, filter-branch ඇත්ත වශයෙන්ම මකාදැමූ තනි ඒකාබද්ධ කිරීමේ කැපවීම විය හැකි අතර , දැන් ගිලී නැති සෑම නූල් වර්ගයක්ම තමන්ගේම කොමිස් පිටපතක් ගත් විට සමාන්තර කාලරාමුව නිර්මාණය විය. ( ජායාරුප කොහෙද මගේ TARDiS තියෙන්නේ?) මම හොදයි නමුත්, මා, විශ්වාසයි මම මෙය නිවැරදි කළ හැකි ඉන්නේ ඇත්තටම එය සිදු වූ ආකාරය තේරුම් ගැනීමට කැමතියි.

පිස්සු ඒකාබද්ධ කිරීමේ-ඕ-රාමා සම්බන්ධයෙන් ගත් කල, මම එය තනිවම අත්හරිනු ඇත, මන්ද එය මගේ කැපවීමේ ඉතිහාසයේ තදින් බැඳී ඇති හෙයිනි - මා ළඟට එන සෑම විටම මට තර්ජනය කිරීම, එය ඇත්ත වශයෙන්ම හේතු වන බවක් නොපෙනේ රූපලාවණ්‍ය නොවන ගැටළු සහ එය Tower.app හි තරමක් ලස්සන නිසා.


3

පහසුම මාර්ගය

  1. ස්ථාපනය කරන්න git splits. ජේකිංගේ විසඳුම මත පදනම්ව මම එය git දිගුවක් ලෙස නිර්මාණය කළෙමි .
  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

  3. කොහේ හරි හිස් ගබඩාවක් සාදන්න. අපි උපකල්පනය කරමු අපි xyzGitHub හි හිස් රිපෝවක් නිර්මාණය කර ඇති අතර එය මාර්ගය ඇත:git@github.com:simpliwp/xyz.git

  4. නව repo වෙත තල්ලු කරන්න. #add a new remote origin for the empty repo so we can push to the empty repo on GitHub git remote add origin_xyz git@github.com:simpliwp/xyz.git #push the branch to the empty repo's master branch git push origin_xyz XYZ:master

  5. අලුතින් සාදන ලද දුරස්ථ repo නව දේශීය නාමාවලියකට ක්ලෝන කරන්න
    #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 git@github.com:simpliwp/xyz.git


"පහසු මාවත" හා සසඳන විට මෙම ක්‍රමයේ වාසියක් වන්නේ නව repo සඳහා දුරස්ථය දැනටමත් සකසා තිබීමයි, එබැවින් ඔබට වහාම උප කුලක එකතු කිරීමක් කළ හැකිය. ඇත්ත වශයෙන්ම මේ ක්‍රමය මට පහසු බව පෙනේ (නැතිව වුවද git splits)
එම්එම්

මෙම විසඳුම පළ කිරීම සඳහා ඇන්ඩ rew ඩී වෙත මුක්කු. එය වෙනත් ඕනෑම කෙනෙකුට ප්‍රයෝජනවත් නම් OSX ( github.com/ricardoespsanto/git-splits ) හි වැඩ කිරීමට මම ඔහුගේ
රෙපෝව ඉල්ලා සිටිමි

2

කසළ එකතු කිරීමට පෙර "git reflog කල් ඉකුත්වීම --expire = දැන් --all" වැනි දෙයක් ඔබට අවශ්‍ය විය හැකිය. git filter-branch ඉතිහාසයේ යොමු කිරීම් ඉවත් කරයි, නමුත් දත්ත රඳවා තබා ඇති reflog ඇතුළත් කිරීම් ඉවත් නොකරයි. ඇත්ත වශයෙන්ම, මෙය පළමුව පරීක්ෂා කරන්න.

මගේ ආරම්භක කොන්දේසි තරමක් වෙනස් වුවද, මෙය සිදු කිරීමේදී මගේ තැටි භාවිතය විශාල ලෙස පහත වැටුණි. සමහර විට --subdirectory-filter මෙම අවශ්‍යතාවය ප්‍රතික්ෂේප කරයි, නමුත් මට එය සැක සහිතය.


2

Https://github.com/vangorra/git_split හි git_split ව්‍යාපෘතිය බලන්න

Git නාමාවලි ඔවුන්ගේම ස්ථානයේ ඇති ඔවුන්ගේම ගබඩාවලට හරවන්න. උපසිරැසි විහිලු ව්‍යාපාරයක් නැත. මෙම ස්ක්‍රිප්ට් එක ඔබගේ 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.

1

මෙය ඔබගේ 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'

1

මට විශ්වාසයි git subtree සියල්ලම කදිම හා පුදුමාකාරයි, නමුත් මට ගෙනයාමට අවශ්‍ය වූ git කළමණාකරන කේතයේ මගේ උප බහලුම් සියල්ලම සූර්යග්‍රහණයෙන් පැවතුනි. එබැවින් ඔබ egit භාවිතා කරන්නේ නම් එය වේදනාකාරී පහසුය. ඔබට ගෙනයාමට අවශ්‍ය ව්‍යාපෘතිය රැගෙන කණ්ඩායම්-> එය විසන්ධි කරන්න, ඉන්පසු කණ්ඩායම-> එය නව ස්ථානයට බෙදා ගන්න. එය පැරණි repo ස්ථානය භාවිතා කිරීමට උත්සාහ කිරීම පෙරනිමිය, නමුත් ඔබට භාවිතයේ පවතින තේරීම සලකුණු කර එය ගෙනයාමට නව ස්ථානය තෝරා ගත හැකිය. සියලුම හිම කැට.


3
උප ක්‍ෂේත්‍රයේ “කදිම හා පුදුමාකාර” කොටස නම් ඔබේ උප බහලුමේ ඉතිහාසය ගමන සඳහා පැමිණීමයි. ඔබට ඉතිහාසය අවශ්‍ය නොවේ නම්, ඔබේ වේදනාකාරී පහසු ක්‍රමය වන්නේ යා යුතු මාර්ගයයි.
pglezen

0

ඔබට පහසුවෙන් උත්සාහ කළ හැකිය https://help.github.com/enterprise/2.15/user/articles/splitting-a-subfolder-out-into-a-new-repository/

මෙය මට වැඩ කළා. ඉහත පියවරයන්හි මා මුහුණ දුන් ගැටළු නම්

  1. මෙම විධානය තුල git filter-branch --prune-empty --subdirectory-filter FOLDER-NAME BRANCH-NAME මෙම BRANCH-NAMEවන්නේ ස්වාමියා

  2. ආරක්ෂණ ගැටළුව හේතුවෙන් සිදු කිරීමේදී අවසාන පියවර අසමත් වුවහොත් අනුගමනය කරන්න - https://docs.gitlab.com/ee/user/project/protected_branches.html


0

මම තරමක් forward ජු ඉදිරි විසඳුමක් සොයාගෙන ඇත, අදහස වන්නේ ගබඩාව පිටපත් කර අනවශ්‍ය කොටසක් ඉවත් කිරීමයි. එය ක්‍රියාත්මක වන ආකාරය මෙයයි:

1) ඔබ බෙදීමට කැමති ගබඩාවක් ක්ලෝන කරන්න

git clone git@git.thehost.io:testrepo/test.git

2) git ෆෝල්ඩරයට ගෙන යන්න

cd test/

2) අනවශ්‍ය ෆෝල්ඩර ඉවත් කර එය සිදු කරන්න

rm -r ABC/
git add .
enter code here
git commit -m 'Remove ABC'

3) BFG සමඟ අනවශ්‍ය ෆෝල්ඩර (ය) ආකෘති ඉතිහාසය ඉවත් කරන්න

cd ..
java -jar bfg.jar --delete-folders "{ABC}" test
cd test/
git reflog expire --expire=now --all && git gc --prune=now --aggressive

ගුණ කිරීමේ ෆෝල්ඩර සඳහා ඔබට කොමාව භාවිතා කළ හැකිය

java -jar bfg.jar --delete-folders "{ABC1,ABC2}" metric.git

4) ඔබ මකා දැමූ ලිපිගොනු / ෆෝල්ඩර ඉතිහාසයේ නොමැති බව පරීක්ෂා කරන්න

git log --diff-filter=D --summary | grep delete

5) දැන් ඔබට ABC නොමැතිව පිරිසිදු ගබඩාවක් ඇත, එබැවින් එය නව සම්භවයක් කරා තල්ලු කරන්න

remote add origin git@github.com:username/new_repo
git push -u origin master

ඒක තමයි. ඔබට වෙනත් ගබඩාවක් ලබා ගැනීම සඳහා පියවර නැවත කළ හැකිය,

XY1, XY2 ඉවත් කර 3 වන පියවරේදී XYZ -> ABC ලෙස නම් කරන්න


ආසන්න වශයෙන් පරිපූර්ණයි ... නමුත් දැන් හිස්ව ඇති සියලුම පැරණි කොමිස් ඉවත් කිරීමට ඔබට "git filter-branch --prune-හිස්" අමතක විය. මූලාරම්භක මාස්ටර් වෙත තල්ලු කිරීමට පෙර කිරීමට!
ZettaCircl

ඔබ වැරැද්දක් කර පැරණි හිස් කැපවීම ඉවත් කිරීමෙන් පසුව "නැවත" කිරීමට අවශ්‍ය නම්, ඉටු කරන්න: "git push -u origin master --force-with-lease"
ZettaCircl
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.