Python 如何在项目中使用自己定制的开源代码同时能把修改提交给项目原仓库?

场景是这样的:假设 GitHub 上有一个第三方库,我觉得正好适合我的项目,但是有一些地方还不完善,我需要对其进行定制。那么我有什么办法保证在项目中使用自己定制的开源代码同时能把修改提交给项目原仓库?也就是说我定制完后,我可能就要废弃掉本地的仓库,以后跟随着原仓库的代码进行更新了。

我想的一个方案是这样,不知道行不行得通?

首先我 fork 原仓库到我的 GitHub 仓库,然后我 clone 一份到本地进行修改,同时我通过 pip 从我自己的仓库安装这个库,这样我自己修改的代码就能及时应用于我的项目。等修改完后,我再提交一份 PR 给原仓库,如果作者合并了我的 PR 后,我就可以废弃掉我 fork 的那个仓库,以后更新这个库的代码时就从项目作者的发行版本安装。

请教一下这种方案可行么?平时大家遇到这种场景是如何处理的呢?
Python 如何在项目中使用自己定制的开源代码同时能把修改提交给项目原仓库?


7 回复

可以
你也可以试试 submodule
其实没必要删自己的,可以等 PR merge 以后反过来覆盖自己的就行。如果经常用的话省得下次再 fork 了


核心方案:Fork + 本地修改 + 向上游提交PR

这其实就是标准的开源协作流程。直接改原仓库的代码你肯定没权限,所以得先“复制”一份到自己的账号下,这叫 Fork

具体操作步骤:

  1. Fork 原仓库:在 GitHub/GitLab 上,找到你想改的那个开源项目,点右上角的 “Fork” 按钮。这会在你的账号下创建一个完全独立的副本。

  2. 克隆到本地:把你 Fork 出来的仓库克隆到你的电脑上。

    git clone https://github.com/你的用户名/项目名.git
    
  3. 添加原仓库为远程上游:为了后续能同步原仓库的新改动,需要把原仓库加为一个叫 upstream 的远程地址。

    cd 项目名
    git remote add upstream https://github.com/原作者/项目名.git
    
  4. 创建功能分支:永远不要在 mainmaster 分支上直接改。为你自己的功能或修复单独开一个分支。

    git checkout -b my-feature-branch
    
  5. 进行你的定制开发:在这个分支上修改代码,完成你的需求。按需提交(commit)。

  6. 同步上游更新(可选但推荐):在推送前,可以先拉取一下原仓库最新的 main 分支,合并到你的分支,减少冲突。

    git fetch upstream
    git merge upstream/main
    # 如果有冲突,解决它
    
  7. 推送到你的 Fork 仓库

    git push origin my-feature-branch
    
  8. 发起 Pull Request (PR):在你的 Fork 仓库页面,GitHub/GitLab 通常会提示你为新推的分支创建 PR。点击后,选择将你的分支合并到原仓库的 main 分支。在 PR 描述里清晰说明你改了啥、为啥改。

  9. 在你的项目中使用:在你的实际项目中,可以通过 pip 直接安装你 Fork 后仓库的特定分支。

    pip install git+https://github.com/你的用户名/项目名.git@my-feature-branch
    

    或者,在 requirements.txt 里写:

    git+https://github.com/你的用户名/项目名.git@my-feature-branch
    

后续维护

  • 当原仓库有更新时,在你的本地仓库拉取 upstream/main,合并到你的功能分支,解决冲突后再次推送,PR会自动更新。
  • 如果原仓库维护者接受了你的 PR,你的修改就进入了官方代码库。之后你可以考虑切换回使用官方版本。
  • 如果 PR 被拒绝或长期未处理,你可以继续维护自己的 Fork 版本,并定期同步上游更新。

一句话总结:Fork项目,在独立分支上开发,通过PR贡献回去,项目里直接引用自己Fork的分支地址。

这个项目下应该只会修改一次?也就是说我以后我从原作者发行的包中更新最新版代码都不会有问题?这我就放心了。

项目稳定运行了一般就不需要更新了啊,如果有新的 feature 是用得到的可以手动 merge 回来

补充一点信息:

自己的 fork 不用删,需要时和原项目同步一下即可:
https://help.github.com/articles/syncing-a-fork/

自己搭一个 PyPI server,用于管理定制过或尚未 PR merge 或尚未发布到 PyPI 的包:
http://doc.devpi.net/latest/

感谢!但是自己搭建 PyPI server 比较麻烦。pip 不是可以从 github 直接安装吗?我能先从我 fork 的项目直接安装到我的本地。然后等我的 PR 被上游仓库合并后,我再改为用 pip 从上游仓库安装。我想知道的是这样做会引起本地项目包的冲突么?因为我肯定这次修改以后就不会再有大的修改,所以我希望还是跟着上游仓库的代码更新。

我没用过直接从 github 安装,但道理一样,在 requirements.txt 中指定 repo 和版本,上游合并后更新 requirements.txt。
https://stackoverflow.com/questions/16584552/how-to-state-in-requirements-txt-a-direct-github-source

回到顶部