2016-07-09 2 views
1

я постараюсь быть как можно более простым ...экспорт Git/импорт совершает история

отпускает:

мы имеем один большой мерзавец репо, который включает в себя 3 папки для различных проектов:

структура папок в главном репо:

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

для Java, в расчете на одну проблему, мы имеем филиал в корне

для android dir, за один выпуск, унаследовали ветку в ветке «android». В gitlab структура следующая:

Ветви структура репо

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 

задача текст:

  • мне нужно создать 3 новых сделок РЕПО для 3 различных проектов
  • .net_newrepo
  • java_newrepo
  • android_newrepo

  • Файлы для каждого проекта должны быть в корне (это для CI), а не в поддиректориях.

  • Ветви должны быть экспортированы/импортированы в правильном направлении:

    issue1_4_java -> java_newrepo/issue1_4_java

    андроида/issue1_4_android -> android_newrepo/issue1_4_android

  • Новый проект должен содержать только историю о конкретном проекте. .net о .net, а не о ИОС и андроид и т.д.

Я думаю, что это нереально мои workaraunds являются

1) импортировать существующий репозиторий в новом конкретном репо, перенести каталоги и удалять ип полезно -> приводит к:

каждый проект будет содержать все старые проекты, сделки рЕПО будет большой

2) создание новых сделок рЕПО с необходимыми ветвями, просто скопировать файлы из appropriare директорий для новых отраслей и совершить - > ведет в

без истории, размер репо небольшой

вероятно, вы предложить мне какие-то новые идеи?

+1

Просто дикая идея: есть перекрывающиеся репозитории, а затем запустить скрипт, который проверяет каждую фиксацию в одной и это к другому. –

+0

хорошо пункт! Я подумаю об этом –

+0

Я имею в виду, это определенно возможно, но, возможно, есть лучший способ сделать это. Если вы идете по этому пути, пожалуйста, разделите написанный вами сценарий. –

ответ

1

Давайте попробуем что-нибудь. Это немного экспериментально и потребует от вас прыгать. Извините меня за использование «dotnet» вместо «.net» в следующем.

$ 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). 

Теперь у вас есть три GIT репо, "dotnet_newrepo", "java_newrepo", "android_newrepo", которые так же, как существующий репозиторий, только без пультов дистанционного управления. Двигаемся дальше.

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

Каждая git filter-branch выше команда будет проходить через все (из-за --all) ветвей репо и переписать свою историю, но ...

Только посмотрите на историю, которая затрагивает данный подкаталог. Результат будет содержать этот каталог (и только тот) как его проект root.

(от git-filter-branch documentation)

Другими словами, содержимое подкаталога будет перейти в корневой каталог Repo и истории мерзавца будет переписан так, что она будет содержать только историю, которая имеет отношение к этому подкаталоге , содержимое которого в конечном итоге станет новым и единственным содержимым корневого каталога.

Следуя инструкциям, описанным выше, вы должны иметь все ветви (все с переписанной историей) в каждом репо. Для каждого репо вы должны удалить ненужные ветви и переименовать соответствующие ветви в соответствии с вашими новыми соглашениями. Если количество ветвей действительно велико, вы можете использовать для этого скрипт. Наконец, после фиксации ваших филиалов для каждого нового репо и после создания соответствующего удаленного репо (например, в GitLab), вы можете добавить его как удаленный и нажать по желанию.

0

кажется, проблема решается с помощью команд

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

благодарю вас @xnakos для вас терпения. Кроме того, во время этого я переименовал ветки, используя специальные клавиши (googled it) и каждую новую ветвь, которую я поместил отдельно, теперь это выглядит потрясающе, команда разработчиков будет счастлива завтра)))

BTW до ночи 3AM Я создал сценарий, по этому не работало, я вижу всю историю за каждую ветвь, я не видел отношений между ветвями (слияния)

Возможно, кому-то это будет интересно, скрипт полон костылей и жесткого кода, но в любом случае он работал для меня)

#!/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()