Source management is essential to software development. Even if you only use it to undo mistakes, there are great benefits. Of the available systems, git is probably the most popular. It is directly supported inside many editors and IDEs as well as the incredible resource that is github. Here is a simple workflow method that you can use to manage projects.
To get started with github, please have a look at their help pages: https://help.github.com/
Assume that the local repository is correctly set up to point to an upstream copy (origin) and has a local branch called master that tracks the remote master.
local and remote branches
- The upstream repository normally contains a single branch – ‘master’
- Content in master is always good-to-go. It is a ready to publish working version of the product.
- The history of the master branch should be clean and linear. When features are added or changes made, the commits shown in master should follow a clean, linear pattern with a logical progression. Clean up development commits before they are merged into the master branch. Use ‘git rebase -i’ for this
- Where possible, local feature branches are deleted when a feature is complete.
- Exceptionally, a feature branch may be pushed upstream temporarily. For example, if development is handed over to another person.
- Pull requests will generate temporary feature branches upstream
adding a feature
In the simplest case the developer will just want to modify the latest version in master. Thus the first step is to prepare the local environment
- Make the local environment up to date with upstream origin
git checkout master
git pull master
- Create a local development branch and get ready to work
git checkout -b feature
- Tag the start of your work so you can find it easily later
git tag start-feature
Note that the tag should be unique. If you work on several features at the same time, then use a tag name that is related to the actual feature being worked on. Perhaps you could use start-. You are now in a feature branch. Commits are made here as and when needed. Commit often. Keep changes granular. For example, if you rename some variables, you might want a commit after each variable is renamed so that you can unpick one from another later if it all goes wrong. After a while, you might consider your feature complete and tested. The local commit history may be untidy and confusing and may not tell the story well. You can tidy it up. Git interactive rebase is the tool to do this. You will get a file containing a list of commits which can be re-ordered, joined and have their messages edited.
IF and ONLY IF you have not modified your master branch, you can modify the entire feature branch history by doing an interactive rebase on master since that is the place the feature started. If master has changed locally, that will not do what you want. Instead, you have to find the start of the feature branch. If you followed the advice above, it will be tagged. This is a safer approach
- Tidy the feature branch history
git rebase -i start-feature
Quite possibly, you did not tag the start of the feature branch or have some other difficulty locating the place in master where the feature branch starts. Git lets you find this with a slightly arcane command:
- Tag the commmon ancestor of the feature and master branches
git tag start-feature $(git merge-base feature master)
After the interactive rebase, you should have a local feature branch history that can be added to the end of the master branch and will form the next published version.
Now you need to make sure that the new feature will work with the current state of master. If you are the only developer and only work on one feature at a time, this will be easy – you already know it works. But, if the master branch has changed for any reason, you need to test your changes. the master branch may have been changed by other developers or you may have changed it in some other operation – perhaps a bugfix, or another feature.
After making sure there are no uncommited changes in the feature branch, you need to switch back to master and bring it up to date. Everything should work without problems because we have a rule that says master is always good and we are just bringing master up to date.
At this point, the feature branch could be repased onto master and any issues dealt with there but that would leave your local master in an uncertain state. It is better to switch back to the feature branch and rebase master onto that and then sort out any issues. This way, only the feature branch is potentially broken.
git checkout master
- Return to the feature and incorporate the new master
git checkout feature
git rebase master
Now you have an up to date copy of master with your changes in your feature branch. If master has not changed, this will cause no problems and nothing will be committed so you can just carry on.
If master has changed while you were working on the feature then your changes may have caused conflicts. These will need to be resolved and changes made until everything is working again.
It is possible that this is an involved process and master changes some more in which case you might have to go around a couple of times. Whoever is in charge of maintaining the upstream repository should use a mechanism to make sure that this is unlikely.
Finally, you have a working feature in an up to date copy of master but it is all in your feature branch. You should also have an up to date master. This is a good time to do an interactive rebase and tidy up all the commit history so that it looks good when pushed up stream. Now you need to get your changes into the local master and push them upstream. (Note that managed repositories will use a pull request to incorporate changes. That is not dealt with here).
If it is important to track this version/revision/build, you can add a tag to the master branch and push that upstream so that specific versions can be pulled as needed at a future date.
- Incorporate the feature into master and push it up.
git checkout master
git rebase feature
git merge feature
git tag V18.09.15.a
git push origin master
git push origin V18.09.15.a
The git merge command will do a fast-forward and just bring the head of master up to the most recent commit.
When you are sure all is done, remember to tidy up. You can delete the local feature branch and temporary tags to save clutter. The tags and branches can be listed out so that you can find them easily.
git tag -d start-feature
git branch -d feature
And you are done. The feature is complete and master is up to date.