CPS Revision control system
A revision control system is a special type of file system that stores the history of each file not just its current state.
The system we are using is called GIT. It is very powerful but has a notoriously difficult user interface. Currently one of the best references is the book Pro Git by Scott Chacon and Ben Straub. I have the book and the full text is available online.
Currently we are using a folder on our server as a central store, however in time I would like to move to running a proper GIT server. The folder serves our immediate on-site needs though.
All actual development work takes place on local copies, not on the server. Later the local copy can be pushed back to the server, updating it. The local copy can be on a hard drive, avoiding the need to keep working folders on the server.
Because all work takes place on local copies multiple people can work on the project at the same time, under Git you do not have to wait for someone to close a file but the downside is it is possible to have conflicting changes. If two people have worked on the project at the same time then a merge will be required. A git merge is very effective at identifying the actual changes and combining them.
Some basic concepts:
Commit: A snapshot of the project at a specific time. Each commit contains a reference to the commit or commits that preceeded it, so the resulting chain forms a history.
Branch: A chain of commits, forming a record of project history. Strictly the branch is a reference pointing to a commit.
Head: A special branch reference that always points to the branch being worked on. The head can also be pointed to a commit directly ("detached head") but this should not be done in general use, generally you either check out an existing branch or make a new one. You can create and delete local branches at will so feel free to make new ones as needed.
Index: An incomplete commit located in front of head and in the process of being built. Files must be added to index using "git add". There is also a command to delete a file and record its deletion. If a file is not added it stays as-is. When you actually commit your changes GIT points "HEAD" to the index, making it the new head.
Remember that revision control keeps a record of changes, so removing a file from index (using reset) doesn’t always delete it, instead it reverts the file to its previous state, though if the file previously did not exist then reset is effectively a delete. To delete a file that was previously committed either delete it normally then add its filename to record that it is no longer there or use git rm to delete it in both index and working tree.
Working Tree: The project folder. Certain operations overwrite this area, for example checking out a different branch will move HEAD to the different branch then replace the working tree files with the files from the new commit
Tracked file: A file that has been added to Index at some time and is now “known” to GIT
Untracked file: A file that is not in HEAD or Index, so will not be recorded
Ignored file: Git can be configured to completely ignore files that you don't want stored, for example temporary files or compiled code
Check out: The process of selecting a branch to work on.
Clean vs Dirty: A Clean working tree and index have files that match those in Head, so nothing will be lost if the working tree is overwritten. A Dirty tree has uncommitted work that could be lost. Several operations will warn or refuse to run if in a dirty state.
Reset: Has two or three meanings. Resetting a file puts it back to its unedited state. “reset head” clears out all uncommitted changes, and resetting a branch points the branch to a different commit.
Master: A default branch name. Git creates a Master branch by default, though to avoid confusion it may be better to avoid having a branch called Master in large projects.
Remote: The remote repository. In our case this is the server folder, but it could be an actual Git server, or a public system such as Github. Alternatively peer to peer operation is also possible, or a "remote" could be stored on a USB drive and passed round as needed.
Origin: The default upstream remote repository that git updates to and from
Clone: The process of taking a copy of a project to work on.
Fetch: Retrieve any updates (other people's work) from the remote
Pull: Retrieve updates and merge them with your copy (you may prefer to fetch, review, then merge.
Push: Update the remote with your work
Force: Ignore warnings and do it anyway. Generally if you need force you are either doing something wrong, or fixing a mistake
Example of using Force: Something was pushed to a remote that really must not be stored there such as a password file. To fix this you might correct it locally then force the corrected version onto the remote. This will cause problems for anyone else who has already pulled in the bad version, so in a team you have to coordinate this kind of rewrite.
Rebase: a tricky concept, normally the chain of commits represents a simple timeline of development but if a branch is based on an obsolete version it may be tricky to merge back into the current version. An alternative is to take the changes that took place in that branch and apply those changes to a newer version, recreating the branch but now it is based on a newer version, hence re-base.
Rebase can also be used to rewrite parts of project history.
Filter-branch: A more drastic version of rebase where a “filter” is applied to each file in each commit, recreating the project history. Examples are:
Line endings: Linux text files end in LF. Windows uses CRLF, and we have it configured to convert files to Linux form when they are stored and back to Windows form when they are extracted ('checked out').
Line endings mostly "just work" but some programs need specific configuration to work properly. One slightly irritating special case is when a Windows program generates some LF-ended text files. These can be committed successfully, but might be converted to CRLF form when checked out.
Slashes in file paths: Git uses forward slashes for paths. Command line Git will mostly correctly convert windows style backslash paths but in the bash shell backslashes have a different meaning, and the graphical git-gui tool seems to need forward slashes exclusively.
Drive letters are often represented by a forward slash followed by the letter, so “C:\Windows” becomes “/C/Windows”.
Bash shell: “Bash” is commonly used in Linux, performing a similar role to Command.com in Windows. By running bash under Windows we can execute commands that would fail under the normal windows command prompt. For example bash can accept UNC server paths.
The issues encountered using MPLAB git are documented elsewhere, however it should be noted that much of this was due to inexperience and mis-configuration.