我在一个名为XXX的文件夹中有一个Git存储库,还有一个名为YYY的Git存储库。
我想将XXX存储库作为名为ZZZ的子目录导入到YYY存储库中,并将所有XXX的更改历史添加到YYY中。
之前的文件夹结构:
├── XXX
│ ├── .git
│ └── (project files)
└── YYY
├── .git
└── (project files)
文件夹结构后:
YYY
├── .git <-- This now contains the change history from XXX
├── ZZZ <-- This was originally XXX
│ └── (project files)
└── (project files)
这可以做到吗,或者我必须使用子模块?
我可以为你的问题建议另一个解决方案(替代git-submodules) - gil (git链接)工具
它允许描述和管理复杂的git存储库依赖关系。
同时也为git递归子模块依赖问题提供了解决方案。
假设你有以下项目依赖项:
示例git存储库依赖关系图
然后你可以用存储库关系描述定义.gitlinks文件:
# Projects
CppBenchmark CppBenchmark https://github.com/chronoxor/CppBenchmark.git master
CppCommon CppCommon https://github.com/chronoxor/CppCommon.git master
CppLogging CppLogging https://github.com/chronoxor/CppLogging.git master
# Modules
Catch2 modules/Catch2 https://github.com/catchorg/Catch2.git master
cpp-optparse modules/cpp-optparse https://github.com/weisslj/cpp-optparse.git master
fmt modules/fmt https://github.com/fmtlib/fmt.git master
HdrHistogram modules/HdrHistogram https://github.com/HdrHistogram/HdrHistogram_c.git master
zlib modules/zlib https://github.com/madler/zlib.git master
# Scripts
build scripts/build https://github.com/chronoxor/CppBuildScripts.git master
cmake scripts/cmake https://github.com/chronoxor/CppCMakeScripts.git master
每一行描述git链接的格式如下:
存储库的唯一名称
存储库的相对路径(从.gitlinks文件的路径开始)
Git存储库,将用于Git克隆命令
要检出的存储库分支
空行或以#开头的行不会被解析(作为注释处理)。
最后,你必须更新你的根示例库:
# Clone and link all git links dependencies from .gitlinks file
gil clone
gil link
# The same result with a single command
gil update
因此,您将克隆所有必需的项目,并以适当的方式将它们相互链接。
如果你想提交一些存储库中的所有更改,以及子链接存储库中的所有更改,你可以用一个命令来完成:
gil commit -a -m "Some big update"
Pull、push命令的工作原理类似:
gil pull
gil push
Gil (git链接)工具支持以下命令:
usage: gil command arguments
Supported commands:
help - show this help
context - command will show the current git link context of the current directory
clone - clone all repositories that are missed in the current context
link - link all repositories that are missed in the current context
update - clone and link in a single operation
pull - pull all repositories in the current directory
push - push all repositories in the current directory
commit - commit all repositories in the current directory
更多关于git递归子模块的依赖问题。
我当时在找-s他们的,当然,这个策略不存在。我的历史是我在GitHub上分叉了一个项目,现在由于某种原因,我的本地master不能与上游/master合并,尽管我没有对这个分支做任何本地更改。(真的不知道那里发生了什么——我猜上游在幕后做了一些肮脏的推动,可能吧?)
我最后做的是
# as per https://help.github.com/articles/syncing-a-fork/
git fetch upstream
git checkout master
git merge upstream/master
....
# Lots of conflicts, ended up just abandonging this approach
git reset --hard # Ditch failed merge
git checkout upstream/master
# Now in detached state
git branch -d master # !
git checkout -b master # create new master from upstream/master
所以现在我的master再次与upstream/master同步(你可以对任何其他分支重复上面的步骤,你也想进行类似的同步)。
简单的方法是使用git format-patch。
假设我们有两个git存储库foo和bar。
foo包含:
福.txt
。去
栏包含:
酒吧.txt
。去
我们希望以foo结束,其中包含bar历史记录和这些文件:
foo . txt。
git。
雷丁酒吧。. txt。
要做到这一点:
1. create a temporary directory eg PATH_YOU_WANT/patch-bar
2. go in bar directory
3. git format-patch --root HEAD --no-stat -o PATH_YOU_WANT/patch-bar --src-prefix=a/foobar/ --dst-prefix=b/foobar/
4. go in foo directory
5. git am PATH_YOU_WANT/patch-bar/*
如果我们想重写所有从bar提交的消息,我们可以这样做,例如在Linux上:
git filter-branch --msg-filter 'sed "1s/^/\[bar\] /"' COMMIT_SHA1_OF_THE_PARENT_OF_THE_FIRST_BAR_COMMIT..HEAD
这将在每条提交消息的开头添加“[bar]”。
下面是脚本,将立即工作。
#!/bin/bash -xe
# script name: merge-repo.sh
# To merge repositories into the current.
# To see the log of the new repo use 'git log --follow -- unprefixed-filename'
# So if the file is repo/test.cpp use 'git log --follow -- test.cpp'
# I'm not sure how this will work when two files have the same name.
#
# `git branch -a` will show newly created branches.
# You can delete them if you want.
merge_another() {
repo="$1" # url of the remote repo
rn="$2" # new name of the repo, you can keep the same name as well.
git remote add ${rn} ${repo}
git fetch ${rn}
git merge -s ours --no-commit --allow-unrelated-histories ${rn}/master
git read-tree --prefix=${rn}/ -u ${rn}/master
git commit -m "Imported ${rn} as a subtree."
git pull -s subtree ${rn} master
}
merge_another $1 $2
运行脚本。转到您希望合并另一个repo的repo,并运行脚本。
cd base-repo
./merge-repo.sh git@github.com:username/repo-to-be-merged.git repo-to-be-merged-new-name
现在将主分支上的更改推到remote/origin。根据您要做的事情,可能不需要此步骤。
git push origin master
我可以为你的问题建议另一个解决方案(替代git-submodules) - gil (git链接)工具
它允许描述和管理复杂的git存储库依赖关系。
同时也为git递归子模块依赖问题提供了解决方案。
假设你有以下项目依赖项:
示例git存储库依赖关系图
然后你可以用存储库关系描述定义.gitlinks文件:
# Projects
CppBenchmark CppBenchmark https://github.com/chronoxor/CppBenchmark.git master
CppCommon CppCommon https://github.com/chronoxor/CppCommon.git master
CppLogging CppLogging https://github.com/chronoxor/CppLogging.git master
# Modules
Catch2 modules/Catch2 https://github.com/catchorg/Catch2.git master
cpp-optparse modules/cpp-optparse https://github.com/weisslj/cpp-optparse.git master
fmt modules/fmt https://github.com/fmtlib/fmt.git master
HdrHistogram modules/HdrHistogram https://github.com/HdrHistogram/HdrHistogram_c.git master
zlib modules/zlib https://github.com/madler/zlib.git master
# Scripts
build scripts/build https://github.com/chronoxor/CppBuildScripts.git master
cmake scripts/cmake https://github.com/chronoxor/CppCMakeScripts.git master
每一行描述git链接的格式如下:
存储库的唯一名称
存储库的相对路径(从.gitlinks文件的路径开始)
Git存储库,将用于Git克隆命令
要检出的存储库分支
空行或以#开头的行不会被解析(作为注释处理)。
最后,你必须更新你的根示例库:
# Clone and link all git links dependencies from .gitlinks file
gil clone
gil link
# The same result with a single command
gil update
因此,您将克隆所有必需的项目,并以适当的方式将它们相互链接。
如果你想提交一些存储库中的所有更改,以及子链接存储库中的所有更改,你可以用一个命令来完成:
gil commit -a -m "Some big update"
Pull、push命令的工作原理类似:
gil pull
gil push
Gil (git链接)工具支持以下命令:
usage: gil command arguments
Supported commands:
help - show this help
context - command will show the current git link context of the current directory
clone - clone all repositories that are missed in the current context
link - link all repositories that are missed in the current context
update - clone and link in a single operation
pull - pull all repositories in the current directory
push - push all repositories in the current directory
commit - commit all repositories in the current directory
更多关于git递归子模块的依赖问题。