Hello CodeNewbie community!
I wrote this post to share some clarifications about what Git helps us to do and how to use it more effectively when working with distributed teams.
For me personally, I used Git a lot back in college without actually knowing how it worked. Being it so foreign for me would cause some sticky situations that I didn't know how to get out of by myself.
I hope this gives others a broader picture of the use of Git and how to avoid some unnecessary pains.
With that said, here it is!
Git is a tool that we use for what is called "Version Control". Something like a team of developers, each one has a copy of a project with changes that are part of the current work.
Each developer has a version of the codebase and the system that allows the seamless integration of those changes is the version control system (i.e. Git)
By using version control the process of development, especially collaborative development, is much easier and user friendly.
It allows us to do things like:
- Have a local archive of all the changes made over the history of the project.
- Be able to go "back in time" to restore changes or go to a point where things were working correctly.
- Avoid the pain of having to agree which person does what changes and integrate them without overwriting someone else's work.
- If done properly, have a log of all the important changes of a project and use it as release notes.
- Reduce communication overhead between teammates and provide a common context of what's being currently worked on.
- Provide some sort of "passive communication" in which it can help spark conversations about what's happening in the codebase.
Among other things. The important part is that version control can allow teams to move faster on the development process and be flexible with the features that can be released or held off for a later time.
Inevitably, the bigger the team and the more people contributing changes to a codebase the more challenging the communication becomes (more across different time zones).
Using Git, and something like GitHub, most of those challenges can be tackled in a simpler and more productive way.
By itself, version control is a very useful tool and it can be even more powerful when used in a proper way.
Since with all the features of Git we have great power and flexibility to manage our code, it is also important that we use it responsibly to not break or wipe the work done by others.
Here are some recommendations that have been useful for me and several others.
I used to be the type of person that would do one commit with the changes of one entire work session and then another commit in the next one and so on. My work history would have a couple of, often very massive, commits.
That's all well and good if you're working solo or with a partner that you know well. However, in a distributed team with perfect strangers, it can lead to some troubles.
In that case, it's best that you shorten the amount of work you put in the commits.
Don't go to the other extreme and make a commit for every random change done. It's best to make one for each task that you have to get done in order to finish a feature/solving a bug.
Still, you can make several commits locally and then squash them before pushing to the remote. That way, the remote repo will have a more descriptive commit log.
Whenever you have to do new work, make sure you're starting from the latest version of the code. This is to avoid conflicts later when trying to merge your work.
(Work that later can create several conflicts due to starting from an outdated version of the codebase).
It depends as well on how is the workflow for approving merges, handling branches, and stuff.
For instance, in some projects, the master branch is protected and no one can push work directly. Any new changes have to be uploaded to a "testing" or "sandbox" branch before it gets approved.
So whether you're starting the work based on the master branch or a feature branch. Make sure you're always checking for new changes and additions to the codebase.
That's so you can have a much smoother experience when uploading your work and requesting a merge.
This one is more related to the project guidelines (if there are any). It's okay to write random stuff that only you understand if the project is a personal thing.
In bigger projects however, it's better to make your commits say what the person is going to find once the changelog gets opened.
If you worked on one part of feature X, then write what it is that had to change for that feature. This is so it's easier for others to review.
As well you don't want to give others extra work especially if you're just starting to work with a new team.
Then again, if there's a set of guidelines for how the commits should be made, (e.g. 'name of the ticket': 'brief description of the change') use those. Align to what's best for the team and the readability of the commit log.
One of the great features of Git is that it gives us a "staging area" where we can keep work that's been done but not ready yet to be committed.
But often what happens is that we might be a little too used to run the command
git add ..
That will add all the current changes even the ones that we don't want to commit.
Even worse the command
git add -A, which makes everything get added (even local config files that have nothing to do on the remote repo).
That's why before committing something, make sure all changes added are related to that commit and make sense as a standalone unit of work. That way, all those commits will make sense once they're pushed to the remote.
Properly using the staging area is a powerful feature that allows us great flexibility when working on several user stories/bugs simultaneously.
And speaking of working on several things in an asynchronous fashion...
This one should go without saying. Git can be the ultimate tool for handling several different lines of work that one can jump between whenever the situation arises.
Still, don't use it as a "multitasking" enhancing feature because, in reality, actual 'good multitasking' doesn't exist. Use it more as a way to keep all work you've been doing organized and separated from each other.
If you were working on a feature that later on showed some bugs in QA, you can switch from what you're currently doing to the branch that has those changes.
Once there, create the fix and upload it upstream. If everything works well, you can go back to the other branch you were initially on and resume work there.
This one could be the most important point because as you've seen, all previous points can be modified or altered in a way based on the results from this one.
Several things can happen when agreeing on a common workflow, like:
- The commit messages are going to be in X format instead of Y format.
- The work it's going to be done in several incremental steps and the commits will be squashed before getting into the master branch.
- They're going to be rebased instead, depending on the feature being worked on.
- What's going to be released and when.
- What day is going to be specifically for QA work so no more commits will be allowed (unless it's something like a hotfix).
And so on.
What's important is to agree on a specific workflow that everyone is aware of and can follow.
That will improve greatly the team communication and avoid wasting time nitpicking on details. The already placed guidelines will give everyone a sense of order and structure.
Knowing how version control works and how to use it effectively, will undoubtedly expand our development productivity and skill when working with distributed teams.
Independently of the service being used to host the code online (GitHub, GitLab, BitBucket, etc...).
Knowing Git will give us the confidence to do our work focusing and what we know instead of the little details of handling pieces of work all around to get to the repo.
It will allow us to recover from errors and help get others out of a tough situation when it arrives.
It's also good to not only know how our tools work but also to use them correctly. And see if there are better alternatives out there to make the work we do better each time.