Git gives you many commands to understand the state of your repository before you act. Used well, they prevent most conflicts at push time. This tutorial explains the key commands, their main parameters, and concrete examples.


1. The Principle: Look Before You Act

A safe routine before every push:

git fetch origin                 # 1. update your view of the remote (does not touch your code)
git status -sb                   # 2. current state + ahead/behind counters
git log --oneline HEAD..@{u}     # 3. what others added that you don't have
git log --oneline @{u}..HEAD     # 4. what you have that is not pushed yet
git pull --rebase                # 5. integrate cleanly
git push

Tip: @{u} (or @{upstream}) is the remote branch tracked by your current branch. You no longer need to type origin/feature/my-branch.


2. Commands to Observe

git fetch

Downloads new data from the remote without modifying your working files.

Main parameters:

  • --all: fetch from all remotes
  • --prune (-p): remove local references to remote branches that were deleted
  • --tags: also fetch tags
git fetch --all --prune
git status
git status -sb
  • -s: short format
  • -b: show the branch and its difference with the remote

Example output:

## feature/my-branch...origin/feature/my-branch [ahead 1, behind 2]
  • ahead 1: you have 1 commit that is not pushed
  • behind 2: the remote has 2 commits you don’t have
  • ahead AND behind means the branches have diverged, so a conflict is possible
git log

The most powerful command for observing history.

Main parameters:

  • --oneline: one commit per line
  • --graph: draw the branch structure
  • --decorate: show branch and tag names
  • --all: include all branches
  • -n 10 or -10: limit to 10 commits
  • --author="Marek": filter by author
  • --since="2 days ago": filter by date
  • --stat: show files changed per commit
  • -p: show the full diff of each commit
  • -- <file>: history of a single file
git log --oneline --graph --decorate --all -15
git log --author="Marek" --since="1 week ago" --stat
git log -p -- estaTektonPipeline.json
The .. and … notations
  • A..B: commits that are in B but not in A
  • A...B: commits that are in A or B, but not in both (symmetric difference)
git log --oneline HEAD..origin/feature/my-branch    # what you don't have yet
git log --oneline origin/feature/my-branch..HEAD    # what you haven't pushed
git log --oneline --left-right HEAD...@{u}          # both sides at once

With --left-right, < means your side and > means the remote side.

git show
git show 72a6c875b                           # full commit
git show 72a6c875b --stat                    # only the changed files
git show 72a6c875b:estaTektonPipeline.json   # the file as it was at that commit

Note for Windows cmd: do not add a trailing # comment on the command line. Windows cmd does not treat # as a comment, so Git will fail with “ambiguous argument ‘#'”.

git diff
  • git diff: working directory vs index (unstaged changes)
  • git diff --staged: index vs last commit
  • git diff HEAD: working directory vs last commit
  • git diff A..B: compare two commits or branches
  • git diff A...B: compare B against the common ancestor (ideal to review a pull request)
  • --stat: summary of changed files
  • --name-only: list file names only
git diff @{u} --stat
git diff origin/master...HEAD --name-only
git blame

Shows who last modified each line, and when.

git blame -L 4,8 estaTektonPipeline.json    # only lines 4 to 8

3. Commands to Avoid Conflicts

git pull: three strategies
  • git pull: fetch + merge (may create a merge commit)
  • git pull --rebase: fetch + rebase (linear history)
  • git pull --ff-only: refuses if branches diverged (the safest option)
git pull --ff-only

If there is a divergence, it fails cleanly and you decide what to do.

Make your preferred behavior the default:

git config --global pull.rebase true
git config --global fetch.prune true
git rebase

Replays your commits on top of another branch.

git fetch origin
git rebase origin/master

Main parameters:

  • --continue: continue after resolving a conflict
  • --abort: cancel everything and return to the initial state
  • --skip: skip the problematic commit
  • -i HEAD~3: interactive mode (squash, reword, drop)

Golden rule: never rebase commits that are already pushed and used by other people.

git merge

Main parameters:

  • --ff-only: accept only a fast-forward
  • --no-ff: force a merge commit
  • --abort: cancel a merge in progress

A dry run to preview conflicts before a real merge:

git merge --no-commit --no-ff origin/master
git merge --abort
Safe git push
  • git push: normal push, rejected if the remote has moved forward
  • git push --force: dangerous, can overwrite other people’s work
  • git push --force-with-lease: refuses if someone pushed in the meantime (much safer)
  • git push --dry-run: simulates the push without sending anything
git push --dry-run
git push --force-with-lease     # only after rebasing your own branch
git stash: set work aside
git stash push -m "wip: side panel"   # stash with a name
git stash list                        # list stashes
git stash pop                         # restore and delete the stash
git stash apply                       # restore and keep the stash
git stash push -u                     # also include untracked files

Use it before git pull --rebase if your working tree is not clean. Shortcut: git pull --rebase --autostash.


4. Commands to Undo Things

Choose the command according to the situation:

  • Unpushed commit, keep changes staged: git reset --soft HEAD~1
  • Unpushed commit, keep changes as modified files: git reset --mixed HEAD~1 (default)
  • Unpushed commit, delete everything: git reset --hard HEAD~1 (destructive)
  • Already pushed commit: git revert <hash>
  • Discard changes in a file: git restore <file>
  • Unstage a file: git restore --staged <file>
  • Fix the last unpushed commit: git commit --amend
The safety net: git reflog

Even after a bad reset --hard, you can usually recover your commits.

git reflog                       # history of all HEAD movements
git reset --hard HEAD@{2}        # go back to the state 2 moves ago

5. Resolving Conflicts

git status                       # lists files marked "both modified"
# edit the file and remove the <<<<<<<, =======, >>>>>>> markers
git add <file>
git rebase --continue            # or: git merge --continue

Useful tools:

git checkout --ours <file>       # keep your version (during a merge)
git checkout --theirs <file>     # keep the other version
git mergetool                    # open the configured tool (VS Code, IntelliJ)
git config --global merge.conflictstyle zdiff3   # also show the original version

Rebase pitfall: during a rebase, ours and theirs are inverted. ours is the branch you rebase onto, and theirs is your own commits.


6. Handy Aliases

git config --global alias.st "status -sb"
git config --global alias.lg "log --oneline --graph --decorate --all -20"
git config --global alias.incoming "log --oneline HEAD..@{u}"
git config --global alias.outgoing "log --oneline @{u}..HEAD"
git config --global alias.sync "pull --rebase --autostash"

Then you can run:

git fetch && git st && git incoming && git outgoing

7. Searching the History

git log -S"buildTaskName" --oneline       # commits that add or remove this string
git log -G"password" --oneline            # commits whose diff matches this regex
git log --grep="fix(ci)" --oneline        # search commit messages
git log --grep="ITOP-9220" --oneline      # find all commits of a Jira ticket
git log --since="2 days ago" --until="1 hour ago" --oneline

8. Git in a DevOps Context

  • CI/CD (Tekton, OpenShift): each push can trigger a pipeline run. Using git push --dry-run and a clean rebase avoids useless and expensive runs.
  • GitOps (ArgoCD): the Git branch is the source of truth. A force push can desynchronize a deployment, so prefer git revert.
  • Traceability (Jira, Confluence): keep the ticket key (for example ITOP-1234) in every commit message.
  • Secrets (Vault): use git log -p -S"secret" or git log -G"password" to detect a secret committed by mistake.
  • Monitoring (Splunk): correlate an error spike with git log --since="..." --until="...".

9. Best Practices

  1. Make small, atomic commits: one logical change per commit.
  2. Use conventional commit messages: feat:, fix:, chore:, revert:.
  3. Always fetch first: look before you act.
  4. Rebase your own branch, merge shared branches.
  5. Never use --force: use --force-with-lease instead.
  6. Keep pull requests short to reduce conflict risk.

10. Recommended Workflow

git fetch --all --prune
git lg                          # graph view (alias)
git incoming                    # what do I need to receive?
git outgoing                    # what am I about to send?
git pull --rebase --autostash   # integrate
git push --dry-run              # simulate
git push                        # send

11. Going Further

  • git bisect: automatically find the commit that introduced a bug
  • git cherry-pick <hash>: apply a single commit from another branch
  • git worktree: work on two branches in parallel without stashing
  • git rerere: remember how you resolved conflicts and reuse the resolution

By Shabazz

Software Engineer, MCSD, Web developer & Angular specialist , BizDevOps

Leave a Reply

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