Frage Split großes Git-Repository in viele kleinere


Nach der erfolgreichen Konvertierung eines SVN-Repositorys in Git habe ich jetzt ein sehr großes Git-Repository, das ich in mehrere kleinere Repositories aufteilen und den Verlauf verwalten möchte.

Also, kann jemand helfen, ein Repo aufzubrechen, das wie folgt aussehen könnte:

MyHugeRepo/
   .git/
   DIR_A/
   DIR_B/
   DIR_1/
   DIR_2/

In zwei Repositories, die wie folgt aussehen:

MyABRepo/
   .git
   DIR_A/
   DIR_B/

My12Repo/
   .git
   DIR_1/
   DIR_2/

Ich habe versucht, die Anweisungen in dieser vorherigen Frage zu befolgen, aber es passt nicht wirklich, wenn mehrere Verzeichnisse in ein separates Repo (Trennen Sie das Unterverzeichnis in ein separates Git-Repository).


76
2017-10-11 22:32


Ursprung


Antworten:


Dies wird MyABRepo einrichten; Sie können natürlich My12Repo tun.

git clone MyHugeRepo/ MyABRepo.tmp/
cd MyABRepo.tmp
git filter-branch --prune-empty --index-filter 'git rm --cached --ignore-unmatch DIR_1/* DIR_2/*' HEAD 

Ein Verweis auf .git / refs / original / refs / heads / master bleibt bestehen. Du kannst das entfernen mit:

cd ..
git clone MyABRepo.tmp MyABRepo

Wenn alles gut gegangen ist, können Sie MyABRepo.tmp entfernen.


Wenn Sie aus irgendeinem Grund einen Fehler in Bezug auf .git-rewrite erhalten, können Sie Folgendes versuchen:

git clone MyHugeRepo/ MyABRepo.tmp/
cd MyABRepo.tmp
git filter-branch -d /tmp/git-rewrite.tmp --prune-empty --index-filter 'git rm --cached --ignore-unmatch DIR_1/* DIR_2/*' HEAD 
cd ..
git clone MyABRepo.tmp MyABRepo

Dadurch wird /tmp/git-rewrite.tmp als temporäres Verzeichnis erstellt und verwendet .git-rewrite. Natürlich können Sie jeden beliebigen Pfad ersetzen /tmp/git-rewrite.tmp, solange Sie Schreibrechte haben und das Verzeichnis noch nicht existiert.


71
2017-10-11 23:37



Du könntest benutzen git filter-branch --index-filter mit git rm --cached Löschen Sie die unerwünschten Verzeichnisse von Klonen / Kopien Ihres ursprünglichen Repositories.

Beispielsweise:

trim_repo() { : trim_repo src dst dir-to-trim-out...
  : uses printf %q: needs bash, zsh, or maybe ksh
  git clone "$1" "$2" &&
  (
    cd "$2" &&
    shift 2 &&

    : mirror original branches &&
    git checkout HEAD~0 2>/dev/null &&
    d=$(printf ' %q' "$@") &&
    git for-each-ref --shell --format='
      o=%(refname:short) b=${o#origin/} &&
      if test -n "$b" && test "$b" != HEAD; then 
        git branch --force --no-track "$b" "$o"
      fi
    ' refs/remotes/origin/ | sh -e &&
    git checkout - &&
    git remote rm origin &&

    : do the filtering &&
    git filter-branch \
      --index-filter 'git rm --ignore-unmatch --cached -r -- '"$d" \
      --tag-name-filter cat \
      --prune-empty \
      -- --all
  )
}
trim_repo MyHugeRepo MyABRepo DIR_1 DIR_2
trim_repo MyHugeRepo My12Repo DIR_A DIR_B

Sie müssen die nicht benötigten Zweige oder Tags jedes Repositorys manuell löschen (z. B. wenn Sie eine Merkmal-x-für-AB verzweigen, dann möchten Sie wahrscheinlich das aus dem Repository "12" löschen).


9
2017-10-12 00:01



Hier ist ein Ruby-Skript, das es tun wird. https://gist.github.com/4341033


3
2017-12-19 22:26



Das git_split-Projekt ist ein einfaches Skript, das genau das tut, wonach Sie suchen. https://github.com/vangorra/git_split

Verwandeln Sie Git-Verzeichnisse in ihre eigenen Repositories an ihrem eigenen Speicherort. Kein lustiges Geschäft mit Unterverzeichnissen. Dieses Skript nimmt ein vorhandenes Verzeichnis in Ihrem Git-Repository und wandelt dieses Verzeichnis in ein eigenständiges Repository um. Dabei wird der gesamte Änderungsverlauf für das von Ihnen angegebene Verzeichnis kopiert.

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

3
2018-01-06 02:45



Vielen Dank für Ihre Antworten, aber am Ende habe ich einfach das Repository zweimal kopiert und dann die Dateien gelöscht, die ich nicht haben wollte. Ich werde den Filterzweig zu einem späteren Zeitpunkt verwenden, um alle Commits für die gelöschten Dateien zu entfernen, da sie bereits anderswo versionsgesteuert sind.

cp -R MyHugeRepo MyABRepo
cp -R MyHugeRepo My12Repo

cd MyABRepo/
rm -Rf DIR_1/ DIR_2/
git add -A
git commit -a

Dies funktionierte für das, was ich brauchte.

EDIT: Natürlich wurde das Gleiche in der My12Repo gegen das A- und B-Verzeichnis gemacht. Dies gab mir zwei Repos mit identischer Geschichte bis zu dem Punkt, an dem ich die unerwünschten Verzeichnisse löschte.


0
2017-10-20 17:34