Andrew Mercer
on this page

03 · Everyday Workflow

← Overview · Prev: Repositories · Next: Rebase →

git switch main && git pull                 # start from fresh main
git switch -c PROJ-1234-short-description   # branch name carries the ticket key
# ...edit...
git add -A
git commit -m "PROJ-1234 - what changed"
git push -u origin HEAD                     # first push sets upstream
# open the PR/MR from the URL git prints

After the PR is merged:

git switch main && git pull
git branch -d PROJ-1234-short-description
git push origin --delete PROJ-1234-short-description   # if the host didn't auto-delete it

If main moved while you were working, bring your branch up to date before pushing: Rebase.

git-adm: git-adm branch create → git-adm commit → git-adm push → git-adm branch delete / branch prune

Merging locally instead of via PR

git switch main
git merge <branch>          # creates the merge commit itself; no extra add/commit needed
git push

Only if the merge stops with conflicts: fix the files, git add <file>, then git commit. To abandon a conflicted merge: git merge --abort.

Merge outcomes:

  • Fast-forward — main is an ancestor of the branch, so git just moves the pointer. No merge commit. Force a merge commit anyway with git merge --no-ff <branch>.
  • Three-way merge — both sides have new commits; git creates a merge commit with two parents.
  • Squash — git merge --squash <branch> stages the combined changes; you write one commit.

Resolving conflicts: git writes markers into the file.

<<<<<<< HEAD
your side (the branch you are merging INTO)
=======
their side (the branch being merged)
>>>>>>> feature-branch

Edit the file to the desired result, delete the markers, git add <file>, then continue. Useful helpers: git diff --name-only --diff-filter=U (list conflicted files), git checkout --ours <file> / --theirs <file> (take one side wholesale), git config --global rerere.enabled true (remember and replay conflict resolutions).

Host web editors ("Resolve conflicts" buttons on GitHub/GitLab) do the same thing: merge the target into your branch, let you edit the markers, and commit the result.

Staging precisely

git add <file>            # stage a file
git add -p                # stage individual hunks interactively
git add -A                # everything: new, modified, deleted
git restore --staged <file>   # unstage
git diff                  # unstaged changes
git diff --cached         # staged changes (same as --staged)

Commit hygiene

  • Subject line ≤ 50 characters (hard limit ~72; hosts truncate beyond that), imperative mood ("Fix login redirect", not "Fixed" / "Fixes").
  • Blank line, then a body explaining why if it is not obvious.
  • One logical change per commit; squash noise before opening a PR.
  • git commit -am stages tracked files only. New files need git add first.
  • Prefix with the ticket key (PROJ-1234 - ...) if your team requires it; enforce it with a commit-msg hook.

Check state and history

git status
git status --short --branch
git log --oneline --graph --decorate -20
git log --name-status                      # files touched per commit
git log --name-status HEAD^..HEAD          # just the last commit
git log -p -- <file>                       # full history of one file, with diffs
git log --follow -- <file>                 # follow across renames
git log -S'some string'                    # commits that added/removed that string
git log --author=<name> --since=2.weeks
git show <sha>                             # one commit, with its diff
git diff main...HEAD                        # what my branch changes relative to where it forked
git blame <file>                           # who last touched each line
git diff --stat --cached                   # what is staged (ready to commit)
git ls-files                               # everything tracked
git fetch && git remote show origin        # is a pull needed?

git-adm: git-adm status, git-adm log, git-adm staged

Tags and releases

git tag v1.4.0                     # lightweight tag
git tag -a v1.4.0 -m "Release 1.4.0"   # annotated tag (preferred for releases)
git push origin v1.4.0             # tags are not pushed by default
git push origin --tags             # all tags
git tag -d v1.4.0 && git push origin --delete v1.4.0   # delete locally and remotely
git describe --tags                # nearest tag + commits since

Versioning scheme: Semantic Versioning, https://semver.org (MAJOR.MINOR.PATCH).

git-adm: git-adm bump updates version file(s); git-adm push asks you to confirm them.

Branching strategies

Model Idea Fits
Trunk-based Tiny branches, merged to main within a day or two; feature flags hide unfinished work Fast CI/CD teams
GitHub/GitLab flow Short-lived feature branch → PR → main; deploy from main Most teams
Git Flow main + develop + feature/*, release/*, hotfix/* Versioned, scheduled releases

Reading: https://nvie.com/posts/a-successful-git-branching-model · https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow · https://git-scm.com/book/en/v2/Git-Branching-Branching-Workflows · https://docs.microsoft.com/en-us/azure/devops/repos/git/git-branching-guidance · https://www.gitkraken.com/learn/git/best-practices/git-branch-strategy

Merge strategy on the host (PR button)

Option Result Trade-off
Merge commit Keeps all commits + adds a merge commit Faithful history, noisier graph
Squash and merge One commit on main Clean; loses individual commits
Rebase and merge Your commits replayed linearly, no merge commit Linear; commit SHAs change

https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/incorporating-changes-from-a-pull-request/about-pull-request-merges