如何“拉请求”一个特定的提交

我有一个特定的提交,我想贡献给一个存储库,我已经在 github 上分叉。 我假设这样做的机制是一个“拉请求”。 但是当我尝试这个,我只能拉请求我的整个分支。 我不希望拉请求其他承诺,因为他们是无关的。 知道我该怎么做吗。

repo I wish to pull request to.

最后一次提交 b50b2e7是我希望拉请求的唯一一次提交。 无论如何,我可以做到这一点,还是所有的提交相互依赖?

commit I wish to pull request

111146 次浏览

Create a new branch with just that change:

# If you haven't set up your remote yet, run this line:
# git remote add upstream https://github.com/konradjk/exac_browser.git
git fetch --all                                   # Get the latest code
git checkout -b my-single-change upstream/master  # Create new branch based on upstream/master
git cherry-pick b50b2e7                           # Cherry pick the commit you want
git push -u origin my-single-change               # Push your changes to the remote branch

Then create the PR from that branch.

I'm not familiar with cherry-pick and had a problem when I tried Joseph's approach (something about the cherry-pick being empty). I found a work-around that seems to have worked well:

# Create new branch directly from specified commit:
$ git checkout -b my-single-change b50b2e7
$ git push --set-upstream origin my-single-change

You can now select this branch in GitHub and create a pull request.

I had the same error of alwaysCurious, so I did a little digging. 1

The regular case

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

You're working on a project, you use a separate branch (feature) for your committed changes (D-E-F-G) and you want to create a pull request. However you want only some of the commits to be included in the pull request (E and F)

The procedure here is the one from Joseph's answer

# optional: set upstream as remote if it's not
git remote add upstream https://github.com/<upstream_github_username>/<upstream_github_repo_name>.git
# fetch changes
git fetch --all
# create specific branch for your partial pull request
git checkout -b partial-change upstream/master

Now this is how it looks:

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

Cherry-pick your specific commits and push the changes:

git cherry-pick <hash of commit E>
git cherry-pick <hash of commit F>
git push -u origin partial-change

After fixing any conflict this is where you'll get:

          E1 - F1 [partial-change]
/
A - B - C [master]
\
D - E - F - G [feature]

The consecutive case

If instead you just want to apply all the consecutive commits up to the last one (or two or three) you can just branch out at the specific commit. For instance here I just want the commits up to E and not the subsequent ones:

git checkout -b partial-consecutive-changes <hash of commit E>
git push -u origin partial-consecutive-changes


A - B - C [master]
\
D - E [partial-consecutive-changes]
\
F - G [feature]

The rookie mistake

The last procedure can also help you if you just applied consecutive changes to master without using a specific branch for them and now you want to cherry-pick them after. This is relevant if you've forked a project at C and proceeded on master with the other commits. Here I am adding an asterisk to signal that new changes are happening on the fork:

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

What you shouldn't do is:

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

In this case you're trying to branch out the master at G* and cherry picking the previous commits will get you the warning:

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 partial-change <hash of commit E>
git push -u origin partial-change


A - B - C - D* - E* - F* - G* [master]
\
D* - E* [partial-change]


After this you're ready to make a pull request with only the selected commits.


Notes:

  1. Here I'm extending this great answer from Schwern.

  2. To get the last n commit hashes it may be useful to use: git log --pretty=oneline --abbrev-commit | head -n