Skip to content

Instantly share code, notes, and snippets.

@dannytranlx
Forked from dmglab/git_bible.md
Last active April 5, 2022 11:15
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dannytranlx/5809c96ab783e43e9717e6ae1c5f73bd to your computer and use it in GitHub Desktop.
Save dannytranlx/5809c96ab783e43e9717e6ae1c5f73bd to your computer and use it in GitHub Desktop.
how to git

Note: this is a summary of different git workflows putting together to a small git bible. references are in between the text


How to branch

Try to keep your hacking out of the master and create feature branches. The feature-branch workflow is a good median between noobs (i have no idea how to branch) and git veterans (let's do some rocket science with git branches!). Everybody get the idea!

Basic usage examples

  • I need a new feature in my awesome software project: git checkout -b f/better-than-before
  • I found a bug! I need to fix that (bug fix) git checkout -b b/weird-error
  • I found a bug! I must do a workaround (hot fix) git checkout -b h/weird-error

Preferred prefixes

  • f/ (feature)
  • b/ (bug fix)
  • h/ (hot fix)

How to commit

  • Avoid staging multiple unrelated changes to the same commit (try git add -p to add specific lines)
  • Keep your first commit subject line short (about 50 chars)
  • Use imperative Add instead of Adds, Added or Adding
  • Use familiar keywords such as: Add, Update, Remove, Fix, Refactor, Improve, etc
  • If you made a typo, feel try to go git commit --amend to edit your message and add a missing file git add folder/file
  • Read more

How to keep your branch up to date

Initial situation

master   *---*---*-------* (master got new commits)
              \
f/new-feature  *---*---* (branched off 2 commits ago)

Do not merge! We should avoid merge bubbles!

Think before you pull changes from origin or you're getting into trouble.

Stop using the standardized merge strategy for git pull

This is wrong less ideal

master   *---*---*-------*
              \           \
f/new-feature  *---*---*---* (merge commit of master)

If you need an update from master or any other branch, try to rebase your branch instead of merging. Try to keep your branch history separated from master, so others can easily follow one straight line of commits.

This is what we want to do

master   *---*---*-------*
                          \
f/new-feature       -->    *---*---* (f/new-feature on top of updated master)

So, if you want to pull, try

git pull --rebase

You may want to set that as default

git config --global pull.rebase true

Then you can only run

git pull

If you want to update your work with stuff from master

git fetch -a && git rebase master

Use merge if rebasing is wasting too much time

If you're running into thousand of merge conflicts, try to merge, but do not merge in case of laziness!

If all hope is gone, use cherry pick as your last hope to get back to work. But use with wisdom! This is only for advanced users: further reading: cherry-pick vs. merge workflow

If you finished rebasing, push before somebody else does

If you try to push your rebased branch, your remote will reject your command, because you changed the history of your branch. You need to do a force push and this is not exactly ideal.

git push origin +f/new-feature

Use the + syntax, this will avoid you wrongly doing a git push -f to and from another branch.

It's dangerous to force push into a common/shared branch

If other people work on that branch too, inform them about your rebase and check before pushing.

But if you really need to (just be sure of what you are going), a teammate can get up-to-date with the new rebased branch

First, make sure to branch out before to not lose his work

git branch f/new-feature

Then you guys can reset the local branch to perfectly match the f/common-feature-branch on origin (the one we forced updated)

git reset --hard origin/f/common-feature-branch

After resetting, he can put his work back on top of the new rebased branch

git checkout f/new-feature

git rebase f/common-feature-branch

I'm done with my work

Merge your stuff into master through a GitHub pull request

Use the Squash and merge button to keep your master branch clean.

Initial situation

master   *---*-------*---*
                          \         
f/new-feature              *---*---*

[done by GitHub] git rebase -i HEAD~3

master   *---*-------*---*
                          \
f/new-feature              * (new squashed commit)

[done by GitHub] git merge master f/new-feature

master   *---*-------*---*
                          \
f/new-feature              * (master's HEAD is fast-forwarded to f/new-feature's HEAD)

This is wrong (merging with merge commit)

[done by GitHub] git merge master f/new-feature --no-ff

master   *---*-------*---*-----------* (merge commit, yikes!)
                          \         /
f/new-feature              *---*---*

We want to prioritize a simple straight line of commit. Feature branches going into master/integration should be squash and merge. However, we should be doing merge commits when going between master <-> integration <-> big-feature-branch as squashing squashed commits would squash too much commits losing our precious and detailed commit messages.

Troubleshooting

You cannot destroy anything (if you do not remove or manipulate your .git)

If you lost one of your commits, try use git log and find your straying commit.

If your commit is still unrecoverable, use the lost+found feature of git

If you fucked up while going git rebase, use git reflog and git reset --hard <sha> to a stable point


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment