I'm working on an open source project for the first time and I'm adding a feature to the source. The way I've been going about, is I've squashed my individual commits into on clean commit for the feature. Now every time I need to fix the something code in the code because it fails tests, I'm editing the code and rebasing git rebase -i HEAD~2
and squash
ing the edit into the original feature commit. This works, however each incremental fix is lost. There's an option when rebasing to extend the comment to have the messages from each of the previous commits but the code diffs are all lost and i'm git push origin master --force
every time I need to update, which is not very good for version control. Is there a better way to do this?
-
this post is rather h`ead (wall of text). Would you mind editing it into a better shape?– gnatAug 4, 2015 at 17:15
1 Answer
In any project where you share code you should be very hesitant to alter the history and force push. This is especially true for open source code.
I didn't quite understand your question, but it sounds like when you try to fix something you end up breaking something, which is revealed by some sort of automated test suite.
A good practice is to open a pull request to the code, even if you own it. This way any continuous integration services can run tests against your code. Moreover, you should run the test suite against your code before you push. This way you know that the fix hasn't broken anything.
A fix should be a separate commit as it isn't a feature. This is because as you start versioning your code, people will expect a certain behavior from a certain version of the code. If you changed the history, those expectations cannot match. Moreover, people using a particular version of the code may have encountered the bug you fixed. They'll expect that a newer version of the code will address the bug. If you rebase and squash the code you'll be putting the fix in a place that they won't expect.
If you're finding that you're having to implement too many fixes per feature perhaps you should slow down, write more comprehensive tests, and attempt to engage your audience in code reviews so as to catch bugs before it becomes part of the code.
Lastly, squashing your feature into a single commit is good hygiene. The commit message should only include pertinent information. A lot of changes that happen as you write code aren't important. If you rename a method that nobody has used yet, nobody needs to know that. However, if you rename a method in already public code then you should mention that as a potentially breaking change, especially in the case of public methods.
-
This is good stuff, thanks. However I still can't think of an alternative when I'm building out
feature x
and it takesn commits
total to get it working and passing tests all around and the project requires that my pull request is all in one nice neat commit. Other than rebasing and squashing the commits into onefeature x
commit. Aug 5, 2015 at 3:55 -
1This is what branches are for. You develop the feature in your branch, and when it's all good you squash it down for your PR. Aug 5, 2015 at 4:02
-
Just to understand a little better. Would these be viable steps. 1) Fork repo. 2) Create feature dev branch (many commits) 3) When ready to commit create new branch from dev & rebase to one commit? Would appreciate your response as answer :) Aug 5, 2015 at 4:11
-
1You could do it that way. You don't even have to fork the repo though. Assuming that you have write access to the upstream repo, you can just push your branch directly to it, and still do the PR process. Additionally, you don't have to create a second branch, you could rebase the commits on your feature branch prior to merging into master. But creating a second branch for the purpose of squashing won't hurt anything either. Aug 5, 2015 at 5:37