简体   繁体   中英

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,

git checkout -b new-branch 8517c80183607461ea

How do I create a PR from here?

Because of the way Git branches work, it's not enough to make a branch off a single commit. 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. master points at commit C. feature points at commit F.

Git commits do not live in isolation. 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).

Let's say you want to send a PR of only E. So you make a branch at 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. If you then push new-branch it will drag D along with it. This is why sometimes when you think you're pushing only a few commits the PR contains many more commits.


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 . 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 .

$ 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.)

Then cherry pick E. This will copy E as a new commit on top of C. There may be conflicts, resolve them as normal.

$ 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.

You need to push new-branch to Github, and then open a pull request. This will include all commits reachable from 8517c80183607461ea but not already in the history of 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 . 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.

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).

Following Schwern's graphs let's say I'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* [master]

If you want to cherry-pick only some of the commits (say D and E ) what you shouldn't do is:

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

"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 will do a patch branch automatic and so you can PR just a single file out of your branch.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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