I'm developing a project, which I'm pushing to private repository on my VPS. However, I'd like to publish it on GitHub.
I make a lot of commits(mostly as backups) which doesn't contain complete implementation of feature. I do not want to include history of these commits in public repo.
So, private history would look like:
- Initial commit
- Part Feature A
- Part Feature A
- Part Feature A
- Finished Feature A
- Part Feature B
- Finished Feature B
- … etc …
And desired history of public repo would look like:
- Initial commit
- Feature A
- Feature B
- … etc …
And there must be no track about partial commits made for development backup. So all internals of a GIT repository would look like there were only just Feature commits, no partial commits.
I know, that I can clone repositories to different folders, and copy-paste between these folders. However, GIT is designed for distributed development. So, I'm wondering whether there's some cleaner and more GIT-like way to solve this.
How to manage separate repositories with different histories?
The first commit on public repo can be completly squeezed, but since then I would like to have a nice commit history in public repo.
Best Answer
Use the Gitflow Workflow
Following this model, the
master
branch contains only releases, thedevelop
branch contains the WIP (work in progress) commits, andfeature
branches are used to develop features.The main benefit of this approach is, if you screw up and publish a bad commit to
develop
you'll be able to rollback the changes without screwing up the the history of the publicly accessible version onmaster
.So, that doesn't answer your question...
What about combining partial features into a single feature commit?
Simple, before merging a
feature
branch intodevelop
squash the commits using interactive rebase.It'll pop up an editor and you can change which commits you want to squash. It also concats the commit logs so you can add all/part of them into the squashed commit message.
Note: There are many ways to squash commit history. IMHO, I think interactive rebase is the most straight-forward but YMMV.
When you're ready for a release, simply create a
release
branch fromdevelop
and merge therelease
branch into `master.Developing features can be challenging because a maintainer may require a contributor to make additional changes piecemeal prior to accepting a PR (pull request).
Using the strategy above, the contributor will still have a granular history containing all of the changes made to the feature throughout development. This makes it easy to roll-back and/or cherry-pick commits individually.
Note: The ability to cherry-pick commits is extremely valuable if the contributor runs into complicated merge conflicts.
If you want features to commit cleanly, simply have the contributor squash the changes as the last step prior to a merge.