So I forked a project, and made a few changes and pushed those to origin/master. I didn't intend to send these changes back开发者_如何学运维 to upstream. All was fine and good until now, but now I have some changes I do want to push upstream.
Can I rebase back to upstream in a different branch, and commit to that branch? Can I commit these changes from my branch? Have I horribly mangled my repo?
No, no mangling. Just branch from upstream/master, make your commits there, and then you can push (or pull-request) those commits, which fit neatly onto upstream/master.
If you have A---B---C, where upstream/master is at A and master is at C, meaning B and C are commits you don't want to send upstream, then:
git checkout -b to-send-upstream A
# work, work, work
# commits
git log A..HEAD # this will be the commits to send upstream
If you have commits you're not going to send back on master, it might be simpler to keep track of things if you move those into a different branch and keep your master in sync with upstream/master:
git branch my-stuff-not-sent-upstream
git reset --hard A # will wipe out local changes!
git push origin master -f # can lose history if a shared remote!
git push origin my-stuff-not-sent-upstream
will effectively replace "master" with "my-stuff-not-sent-upstream" and set master and origin/master back to the same commit as upstream/master.
Assuming commits A,B,C are your private changes, and commits 1,2,3 are what you want to push up, your history will look like so:
(origin/master)
/
.... o - A - B - C - 1 - 2 - 3 (master)
\
(upstream/master)
Now you want to move 1,2,3 to a new branch from upstream:
git checkout master
git checkout -b upstream
git rebase origin/master --onto upstream/master
What this does is switch to a new branch called upstream
where your current master
is. Then it rebases commits 1,2,3 after commit referenced by upstream/master
.
After the operation you will have:
1' - 2' - 3' (upstream)
/
/ (origin/master)
/ /
.... o - A - B - C - 1 - 2 - 3 (master)
\
(upstream/master)
Now you will be ready to push upstream branch to the upstream remote.
First, you need to add upstream as a remote.
git remote add upstream https://github.com/upstream/repo.git
Meaning you not only have "origin" (which references your own clone on the GitHub side), but also "upstream" (which is the original repo you have forked on the GitHub side).
Then you need to fetch upstream, and checkout from there:
git checkout -b upstream/master
You can make your commits there, and then push back to origin, allowing you to make a clean pull request from there.
精彩评论