Git-Best-Practice

Git Best Practice

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.

  1. Set up your personal information
  2. Define the files to ignore
  3. B. Lifecycle
  4. Start properly
  5. Save changes
  6. Do not add current directory ‘.’
  7. Commit often
  8. Create as many branches as you need
  9. Don’t work in the destination branch
  10. Publish your branch when you’re ready
  11. Clean your repository after work
  12. Keep your repository update to date
  13. Use rebase when pulling a branch
  14. Put your work aside properly
  15. Commit Methodology (Write useful commit message)
  16. Write useful commit message
  17. Use the commit-msg hook to validate the commit message
  18. Make stable commit and test them
  19. Use the right tools
  20. D. Collaboration
  21. Normalize branches names
  22. Don’t rewrite public history
  23. 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

Getting starting

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:

  1. make the change
  2. index the change
  3. 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

About zelmanti

GHM Notes is my personal blog, where I share about technologies ,framework I used, the books I'm reading, and what I'm learning. I hope that you'll join the conversation.

1 Comment

  1. Thank you ghm notes , very usefull

Leave a Comment

Your email address will not be published. Required fields are marked *