Git两库合并历史记录
Git两库合并历史记录
情景
有两个库, A与B
需要合并两个库的代码并保留完整的记录
思路
两库合并的重点在于,在原本一个库上加上另一个库.
实际操作主要的点在remote add
, 关联多的一个库
之后再进行,检出与新库关联的新分支,把新分支与老分支进行合并.
要点
- remote add
- 两库对应分支的合并方式, 是merge还是rebase
- 关于合并记录的先后顺序
操作步骤(单分支)
- 检出第1个库
# git clone <repo1-url>
git clone http://192.168.1.1/root/A-project.git
- 添加库与项目
# git remote add <repo2-name> <repo2-url>
git remote add other http://192.168.1.1/root/B-project.git
- 获取新旧项目与远程地址的更新
git fetch --all
- 检出一个新的本地分支, 用来与远程分支对应
# git checkout -b <repo2-branchName> remotes/<repo2-name>/<repo2-branchName>
git checkout -b otherMaster remotes/other/master
- 合并两个分支
# 此处, 可以基于提交数较少的分支, 把相较而言更新的分支合并进当前分支. 此处, 我基于otherMaster,把master分支合并入该分支,因为master的记录更多且更新
# git merge <repo1-branchName> --allow-unrelated-histories
git merge master --allow-unrelated-histories
多个仓库以子目录形式合并脚本
# @Author: LiuJunya
# @Date: 2022-11-14 14:03:44
# @Last Modified by: LiuJunya
# @Last Modified time: 2022-11-15 14:33:17
# 帮助完成多库合并记录的脚本: 可实现多个子库以子目录的形式合并至单个仓库
# before
# +--- Repo-A
# | +--- .git
# +--- Repo-B
# | +--- .git
# +--- Repo-C
# | +--- .git
# after
# +--- ALL
# | +--- .git
# | +--- Repo-A
# | +--- Repo-B
# | +--- Repo-C
# process
# 1. 新建仓库目录: 总仓库, partA,partB
# 2. 分别克隆不同的子仓库, 调整其目录结构, 将所有内容都放置到同名子目录内
# 3. 在总仓库依次添加对应的子库, 合并分支, 合并目录.
# 无推送流程, 调整完成后自行按需推送
# variable: 本地主库名
MAIN_REPO_NAME="_MainRepo"
# variable: 子库列表(url 分支;;两者以空格区分)
## 列表有顺序, 靠前则先进行合并
PART_REPO_URL_LIST=(
"git@git.ept.com:project/C3000202200001_GAC_A02/Cluster_App.git develop"
"git@git.ept.com:project/C3000202200001_GAC_A02/HAVC_App.git master"
"git@git.ept.com:project/C3000202200001_GAC_A02/Cluster_AVM.git master"
)
# base info
SCRITP_NAME=$(basename $0)
SCRITP_PATH=$(realpath $0)
SCRITP_DIR=$(dirname $SCRITP_PATH)
SCRIPT_USER=$(whoami)
TIMESTAMP=$(date "+%Y/%m/%d %H:%M:%S")
LOG_HEAD="[$TIMESTAMP $SCRIPT_USER-$SCRITP_NAME]:"
LOG_FILE="info_$SCRITP_NAME.log"
# git库操作
function moveRepoToSameDirectory(){
move_repo_name=$1
cd $move_repo_name
if [[ -d $move_repo_name ]]; then
rm -rf $move_repo_name
fi
mkdir $move_repo_name
ls -A | grep -wv '.git\|$move_repo_name' | xargs -t -I '{}' git mv {} $move_repo_name/{}
git add .
git commit -m "change base directory, to $move_repo_name"
}
function createNewRepo(){
if [[ -d $1 ]]; then
rm -rf $1
fi
git init $1
}
# 文件夹操作
function resetFolder(){
if [[ -d $1 ]]; then
rm -rf $1
fi
mkdir $1
}
# 字符串操作
function getRepoName(){
repo_url=$1
repo=${repo_url##*/}
repo=${repo%*.git}
echo $repo
}
# 创建主库, 并准备基础分支
resetFolder $MAIN_REPO_NAME
createNewRepo $MAIN_REPO_NAME
cd $MAIN_REPO_NAME
git checkout -b master
echo "" > readme.md
git add .
git commit -m "init branch"
git push origin master
for line in "${PART_REPO_URL_LIST[@]}"; do
# 库的url/name/branch
read -a var <<< $line
repo_url=${var[0]}
repo_branch=${var[1]}
repo_name=$(getRepoName $repo_url)
echo $repo_url
echo $repo_name
echo $repo_branch
cd $SCRITP_DIR
# 创建目录及克隆子库
resetFolder $repo_name
git clone -b $repo_branch $repo_url $repo_name
# 调子库目录结构
moveRepoToSameDirectory $repo_name
cd $SCRITP_DIR
cd $MAIN_REPO_NAME
# 增加库与合并
git remote add $repo_name ../$repo_name
git remote -v
git fetch --all
git checkout -b $repo_name remotes/$repo_name/$repo_branch
git checkout master
git merge $repo_name --allow-unrelated-histories -m "merge subrepo $repo_name"
git remote remove $repo_name
git branch -D $repo_name
done