考虑以下场景:
我在自己的Git repo中开发了一个小型实验项目a。它现在已经成熟,我希望A成为更大的项目B的一部分,该项目有自己的大仓库。现在我想将A添加为B的子目录。
我如何将A合并为B,而不丢失任何方面的历史?
考虑以下场景:
我在自己的Git repo中开发了一个小型实验项目a。它现在已经成熟,我希望A成为更大的项目B的一部分,该项目有自己的大仓库。现在我想将A添加为B的子目录。
我如何将A合并为B,而不丢失任何方面的历史?
当前回答
我今天必须按如下方式解决:项目A在bitbucket中,项目B在代码提交中。。这两个项目都是相同的,但必须将A到B的更改合并。(诀窍是在项目A中创建同名分支,与在项目B中相同)
git签出项目Agit远程删除原点git远程添加源项目Bgit结帐分行git加法*gitcommit-m“我们已经移动了代码”数字推送
其他回答
如果您想单独维护项目,子模块方法是很好的。然而,如果您真的想将两个项目合并到同一个存储库中,那么您还有更多的工作要做。
第一件事是使用gitfilter分支将第二个存储库中所有内容的名称重写到您希望它们结束的子目录中。因此,您将使用projb/foo.c和projb/bar.html代替foo.c和bar.html。
然后,您应该能够执行以下操作:
git remote add projb [wherever]
git pull projb
git pull将执行git fetch,然后执行git merge。如果您要拉到的存储库还没有projb/目录,那么应该不会有冲突。
进一步搜索表明,在将gitk合并为git时也做了类似的操作。Junio C Hamano在这里写道:http://www.mail-archive.com/git@vger.kernel.org/msg03395.html
要在B中合并a:
1) 在项目A中
git fast-export --all --date-order > /tmp/ProjectAExport
2) 在项目B中
git checkout -b projectA
git fast-import --force < /tmp/ProjectAExport
在这个分支中,执行所有需要执行的操作并提交它们。
C) 然后回到主节点,两个分支之间进行经典合并:
git checkout master
git merge projectA
我知道事情已经过去很久了,但我对我在这里找到的其他答案并不满意,所以我写了这样一篇文章:
me=$(basename $0)
TMP=$(mktemp -d /tmp/$me.XXXXXXXX)
echo
echo "building new repo in $TMP"
echo
sleep 1
set -e
cd $TMP
mkdir new-repo
cd new-repo
git init
cd ..
x=0
while [ -n "$1" ]; do
repo="$1"; shift
git clone "$repo"
dirname=$(basename $repo | sed -e 's/\s/-/g')
if [[ $dirname =~ ^git:.*\.git$ ]]; then
dirname=$(echo $dirname | sed s/.git$//)
fi
cd $dirname
git remote rm origin
git filter-branch --tree-filter \
"(mkdir -p $dirname; find . -maxdepth 1 ! -name . ! -name .git ! -name $dirname -exec mv {} $dirname/ \;)"
cd ..
cd new-repo
git pull --no-commit ../$dirname
[ $x -gt 0 ] && git commit -m "merge made by $me"
cd ..
x=$(( x + 1 ))
done
git子树很好,但它可能不是您想要的。
例如,如果projectA是在B中创建的目录,在git子树之后,
git log projectA
仅列出一个提交:合并。合并项目的提交针对不同的路径,因此不会显示。
格雷格·休吉尔(Greg Hewgill)的答案最接近,但实际上并没有说明如何重写路径。
解决方案出奇地简单。
(1) 在A中,
PREFIX=projectA #adjust this
git filter-branch --index-filter '
git ls-files -s |
sed "s,\t,&'"$PREFIX"'/," |
GIT_INDEX_FILE=$GIT_INDEX_FILE.new git update-index --index-info &&
mv $GIT_INDEX_FILE.new $GIT_INDEX_FILE
' HEAD
注意:这将重写历史;你可能想先备份a。
注意Bene:如果在文件名或路径中使用非ascii字符(或白色字符),则必须修改sed命令中的替代脚本。在这种情况下,“ls files-s”生成的记录中的文件位置以引号开头。
(2) 然后在B中,运行
git pull path/to/A
瞧!在B中有一个projectA目录。如果运行git-log-projectA,您将看到a中的所有提交。
在我的例子中,我需要两个子目录,projectA和projectB。在这种情况下,我也执行了步骤(1)到B。
我遇到了类似的挑战,但在我的情况下,我们在回购协议a中开发了一个版本的代码库,然后将其克隆到新的回购协议B中,用于新版本的产品。修复了回购协议A中的一些错误后,我们需要将更改FI到回购协议B中
向指向回购a的回购B添加远程(git remote add…)拉动当前分支(我们没有使用master修复错误)(git pull-remoteForRepabugFixBranch)将合并推送到github
工作愉快:)