简体   繁体   English

从特定提交创建 PR

[英]Creating a PR from a specific commit

I want to create a PR with a single commit, so I checkout a new branch with commmit SHA,我想用一次提交创建一个 PR,所以我用提交 SHA 签出一个新分支,

git checkout -b new-branch 8517c80183607461ea

How do I create a PR from here?我如何从这里创建 PR?

Because of the way Git branches work, it's not enough to make a branch off a single commit. 由于Git分支的工作方式,仅凭一次提交就不足以创建分支。 You might drag in more commits. 您可能会拖入更多提交。

For example, let's say your repository looks like this. 例如,假设您的存储库如下所示。

A - B - C [master]
         \
          D - E - F [feature]

master and feature are just labels pointing to a commit. masterfeature只是指向提交的标签。 master points at commit C. feature points at commit F. 提交C的master点。提交F的feature点。

Git commits do not live in isolation. Git提交不是孤立存在的。 They take their whole history with them. 他们把整个历史都带走了。 F cannot exist without E, D, C, B, and A. If you push feature then F will bring E and D along with it (assuming C is already pushed). 没有E,D,C,B和A的情况下F不能存在。如果按下feature则F将E和D一起带来(假设C已经被按下)。

Let's say you want to send a PR of only E. So you make a branch at E. 假设您只想发送PR的PR。因此您在E建立分支。

$ git checkout -b new-branch E

A - B - C [master]
         \
          D - E [new-branch]
               \
                F [feature]

All that's done is created a label called new-branch pointing to commit E. The structure of the commits remains the same. 完成的所有操作均创建了一个名为new-branch的标签,该标签指向提交E。提交的结构保持不变。 If you then push new-branch it will drag D along with it. 如果您随后按下new-branch ,它将拖动D。 This is why sometimes when you think you're pushing only a few commits the PR contains many more commits. 这就是为什么有时当您认为您只推送少量提交时,PR包含更多提交的原因。


In order to really push just one commit, you need to detach it from its history. 为了真正只推送一个提交,您需要将其与历史分离。 You can do this with a git cherry-pick . 您可以使用git cherry-pick做到这一点。 This basically takes the commit, turns it into a patch, and patches it somewhere else. 这基本上就是提交,将其变成补丁,然后在其他地方对其进行补丁。

Going back to your original repository... 回到您的原始存储库...

A - B - C [master]
         \
          D - E - F [feature]

You'd make a new branch off master . 您将在master创建一个新分支。

$ git checkout -b new-branch master

          [new-branch]
A - B - C [master]
         \
          D - E - F [feature]

(Note that nothing changed except a new branch label was made pointing at C.) (请注意,除了指向C的新分支标签外,其他都没有更改。)

Then cherry pick E. This will copy E as a new commit on top of C. There may be conflicts, resolve them as normal. 然后选择E。这会将E复制为C之上的新提交。可能存在冲突,请按正常方式解决它们。

$ git cherry-pick E

          E1 [new-branch]
         / 
A - B - C [master]
         \
          D - E - F [feature]

Now you can push new-branch and only E1 will be in the PR. 现在,您可以按new-branch ,只有E1会出现在PR中。

You need to push new-branch to Github, and then open a pull request. 您需要将new-branch推送到Github,然后打开一个请求请求。 This will include all commits reachable from 8517c80183607461ea but not already in the history of master . 这将包括从8517c80183607461ea可达到的所有提交,但尚未包括在master的历史中。

If you want to include only 8517c80183607461ea , then you need to rebase new-branch onto master using git rebase -i master , and delete all the lines except the one mentioning 8517c80183607461ea . 如果你想包括8517c80183607461ea ,那么你需要重订new-branch上使用主git rebase -i master ,并删除除一个提到的所有行8517c80183607461ea After the rebase, your branch new-branch will contain the rebased 8517c80183607461ea with its new commit ID, directly on top of master, and you can push your branch/issue a pull request. 在重新设置8517c80183607461ea之后,分支的new-branch将直接在主8517c80183607461ea上包含重新设置的8517c80183607461ea及其新的提交ID,您可以推送分支/发出拉取请求。

I've had a little bit of trouble using Schwern's answer since I was making the error of being on master of a forked project while making commits ( here I'm calling it a rookie mistake). 我在使用Schwern的答案时遇到了一些麻烦,因为在进行提交时犯了一个在派生项目的主人身上的错误( 这里我称之为菜鸟错误)。

Following Schwern's graphs let's say I've forked a project at C and proceeded on master with the other commits. 遵循Schwern的图,可以说我已经在C分支了一个项目,并在其他提交方面继续掌握。 Here I am adding an asterisk to signal that new changes are happening on the fork: 在这里,我添加一个星号来表示叉上正在发生新的更改:

A - B - C - D* - E* - F* [master]

If you want to cherry-pick only some of the commits (say D and E ) what you shouldn't do is: 如果您只想挑选某些提交(例如DE ),则不应该执行以下操作:

git checkout -b new-branch upstream/master
git cherry-pick <hash of commit D>
git cherry-pick <hash of commit E>
git push -u origin new-branch

In this case you're trying to branch out the master at F* and cherry picking the previous commits will get you the warning 在这种情况下,您尝试从F*分支出master节点,然后选择先前的提交会警告您

"The previous cherry-pick is now empty, possibly due to conflict resolution." “以前的挑剔现在是空的,可能是由于解决冲突的缘故。”

since you're adding the same old commits on the new branch. 因为您要在新分支上添加相同的旧提交。

What you should do instead is: 相反,您应该做的是:

git checkout -b new-branch <hash of commit E>
git push -u origin new-branch

A - B - C - D* - E* - F* - G* [master]
                  \
              D* - E* [new-branch]               

After this you're ready to make a pull request with only the selected commits. 之后,您就可以仅使用选定的提交来发出拉取请求。

Just edit the specific file direct on github.直接在github上编辑特定文件即可。 Github will do a patch branch automatic and so you can PR just a single file out of your branch. Github 会自动做一个补丁分支,所以你可以从你的分支中 PR 一个文件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM