我想做点什么,在我发现的这篇邮件列表中描述得最好:
git档案: GIT覆盖库(unsw.edu.au)
从两个存储库开始,我们将它们命名为Repo和Repo。Repo托管在某个服务器上,包含大量代码(假设它是一个内核源代码存储库)。回购-B只是在回购-A已经提供的基础上添加了少量的修改(为了论证起见,假设是IPW2100和IPW2200项目)。 出于几个原因,我们希望用户能够从我那里得到回购A和回购B之间的区别。 例如,用户获得完整的Repo-A:. 然后覆盖在三角洲,他们从我那里得到:.
问题是,我只是找不到对这个概念的任何其他引用(另一件令搜索工作感到沮丧的事情是,Gentoo在其包管理器中有一个叫做"git“的东西;而TortoiseGIT有"overlay”图标)。线程本身似乎只有一个答复,是从2005年开始的,它建议引入“存储在覆盖存储库中的ancestors文件”,这可能从来没有在git中实现过。虽然那篇文章实际上包括了用来演示这个概念的bash脚本,但是它们直接基于rsync-ing .git内部,我对测试并不是很有信心。
我的问题是--是否有一种标准的方法(例如,使用git命令或在git上下文中调用的shell脚本)来实现这种操作?或者,我可以在Linux下使用一些“文件系统覆盖”技巧来达到这个目的吗?
我认为可以使用git子模块,但显然它们不能使用;我准备了一个小型bash脚本来测试:
#!/usr/bin/env bash
set -x
rm -rf repoM-git
mkdir repoM-git
cd repoM-git
git init
git config user.name "me"
git config user.email "my@self.com"
git submodule add https://github.com/defunkt/github-gem.git repo1
git submodule add https://gist.github.com/6462971.git repo2
git status
git commit -m "initial checkin"
cd repo1
git config user.name "me"
git config user.email "my@self.com"
SOMETAG=$(git tag --list | awk 'NR==4{print $0;}')
{ echo "Checking out $SOMETAG in repo1"; } 2>/dev/null
git checkout $SOMETAG
{ echo "Creating myhack branch"; } 2>/dev/null
git checkout -b myhack
{ echo "Attempting to change"; } 2>/dev/null
echo "AHOOOOOY" >> README
git add -u
git status
{ echo "Commiting in submodule repo1..."; } 2>/dev/null
git commit -m "first change"
git status
{ echo "Going back to main repoM"; } 2>/dev/null
cd ..
git add -u
git status
git diff --cached运行此脚本将在最后报告:
HEAD is now at b6df531... Bump the version to 0.1.3
Creating myhack branch
+ git checkout -b myhack
Switched to a new branch 'myhack'
Attempting to change
+ echo AHOOOOOY
+ git add -u
+ git status
# On branch myhack
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: README
#
Commiting in submodule repo1...
+ git commit -m 'first change'
[myhack 0e01195] first change
1 file changed, 1 insertion(+)
+ git status
# On branch myhack
nothing to commit (working directory clean)
Going back to main repoM
+ cd ..
+ git add -u
+ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: repo1
#
+ git diff --cached
diff --git a/repo1 b/repo1
index 8ef0c30..0e01195 160000
--- a/repo1
+++ b/repo1
@@ -1 +1 @@
-Subproject commit 8ef0c3087d2e5d1f6fe328c06974d787b47df423
+Subproject commit 0e01195675f2e1585cdbdffb9fffb3cca2e5f547这基本上证实了子模块是它自己的repo/work区域,它有自己的.git目录。;相反,我想要的是我的“主”存储库记录可能包含的对任何“子”存储库的更改。例如,在上面的示例中,我希望repoM不仅跟踪repo1中的标记'v0.1.3‘(即它是底层的SHA-1提交散列),而且还记录更改(或差异)本身,这个更改最初来自其他地方。使用子模块或其他方式可以这样做吗?
发布于 2015-02-02 18:13:55
Git已经非常适合您想要做的事情,即使没有任何扩展。
下面是使用存储库作为示例维护自己的上游存储库的分支的一种方法:
v1.12.4。从一个已知的状态开始工作总是一个好主意。hub的一个版本,因此在开始之前,我需要将master分支移动到v1.12.4标记:
git重置--硬v1.12.4master分支或您可能提交的任何新标记来检索源代码。因为提交A、B和C存在于您的存储库和上游存储库中,所以以前克隆了上游存储库的人可以简单地将您的更改获取到sdaau-master中。v1.12.4,但是当上游存储库发生更改时会发生什么呢?假设他们已经发布了一个新版本的v1.13,您也希望支持这个版本。
简单:只要git fetch upstream得到新的改变.
I-J-K上游/主/D-E
...and将它们与git merge v1.13合并到您的master分支中:
I-J-K上游/主/D-E-F-G-H标记:v1.13/\A-B--C标记:v1.12.4\1-2-3-4位大师这种办法的一些好处如下:
bundle、format-patch、apply和am。唯一真正的缺点是带宽,可以通过在GitHub、GitLab或Bitbucket这样的服务上托管存储库来缓解带宽问题。
发布于 2017-08-18 13:51:37
我也遇到了同样的情况,并在SE的其他地方找到了解决方案,我将尝试描述:
给定两个repos和目录结构:
project.git /full_project/sub文件夹/a.txt delta.git /a.txt
需要重定向.git目录:
CurrentDir=$PWD
git clone https://github.com/company/full_project.git full_project
git clone https://github.com/me/project_delta.git project_delta
echo "gitdir: ${PWD}/project_delta/.git" > ${PWD}/full_project/subfolder/.git现在在${PWD}/full_project/subfolder中运行a.txt给出了a.txt在project_delta中的“未实现”的变化
cd full_project/subfolder
git checkout .这应该可以做到--现在“更改”被重置为me/project_delta.git状态。
发布于 2022-03-28 21:42:35
有两个用例我可以想到:
在第一种情况下,我发现最简单的方法是将个人更改保存在半永久性的基础上,并在从上游提取最新变化后任意使用它们。
在第二种情况下,可以在单独的git存储库中签入其他更改并对其进行版本化,可以通过设置GIT_DIR =和GIT_WORK_TREE=来应用和更新这些更改,如下所示
GIT_DIR=$external_git_repo_dir GIT_WORK_TREE=$project_dir git状态
可以使用shell别名/函数/脚本来简化git操作。
https://stackoverflow.com/questions/28263766
复制相似问题