Git Best Parctice
Using git can somehow be tricky and lead to misusage of some features due to a lack of experience.
The purpose of the current page is to provide best practices so you can develop the right reflexes to ease your
use of git and your understanding.
- Set up your personal information
- Define the files to ignore
- B. Lifecycle
- Start properly
- Save changes
- Do not add current directory ‘.’
- Commit often
- Create as many branches as you need
- Don’t work in the destination branch
- Publish your branch when you’re ready
- Clean your repository after work
- Keep your repository update to date
- Use rebase when pulling a branch
- Put your work aside properly
- Commit Methodology (Write useful commit message)
- Write useful commit message
- Use the commit-msg hook to validate the commit message
- Make stable commit and test them
- Use the right tools
- D. Collaboration
- Normalize branches names
- Don’t rewrite public history
- Let your coworkers know directly when you’re done
A. Configuration
Set up your personal information
Rule
Always configure your account before starting working
Situation
You want to initiate a repository or clone a new one but your personal information are not defined thus it prevents you from committing properly.
Solution
Configure your global settings so you don’t need to do it everytime you create a new repository.
Here is how to set them:
prompt> git config –global user.name “GHM NOTES” prompt> git config –global user.email “contact@ghm-labs.com” |
Here is how to check the defined values:
prompt> git config –global –get user.name Ghm note prompt> git config –global –get user.email contact@ghm-notes.net |
Pros & Cons
- Advantages
- you always have elementary information defined so you can work
- Drawbacks
- you will have to set the information for a local repository
Further reading
Define the files to ignore
Rule
Always create a .gitignore file at repository root
Situation
You’ve created a repository from an existing directory or a brand new one. You want to avoid adding accidentally files that are not supposed to be recorded for versioning.
Solution
You create a .gitignore file at the root of your repository tree.
prompt> echo “# Root ignore file” > .gitignore prompt> printf “*.bak\n*.swp\*.swp” >> .gitignore |
Pros & Cons
- Advantages
- you don’t add files you don’t want to be versioned anymore
- every contributor will have the configuration
- Drawbacks
- you have to provide a file for your repository
- you have to explicitly add a file which pattern is being ignored
Further reading
B. Lifecycle
Start properly
Rule
Always make an initial commit to your repository
Situation
You want to create a new repository but don’t know how to start.
Reason
An initial commit is just there to mark the start of the versioning and allows you to add in a next commit all your changes . You can’t reset an initial commit and thus undo all the changes in it.
Solution
An initial commit can be created in two ways.
- with an empty commit
prompt> git commit –allow-empty -m “Initial commit” |
- This will create a totally empty commit.
- with a committed file, e.g. an README.md.
prompt> touch README.md prompt> git add README.md && git commit -m “Initial commit” |
Pros & Cons
- Advantages
- You can amend any changes after the initial commit if you’re not satisfied
- Repository can be restored to a fully empty state
- Drawbacks
- History starts with no changes
Save changes
Rule
Add your changes to the index as soon you’re satisfied
Situation
You’re making changes and arrived up to a point where some of them are stable enough for the element you’re
working on, thus you want them saved to avoid losing them after making a little change, an undo might cause losing them.
Reason
The index is the anti-chamber of the commit, every element added to it induce the creation of a git object tracking the file(s) state. Master the index it you’ll see every possibility to work on your changes.
Solution
You add the file state to the index. That way you can undo everything by discarding the current working tree state.
Here is an illustration:
prompt> echo ‘My stable change’ >> file-config.txt prompt> git add ze_file.txt prompt> echo ‘Another change to be discarded’ >> file-config.txt |
Then you can delete safely the added change:
prompt> sed -i.bak ‘2d’ file-config.txt prompt> rm -f *.bak |
Pros & Cons
- Advantages
- you’re change can be restored even if you undo everything in your editor
- Drawbacks
- you create a lot of objects in the git tree
Don’t add current directory ‘.’
Rule
Don’t add the current directory to the index
Situation
You want to add files that you have modified or created.
Reason
A repository might not be properly defined in its management of the file
Solution
Add the new files manually and/or add only the file updated using the -u flag.
prompt> git add -u |
This will prevent from adding any file not yet track but present in the working directory.
Pros & Cons
- Advantages
- ensure that only what is already known from git is added
- avoid adding file patterns that where not yet excluded from versioning through .gitignore file
- Drawbacks
- you have to add your files explicitly
Commit often
Rule
The often you commit the better Git will manage your changes
Situation You want to perform some changes and don’t want to lose their state
Reason
Commit is the way git stores your changes in a coherent whole.
Solution
Commit them by following the git saving process:
- make the change
- index the change
- commit the change
Example:
# 1. make the change prompt> echo ‘a new file content’ > myfile.txt # 2. index the change prompt> git add myfile.txt # 3. commit the change prompt> git commit |
Pros & Cons
- Advantages
- all your changes are stored and won’t be lost (supposing no disk crashing)
- Drawbacks
- you introduce a lot of objects in your git repository so you might need to garbage them more frequently
- your history becomes pretty long
Create as many branches as you need
Rule
Create as many branches as you need
Situation
You want to create a branch at a particular commit to easily go to the recorded state to perform tests or so on.
Reason
Creating a branch is cheap in Git so create as many branches as you need at the desired locations. Since branches are just files storing SHA-1 it’s cheap to handle.
Solution
Create a branch
prompt> git branch my-new-branch [<the-commit>] |
Example:
prompt> git branch develope/correct-error-feedback |
Pros & Cons
- Advantages
- branches are cheap to create
- Drawbacks
- repository can be cumbersome
Don’t work in the destination branch
Rule
Never work on the branch you must integrate your changes to.
Situation
You’re working on a feature that must be integrated in, let’s say, the develop branch.
Reason
Since the destination branch, here develop, might be shared by several contributors it will frequently receive new changes. The purpose this rule is to:
- avoid introducing undesired commits in it, like merge commits
- keep it as is so you can have a look on its behaviour
Solution
Create a feature branch in which you will do your changes, making them isolated from the shared branch.
prompt> git checkout -b feature/JiraId/initiate-work |
Pros & Cons
- Advantages
- you work without being polluted by others changes
- you can detect incompatibility easily when merging or rebasing your branch onto the shared one
- Drawbacks
- you have several branches
Publish your branch when you’re ready
Rule
Publish your work when you’re ready
Situation
You’ve work on a new feature and you are ready to publish it to the remote server either because you want to ensure that the CI/CD will work on it, or, that you’re about to create a pull request/merge request for it to be reviewed.
Reason
You want to proceed to the review of your work or even secrure your changes once their ready so they can be broadcast over every contributor repositories.
Solution
Use the push sub-command to publish to a remote.
Usage:
prompt> git push <the-remote> <the-source-branch-to-publish>[:<the-destination-branch>] |
Example:
prompt> git push origin -u feature/JiraId/add-Selectbox |
Pros & Cons
- Advantages
- make the branch available for peer review
- save the branch on another machine making it easily recoverable
- Drawbacks
- using the remote server as a backup
Clean your repository after work
Rule
Keep your repository as clean as possible.
Situation
You have work on many features and you’re done with most of them, i.e they all have been integrated in the main branches (develop or mastergenerally).
Reason
The more objects you create the more large becomes your local repository making it slower as things progress. Since local branches retain such objects is good to remove them if not necessary anymore.
Solution
Delete the old branches and eventually prune the remote ones.
prompt> git branch -d feature/jira_id/add-select-box |
You might use the flag -D instead of -d to force the deletion whenever the branch is not ‘fully’ merged.
prompt> git remote prune origin |
To clean up your local remote branches.
Pros & Cons
- Advantages
- low number of actives branches
- only branches you’re working on
- Drawbacks
- N/A
Keep your repository update to date
Rule
Stay up to date by fetching branches
Situation
You want to stay informed on any changes occurring on the repository.
Reason
Every time a change is performed on the server you need to retrieve a local copy of the remote elements. This way you can see if your local history is late regarding any updates.
Solution
You use the fetch sub-command to have the repository synchronised.
prompt> git fetch [origin] |
This will retrieve the remote branches of the origin remote.
Pros & Cons
- Advantages
- you can see incoming changes without updating your checked out branches.
- you can detect in advance sources of conflicts
- Drawbacks
- you might lose the state of a remote branch making you unable to restore it
Use rebase when pulling a branch
Rule
Pull rebase your branches
Situation
You want to retrieve the upcoming changes on a branch (after having fetched it).
Reason
Using –rebase option on pulling ensures that the branch history is kept as it is, that way it is straight forward and avoids any merge commit.
Solution
Pull your branch using –rebase flag or change the default behaviour of pull subcommand by setting option pull.rebase to true.
Example:
prompt> git chekout develop prompt> git fetch origin prompt> git pull –rebase |
Setting the option:
prompt> git config –global pull.rebase true |
Pros & Cons
- Advantages
- avoids pollution in the pulled branch
- keep history straight forward
- replays your work on top of the incoming changes
- Drawbacks
- you might lose the state of a remote branch making you unable to restore it
Put your work aside properly
Rule
Stash your changes when interrupted
Situation
You’re making some changes but need to switch to another branch to fix it or add something. You need to put your current working tree a side.
Reason
You can be asked to make a quick fix on a branch or help someone to do it. Thus you have to interrupt what you were working on without losing your changes.
Solution
Use the stash subcommand.
Example:
prompt> git stash save “Partial work of ticket” |
C. Methodology
Write useful commit message
Rule
Write a commit message which meaning and the less prone to interpretation
Situation
You’ve performed some changes and are about to commit them. You need to give a clear feedback of what you have done.
Solution
Write a clear commit message giving the context of the change and the list of actions taken to perform it using bullet points.
Principle:
[ISSUE REF] Brief purpose – action 1 – action 2 – … – action n |
Example:
[JIRA-ID] FIELD: add checkbox field – add a new checkbox field – add persistency layer – add service layer – … |
Pros & Cons
- Advantages
- your commit is self-describing
- you give reference for the issue tracking
- you gibe context so its easy to understand without exploring all the files changed (keeping it for code review details)
- Drawbacks
- you need discipline
- can be too verbose depending on the contributor (you need conventions)
Use the commit-msg hook to validate the commit message
Rule
Define a commit message convention and validate the commit message using the commit-msg hook
Situation
You want to ensure that the commit message complies to a predefined convention so that if it is not respected an commit will be rejected.
Solution
Use the commit-msg hook to validate the commit message pattern. You can write it using a script language such as bash, perl, python and ruby
Pros & Cons
- Advantages
- it prevents from committing a not-compliant commit message
- it disciplines you
- it slows down the commit rhythm so you improve your commit quality
- code review only focuses on the content of the message not its formatting
- Drawbacks
- it slows down the commit rhythm in case of mistakes
Make stable commit and test them
Rule
A commit must be step which is tested and stable.
Situation
You’ve made a change and are ready to submit it. You need to ensure that your changes are coherent.
Solution
You make a self-sufficient commit which is tested, adding unit tests to it, and stable. To ensure it use the hook pre-commit to run the unit test locally. Doing this you’ll ask yourself the following questions:
- is my feature completed?
- is my commit message relevant and understandable?
- is my code compiling
- did I test my changes locally (unit tests or manual test)?
- did I forgotten something (a file, etc.)?
Pros & Cons
- Advantages
- it ensures that tests are green before the commit
- it disciplines you and make you take good habits
- it helps improve code quality
- it decreases the CI failure rate
- Drawbacks
- it slows down the development process since test must be run before every commit
Use the right tools
Rule
Use the right tools
Situation
You’re new to git or you want to be proficient, thus you need to use the tools that will help you to be more efficient in your duties.
Reason
Git can be pretty complex for the noob and even for a confirmed user. Knowing the tools that can help you managing it and mastering it is a key.
Advice
You can use a set of tools like:
- Source Tree
- GitUp
- GitKraken
- Ungit
- Visual Studio Code
- Gerrit
- Gitolite
D. Collaboration
Normalize branches names
Rule
Normalize the branches names
Situation
You’re working on a feature and want to create a new branch for it.
Reason
When working in team or on an open source project it is good to follow a naming convention on branches. This way you can distinguish several purpose such as features, fixes, documentation, technical debts, work in progress and so on.
Solution
Define a branch naming convention and enforce it using hooks so that when pushing the branch it is rejected.
Pros & Cons
- Advantages
- ensures that every branch follows a naming pattern
- identifies the context and the purpose of the feature
- Drawbacks
- adds a convention
- must be enforced to be efficient
Don’t rewrite public history
Rule
Don’t rewrite public history
Situation
You’ve made some changes on your feature branch but you want to edit them back again, unfortunately you’ve publish it already and a colleague or a contributor is working on it already.
Reason
Since your branch is publicly available you need to inform each contributor working on it that you want you amend a commit in it and then force the branch.
The consequence are:
- contributor state might have diverged
- their must be too many contributor to reach
Thus once you’ve publish a branch is generally a bad idea to rewrite its history.
Solution
You can define a hook to prevent the rewrite of branches already published.
Pros & Cons
- Advantages
- ensures that all contributors are working on branches evolving the same way
- Drawbacks
- can’t sanitize a publicly exposed branch
Let your coworkers know directly when you’re done
Rule
Inform your fellow co-developer directly when they are interested in your changes
Situation
You made some changes on a branch and published them. These changes are followed by some other colleagues.
Solution
You communicate directly via a direct message using the collaborative messaging system your company use or you let them know when they are physically close .
Pros & Cons
- Advantages
- direct communication is cognitively more efficient than receiving an email lost among a lot
- Drawbacks
- you might interrupt someone
- you have to interact with another human being
Thank you ghm notes , very usefull