我会尽量简单......
放手:
我们有一个大的git repo,其中包含3个不同项目的文件夹:
主要仓库中的文件夹结构:
existing_repo
├── .net_is_dir
├── java_is_dir
└── android_is_dir
对于java,对于一个问题,我们在root中有分支
对于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
任务是文字:
android_newrepo
每个项目的文件应该是root(用于CI),而不是在子目录中。
应以正确的方式导出/导入分支:
issue1_4_java - > java_newrepo / issue1_4_java
android / issue1_4_android - > android_newrepo / issue1_4_android
新项目应仅包含特定项目的历史记录。 .net关于.net,而不是关于ios和android等。
我认为这是不真实的 我的工作手册是
1)在新的特定仓库中导入现有仓库,移动目录,删除无用的 - >导致:
每个项目都将包含所有旧项目,回购将很大
2)创建具有所需分支的新回购,只需将文件从appropriare dirs复制到新分支并提交 - >导致
没有历史,回购规模很小
可能你会建议我一些新的想法?
答案 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 repos," 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
命令都将通过repo的所有(因为--all
)分支并重写其历史记录,但是......
仅查看触及给定子目录的历史记录。该 结果将包含该目录(并且仅包含该项目)作为其项目 根
(来自git-filter-branch documentation)
换句话说,子目录的内容将转到repo的根目录,git历史记录将被重写,以便它只包含与该子目录相关的历史记录,其内容最终将是根目录的新内容。
按照上述步骤,您仍应在每个仓库中拥有所有分支(均具有重写历史记录)。对于每个仓库,您应该删除不相关的分支,并根据您的新约定重命名相关分支。如果分支的数量非常大,您可以使用脚本。最后,在为每个新仓库修复分支并在创建相应的远程仓库(例如在GitLab中)之后,您可以将其添加为远程并随意推送。
答案 1 :(得分:0)
似乎通过使用命令
解决了问题git filter-branch --subdirectory-filter android_is_dir -- --all
谢谢@xnakos耐心等待。此外,在此期间我重命名了分支,使用特殊键(谷歌搜索)和每个新分支我分开推,现在看起来很棒,开发团队明天会很开心)))
BTW直到凌晨3点我制作剧本,由于它没有用,我看到每个分支的所有历史记录,我没看到分支之间的关系(合并)可能有人会发现它很有趣, 脚本充满了拐杖和硬编码,但无论如何,它对我有用)
#!/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()