Git Subrepo

git-subrepo项目已经存在很长时间了,但是很少引用它。 git-subrepo的作者是IngydötNet


如果您查看该项目的master分支的提交历史,则该项目似乎在2年前就已停止开发。 但是,该项目的工作正在进行中,我希望0.4.0版能尽快发布。


该工具的一个重要属性是,在用户决定在子项目的上游存储库中进行提交之前,用户无需安装git-subrepo 。 此外,在使用标准git-clone(1)命令复制主存储库时,用户会收到准备充分并已配置好的源树。


在选择支持主容器存储库的子模块/子树/子项目的方法时,开发人员首先确定该机制提供的可能性范围,并给出以下问题的答案:


  • 是否有必要将子项目的完整历史记录保留在主存储库中,或者是否有足够的压缩提交;
  • 是否需要将更改从子项目传递到子树的上游存储库的能力;
  • 是否需要连接子项目上游存储库的固定标签,或者是否可以连接分支?
  • 是否有必要进一步删除这两个子项目本身,以及是否有必要删除这些子项目历史的一部分;
  • 克隆主项目的存储库后,用户是否必须采取任何措施手动配置子项目;
  • 分析连接子项目的历史以及子项目所源自的特定修订版本的工作量将是多么艰巨;
  • 该工具或该工具将如何影响“源配置管理”策略以及该工具将使工程师的日常工作复杂化的程度。

当然,这个问题清单不能反映正确选择所必需的输入参数的完整性 ,但是对于现有工具的初步审查来说,这已经足够了,就git-subrepo项目而言 ,我们敦促读者从这些角度考虑这个项目。


Git-subrepo安装


git-subrepo软件包 (在开发人员方面)既可以本地安装,也可以安装在其主目录中,也可以安装在系统级别。


在第一种情况下,将git-subrepo信息库克隆到所需目录就足够了,例如〜/ bin


bash-4.4$ cd ~/bin bash-4.4$ git clone https://github.com/ingydotnet/git-subrepo.git 

并设置环境变量


 bash-4.4$ vim subrepo-env.sh #!/bin/sh export GIT_SUBREPO_ROOT="/home/username/bin/git-subrepo" export PATH="/home/username/bin/git-subrepo/lib:$PATH" export MANPATH="/home/username/bin/git-subrepo/man:$MANPATH" :wq bash-4.4$ source ./subrepo-env.sh 

如果您查看git-subrepo Makefile中定义的变量:


 # Install variables: PREFIX ?= /usr/local INSTALL_LIB ?= $(DESTDIR)$(shell git --exec-path) INSTALL_EXT ?= $(INSTALL_LIB)/$(NAME).d INSTALL_MAN1 ?= $(DESTDIR)$(PREFIX)/share/man/man1 

很容易发现,在系统级别, git-subrepo安装在Git所在的目录中:


 bash-4.4$ bash-4.4$ git --exec-path /usr/libexec/git-core bash-4.4$ 

因此,用于安装git-subrepo的命令可能如下所示:


 bash-4.4$ make PREFIX=/usr install 

DESTDIR变量的存在使您无需付出额外的努力(当然,如果我们不在跨环境中)就可以为任何Linux 发行版制作软件包,这对于DevOps工程师而言非常有用。


以root身份安装git-subrepo


 bash-4.4$ bash-4.4$ cd git-subrepo/ bash-4.4$ make PREFIX=/usr install install -C -d -m 0755 /usr/libexec/git-core/ install -C -m 0755 lib/git-subrepo /usr/libexec/git-core/ install -C -d -m 0755 /usr/libexec/git-core/git-subrepo.d/ install -C -m 0755 lib/git-subrepo.d/help-functions.bash lib/git-subrepo.d/bash+.bash /usr/libexec/git-core/git-subrepo.d/ install -C -d -m 0755 /usr/share/man/man1/ install -C -m 0644 man/man1/git-subrepo.1 /usr/share/man/man1/ bash-4.4$ 

要分析git-subrepo的功能我们需要一个简单的测试环境,在其中可以重现标准操作方案。


测试环境


我们创建三个目录ownerremoteuser ,在其中放置开发人员和用户的上游和本地存储库的模型。


 bash-4.4$ vim _init.sh #!/bin/sh CWD=`pwd` mkdir remote owner user cd remote git init --bare build-system.git git init --bare platform.git cd ../owner git clone $CWD/remote/build-system.git git clone $CWD/remote/platform.git cd build-system echo -e "\n[master] build-system 1.0.0\n" >README git add README git commit -m "init build-system master 1.0.0" git push cd ../platform echo -e "\n[master] platform 1.0.0\n" >README git add README git commit -m "init platform master 1.0.0" git push cd ../../user git clone $CWD/remote/build-system.git git clone $CWD/remote/platform.git cd $CWD :wq bash-4.4$ bash-4.4$ ./_init.sh bash-4.4$ 


在这里


拥有者--项目作者的工作目录;
遥远的--代表项目作者服务器的目录,主项目platform.git和子项目build-system.git的上游存储库位于该目录中
使用者--用户或开发团队成员的工作目录。

项目的作者和用户在其计算机上拥有自己的上游存储库副本,在我们的示例中分别在所有者目录和用户目录中提供了副本。


作者的任务是通过在主树中包含builld-system子项目,在平台的主树中包括以下功能:


  • 用结构中包含的构建系统子项目克隆主存储库,不必担心设置版本或修订版。 也就是说, 平台存储库的每个分支都应对应于构建系统存储库的特定分支的特定版本,并且用户应在一个git-clone(1)操作中接收自定义的源树,而无需执行任何其他操作。
  • 将它们的更改交付到上游项目存储库,无论是在主项目库还是在辅助项目库中。
  • 当然,如果其他项目参与者或用户拥有适当的权利,则他们会收到更改。

考虑作者为实现这些要求必须执行的动作。


子项目连接


要连接新的子树,请使用git subrepo clone命令,该命令的用途类似于git-clone(1)命令。 该命令的必需参数是远程存储库的URL 。 您还可以指定子项目和远程存储库分支所在的目录。 我们将使用master分支,因此,在我们的示例中,我们省略了不必要的命令参数。


因此,项目的作者可以在其工作计算机上使用git subrepo clone ../../remote/build-system.git/ build-system命令连接构建系统子项目:


 bash-4.4$ bash-4.4$ cd owner/platform/ bash-4.4$ git subrepo clone ../../remote/build-system.git/ build-system Subrepo '../../remote/build-system.git' (master) cloned into 'build-system'. bash-4.4$ 

考虑一下本地平台存储库中发生了什么更改:


 bash-4.4$ bash-4.4$ git status On branch master Your branch is ahead of 'origin/master' by 1 commit. (use "git push" to publish your local commits) nothing to commit, working tree clean bash-4.4$ bash-4.4$ bash-4.4$ git subrepo status 1 subrepo: Git subrepo 'build-system': Remote URL: ../../remote/build-system.git Upstream Ref: b2f5079 Tracking Branch: master Pulled Commit: b2f5079 Pull Parent: b5e76a7 bash-4.4$ 

构建系统子项目的历史记录未传递到主树中;我们只有一个压缩的提交,并附带背景信息。 此信息受文件./build-system/.gitrepo/config中的版本控制:


 [subrepo] remote = ../../remote/build-system.git branch = master commit = b2f507918f2821cb7dd90c33223ed5cc3c9922a2 parent = b5e76a713f895565b06ee3ccfa29f19131ba06dd method = merge cmdver = 0.4.1 

可以使用git subrepo config命令获取有关子项目的信息,例如,使用以下命令找出刚刚到达主存储库的上游项目remote / build-system.git的修订版:


 bash-4.4$ bash-4.4$ git subrepo config build-system commit Subrepo 'build-system' option 'commit' has value 'b2f507918f2821cb7dd90c33223ed5cc3c9922a2'. bash-4.4$ 

应该提到的是,原始的git-subrepo软件包不会将有关子项目的信息保存在.gitrepo / config文件中,而是保存在.gitrepo文件中。

因此,我们获得了上游存储库remote / build-system.git的master分支的最新版本,并将其放在主平台项目的build-system子目录中。


要将这些更改传递到上游资源库remote / platform.git ,作者需要运行git push命令:


 bash-4.4$ bash-4.4$ git push Enumerating objects: 7, done. Counting objects: 100% (7/7), done. Delta compression using up to 4 threads Compressing objects: 100% (4/4), done. Writing objects: 100% (6/6), 849 bytes | 849.00 KiB/s, done. Total 6 (delta 0), reused 0 (delta 0) To /home/prog/0.4.1/remote/platform.git <font color="#8b0000">b5e76a7..6b831e4</font> master -> master bash-4.4$ 

可以从ReadMe.pod文件或在命令行中获取有关git subrepo命令的更多信息。


 bash-4.4$ git subrepo help <command> 

例如:


 bash-4.4$ git subrepo help clone 

现在考虑用户方面正在发生的事情。



用户获取代码


目前,当用户尚未收到上游存储库platform.git的更新时,其副本包含一个README文件。


 bash-4.4$ bash-4.4$ cd user/platform/ bash-4.4$ ls README bash-4.4$ 

包含一行:


 bash-4.4$ bash-4.4$ cat README [master] platform 1.0.0 bash-4.4$ 

中断上游存储库更改后


 bash-4.4$ bash-4.4$ git pull remote: Enumerating objects: 7, done. remote: Counting objects: 100% (7/7), done. remote: Compressing objects: 100% (4/4), done. remote: Total 6 (delta 0), reused 0 (delta 0) Unpacking objects: 100% (6/6), done. From /home/prog/0.4.1/remote/platform b5e76a7..6b831e4 master -> origin/master Updating <font color="#8b0000">b5e76a7..6b831e4</font> Fast-forward build-system/.gitrepo/config | 12 ++++++++++++ build-system/README | 3 +++ 2 files changed, 15 insertions(+) create mode 100644 build-system/.gitrepo/config create mode 100644 build-system/README bash-4.4$ 

用户将可以使用该版本的构建系统子项目的代码,该版本正是该项目的作者确定的。 用户可以随时使用config命令更新当前修订:


 bash-4.4$ bash-4.4$ git subrepo config build-system/ commit Subrepo 'build-system' option 'commit' has value 'b2f507918f2821cb7dd90c33223ed5cc3c9922a2'. bash-4.4$ 

值得注意的是,用户不需要进行其他设置,而他可以依靠项目的作者为他提供了当前平台正常工作所必需的构建系统修订版这一事实。


这正是该项目的作者所追求的。


将更改交付到上游项目


现在假设我们的用户是项目的成员,并且不仅可以将更改传递到上游存储库remote / platform.git ,而且还可以传递到remote / build-system.git子项目的上游存储库。


然后,如果用户进行更改:


 bash-4.4$ bash-4.4$ cd build-system/ bash-4.4$ vim README bash-4.4$ cat README [master] build-system 1.0.1 bash-4.4$ bash-4.4$ git commit -a -m "update BS version to 1.0.1" [master d30b001] update BS version to 1.0.1 1 file changed, 1 insertion(+), 1 deletion(-) bash-4.4$ bash-4.4$ cd .. bash-4.4$ git log commit d30b001286b08708f5c30c1f5346a90e4339f969 (HEAD -> master) Author: user <___@_____> Date: Tue Oct 30 10:49:32 2018 +0300 update BS version to 1.0.1 . . . bash-4.4$ 

他将能够将它们放置在上游存储库中,如下所示:


 bash-4.4$ bash-4.4$ git subrepo push build-system/ Subrepo 'build-system' pushed to '../../remote/build-system.git' (master). bash-4.4$ 

在这里重要的是要注意...

由于子项目.gitrepo / config的配置文件存储在版本控制下,因此用户需要将子项目的状态更改发送到主项目remote / platform.git的上游存储库。


也就是说,用户不应忘记检查本地存储库的状态并及时执行git-push(1)命令。


 bash-4.4$ bash-4.4$ git status On branch master Your branch is ahead of 'origin/master' by 2 commits. (use "git push" to publish your local commits) nothing to commit, working tree clean bash-4.4$ bash-4.4$ git push Enumerating objects: 14, done. Counting objects: 100% (14/14), done. Delta compression using up to 4 threads Compressing objects: 100% (7/7), done. Writing objects: 100% (9/9), 992 bytes | 992.00 KiB/s, done. Total 9 (delta 1), reused 0 (delta 0) To /home/prog/0.4.1/remote/platform.git d00be9f..deccb66 master -> master bash-4.4$ 

否则,下次您对上游存储库进行更改时,它将收到合并冲突。


当然,这里没有什么异常,但是,执行git subrepo push ...命令后,很容易忘记主存储库的本地副本的状态。




直接使用上游存储库


现在考虑上游存储库remote / build-system.git中发生的情况


 bash-4.4$ bash-4.4$ cd owner/build-system/ bash-4.4$ bash-4.4$ git pull remote: Enumerating objects: 5, done. remote: Counting objects: 100% (5/5), done. remote: Total 3 (delta 0), reused 0 (delta 0) Unpacking objects: 100% (3/3), done. From /home/prog/0.4.1/remote/build-system b2f5079..d229920 master -> origin/master Updating b2f5079..d229920 Fast-forward README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) bash-4.4$ bash-4.4$ git log commit d229920c7de34405bc7b8d47f36d420987687908 (HEAD -> master, origin/master) Author: user <___@_____> Date: Tue Oct 30 10:49:32 2018 +0300 update BS version to 1.0.1 commit b2f507918f2821cb7dd90c33223ed5cc3c9922a2 Author: user <___@_____> Date: Tue Oct 30 10:05:30 2018 +0300 init build-system master 1.0.0 bash-4.4$ 

也就是说,项目的作者收到了项目参与者所做的更改。


当然,作者可以直接对构建系统项目的上游存储库进行更改:


 bash-4.4$ bash-4.4$ cd owner/build-system/ bash-4.4$ bash-4.4$ vim README bash-4.4$ cat README [master] build-system 1.0.2 bash-4.4$ git commit -a -m "update build-system version to 1.0.2" [master 8255f59] update build-system version to 1.0.2 1 file changed, 1 insertion(+), 1 deletion(-) bash-4.4$ git push Enumerating objects: 5, done. Counting objects: 100% (5/5), done. Writing objects: 100% (3/3), 281 bytes | 281.00 KiB/s, done. Total 3 (delta 0), reused 0 (delta 0) To /home/prog/0.4.1/remote/build-system.git d229920..8255f59 master -> master bash-4.4$ 

所有参与者以及主项目的用户都可以使用git subrepo pull命令接收这些更改。


 bash-4.4$ bash-4.4$ cd owner/platform/ bash-4.4$ bash-4.4$ git subrepo pull build-system/ Subrepo 'build-system' pulled from '../../remote/build-system.git' (master). bash-4.4$ git status On branch master Your branch is ahead of 'origin/master' by 1 commit. (use "git push" to publish your local commits) nothing to commit, working tree clean bash-4.4$ git push Enumerating objects: 11, done. Counting objects: 100% (11/11), done. Delta compression using up to 4 threads Compressing objects: 100% (4/4), done. Writing objects: 100% (6/6), 670 bytes | 670.00 KiB/s, done. Total 6 (delta 1), reused 0 (delta 0) To /home/prog/0.4.1/remote/platform.git 6b831e4..b6f4a7b master -> master bash-4.4$ 

结论


如果开发人员不需要在主存储库中存储子项目的历史记录,并且在交付代码时,他使用分支而不是固定标签进行操作,那么git-subrepo非常适合组织日常工作。


有条件地, git-subrepo的缺点之一是git subrepo克隆操作仅在子项目分支上才是可能的。 换句话说,用户不能参考其固定标签或特定修订版来连接子项目,即,诸如


 bash-4.4$ git subrepo clone ../../remote/build-system.git build-system -t 1.0.1 bash-4.4$ git subrepo clone ../../remote/build-system.git build-system 7f5d1113eb0bc6 

无效。


文学作品:


Source: https://habr.com/ru/post/zh-CN428493/


All Articles