Some Background:
Currently, I have a central, bare repository on my server. Each computer clones from and pushes changes to this repository. I currently have branch Master and branch dev. All of the work is done in the dev branch. Master is always the current, stable production code. Changes can be applied to Master at any point along with the changes that are going on in dev.
My everyday workflow consists of:
git checkout dev
//pull in changes from remote
git pull
//make and commit changes as need throughout the day
git add -u
git commit
//these steps only happens when I know master has changed
git checkout master
git pull
git checkout dev
git rebase master //to get changes to master into dev branch
//push changes to central remote at end of day
git push
I believe this should be a fairly standard workflow for a single developer.
Now with all that out of the way, to the purpose of my question. I recently ran into a situation that I'm not sure how to properly handle and how to prevent it in the future. Currently, my dev branch is a long running dev branch that is a major rewrite of a portion of the site. As such, it has been in development for a couple of months. While I've been doing this work, I've also been making small changes/bug fixes to Master. When I finish one of the changes to Master, I rebase dev onto Master to get the changes, then push them up to the central repo. This has been working fine.
However, I made a change to Master a couple of days ago - the first such change in about a month. When I went to rebase, all hell seemed to break loose. I was getting merge conflicts on files that didn't exist in Master, and I was getting the same conflicts in the same files over and over. After spending the better part of a day trying to resolve all the conflicts, I finally gave up.
This morning, I went to try again, but before I started I examined the project commit history and found something rather odd. I found that around 15 of the commits were repeated. It showed all of the commits from 07/12/2012 - 08/24/2012. Then, I had the same commits listed again, all with different SHA Hashes. I didn't notice it until I saw that the Dates of the commits were listed all in chronological order as you would expect, but then it suddenly jumped back into the past again.
To resolve I did another rebase, but skipped the duplicate commits. When I did that, everything worked just as I would expect with no conflicts at all.
So, my question to you guys is how did those commits come to be done twice, and how can I prevent this nightmare from happening again in the future? As the title of the question suggests, I assume the problem has something to do with my use of rebaseing and pushing the rebased branch. But I'm really just guessing there. I just need some help figuring out what I did wrong.
You can use git rebase -i HEAD~x replace x with whichever number of commits you want to look at top to bottom e.g git rebase -i HEAD~3 this will give you three last commits. You can then select which commits you want to preserve and which ones you want to delete.
Yes, you can rebase more than once. After rebasing, you get a fresh set of commits. These commits are exactly like all other commits and hold no record of having been rebased. The main thing you need to be careful for is the possibility of rebase conflicts.
It sounds like your dev branch is behind master by a few commits, you will need get the latest changes from master into your branch (either by performing a merge or rebase). Once your dev branch has your latest changes from master, you diff should only show the newest changes in your dev branch.
The purpose of rebase is make your commits look as if they were changes to the branch you rebase onto. So the most logical way is to incorporate merge conflicts into these commits. No additional commits is required thus.
I'd consider that your model is essentially the same as having three developers, since you have three development machines. So, your dev branch is shared in that sense. I've also read on SO that rebasing as shared branch leads to issues, and it's better to merge than rebase shared branches. After reading that I've started using rebase for private branches only, with good results. I'd suggest creating a test repository and trying the two approaches to see how they compare.
If I can find the other SO question, I'll add a link here.
Edit:
Here it is Rebasing remote branches in Git
Of course, there are many different opinions on this. :)
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