* checkout my bug branch
* work work work, commit commit commit
* git rebase MOODLE_19_STABLE (which was previously updated to the latest)
* git push github
Can't - the branches have 'diverged'. Although I kinda see what has happened. I don't really understand what I should have done. Obviously I can just force it, but is that the right thing to do? Something bad always happens when I use rebase
Any help appreciated.
Hi Howard,
No, I am not offering help, but asking the same question. What does rebase do?
Joseph
Rebase is clever because it replays my commits from what MOODLE_19_STABLE looks like *now*. That is the result is as if I had created the new branch (and made all the commits) today, not last month.
It can also do some really mental stuff when you want to move a complete branch with multiple commits from one place to another.
(Please excuse the ASCII art ;) ) Say Moodle has the following commits:
- M1 - M2 -and you start developing at this point
- M1 - M2 - H1 - H2 -While you're developing, Moodle also makes some changes
- M1 - M2 - M3 - M4 -
A merge will do this:
- M1 - M2 - M3 - M4 - * - \- H1 - H2 -/That is, it will create a new commit that tells git that two branches have been merged.
A rebase will do this:
- M1 - M2 - M3 - M4 - H1' - H2' -That is, it will rewrite your changes so that they apply on top of the end of the tree (M4), instead of apply onto M2. (H1' is a rewritten version of H1.)
Now, if you keep developing off of the rebased version:
- M1 - M2 - M3 - M4 - H1' - H2' - H3 - H4 -and Moodle keeps developing:
- M1 - M2 - M3 - M4 - M5 - M6 -
If you rebase again, you will get this:
- M1 - M2 - M3 - M4 - M5 - M6 - H1'' - H2'' - H3' - H4' -In other words, it rewrites all four of your commits to apply on top of M6, instead of M4.
If you try to push now, then github has:
- M1 - M2 - M3 - M4 - H1' - H2' -but, the trees have 'diverged', so it doesn't know what to do.
To decide what to do at this point, you need to consider how your actions affect 1. yourself, 2. the Moodle tracker issue you're working on, and 3. people (if any) who have cloned your tree.
Some options that you have are:
- force push: this is probably easiest on yourself, probably doesn't affect the Moodle tracker issue much, but will mess up anyone who has cloned from your tree (and made any modifications of their own on top of yours). This is because anyone who has cloned from your tree will have the "- M1 - M2 - M4 - H1' - H2' -" version, and when they pull the new version, their git will be confused, and they'd probably end up having to re-clone your tree and re-apply their own changes.
- create a new branch for the newly rebased tree, and leave the old tree as-is: this will leave you with a useless (to you) branch, probably doesn't affect the Moodle tracker issue much, and will leave anyone who has cloned from your tree with a non-broken setup, but they wouldn't get your new changes.
- go back in time and do a merge instead of a rebase: If you did a merge the second time instead of a rebase, it would have resulted in:
- M1 - M2 - M3 - M4 - M5 - M6 - * \- H1' - H2' - H3 - H4 -/
which git would understand how to handle when you do a push, because it has "- M1 - M2 - M3 - M4 - H1' - H2' -" as a sub-tree. Aside from having to build a time machine (or figure out how to get git to go back in time), this is also easy on yourself, and would also be easy for anyone who has cloned from your tree. I do not know how it would affect the Moodle tracker issue -- maybe a core developer could comment.
Basically, if nobody has cloned from your tree (or you don't support people cloning from your tree), option 1 is the best -- rebasing gives a nice linear commit tree. If other people are cloning from your tree, option 3 is best, as long as it doesn't hinder the Moodle tracker issue too much. If it does hinder the Moodle tracker issue, and you need to support people cloning from your tree, then you may need to manually maintain two branches -- one for option 1 and one for option 2.
Thanks for this thorough explanation. Should be moved to the dev docs asap.
For more fancy graphics see http://progit.org/book/ch3-6.html
git push -f {branchname}
The -f option tells git that you are sure you want to push the re-written history. (Doesn't the error message suggest using -f?)
I'll have another look, but I don't remember seeing anything like that.
Git's not too bad once you know what your doing, its just the commands arent that obvious, personally I prefer mercurial as its essentially the same thing, but with a more user friendly front end. However if your interested in a more comericial git support option I'd recommend Clearvision-CM
One of my branches in my forked Github Moodle has been merged in the main project. (http://tracker.moodle.org/browse/MDL-31903)
It is instructed here that you should delete the merged branches from you repositories.
I first did this to get my repositories up to date...
-----------------------------------
git remote add upstream git://git.moodle.org/moodle.git
git fetch upstream
git push origin refs/remotes/upstream/MOODLE_22_STABLE:MOODLE_22_STABLE
git push origin refs/remotes/upstream/master:master
git checkout master
git merge origin/master
----------------------------------------
Then I did this to see which branches were merged:
git branch --merged upstream/master
It just prints:
master
What to do?