首页 > 解决方案 > 将存储库的一部分合并到我的存储库中

问题描述

我有一个存储库,我想将另一个存储库的主分支添加到我的,所以我这样做了:

git remote add upstream repo_link
git pull upstream master --allow-unrelated-histories

然后我推到原点,就是这样。

现在,我想让它保持最新,但不会丢失我的更改,所以我过滤了我创建/修改的文件,用这个获取作者的电子邮件(然后用 python 或 bash 做一些逻辑)

git ls-tree -r main --name-only
git log -n 1 --pretty=format:%ae -- file_iterator

我从另一个存储库中提取...

git pull upstream maaster -X theirs

然后,我重置了我在检查电子邮件之前得到的文件,就像这样......

git reset origin/HEAD -- myfile_iterator

这很好,但有一个大问题:myfiles 必须再次提交,为什么?它们是完全相同的文件。我不想修改myfiles 的历史,我想让s永远myfile保持原样。

据我了解,reset在给定分支、repo 等中下载给定提交的文件,使其像一个未修改的文件,所以我不明白为什么它要求我再次提交它。

有没有更好的方法来实现这一目标?基本上我想要的是“及时冻结”我修改过的那些文件,其他所有文件,从外部存储库中提取。我澄清说我刚开始使用 git,所以可能有更好的方法。

标签: gitgithubversion-control

解决方案


这种关系基本上是我修改那个项目,我知道我可以做一个分叉或类似的事情,但我不想丢失提交历史,我也不想启动一个新的存储库,因为“手表” , forks 等。我最初创建了一个新的存储库而不是 fork,因为我对 git 几乎一无所知

你可能认为你正在让它变得更容易,但你正在与 Git 抗争并以艰难的方式做到这一点。git reset并且处理不相关的历史和花哨的合并都是非常先进的,并且对于您正在做的事情完全没有必要。

现在,我想让它保持最新,但不会丢失我的更改,所以我过滤了我创建/修改的文件......

更改经常涉及许多文件,并且需要所有这些更改才能工作。排除他们对您接触过的任何文件的更改可能会破坏代码。

你不需要做任何花哨的事情,这就是合并的目的。将您的代码与他们的代码合并将使他们的更改与您的代码交织在一起。如果您都更改相同的代码,则会发生冲突。冲突不能 Git 无法为您解决。如果您使用 --ours 或 --theirs 让它们消失,您可能会破坏代码。您必须考虑每个冲突以及如何解决它们。

这些都不是必需的,这就是合并的目的。git pull只是 agit fetch和 a git merge,所以git pull应该做正确的事。


把事情简单化。git clone该项目。做一个分支。在那个分支做你的工作。当您想要更新git fetch以从上游项目获取最新版本,然后git merge origin/master将他们的工作合并到您的分支中时。

  • git fetch origin
  • git merge origin/master

(您可以将其作为git pull.

在分支中完成所有工作。只有git pull在 master 中才能使您的本地版本保持最新。将您的所有工作与他们的工作隔离开来很重要。

一旦您对此感到满意,使用 Github 分叉就不会复杂得多。Github 有很好的文档,请仔细阅读。Pro Git也不错。

关于具体问题。


*reset 在给定的分支、repo 中下载给定提交的文件...

git reset很复杂。它做了很多不同的事情。

一开始,git reset不下载任何东西。未经您的同意, Git从不与网络对话。三个基本的网络命令是git fetchgit pushgit pull(执行 a git fetch)。其他一切都是本地的。

使它像一个未修改的文件,所以我不明白为什么它要求我再次提交它。

它不是未经修改的。这有点乱。

git reset origin/HEAD -- myfile_iterator

这只会影响暂存区(你的东西git add)。它不会更改工作树(实际文件)或提交。它相当于新的git restore --source origin/HEAD --staged myfile_iterator.

剩下的是 myfile_iterator 的 origin/HEAD 版本和磁盘上的 myfile_iterator 版本。如果 origin/HEAD 中的 myfile_iterator 与您的 HEAD 中的版本不同(即您的最后一次提交),它将显示为分阶段更改。

使用git reset需要对工作树、暂存区、HEAD 和提交历史有深入的了解。暂时不要惹它。改为使用git restore

注意:origin/HEAD不一定等同于origin/masterorigin/HEAD可能是任何东西。

但这一切都是不必要的。


推荐阅读