git best practice
Git is easy to start with and hard to master. Over the years I have collected a short list of habits that keep a repository clean, keep the history readable, and keep teammates happy. None of them are complicated, but skipping them tends to create pain later.
-
Configure
user.nameanduser.emailproperlyEvery commit is stamped with the name and email from your git config. If these are wrong, your commits show up under the wrong identity, blame becomes misleading, and on hosted platforms the commits may not link to your account. Set them globally with
git config --global user.nameandgit config --global user.email, and override them per repository when you contribute under a different identity (for example a work email on work projects). Double check withgit config user.emailinside a fresh clone before your first commit. -
Understand and use common git CLI commands
GUIs are convenient, but they hide what git is actually doing and often lag behind git’s features. Knowing the core commands by heart —
status,add,commit,log,diff,branch,checkout/switch,fetch,pull,push,stash,rebase,reset— lets you work anywhere, script repetitive tasks, and understand error messages instead of guessing. When something goes wrong, the CLI is also where the answers and recovery tools live. -
Make good commit messages
A commit message explains why a change was made; the diff already shows what changed. Write a concise summary line (roughly 50 characters, imperative mood, like “Fix null check in parser”), then a blank line, then a body that gives context: the problem, the approach, and any trade-offs or links to tickets. Future readers — including yourself six months from now — will rely on these messages when hunting for the reason behind a line of code.
-
Use
.gitignoreto filter files that shouldn’t be committedBuild artifacts, dependency folders (
node_modules), local environment files, editor settings, and secrets should never enter the repository. Committing them bloats the repo, causes constant merge conflicts, and can leak credentials. Add a.gitignoreearly, use community templates for your language or framework, and remember that.gitignoreonly affects untracked files — anything already committed must be removed withgit rm --cachedfirst. -
Avoid committing large binary files
Git stores the full history of every file forever. Large binaries (videos, datasets, compiled archives, design assets) make every clone slow and permanently inflate the repository, even after you delete them. Keep binaries out of git when you can; when you genuinely need them versioned, use Git LFS or an external artifact store so the main history stays lean.
-
Understand rebase and merge
Both commands combine work from two branches, but differently.
mergecreates a merge commit that ties two histories together, preserving exactly what happened.rebasereplays your commits on top of another branch, producing a straight, linear history but rewriting your commit hashes. Knowing how each behaves — and that rebasing rewrites history — is essential before choosing one in a given situation. -
Try to rebase when merging
For integrating a feature branch, rebasing onto the target branch first keeps history linear and easy to read, makes
git bisectandgit logfar more useful, and avoids a tangle of merge commits. The rule of thumb: rebase your local, unpushed work freely, but never rebase commits that others have already pulled, since that rewrites shared history. -
Rebase from your target branch often
If your feature branch drifts far from
main, the eventual integration becomes a painful, error-prone conflict resolution session. Pulling the latest target branch and rebasing onto it frequently — daily, or whenever the target moves significantly — keeps conflicts small and lets you resolve them while the context is still fresh in your mind. -
Understand and use
resetgit resetmoves the current branch pointer and, depending on the mode, your staging area and working tree.--softkeeps your changes staged,--mixed(the default) unstages them, and--harddiscards them entirely. It is the tool for undoing local commits, unstaging files, or starting over. Use it confidently on local work, but be careful with--hardand never reset commits you have already pushed to a shared branch. -
Avoid creating short one-word branch names like
fix,test, etc.Vague branch names tell nobody what the branch is for, collide easily, and become impossible to clean up later because you can’t tell which is safe to delete. Use a descriptive convention such as
type/short-descriptionor include a ticket number, for examplefix/login-redirect-looporfeature/1234-export-csv. The name should still make sense to a teammate weeks from now. -
Clean up branches; delete unused, obsolete branches
Merged and abandoned branches pile up until
git branchoutput is unusable and nobody knows what is active. Delete branches once they are merged (git branch -d, and prune remotes withgit fetch --prune), and periodically review stale branches. A short branch list makes the repository easier to navigate and signals what work is actually in progress.