Git exporta / importa confirma el historial

Trataré de ser lo más simple posible …

vamonos:

tenemos un gran repo de git, que incluye 3 carpetas para diferentes proyectos:

Estructura de carpetas en repository principal:

existing_repo ├── .net_is_dir ├── java_is_dir └── android_is_dir 

para Java, por un problema, tenemos una twig en la raíz

para Android dir, por un problema, hemos henetworkingado la twig en la twig "android". En la estructura de gitlab es el siguiente:

Estructura de sucursales en repos

 existing_repo ├── .net_dev ├── .net_qa | ├── java_dev ├── java_qa ├── java_issue_1 ├── java_issue_n | ├── android_dev ├── android_qa └── android ├─ android_issue_1 └─ android_issue_n 

la tarea es text:

  • Necesito crear 3 repositorys nuevos para 3 proyectos diferentes
  • .net_newrepo
  • java_newrepo
  • android_newrepo

  • Los files, para cada proyecto, deben estar en la raíz (para CI), no en subdirectorys.

  • Las sucursales se deben exportar / importar de la manera correcta:

    issue1_4_java -> java_newrepo / issue1_4_java

    android / issue1_4_android -> android_newrepo / issue1_4_android

  • El nuevo proyecto debe contener historia solo sobre un proyecto en particular. .net sobre .net, y no sobre ios y android, etc.

Creo que es irreal mis niveles de trabajo son

1) importe el repository existente en un nuevo repository en particular, mueva los directorys y elimine un recurso útil -> conduce a:

cada proyecto contendrá todos los proyectos antiguos, el repos será grande

2) crear nuevos repositorys con las twigs necesarias, simplemente copie los files de los directorys apropiados a las nuevas twigs y confirme -> conduce a

sin historial, el tamaño del repository es pequeño

probablemente me sugieras algunas ideas nuevas?

Permítanos probar algo. Es un poco experimental y requerirá que saltes. Disculpa por usar "dotnet" en lugar de ".net" a continuación.

 $ cp -r existing_repo dotnet_newrepo # Get a copy of the existing repo. The new directory will ultimately be the repo for dotnet. $ cd dotnet_newrepo # Go to the new directory for dotnet. $ git remote rm origin # Remove the "origin" remote. Do this for all remotes. $ cd .. # Go back. $ cp -r dotnet_newrepo java_newrepo # Get a copy for java (without remotes). $ cp -r dotnet_newrepo android_newrepo # Get a copy for android (without remotes). 

Ahora tiene tres repositorys git, "dotnet_newrepo", "java_newrepo", "android_newrepo", que son exactamente como su repository existente, solo que sin controles remotos. Continuando.

 $ cd dotnet_newrepo $ git filter-branch --subdirectory-filter dotnet_is_dir -- --all $ cd .. $ cd java_newrepo $ git filter-branch --subdirectory-filter java_is_dir -- --all $ cd .. $ cd android_newrepo $ git filter-branch --subdirectory-filter android_is_dir -- --all $ cd .. 

Cada command de git filter-branch arriba pasará por todas (debido a – todas) las twigs del repository y reescribirá su historial, pero …

Solo mira la historia que toca el subdirectory dado. El resultado contendrá ese directory (y solo eso) como su raíz de proyecto.

(de la documentation de git-filter-branch )

En otras palabras, el contenido del subdirectory irá al directory raíz del repository y el historial de git será reescrito para que contenga solo el historial que sea relevante para ese subdirectory, cuyo contenido será finalmente el contenido nuevo y único del directory raíz.

Siguiendo los pasos descritos anteriormente, aún debe tener todas las twigs (todas con historial reescrito) en cada repository. Para cada repository, debe eliminar las twigs irrelevantes y renombrar las sucursales relevantes de acuerdo con sus nuevas convenciones. Si el número de sucursales es realmente grande, podrías usar un script para esto. Finalmente, después de arreglar sus sucursales para cada repository nuevo y después de crear un repository remoto correspondiente (por ejemplo, en GitLab), puede agregarlo como control remoto y pulsar a voluntad.

parece un problema resuelto mediante el uso de commands

 git filter-branch --subdirectory-filter android_is_dir -- --all 

gracias @xnakos por tu paciencia. Además, durante este cambio de nombre de las sucursales, el uso de keys especiales (en Google) y cada nueva twig que empujé por separado, se ve increíble ahora, el equipo de desarrollo estará feliz mañana)))

Por cierto, hasta la 3 AM de la noche hice el guión, por eso no funcionó, veo toda la historia por cada twig, por lo que no vi las relaciones entre las twigs (fusiones)

probablemente alguien lo encuentre interesante, el guión está lleno de muletas y código duro, pero de todos modos, funcionó para mí)

 #!/usr/bin/python import os import json import shutil import subprocess from distutils.dir_util import copy_tree old_repo = "/home/ostetsia/coding/java" old_repo_dir = "/home/ostetsia/coding/java/java_subdir" new_repo = "/home/ostetsia/coding/java old_repo_branch = "java/java_case_number" new_repo_branch = "java_case_number" #changing branch in new repo os.chdir(new_repo) try: subprocess.check_output(["git", "branch", new_repo_branch]) except: print "branch {0} exist in new repo".format(new_repo_branch) subprocess.check_output(["git", "checkout", new_repo_branch]) os.chdir(old_repo) try: subprocess.check_output(["git", "branch", old_repo_branch]) except: print "branch {0} exist in old repo".format(old_repo_branch) os.chdir(old_repo) subprocess.check_output(["git", "checkout", old_repo_branch]) git_add = "git add *" git_old_log = subprocess.check_output(['git', 'log', '--reverse', '--pretty=format:{"hash": "%H", "reporter":"%an", "mail": "%ce", "date": "%cd", "comment": "%s"}']) commit_list = {} i=0 for data_line in git_old_log.split('\n'): i+=1 data_line = json.loads(data_line) commit_list[i] = dict(data_line) git_old_log_count_commint = i for commit, data in commit_list.iteritems(): for key, value in data.iteritems(): if key == "date": date=value print date elif key == "mail": mail = value elif key == "hash": hash = value elif key == "comment": comment = value elif key == "reporter": reporter = value git_commit_command = "git commit -a --author='{0} <{1}>' --date='{2}' -am '{3}'".format(reporter, mail, date, comment) #print git_commit_command os.chdir(new_repo) os.system("pwd") os.system("rm -rf") print commit os.chdir(old_repo) subprocess.check_output(["git", "checkout", hash]) copy_tree(old_repo_dir, new_repo) os.chdir(new_repo) os.system(git_add) os.system(git_commit_command) print os.getcwd()