1

我正在尝试将特定提交推送到upstream存储库,这与我正在处理的相同,但略有更改。

当前的 repo 领先于upstream一个,我想推动我在当前 repo 中所做的一些更改,但不是全部。

当我做类似的事情时

git push upstream <commit SHA>:<remotebranchname>

它可以工作,但它也会推送在我的仓库中的最后一次提交upstream和我正在推送的提交之间完成的所有其他提交。

但是,我希望只推送在该一次提交中所做的更改,而不是在该提交之前所做的更改。

如何避免它们被集成?

更新给出的答案解释了如何推送特定的提交(之前的所有历史记录),但我只想推送特定的提交而没有背后的历史记录

4

3 回答 3

0

这是禁止的。

Git 提交包含其父哈希 ID。如果您作为发送者,向另一个 Git 提供提交H(对于某个哈希 ID H),则其他 Git 不需要接受H,直到它也有H的父级(或父级,如果它是合并提交)。所以你必须提供H的父母。它不需要接受该提交,直到它依次拥有那个(或那些)提交的父级,依此类推。

换句话说,提交的 ID 是它的哈希,但是在存储库中拥有该提交意味着您也拥有它的所有祖先1 因此,处理此类提交的唯一方法是拥有其所有祖先。

此时,您可以制作该提交的副本(例如,通过)git cherry-pick以获取具有不同哈希 ID、不同父级以及由于该不同父级而可能导致的任何其他差异的不同提交。2 然后,您可以将此不同的提交(通过其不同的哈希 ID)传递到其他 Git 存储库。如果那个其他 Git 存储库确实有这个新副本的父级,他们不会首先要求任何额外的提交。


1该规则在浅层克隆中有所放松,并且正在进行以其他方式放松它的工作,但至少在原则上仍然是必需的。没有祖先的提交至少是可疑的;可能是假的;链的完整性是通过跟踪链一直回到根来确定的。

2特别是,您可能还需要不同的快照。请记住,Git 提交保存快照——每个文件的完整副本——而不是变更集。H'因此,如果要将commit的副本H应用于 commit B,那么您想要的H'不是其中的快照H,而是更改 H 为变更集的快照,然后将该变更集应用于commit ,同时考虑任何其他的父母和之间的差异。要更改为变更集,我们(或 Git)会将其快照与其父快照进行比较。BHBH

(该git cherry-pick命令是在提交签出时H'H-and-its-parent进行制作的工具。)B

于 2019-11-27T18:32:57.253 回答
0

为了避免推送某些更改,您的分支应设置为您想要包含的最后一次提交。在您的情况下,最好的选择是创建一个新的分支,将其重置为您想要包含的最后一个提交,挑选您想要推送和推送的一个提交。

git checkout -b new-branch # make sure to do this **while you're on** the upstream branch
git pull <remote> <upstream branch> #just to be sure you're right where the remote upstream branch is
git cherry-pick <commit hash>
git push <remote> new-branch
于 2019-11-27T10:22:06.773 回答
0

您首先必须使您的本地历史看起来像您想要推送的内容。然后就可以推了。

数千种可能的方法之一是使用 git rebase,例如:

git rebase -i upstream/remotebranchname

将向您显示一个编辑器窗口,其中包含您所做的尚未推送的提交列表以及一个小文档要做什么。只需保留您想要推送的提交的行,但删除您不想推送的行。然后保存退出。希望您不会有冲突(在您想要的提交您不想要的提交中更改了文件)。

然后就可以推了。

(如果您在本地想要保留不想推送的提交(无论出于何种原因),请首先制作一个标签:

git tag usefultagname
于 2019-11-27T10:08:10.107 回答