{"id":26129067,"url":"https://github.com/zyestin/mainrepodemo","last_synced_at":"2026-04-11T21:41:06.542Z","repository":{"id":199405081,"uuid":"702798232","full_name":"zyestin/MainRepoDemo","owner":"zyestin","description":"多个仓库共享某一模块/代码/仓库 各方案实操对比","archived":false,"fork":false,"pushed_at":"2023-11-20T10:16:52.000Z","size":95,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-08-03T19:44:41.768Z","etag":null,"topics":["git","submodule","subtree"],"latest_commit_sha":null,"homepage":"https://github.com/zyestin/MainRepoDemo","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zyestin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-10-10T03:24:38.000Z","updated_at":"2023-10-12T03:48:40.000Z","dependencies_parsed_at":null,"dependency_job_id":"3a22c0d3-937b-4998-ab08-f04da8bf26f2","html_url":"https://github.com/zyestin/MainRepoDemo","commit_stats":null,"previous_names":["zyestin/mainrepodemo"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/zyestin/MainRepoDemo","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zyestin%2FMainRepoDemo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zyestin%2FMainRepoDemo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zyestin%2FMainRepoDemo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zyestin%2FMainRepoDemo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zyestin","download_url":"https://codeload.github.com/zyestin/MainRepoDemo/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zyestin%2FMainRepoDemo/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31696743,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-11T21:17:31.016Z","status":"ssl_error","status_checked_at":"2026-04-11T21:17:24.556Z","response_time":54,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["git","submodule","subtree"],"created_at":"2025-03-10T19:37:19.513Z","updated_at":"2026-04-11T21:41:06.515Z","avatar_url":"https://github.com/zyestin.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 多个仓库 如何 共享某一模块/代码/仓库\nHow do multiple repos share dir/code/module/repo, some solutions as below:\n* git subtree  \n  一般不可忍受：子仓库的记录，一旦被主仓库拉取，子仓历史commit记录全都进入主仓；未来在本地主仓更改了子仓代码，在主仓提交后，然后同步到子仓远端，这样的正常操作，主仓的commit其实融合了子仓的代码改动的，显得混乱。而submodule就很纯粹，子仓的更新commit永远在子仓， 主仓仅仅是指定选用子仓的某个commit拉取过来用而已，父子联系上仅仅一个commit号即可。\n* git fetch \u0026\u0026 checkout方式 merge 子仓库代码 到 主仓库指定的目录  \n  很强不可忍受点：与手动从子仓库拷贝代码到主仓库方式一样，这些diff，又会出现在主仓库 又需要重新在主仓库commit。。。\n* soft link (电脑上建立目录软链)  \n  较强不可忍受点：.gitignore是忽略了主仓库中的 子仓库的所有代码的，相当于远端代码库 缺了这一块，然而，连这块的关联信息 该如何解决？ \n  一般不可忍受点：在VSC主仓库修改了子仓库代码，（可以忍受：需要去真正的子仓库去提交代码），就必然会多开一个子仓库窗口 进行git操作。\n* git submodule  \n  需要注意地方：在主仓库中修改子仓库，通过命令先提交子仓库代码，再提交主仓库代码。认为这是顺理成章的，因为子仓库代码改动，本该独立更新\n  \u003e 越来越觉得，这是软链的增强版\n  \u003e 1. 主仓库远端，缺失的子仓库这一块，但`.gitmodule`能表示与具体子仓库的关联关系\n  \u003e 2. 在VSC主仓库修改了子仓库代码，可以在主仓库，打包几个命令，做到在主仓库直接维护子仓库。\n* multiple workspace  \n  暂未实践\n\n## dir structure \u0026\u0026 description\n\n```\n├── README.md                 当前文件\n└── app                       应用代码目录\n    ├── base_shared           基础设施代码 **与其它项目可共享的**\n    │   ├── components\n    │   │   └── list\n    │   │       └── base.js\n    │   └── utils\n    │       └── theme\n    │           └── index.js\n    ├── common                 常用组件、工具代码  非共享的、MainRepoDemo才会用到的\n    │   ├── components\n    │   │   └── navigationBar\n    │   │       └── index.js\n    │   └── utils\n    │       └── time\n    │           └── index.js\n    └── modules                模块集合，存放MainRepoDemo用到的各业务模块 \n        ├── graphic_shared     graphic模块 **共享自(来自于)其他项目**\n        └── home\n            └── index.js\n```\n\n\n## 方式1： git subtree 合并某仓库 ~~的指定目录~~ 到 另一仓库的指定目录\n\n### 尝试 指定子仓库的指定目录\n* 添加 [GraphicRepoDemo](https://github.com/zyestin/GraphicRepoDemo) 仓库作为远程仓库，以便后续使用它的内容\n```\ngit remote add graphicproject-remote git@github.com:zyestin/GraphicRepoDemo.git\n```\n\nsourceTree效果图\n\u003cimg width=\"914\" alt=\"image\" src=\"https://github.com/zyestin/MainRepoDemo/assets/51897571/464c765f-bdbf-44b0-ac14-e4eab1abfc91\"\u003e\n\n* 使用 Git subtree 将 \"[GraphicRepoDemo](https://github.com/zyestin/GraphicRepoDemo)\" 的 \"app/modules/graphic_shared\" 目录合并到 \"MainRepoDemo\" 仓库的相同路径下。运行以下命令：\n```\ngit subtree add --prefix=app/modules/graphic_shared graphicproject-remote master --squash\n```\n但结果却是 把`GraphicRepoDemo`全部代码 合并到了 `MainRepoDemo`的\"app/modules/graphic_shared\" 目录下。 确实做到了commit信息继续，而不产生新的commit信息\n\u003cimg width=\"1202\" alt=\"image\" src=\"https://github.com/zyestin/MainRepoDemo/assets/51897571/e873343a-7f56-4eb3-84d7-f239e4980c12\"\u003e\n\n既然希望commit信息继续保留（**范围是整个GraphicRepoDemo仓库**） 而不会产生新的commit，又希望指定仓库中的一个子目录\"app/modules/graphic_shared\"（**范围并不是整个仓库**）来merge，看来本该就是做不到了，不管用不用`subtree`\n\n于是，需要将`graphic_shared`单独作为一个仓库，供`MainRepoDemo`和`GraphicRepoDemo`用subtree方式享用，即可~\n\n### 尝试 将子目录抽出来作为单独子仓库 去作为整体共享\n\n* 将`GraphicRepoDemo`下\"app/modules/graphic_shared\"内的文件转移到 [GraphicRepo](https://github.com/zyestin/GraphicRepo)\n\n* 删掉`MainRepoDemo`和`GraphicRepoDemo`下\"app/modules/graphic_shared\"\n\n拿[MainRepoDemo](https://github.com/zyestin/MainRepoDemo)试一试\n* 移除`MainRepoDemo`之前的subtree \n```\ngit remote remove graphicproject-remote\n```\n\n* 为`MainRepoDemo`添加子仓库\n```\ngit remote add graphicrepo git@github.com:zyestin/GraphicRepo.git\ngit subtree add --prefix=app/modules/graphic_shared graphicrepo main --squash\n```\n这样，\n\n* 在父仓库`MainRepoDemo`中更新了子仓库中的内容，同步到子仓库\n```\n//先提交父仓库\ngit add\ngit commit\n\n//再提交到子仓库\ngit subtree push --prefix=app/modules/graphic_shared graphicrepo main          \ngit push using:  graphicrepo main\nEnumerating objects: 55, done.\nCounting objects: 100% (55/55), done.\nDelta compression using up to 8 threads\nCompressing objects: 100% (42/42), done.\nWriting objects: 100% (50/50), 7.40 KiB | 2.47 MiB/s, done.\nTotal 50 (delta 10), reused 0 (delta 0), pack-reused 0\nremote: Resolving deltas: 100% (10/10), completed with 1 local object.\nTo github.com:zyestin/GraphicRepo.git\n   0cb8da2..ff099bb  ff099bbbc7ac3939ec0073f1bdc302fa4f5bfc26 -\u003e main\n```\n可以看到子仓库，有许多待拉取的，吓人\n\u003cimg width=\"1269\" alt=\"image\" src=\"https://github.com/zyestin/MainRepoDemo/assets/51897571/6b73e49d-531b-45af-bd0e-c703bd70da90\"\u003e\n\n\u003e 注：应该是某种操作导致，正常使用不会这样(吓人情况 主仓一堆commit记录跑到子仓去了)。 正常情况下，在本地主仓更改了子仓，提交主仓后，若同步到子仓，仅仅只是从主仓中挑出属于子仓代码 进行合并提交到子仓远端。\n\n* 子仓库 pull\n可以看到，在父仓库对子仓库做的修改，已经同步过来了\n\u003cimg width=\"1087\" alt=\"image\" src=\"https://github.com/zyestin/MainRepoDemo/assets/51897571/c9ef0ec3-7823-4bf6-94b3-aa97fa72ccb8\"\u003e\n\n可见，虽然在父仓库对子仓库做的修改后 可以通过`subtree push`将更改同步到子仓库，但是 **子仓库的commit信息，竟然被污染了！！！**\n\n\n## 方式2：`git fetch \u0026\u0026 checkout`方式merge\n执行如下命令\n```\ngit fetch graphicproject-remote\ngit checkout graphicproject-remote/main -- app/modules/graphic_shared\n```\n类似于手动 从`GraphicRepoDemo`把\"app/modules/graphic_shared\"拷贝，黏贴到`MainRepoDemo`的该目录\n\n\n## 方式3：软链\n在本地`MainRepoDemo`的\"app/modules/graphic_shared\"，通过软链指向`GraphicRepoDemo`的\"app/modules/graphic_shared\"\n\n注意：`.gitignore`中需要忽略\"app/modules/graphic_shared\"，防止提交了这个软链空壳文件上去\n\n## 方式4：git submodule \n拿[GraphicRepoDemo](https://github.com/zyestin/MainRepoDemo)试一试 往里面关联 一个新的子仓库[Graphic2Repo](https://github.com/zyestin/Graphic2Repo)\n\n### 往`GraphicRepoDemo`的\"app/modules/graphic_shared\"目录，拉取子仓库`Graphic2Repo`代码\n```\npwd                                 \n/Users/yestin/Desktop/gitfiles/RepoShare/GraphicRepoDemo\n\ngit submodule add git@github.com:zyestin/Graphic2Repo.git app/modules/graphic_shared\n```\n\u003cimg width=\"1146\" alt=\"image\" src=\"https://github.com/zyestin/MainRepoDemo/assets/51897571/3e16d68f-7b7f-41f4-9023-ee34578df4a5\"\u003e\n`git submodule add`这个关联操作，只会新增两个改动`.gitmodules`、`app/modules/graphic_shared` （而不会将`graphic_shared`内部的各个文件都作为新增改动）\n\n实际的`app/modules/graphic_shared`目录下的文件，是与 子仓库`Graphic2Repo`代码 一致的\n\u003cimg width=\"856\" alt=\"image\" src=\"https://github.com/zyestin/MainRepoDemo/assets/51897571/d8fbbc33-4375-4002-b711-a42c96a70e68\"\u003e\n\n\n### 子仓库`Graphic2Repo`代码更新，更新 父仓库`GraphicRepoDemo`的\"app/modules/graphic_shared\"目录代码\n```\ngit submodule update --remote app/modules/graphic_shared\nSubmodule path 'app/modules/graphic_shared': checked out '68e524d1b15e3d678a094e83e6a02d3cb8116fc8'\n```\n`git status`变化：仅`app/modules/graphic_shared`的`commit id`变化了\n\u003cimg width=\"509\" alt=\"image\" src=\"https://github.com/zyestin/MainRepoDemo/assets/51897571/8ea4787a-2113-4942-8a1b-8bcbd6eb7307\"\u003e\n\n实际代码变化：父仓库`app/modules/graphic_shared`内代码与子仓库一致了\n\u003cimg width=\"884\" alt=\"image\" src=\"https://github.com/zyestin/MainRepoDemo/assets/51897571/b16cec7d-1507-46c4-ae1f-f7b8002a17e8\"\u003e\n\n### 在父仓库更改子仓库代码，将改动更新到子仓库远端\n* 更改代码，保存\n    * 更改前  \n    \u003cimg width=\"400\" alt=\"image\" src=\"https://github.com/zyestin/MainRepoDemo/assets/51897571/88d7e35c-3002-4d1d-bebc-52f9743f1d86\"\u003e  \n    * 更改后  \n    \u003cimg width=\"400\" alt=\"image\" src=\"https://github.com/zyestin/MainRepoDemo/assets/51897571/2dfb4f85-e367-466d-b904-a9b9cb0bda79\"\u003e  \n发现，此时仅子仓库的`git status`有变化。\n\u003e 对比subtree 就会发现在主仓库也发现代码变更信息，那么用subtree就明显不合适了\n\u003e  \u003cimg width=\"452\" alt=\"image\" src=\"https://github.com/zyestin/MainRepoDemo/assets/51897571/a1ab3d69-fae2-4662-a4aa-1d5a94591f72\"\u003e\n\n* commit\n```\ncd app/modules/graphic_shared\ngit add .\ngit commit -m \"test: 在父仓库更改子仓库代码，更新远端子仓库代码\"\n```\ncommit后，父仓库下`git status`就有变化了，`app/modules/graphic_shared`的`commit id`变化了\n\u003cimg width=\"484\" alt=\"image\" src=\"https://github.com/zyestin/MainRepoDemo/assets/51897571/80a80098-91a4-4f2f-9b9c-31258d2248f8\"\u003e\n\n* push 子仓库的改动同步到远端子仓库\n  * 通过命令\n    ```\n    cd app/modules/graphic_shared\n    //... add commit ... 可直接在VSC操作\n    git push origin HEAD:graphic2-remote       //可以指定 main 或别的 远程分支\n    Enumerating objects: 10, done.\n    Counting objects: 100% (10/10), done.\n    Delta compression using up to 8 threads\n    Compressing objects: 100% (4/4), done.\n    Writing objects: 100% (6/6), 629 bytes | 629.00 KiB/s, done.\n    Total 6 (delta 2), reused 0 (delta 0), pack-reused 0\n    remote: Resolving deltas: 100% (2/2), completed with 1 local object.\n    To github.com:zyestin/Graphic2Repo.git\n       16b612c..0833e03  HEAD -\u003e graphic2-remote\n    ```\n    下图可见，子仓库的git log非常纯粹，commit 都是子仓库代码改动信息\n    \u003cimg width=\"1014\" alt=\"image\" src=\"https://github.com/zyestin/MainRepoDemo/assets/51897571/06835f74-5d71-4863-8fab-e1e51e8c0adc\"\u003e\n  * 通过VSC也可以push子仓库代码\n    \u003cimg width=\"1340\" alt=\"image\" src=\"https://github.com/zyestin/MainRepoDemo/assets/51897571/81d10634-660e-4953-8411-ea63f5310524\"\u003e\n    \u003e VSC push后，确实子仓库远端ok了\n    \u003e \u003cimg width=\"1276\" alt=\"image\" src=\"https://github.com/zyestin/MainRepoDemo/assets/51897571/7e0442c0-d856-4b2a-94ea-3b2e6d920ae9\"\u003e\n\n\u003e 一般`git push`前还是先`git pull`一次，以免他人push了，就会报如下错误  \n\u003e 报这个错的话，就执行`git config pull.rebase false`，然后再`pull`\n```\ngit pull origin graphic2-remote\nFrom github.com:zyestin/Graphic2Repo\n * branch            graphic2-remote -\u003e FETCH_HEAD\nhint: You have divergent branches and need to specify how to reconcile them.\nhint: You can do so by running one of the following commands sometime before\nhint: your next pull:\nhint: \nhint:   git config pull.rebase false  # merge\nhint:   git config pull.rebase true   # rebase\nhint:   git config pull.ff only       # fast-forward only\nhint: \nhint: You can replace \"git config\" with \"git config --global\" to set a default\nhint: preference for all repositories. You can also pass --rebase, --no-rebase,\nhint: or --ff-only on the command line to override the configured default per\nhint: invocation.\n```\n\n### 多人协作 在主仓拉取子仓代码\n\n* 对于首次，直接操作`submodule update` ?  不，首次需要先操作`git submodule update --init`  \n  他人首次拉取[GraphicRepoDemo](https://github.com/zyestin/GraphicRepoDemo)后，会发现`app/modules/graphic_shared`目录下的代码是空的，看来需要额外的操作去同步这块代码\n```\ngit submodule update --init --recursive                15:30:27\nSubmodule 'app/modules/graphic_shared' (git@github.com:zyestin/Graphic2Repo.git) registered for path 'app/modules/graphic_shared'\nCloning into '/Users/yestin/Desktop/gitfiles/RepoShare/GraphicRepoDemo2/app/modules/graphic_shared'...\nSubmodule path 'app/modules/graphic_shared': checked out '6ee3837c117a0f9b2696f3f0b3099ff21333b235'\n```\n操作完`git submodule update --init --recursive` 发现`app/modules/graphic_shared`目录下的代码已经同步过来了\n\u003cimg width=\"1161\" alt=\"image\" src=\"https://github.com/zyestin/MainRepoDemo/assets/51897571/46239afe-e019-4ec3-9ffb-c742beb7648b\"\u003e\n\n\u003e 直接操作，会出现什么问题呢？会有如下提示\n```\ngit submodule update --remote app/modules/graphic_shared\nSubmodule path 'app/modules/graphic_shared' not initialized\nMaybe you want to use 'update --init'?\n```\n\n* 非首次，操作`git submodule update --remote app/modules/graphic_shared`\n    * 当一个同事更新了 子仓库[Graphic2Repo](https://github.com/zyestin/Graphic2Repo) 其他同事如何感知呢？  \n    使用sourcetree的同事，在主仓库是感知不到有未pull的commit的，（VSC本来就不支持提示有N个待pull的commit）\n    此时可以打开VSC的`commit graph`可视化窗口，能看出是否有待pull的commit，如下图\n    \u003cimg width=\"1230\" alt=\"image\" src=\"https://github.com/zyestin/MainRepoDemo/assets/51897571/886ea7f5-8844-4474-9ebc-b53825ce7175\"\u003e\n    * 执行 在主仓库拉取子仓库代码\n```\ngit submodule update --remote app/modules/graphic_shared\nSubmodule path 'app/modules/graphic_shared': checked out '3ab3f32779995d68522878d563dfb63bfbd5f2ab'\n```\n\u003e 本以为 .gitmodule文件中记录了 `path = app/modules/graphic_shared`，以为直接执行`git submodule update`，不用指定路径了，\n\u003e 但依然需要执行完整的`git submodule update --remote app/modules/graphic_shared`\n\n### 多人协作 子仓库多人次修改和提交\n\n* 没有冲突时  \n在主仓改子仓，commit但不push；  \n在子仓改，commit且push\n\u003cimg width=\"1521\" alt=\"image\" src=\"https://github.com/zyestin/MainRepoDemo/assets/51897571/d86ebc33-a80d-4040-9464-762ffd17ea1a\"\u003e\n然后，在主仓先pull后push，即点击`Sync Changes`\n\u003cimg width=\"1127\" alt=\"image\" src=\"https://github.com/zyestin/MainRepoDemo/assets/51897571/d0731390-59db-4f74-b4df-ea8758a768c4\"\u003e\n会报错一次，如下，执行一次`git config pull.rebase false`就好了，以后`Sync Changes`将不再被中断，直接会进行merge\n```\nhint: You have divergent branches and need to specify how to reconcile them.\n...\n```\nVSC 通过`Sync Changes`执行 pull \u0026\u0026 push后，本地、远程子仓库更新成功\n\u003cimg width=\"1363\" alt=\"image\" src=\"https://github.com/zyestin/MainRepoDemo/assets/51897571/d3f9f9d2-b976-4b15-93bd-6a52a25719f3\"\u003e\n\n* 有冲突时\nVSC操作`Sync Changes`后，正常走熟悉的merge流程，标记出了冲突代码\n\u003cimg width=\"1204\" alt=\"image\" src=\"https://github.com/zyestin/MainRepoDemo/assets/51897571/829fb90c-ba72-475d-862b-627b904016f5\"\u003e\n然后，修复掉冲突代码，操作 `stage`、`commit`、`Sync Changes`就可以了\n\n\n## 参考\n* [Subtree 与 Submodule](https://gb.yekai.net/concepts/subtree-vs-submodule)\n\u003e commit: 父仓库直接提交父子仓库目录里的变动。若修改了子仓库的文件，则需要执行 subtree push\n\n* [Git subtree用法与常见问题分析](https://zhuanlan.zhihu.com/p/253148857)\n\u003e 四个方案个人认为的排序是subtree = submodule \u003e dll \u003e npm\n\n* GPT 对比 subtree与submodule\n\u003e ![image](https://github.com/zyestin/MainRepoDemo/assets/51897571/50b20661-707c-46b7-93b7-a76547e13878)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzyestin%2Fmainrepodemo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzyestin%2Fmainrepodemo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzyestin%2Fmainrepodemo/lists"}