首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >git "overlays“的可能性(仅将差异存储到本地存储库中的外部存储库)?

git "overlays“的可能性(仅将差异存储到本地存储库中的外部存储库)?
EN

Stack Overflow用户
提问于 2015-02-01 14:28:00
回答 3查看 5.9K关注 0票数 11

我想做点什么,在我发现的这篇邮件列表中描述得最好:

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脚本来测试:

代码语言:javascript
复制
#!/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

运行此脚本将在最后报告:

代码语言:javascript
复制
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提交散列),而且还记录更改(或差异)本身,这个更改最初来自其他地方。使用子模块或其他方式可以这样做吗?

EN

回答 3

Stack Overflow用户

发布于 2015-02-02 18:13:55

Git已经非常适合您想要做的事情,即使没有任何扩展。

下面是使用存储库作为示例维护自己的上游存储库的分支的一种方法:

  1. 克隆上游存储库并重命名其远程. git克隆git@github.com:github/hub.git远程重命名 此时,我的存储库将如下所示: D 请注意,我在图表中包含了最近的标记v1.12.4。从一个已知的状态开始工作总是一个好主意。
  2. 进入一个已知的状态。 我将使用hub的一个版本,因此在开始之前,我需要将master分支移动到v1.12.4标记: git重置--硬v1.12.4
  3. 做了一些修改. 过一段时间后,我的存储库现在看起来可能如下所示: D-E上游/主/A-B-C标记:v1.12.4\1-2-3主
  4. 发布. 只要准备就绪,用户就可以使用您的master分支或您可能提交的任何新标记来检索源代码。因为提交ABC存在于您的存储库和上游存储库中,所以以前克隆了上游存储库的人可以简单地将您的更改获取到sdaau-master中。
  5. 更新. 您的更改相对于标记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位大师
  6. Rinse和重复. N--O上游/主/i--J--K--L--M标签:v1.13.1/\D--E--F--G--H标签:V1.13 \/\A--B--C标记:v1.12.4\1--2-35

这种办法的一些好处如下:

  • 在所有这些过程中,您的更改都保留在您自己的分支中,当然,您可以创建您自己的分支中的任意多个分支,并标记您想要的多少个版本。根据项目的复杂性,这可能是个好主意。
  • 您的工作仍然链接到上游存储库。您可以在更新上游项目时更新您的代码,并且其他用户可以很容易地进行更改。
  • 您可以向上游贡献。这种配置还允许您很容易地向上游项目提交补丁。您可以通过GitHub“叉”来完成这一任务,使用它们的专用拉请求,或者使用标准的Git命令,如bundleformat-patchapplyam
  • 显式关系。查看网络图,很明显您的工作是您自己的,并且它是基于上游项目的。

唯一真正的缺点是带宽,可以通过在GitHub、GitLab或Bitbucket这样的服务上托管存储库来缓解带宽问题。

票数 6
EN

Stack Overflow用户

发布于 2017-08-18 13:51:37

我也遇到了同样的情况,并在SE的其他地方找到了解决方案,我将尝试描述:

给定两个repos和目录结构:

project.git /full_project/sub文件夹/a.txt delta.git /a.txt

需要重定向.git目录:

代码语言:javascript
复制
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.txtproject_delta中的“未实现”的变化

代码语言:javascript
复制
cd full_project/subfolder
git checkout .

这应该可以做到--现在“更改”被重置为me/project_delta.git状态。

票数 0
EN

Stack Overflow用户

发布于 2022-03-28 21:42:35

有两个用例我可以想到:

  • 您自己的更改从上游修改现有代码;或
  • 您自己的更改会添加代码(用于安装env、运行等的实用工具)

在第一种情况下,我发现最简单的方法是将个人更改保存在半永久性的基础上,并在从上游提取最新变化后任意使用它们。

在第二种情况下,可以在单独的git存储库中签入其他更改并对其进行版本化,可以通过设置GIT_DIR =和GIT_WORK_TREE=来应用和更新这些更改,如下所示

GIT_DIR=$external_git_repo_dir GIT_WORK_TREE=$project_dir git状态

可以使用shell别名/函数/脚本来简化git操作。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28263766

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档