Foi útil?

Solução

Atualizar : Este processo é tão comum, que a equipe git tornou muito mais simples com uma nova ferramenta, git subtree. Veja aqui: Detach (mover) subdiretório em separado Git repositório


Você deseja clonar seu repositório e, em seguida, usar git filter-branch a marca de tudo, mas o subdiretório que você quer em seu novo repo para ser coletado como lixo.

  1. Para clonar seu repositório local:

    git clone /XYZ /ABC
    

    . (Nota: o repositório será clonado utilizando hard-links, mas isso não é um problema, já que os arquivos com link não será modificado em si mesmos - novos serão criados)

  2. Agora, vamos preservar os ramos interessantes que queremos reescrever bem, e depois remover a origem para evitar empurrando lá e ter certeza de que commits velhos não será referenciado pela origem:

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

    ou para todas as filiais remotas:

    cd /ABC
    for i in $(git branch -r | sed "s/.*origin\///"); do git branch -t $i origin/$i; done
    git remote rm origin
    
  3. Agora você também pode querer remover tags que não têm relação com o subprojeto; você também pode fazer isso mais tarde, mas você pode precisar para podar sua repo novamente. Eu não fazê-lo e tem um WARNING: Ref 'refs/tags/v0.1' is unchanged para todas as tags (desde que foram todos sem relação com o subprojeto); Além disso, após a remoção de tais marcas mais espaço será recuperada. Aparentemente git filter-branch deve ser capaz de reescrever outras tags, mas eu não poderia verificar isso. Se você deseja remover todas as tags, o uso git tag -l | xargs git tag -d.

  4. Em seguida, use filter-branch e redefinir a excluir os outros arquivos, assim eles podem ser podadas. Vamos também adicionar --tag-name-filter cat --prune-empty para remover commits vazias e reescrever as etiquetas (note que este terá que retirar a sua assinatura):

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

    ou, alternativamente, para reescrever apenas o ramo HEAD e ignorar tags e outros ramos:

    git filter-branch --tag-name-filter cat --prune-empty --subdirectory-filter ABC HEAD
    
  5. Em seguida, exclua os reflogs de backup para o espaço pode ser realmente recuperado (embora agora a operação é destrutivo)

    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
    

    e agora você tem um repositório git local do sub-diretório ABC com toda a sua história preservada.

Nota: Para a maioria dos usos, git filter-branch deve realmente ter o -- --all parâmetro adicionado. Sim, isso é realmente - - espaço - - all. Isso precisa ser os últimos parâmetros para o comando. Como Matli descoberto, isso mantém os ramos do projeto e tags incluídas no novo repo.

Edit:. Várias sugestões de comentários abaixo foram incorporadas para certificar-se, por exemplo, que o repositório é realmente diminuiu (o que nem sempre foi o caso antes)

Outras dicas

A maneira fácil ™

Acontece que isso é tão comum um e prática útil que os senhores de git tornou muito fácil, mas você tem que ter uma versão mais recente do git (> = 1.7.11 maio 2012). Veja apêndice para saber como instalar o mais recente git. Além disso, há um exemplo de real na passo a passo abaixo.

  1. Prepare o velho repo

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

    Nota: <name-of-folder> não podem conter esquerda ou à direita caracteres. Por exemplo, o subproject pasta chamada deve ser passado como subproject, NÃO ./subproject/

    Nota para usuários do Windows: quando a sua profundidade pasta é> 1, <name-of-folder> deve ter separador * pasta estilo nix (/). Por exemplo, o path1\path2\subproject pasta chamada deve ser passado como path1/path2/subproject

  2. Criar o novo repo

    mkdir <new-repo>
    pushd <new-repo>
    
    git init
    git pull </path/to/big-repo> <name-of-new-branch>
    
  3. Fazer a ligação do novo repo para Github ou onde

    git remote add origin <git@github.com:my-user/new-repo.git>
    git push origin -u master
    
  4. Cleanup, se desejar

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

    Nota : Isso deixa todas as referências históricas no repository.See o Apêndice abaixo se você está realmente preocupado com ter cometido uma senha ou você precisa diminuir o tamanho do arquivo da sua pasta .git.

...

Passo a passo

Estas são as mesmos passos acima , mas seguindo os meus passos exatos para meu repositório em vez de usar <meta-named-things>.

Aqui está um projeto que tenho para a implementação de módulos do navegador JavaScript no nó:

tree ~/Code/node-browser-compat

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

Eu quero dividir uma única pasta, btoa, em um git separado repositório

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

Agora tenho um novo ramo, btoa-only, que só tem commits para btoa e eu quero criar um novo repositório.

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

Em seguida eu criar um novo repo no Github ou bitbucket, ou o que quer e adicioná-lo é o origin (aliás, "origem" é apenas uma convenção, não faz parte do comando - você poderia chamá-lo de "remote-server" ou qualquer outra coisa você gosta)

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

Dia feliz!

Nota: Se você criou um repo com um README.md, .gitignore e LICENSE, você terá que puxar primeiro:

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

Por fim, eu vou querer remover a pasta a partir do repo maior

git rm -rf btoa

...

Apêndice

Últimas git no OS X

Para obter a versão mais recente do git:

brew install git

Para obter bebida para OS X:

http://brew.sh

Últimas git no Ubuntu

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

Se isso não funciona (você tem uma versão muito antiga do ubuntu), tente

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

Se isso ainda não funcionar, tente

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

Graças a rui.araujo a partir dos comentários.

limpar seu histórico

Por padrão removendo arquivos de git na verdade não removê-los do git, ele só compromete que eles não estão mais lá. Se você quiser realmente remover as referências históricas (ou seja, você tem uma cometido uma senha), você precisa fazer isso:

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

Depois que você pode verificar se o seu arquivo ou pasta não mostra mais longos-se na história git em tudo

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

No entanto, você não pode "empurrar" exclusões para github e similares. Se você tentar, você obterá um erro e você vai ter que git pull antes que você possa git push -. E então você está de volta para ter tudo em seu histórico

Então, se você quiser história de exclusão da "origem" - o que significa para excluí-lo do github, bitbucket, etc - você vai precisar excluir o repo e re-empurrar uma cópia podada do repo. Mas espera - há mais ! - Se você está realmente preocupado sobre como se livrar de uma senha ou algo como que você vai need para podar o backup (veja abaixo).

fazendo .git menor

O comando história de exclusão acima mencionado ainda deixa para trás um monte de arquivos de backup - porque git é muito tipo para ajudar você a não estragar o seu repo por acidente. Ele acabará eliminado arquivos órfãos ao longo dos dias e meses, mas deixa-los lá por um tempo no caso de você perceber que você acidentalmente apagado algo que você não quer.

Então, se você realmente quiser esvaziar a lixeira para reduzir o tamanho clone de um repo imediatamente você tem que fazer todo este material realmente estranho:

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

Dito isso, eu recomendo não executar essas etapas se você não sabe o que você precisa - apenas no caso de você fez podar o subdiretório errado, sabe? Os arquivos de backup não deve ter clonado quando você aperta o repo, eles vão ser apenas em sua cópia local.

Crédito

A resposta de

Paul cria um novo repositório que contém / ABC, mas não remove / ABC de dentro / XYZ. O seguinte comando irá remover / ABC de dentro / XYZ:

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

Claro, testá-lo em um 'clone --no-hardlinks' repositório primeiro, e segui-lo com o reset, gc e ameixa comandos listas Paulo.

Descobri que, a fim de eliminar adequadamente a antiga história do novo repositório, você tem que fazer um pouco mais de trabalho após a etapa filter-branch.

  1. Faça o clone eo filtro:

    git clone --no-hardlinks foo bar; cd bar
    git filter-branch --subdirectory-filter subdir/you/want
    
  2. Remova todas as referências à história antiga. “Origem” foi manter o controle de seu clone, e “original” é onde filter-branch salva o material antigo:

    git remote rm origin
    git update-ref -d refs/original/refs/heads/master
    git reflog expire --expire=now --all
    
  3. Mesmo agora, sua história poderia ser preso em um packfile que fsck não irá tocar. Rasgá-lo em pedaços, criando um novo packfile e apagar os objetos não utilizados:

    git repack -ad
    

uma explicação desse no manual para filter-branch .

Editar:. Bash roteiro adicionado

As respostas dadas aqui trabalhou apenas parcialmente para mim; Lotes de grandes arquivos permaneceu no cache. O que finalmente funcionou (depois de horas em #git no 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

Com as soluções anteriores, o tamanho do repositório foi de cerca de 100 MB. Este trouxe-a para baixo para 1,7 MB. Talvez ele ajuda a alguém:)


O seguinte script bash automatiza a tarefa:

!/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

Isto já não é tão complexo que você pode simplesmente usar o git filter-branch comando em um clone de você repo para abater os subdiretórios que você não quer e depois empurrar para o novo controle remoto.

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

Atualizar : O módulo git-sub foi tão útil que a equipe git puxou-o no núcleo e tornou git subtree. Veja aqui: Detach (mover) subdiretório em separado Git repositório

git-sub pode ser útil para este

http://github.com/apenwarr/git -subtree / blob / mestre / git-subtree.txt (preterido)

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

Aqui está uma pequena modificação para CoolAJ86 's " a maneira fácil ™" resposta , a fim de dividir múltiplas sub-pastas (digamos que sub1 sub2and) em um novo repositório git.

The Easy Way ™ (várias sub-pastas)

  1. Prepare o velho 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
    

    Nota: <name-of-folder> não podem conter esquerda ou à direita caracteres. Por exemplo, o subproject pasta chamada deve ser passado como subproject, NÃO ./subproject/

    Nota para usuários do Windows: quando a sua profundidade pasta é> 1, <name-of-folder> deve ter separador * pasta estilo nix (/). Por exemplo, a pasta chamada path1\path2\subproject deve ser passado como path1/path2/subproject. Além disso não use mvcommand mas move.

    Nota final: a diferença única e grande com a resposta base é a segunda linha do script "git filter-branch..."

  2. Criar o novo repo

    mkdir <new-repo>
    pushd <new-repo>
    
    git init
    git pull </path/to/big-repo> <name-of-new-branch>
    
  3. Fazer a ligação do novo repo para Github ou onde

    git remote add origin <git@github.com:my-user/new-repo.git>
    git push origin -u master
    
  4. Cleanup, se desejar

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

    Nota : Isso deixa todas as referências históricas no repository.See o Apêndice na resposta original, se você está realmente preocupado com ter cometido uma senha ou você precisa para diminuir o tamanho do arquivo da sua pasta .git.

A pergunta original quer XYZ / ABC / (* arquivos) para se tornar ABC / ABC / (* arquivos). Depois de implementar a resposta aceita para o meu próprio código, notei que ele realmente muda (arquivos *) (arquivos *) XYZ / ABC / em ABC /. A página man filter-branch mesmo diz,

O resultado irá conter esse diretório (e só isso) como seu raiz do projeto ."

Em outras palavras, promove a pasta de nível superior "up" um nível. Essa é uma distinção importante porque, por exemplo, na minha história que eu tinha renomeado a pasta de nível superior. Ao promover pastas "up" um nível, git perde continuidade ao cometer onde fiz a renomeação.

I contiuity perdida após filter-branch

A minha resposta para a pergunta, então, é para fazer 2 cópias do repositório e excluir manualmente a pasta (s) que deseja manter em cada um. A página man costas me com isto:

[...] evitar o uso de [este comando] se um simples único cometer seria suficiente para resolver o problema

Para adicionar de Paulo resposta , descobri que para finalmente recuperar espaço, eu tenho que empurrar HEAD para um repositório limpo e que apara para baixo o tamanho do / objetos / diretório .git Pack.

i.

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

Após a poda gc, também fazer:

$ git push ...ABC.git HEAD

Em seguida, você pode fazer

$ git clone ...ABC.git

eo tamanho do ABC / .git é reduzida

passos Na realidade, algum do tempo de consumo (por exemplo git gc) não são necessários com o impulso de repositório limpo, isto é:.

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

Maneira correta agora é a seguinte:

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

GitHub agora ainda têm pequeno artigo sobre tais casos.

Mas certifique-se de clonar seu repo original para diretório separado primeiro (como seria apagar todos os arquivos e outros diretórios e você provável necessidade de trabalhar com eles).

Portanto, o seu algoritmo deve ser:

  1. clone seu repositório remoto para outro diretório
  2. usando git filter-branch deixou apenas arquivos sob algum subdiretório, push to novo controle remoto
  3. criar comprometer a remover este subdiretório de seu repo remoto original

Parece que a maioria (todos?) Das respostas aqui dependem de alguma forma de git filter-branch --subdirectory-filter e sua laia. Isso pode funcionar "na maioria das vezes" No entanto, para alguns casos, por exemplo, o caso de quando você renomeou a pasta, ex:

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

ABC/
    /move_this_dir_renamed

Se você fizer um estilo filtro git normal extrato "move_me_renamed" você vai perder histórico de alterações de arquivo que ocorreram a partir de quando foi inicialmente move_this_dir ( ref ).

Assim, parece que a única maneira de realmente manter todas histórico de alterações (se o seu é um caso como este), é, em essência, para copiar o repositório (criar um novo repo, conjunto que para ser a origem), então tudo Nuke pessoa e mudar o nome do subdiretório para o pai como este:

  1. Clone o projeto multi-módulo localmente
  2. Ramos - verificação que está lá: git branch -a
  3. Faça um check-out para cada ramo para ser incluído na divisão para obter uma cópia local na estação de trabalho: git checkout --track origin/branchABC
  4. Faça uma cópia em um novo diretório: cp -r oldmultimod simple
  5. Vá para a nova cópia do projeto: cd simple
  6. Se livrar dos outros módulos que não são necessários neste projeto:
  7. git rm otherModule1 other2 other3
  8. Agora apenas o subdir dos restos módulo de destino
  9. Se livrar da subdir módulo para que a raiz do módulo torna-se a nova raiz do projeto
  10. git mv moduleSubdir1/* .
  11. Exclua o subdir relíquia: rmdir moduleSubdir1
  12. Verificar alterações em qualquer ponto: git status
  13. Criar o novo repositório git e copiar sua URL para apontar esse projeto para ele:
  14. git remote set-url origin http://mygithost:8080/git/our-splitted-module-repo
  15. Verifique se isso é bom: git remote -v
  16. Empurre a muda-se para o repo remoto: git push
  17. Vá para o repo remoto e verificar que está tudo lá
  18. Repita isso por qualquer outro ramo necessário: git checkout branch2

Isto segue o github doc " Dividindo uma subpasta para fora em um novo repositório " os passos 6-11 para empurrar o módulo para um novo repo.

Isso não vai poupar qualquer espaço em sua pasta .git, mas vai preservar toda a história a sua mudança para esses arquivos mesmo através renomeações. E isso pode não valer a pena se não há "um monte" de história perdida, etc. Mas pelo menos você está garantido para não perder commits mais velhos!

Eu tive exatamente esse problema, mas todas as soluções padrão baseadas em git filter-branch foram extremamente lento. Se você tem um pequeno repositório então este não pode ser um problema, que era para mim. I escreveu outro git filtragem programa baseado em libgit2 que, como um primeiro passo cria ramos para cada filtragem do repositório primário e, em seguida, empurra-os para repositórios limpas como a próxima etapa. No meu repositório (500MB 100000 commits) GIT métodos filter-branch padrão levou dias. Meu programa leva alguns minutos para fazer o mesmo filtragem.

Tem o nome fabulosa de git_filter e vive aqui:

https://github.com/slobobaby/git_filter

no GitHub.

Espero que seja útil para alguém.

Por que vale a pena, aqui é como usar GitHub em uma máquina Windows. Vamos dizer que você tem um repositório clonado em residente em C:\dir1. A estrutura de diretórios parecida com esta: C:\dir1\dir2\dir3. O diretório dir3 é o que eu quero ser um novo repo separado.

Github:

  1. Crie o seu novo repositório: MyTeam/mynewrepo

Bash Prompt:

  1. $ cd c:/Dir1
  2. $ git filter-branch --prune-empty --subdirectory-filter dir2/dir3 HEAD
    Retornado: Ref 'refs/heads/master' was rewritten (fyi:. Dir2 / pasta3 é case sensitive)

  3. $ git remote add some_name git@github.com:MyTeam/mynewrepo.git
    git remote add origin etc. não funcionou, voltou "remote origin already exists"

  4. $ git push --progress some_name master

, I teve de utilizar o inverso solução (excluindo todos os commits não tocando minha dir/subdir/targetdir) que parecia funcionar muito bem removendo cerca de 95% dos commits (como desejado). Há, no entanto, duas pequenas questões pendentes.

PRIMEIRO , filter-branch fez um estrondo-se trabalho de remoção de commits que introduzem ou modificar o código, mas, aparentemente, merge commits estão abaixo de sua estação no Gitiverse.

Este é um problema cosmético que eu posso provavelmente ao vivo com (ele diz ... se afastando lentamente, com os olhos desviados) .

SEGUNDO os poucos commits que permanecem são praticamente ALL duplicada! I parecem ter adquirido uma segunda linha de tempo, redundante que abrange apenas cerca de toda a história do projeto. O interessante (que você pode ver na foto abaixo), é que meus três ramos locais não estão todos na mesma linha do tempo (que é, certamente por isso que ele existe e não é apenas lixo coletado).

A única coisa que posso imaginar é que um dos commits excluídos foi, talvez, o único merge cometer esse filter-branch realmente queria excluir , e que criou o cronograma paralelo como cada vertente agora não mesclado levou sua própria cópia dos commits. ( ombros Onde está meu Tardis?) Eu tenho certeza que eu posso corrigir esse problema, embora eu realmente amor para entender como isso aconteceu.

No caso de louco mergefest-O-Rama, eu provavelmente vai estar deixando que um sozinho, uma vez que tem tão firmemente entrincheirado-se no meu histórico de commits-ameaçador para mim sempre que eu venho quase-, ele não parece ser realmente causando problemas não cosméticos e porque é muito bonito em Tower.app.

Use este comando filtro para remover um subdiretório, preservando suas tags e ramos:

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

O mais fácil Way

  1. git splits . Eu criei-lo como uma extensão git, com base em de jkeating solução .
  2. Dividir os diretórios em uma filial local #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. Criar um em algum lugar repo vazio. Vamos supor que nós criamos um repo vazio chamado xyz no GitHub que tem caminho: git@github.com:simpliwp/xyz.git

  4. Premir o novo 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. Clone o repo remoto recém-criado em um novo diretório local
    #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

Eu recomendo guia do GitHub para divisão subpastas em uma nova repositório. Os passos são semelhantes aos de Paulo resposta , mas eu achei as instruções mais fáceis de entender.

Eu modifiquei as instruções para que se candidatam a um repositório local, ao invés de um hospedado no GitHub.


Splitting uma subpasta para fora em um novo repositório

  1. Open Git Bash.

  2. Alterar o diretório de trabalho atual para o local onde você deseja criar o seu novo repositório.

  3. Clone o repositório que contém a subpasta.

git clone OLD-REPOSITORY-FOLDER NEW-REPOSITORY-FOLDER
  1. Altere o diretório de trabalho atual para o repositório clonado.

cd REPOSITORY-NAME
  1. Para filtrar a subpasta do resto dos arquivos no repositório, git filter-branch executar, fornecendo as seguintes informações:
    • FOLDER-NAME: A pasta dentro do seu projeto que você gostaria de criar um repositório separado do.
      • Dica:. Usuários do Windows devem usar / para pastas delimitam
    • BRANCH-NAME:. O ramo padrão para seu projeto atual, por exemplo, master ou 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

Você pode precisar de algo como "git reflog expirar --expire = agora --all" antes da coleta de lixo para realmente limpar os arquivos para fora. git filter-branch apenas remove as referências na história, mas não remove as entradas reflog que contêm os dados. Claro, testar isso em primeiro lugar.

O meu uso do disco caiu drasticamente em fazer isto, embora minhas condições iniciais eram um pouco diferentes. Talvez --subdirectory-filtro nega essa necessidade, mas eu duvido.

Confira projeto git_split em https://github.com/vangorra/git_split

Vire diretórios git em seus próprios repositórios na sua própria localização. No sub negócio engraçado. Este roteiro terá um diretório existente em seu repositório git e transformar esse diretório em um repositório independente da sua própria. Ao longo do caminho, ele irá copiar sobre todo o histórico de alterações para o diretório que você forneceu.

./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.

Coloque isso em seu 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'

Eu tenho certeza sub git é tudo muito bem e maravilhoso, mas meus subdiretórios do git código gerenciado que eu queria movimento era tudo em eclipse. Então, se você estiver usando egit, é dolorosamente fácil. Tome o projeto que você deseja mover e em equipa> desligá-lo e, em seguida, em equipa> compartilhá-lo para o novo local. Ele será o padrão para tentar usar o antigo local repo, mas você pode desmarcar a seleção-existente uso e escolher o novo local para movê-lo. Todos egit granizo.

Eu encontrei solução para a frente bastante simples, A idéia é copiar repositório e, em seguida, basta remover parte desnecessária. É assim que funciona:

1) Clone um repositório que você gostaria de dividir

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

2) Mover para git pasta

cd test/

2) Remova pastas desnecessárias e cometê-lo

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

3) Remover filtro desnecessário (s) histórico de formulários com BFG

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

para pastas multiplicam você pode usar a vírgula

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

4) Verifique que a história não contém os arquivos / pastas que você acabou de excluir

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

5) Agora você tem repositório limpa sem ABC, portanto basta empurrá-lo para nova origem

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

É isso. Você pode repetir os passos para obter outro repositório,

apenas remover XY1, XY2 e renomear XYZ -> ABC na etapa 3

Você pode facilmente experimentar o https://help.github.com/enterprise/2.15/user/articles/splitting-a-subfolder-out-into-a-new-repository/

Isso funcionou para mim. Os problemas que eu enfrentei nas etapas acima são

  1. Neste comando git filter-branch --prune-empty --subdirectory-filter FOLDER-NAME BRANCH-NAME O BRANCH-NAME é mestre

  2. se a última etapa falhar quando cometer devido ao problema follow proteção - https://docs.gitlab.com/ee/user/project/protected_branches.html

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top