On 8/18/2014 11:35 PM, Gavin Lambert wrote:
On 19/08/2014 14:53, Edward Diener wrote:
I share a library with others and make some commit to a branch of that library. Then I try to 'push' the commit, only to be told that there are changes that have been made which I need to 'pull'. So I 'pull' the latest changes for that branch, and luckily there is no conflict(s) with my local commit(s).
What do I do now ?
I can 'push' my changes successfully but then the history of my particular changes appears to be lost.
Lost in what way?
The message in the log for my push says: 'Merge branch 'develop' of https://github.com/boostorg/build into develop' rather than the actual commit message for my local repository change.
Am I supposed to revert my changes to the local repository by doing a 'reset' and then reapply those changes ? That seems onerous.
What is the right way to 'push' my changes and still preserve the history of each one of them on the remote repository ?
What should have happened is something like this:
A - B - D - F \ / C - E
Where A/B are the common ancestors of the changes (B is the version that you last fetched). You made commits C & E in your local copy, but in the meantime your collaborators made commit D and pushed it. When you try to push E, git will warn you that you don't have the latest code and you should pull.
When you "git pull", you will fetch D and then git will merge this to create F. You should now be able to push F and it will include all changes from both sides and the revision graph will look like the above. (git's revision graph is a very powerful and handy thing, completely unlike svn's graph, which is fairly useless; if in doubt, always look at the graph.)
There's an alternate method of merging changes ("git pull --rebase") that would instead result in this graph:
A - B - D - C' - E'
ie. git fetches D, then rebases your original changes C and E onto it, thereby pretending that you created them after D as far as the history is concerned. Some people prefer this, others dislike it, but it's important to note that rebasing is a history-modifying action and you should never do it on anything that has already been pushed publicly (note that the original C and E are "destroyed" during the course of the above -- this means that if anyone else had based further work on one of these they would be forced to rebase in turn to get their copy back into a sane state). Which sounds a little scary when you first read it, but once you get your head around it can be quite handy when used correctly.
I think I was supposed to do the "git pull --rebase" so that my change is applied on top of the pull's latest. When I use Tortoise Git there is no "Pull&Rebase" but there is a "Fetch&Rebase" so maybe that is what I am supposed to use in tgit. Thanks !