合作开发git仓库同步方案

方案1:使用 Git 的补丁(patch)功能

  1. 首先,在一个仓库中生成补丁文件:在一个仓库中,使用 git diff 命令生成表示该仓库更改的补丁文件。例如,假设有仓库A和仓库B,想将A的更改应用到B中。在仓库A中,执行以下命令生成补丁文件:
git diff > mypatch.patch

这将生成一个名为 mypatch.patch 的补丁文件,其中包含了仓库A中的更改。

  1. 然后,在另一个仓库中应用补丁文件:将补丁文件应用到另一个仓库B中。在仓库B中,执行以下命令应用补丁:
git apply mypatch.patch

这种方案适用于只需要将某个仓库的特定更改应用到另一个仓库,而不需要保持完全同步的情况。补丁文件可以通过电子邮件或其他方式传递给另一个仓库的维护者。

参考:

  1. https://git-scm.com/docs/git-diff/zh_HANS-CN
  2. 《Pro Git》分布式 Git,向一个项目贡献

方案1验证:

上述方案中如果KOCA仓库和客户仓库同时修改一个文件时会出现冲突,冲突的报错比较简单,无法定位冲突的位置,最终还是需要人工比对的方式进行合并。如下图

KOCA仓库修改:

客户仓库修改:

报错:

结论:因为二个仓库都修改了同一个文件,会导致冲突,同时Git没有自动插入这些冲突标记,会导致不能一眼看出哪里冲突了,需要人工比对代码。这种方式容易出错,同时也比较麻烦。

方案1改进:

前提:要保持KOCA仓库与客户仓库目录结构一至

在源仓库创建bundle文件

  1. 定位到源仓库:首先,你需要在你想要导出更改的本地仓库的根目录下打开命令行。

  2. 创建bundle文件:使用 git bundle create 命令创建一个包含所有提交历史的bundle文件。你可以指定从哪个提交开始打包,以及是否包含所有分支。例如,如果你想包含所有分支和标签,可以使用 --all 参数。如果你只想包含特定分支,可以指定分支名。

    git bundle create my_repo.bundle --all 所有分支
    
    git bundle create my_repo.bundle develop 开发分支
    
    git bundle create my_repo.bundle 8c42d95b43a94bb79a7e04e55cfa47b143cab5bd develop 
    开发分支从8c42d95b43a94bb79a7e04e55cfa47b143cab5bd提交开始所有的提交
    
    git bundle create my_repo.bundle strtcommit..endcommit develop 
    

同步开发分支从提交strtcommit到endcommit之间的提交
这将会创建一个名为 my_repo.bundle 的文件,其中包含了从仓库初始化以来的所有提交历史和数据。

将bundle文件传递到目标仓库

  • 实体传递:将生成的 .bundle 文件通过U盘、网络共享、邮件附件等离线方式传递到目标仓库所在的机器。

在目标仓库应用bundle文件

  1. 复制bundle文件:将bundle文件放到目标仓库的根目录下。

  2. 检查bundle文件(可选):在应用bundle之前,可以先验证bundle文件的完整性。

    Bash

    git bundle verify my_repo.bundle
    
  3. 从bundle中拉取或克隆:如果目标仓库是全新的,可以使用 git clone 命令克隆bundle文件。

    Bash

    git clone my_repo.bundle new_repo_directory
    

    如果目标仓库已存在,则需要添加bundle文件为临时的远程仓库,然后拉取数据。

    Bash

    git remote add bundle /path/to/my_repo.bundle
    git fetch bundle
    
  4. 合并更改:根据需要,可能要检查outstanding的分支和提交,然后决定是merge还是rebase这些更改到目标仓库的相应分支上。

    Bash

    git checkout develop
    git merge bundle/develop
    
    git merge bundle/develop 并收到错误 fatal: refusing to merge unrelated histories 时,这意味着Git检测到你正在尝试合并两个没有共同提交历史的分支。换句话说,Git认为develop分支和从bundle中来的develop是完全不相关的两个历史线,因此默认拒绝合并,以防止意外地创建一个混乱的合并提交。
    要解决这个问题,你可以通过允许合并不相关的历史来强制执行合并。在执行 git merge 命令时加入 --allow-unrelated-histories 参数
    
    
git merge bundle/develop --allow-unrelated-histories

会看到冲突被标记,可以定位到冲突,然后快速解决冲突。

当然客户可能只想合并部分的提交,可以使用git cherry-pick <start_commit_hash>…<end_commit_hash>