git subtree - Detach (move) subdirectory into separate Git repository -
i have git repository contains number of subdirectories. have found 1 of subdirectories unrelated other , should detached separate repository.
how can while keeping history of files within subdirectory?
i guess make clone , remove unwanted parts of each clone, suppose give me complete tree when checking out older revision etc. might acceptable, prefer able pretend 2 repositories doesn't have shared history.
just make clear, have following structure:
xyz/ .git/ xy1/ abc/ xy2/
but instead:
xyz/ .git/ xy1/ xy2/ abc/ .git/ abc/
update: process common, git team made simpler new tool, git subtree
. see here: detach (move) subdirectory separate git repository
you want clone repository , use git filter-branch
mark subdirectory want in new repo garbage-collected.
to clone local repository:
git clone /xyz /abc
(note: repository cloned using hard-links, not problem since hard-linked files not modified in - new ones created.)
now, let preserve interesting branches want rewrite well, , remove origin avoid pushing there , make sure old commits not referenced origin:
cd /abc in branch1 br2 br3; git branch -t $i origin/$i; done git remote rm origin
or remote branches:
cd /abc in $(git branch -r | sed "s/.*origin\///"); git branch -t $i origin/$i; done git remote rm origin
now might want remove tags have no relation subproject; can later, might need prune repo again. did not , got
warning: ref 'refs/tags/v0.1' unchanged
tags (since unrelated subproject); additionally, after removing such tags more space reclaimed. apparentlygit filter-branch
should able rewrite other tags, not verify this. if want remove tags, usegit tag -l | xargs git tag -d
.then use filter-branch , reset exclude other files, can pruned. let's add
--tag-name-filter cat --prune-empty
remove empty commits , rewrite tags (note have strip signature):git filter-branch --tag-name-filter cat --prune-empty --subdirectory-filter abc -- --all
or alternatively, rewrite head branch , ignore tags , other branches:
git filter-branch --tag-name-filter cat --prune-empty --subdirectory-filter abc head
then delete backup reflogs space can reclaimed (although operation destructive)
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
and have local git repository of abc sub-directory history preserved.
note: uses, git filter-branch
should indeed have added parameter -- --all
. yes that's dash dash space dash dash all
. needs last parameters command. matli discovered, keeps project branches , tags included in new repo.
edit: various suggestions comments below incorporated make sure, instance, repository shrunk (which not case before).
Comments
Post a Comment