I've implemented classic OSS maintainer/contributor git workflow for a company project on github, however one edge case produces some weird results that I'm not sure how to get around.
Lets say there is a typical project that I forked and added upstream remote to keep it up to date.
git clone [email protected]:kozhevnikov/<project>.git
git remote add upstream [email protected]:<company>/<project>.git
For the purposes of this example this fork is behind by a few commits.
git reset --hard HEAD~5 && git push --force
I work on this fork and push some commits, before pushing my last commit and creating a pull request I update my fork's clone to make sure there are no conflicts.
touch foo && git add foo && git commit -m foo && git push
touch bar && git add bar && git commit -m bar
git pull --rebase upstream master
From github.com:<company>/<project>
* branch master -> FETCH_HEAD
First, rewinding head to replay your work on top of it...
Applying: foo
Applying: bar
Now, when I try to push to my fork I get rejected.
git push
To [email protected]:kozhevnikov/<project>.git
! [rejected] master -> master (non-fast-forward)
error: failed to push some refs to '[email protected]:kozhevnikov/<project>.git'
To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes (e.g. 'git pull') before pushing again. See the
'Note about fast-forwards' section of 'git push --help' for details.
What should I do next? All I want is for the pull request to contain foo and bar commits, however...
When I pull
, pull request contains duplicate foo commits as well as extra merge one.
git pull
Merge made by the 'recursive' strategy.
git push
On github pull request looks like this.
Showing 4 unique commits by 1 author.
12345
kozhevnikov foo 4 minutes ago
67890
kozhevnikov foo 4 minutes ago
abcde
kozhevnikov bar 2 minutes ago
fghij
kozhevnikov Merge branch 'master' of github.com:kozhevnikov/<project> just now
When I git pull --rebase
instead of pull
, at best it'll include other people's commits into my pull request (those from reset), and at worst it gives me merge conflicts.
When I git push --force
without any pull
or --rebase
it works perfectly, however I'm very uneasy in saying to everyone use the force or making it part of standard workflow as I can imagine few people or a small subteam collaborating on a single fork and stepping on each other's toes with forced push.
Any ideas? What am I missing?
When you
git pull --rebase upstream master
you are rewriting your own history, since you are rebasing your master branch on the updated upstream repository. When you push your rebased repo to your fork git complains. You need to push with --force
git push --force origin master
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With