Skip to content

Instantly share code, notes, and snippets.

@velfundert
Last active October 26, 2016 17:56
Show Gist options
  • Save velfundert/9372f700d4f7a6f28108b6526d899991 to your computer and use it in GitHub Desktop.
Save velfundert/9372f700d4f7a6f28108b6526d899991 to your computer and use it in GitHub Desktop.
En liten oppskrift på hvordan man kan splitte et java-repo og få det til å kompilere igjen vha. git subtree split, git filter-branch

Å splitte et java-repository i to deler

Har du en java-applikasjon i et git-repository som du har lyst til å dele opp i flere deler, men helst med så mye historikk som mulig? Det hadde jeg, og jeg fikk fikset det på et slags vis:

  1. Lag en arbeidskopi av git-repositoriet (dette kan du i og for seg skippe om du er kul nok):

    cp -r mitt-repo mitt-repo-kopi
    cd mitt-repo-kopi
    
  2. Kjør en subtree-split med git

    git subtree split -P src/main/java/[path]/det-du-vil-ha-ut -b tree-split-branch
    

    Nå har du en branch i indeksen i repoet ditt som er et subtree som bare inneholder filene + historikken for filene i den delen av treet du splittet ut.

  3. Lag et nytt repo, pull inn den nye branchen

    cd ..
    mkdir mitt-nye-repo && cd mitt-nye-repo
    git init
    git pull ../mitt-repo-kopi/.git tree-split-branch
    

    Du har alt. Men det ligger på rot. Nå må vi rydde litt så ikke java dør:

  4. Siden vi driver med java, er det en streng sammenheng mellom plasseringen til filene i filsystemet, og package-navn i filen. Det må fikses (nå bør du tenke over hvordan det skal se ut i 5. på forhånd):

    git filter-branch -f --tree-filter 'for i in $( ls *.java); do sed -e "s/filenes gamle package/filenes nye package/" -i "" $i; done'
    

    Om du har flere packages i samme repo må du seff fikse på det også

  5. git subtree flyttet mappen din til roten i den nye repoet, men den må jo selvfølgelig ligge i src/main/java/din/package/din-applikasjon for at java skal fungere:

    git filter-branch -f --tree-filter 'mkdir -p src/main/java/din/package/din-applikasjon && mv *.java  src/main/java/din/package/din-applikasjon' HEAD
    

    NB: Det er betydelig enklere å gjøre dette skrittet etter 4. og ikke omvendt.

  6. Nå viser det seg sikkert at den koden du flyttet ikke var helt uavhengig allikevel, så da må du kopiere over noen filer fra det gamle repoet.

    git checkout --orphan ny_initial_commit
    git clean -f -d 
    cp ../mitt-repo/ting-du-vil-ha .
    git add .
    git commit -m "initial commit ;)"
    git checkout master
    git rebase --onto ny_initial_commit --root master
    

    Et tips: Det er ofte litt tricky å finne ut hva du mangler, det kan fort være at det enkleste er å ikke sjekke ut den tomme commiten før du vet det, og er klar:

    git checkout -b temp-branch
    cp ../mitt-repo/ting-du-vil-ha
    [build]
    cp ../mitt-repo/src/main/resources/hva-faen.txt src/main/resources/
    [build]
    git add .
    git commit -m "temp"
    git format-patch -1
    mv 0001-temp.patch ..
    git checkout --orphan ny_initial_commit
    git apply ../0001-temp.patch
    git commit -am "initial commit ;)"
    (resten som over)
    ...
    git branch -D temp-branch
    
  7. Nå har du et nytt repo, med historikk, som antagelig til og med bygger om du sjekker ut historiske commits. Helt vilt. Thank u git.

    Lag et nytt repo upstream (på github, ikke sant), push med git push -u origin master

    Men vent, hva med testene?

  8. Trinn 2, 4, og 5 er de samme for testene dine også. For å kunne gjøre alle operasjonene i samme repository kan du sjekke ut en ny orphan-branch og pulle endringene rett inn i den, i stedet for å lage et nytt repo:

    git checkout --orphan din-applikasjon-tester
    git reset --hard
    git pull ../mitt-repo-kopi/.git applikasjon-tester
    

    Gjør trinn 4 og 5, men med test på de rette stedene. Gjør til slutt en rebase opp på master (eller på ditt initielle commit, om du mener det er bedre). Merge test-branchen med master.

    git rebase --onto master --root din-applikasjon-tester
    git checkout master
    git merge din-applikasjon-tester
    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment