Inspecting Branch States
Determining which branch your working directory is attached to can be done instantly. The active branch corresponds to the current HEAD reference:
$ git branch --show-current
main
To list all locally available branches, execute:
$ git branch
feature/auth
* main
The asterisk (*) marks the currently checked-out branch. To inspect remote tracking references managed by your repository, use:
$ git branch -r
origin/release-v2
origin/main
A comprehensive view that combines both local and remote pointers requires the -a flag:
$ git branch -a
* main
feature/auth
remotes/origin/main
remotes/origin/release-v2
Appending verbose information reveals the latest commit hash associated with each branch:
$ git branch -v
feature/auth a8f2c1d Initial authentication setup
* main b9e4d02 Update deployment scripts
Merged vs. Unmerged History
Branches whose changes have already been integrated into the current HEAD can be identified safely for removal:
$ git branch --merged
release-notes
* main
Lines missing the leading asterisk represent integrated history. These can typically be removed without data loss. Conversely, branches containing unresolved work will appear under the unmerged filter:
$ git branch --no-merged
bugfix/header-overlap
Attempting to remove an unmerged branch with a standard deletion command triggers a safeguard warning:
$ git branch -d bugfix/header-overlap
error: The branch 'bugfix/header-overlap' is not fully merged.
If you are sure you want to delete it, run 'git branch -D bugfix/header-overlap'.
When you explicitly intend to discard uncommitted work on that lineage, the forceful deletion flag bypasses the safety check:
$ git branch -D bugfix/header-overlap
Deleted branch bugfix/header-overlap (was a8f2c1d).
Navigating Branch Contexts
Transferring your working directory to a different branch rewrites the tree according to that branch's commit history:
$ git checkout feature/auth
Ensure all pending modifications are committed or stashed before switching, as checkout overwrites local files to match the target branch's snapshot.
Removing Branch References
Standard removal requires the branch to be fully merged into its upstream counterpart:
$ git branch -d feature/auth
$ git branch --delete feature/auth
Force removal overrides the merge validation and permanently discards the branch history:
$ git branch -D feature/auth
This operation is irreversible and should be executed with caution in shared environments.
Establishing New Branches
Create a detached lineage without altering your current position:
$ git branch feature/api-refactor
Instantiate a branch and immediately pivot your workspace into it:
$ git checkout -b feature/api-refactor
When initializing development work based on a remote repository's state, first synchronize references and then spawn a local tracking branch:
$ git fetch origin
$ git checkout -b feature/api-refactor origin/release-v2
Visualizing the commit graph alongside branch pointers helps clarify lineage relationships:
$ git log --oneline --decorate
The --oneline flag condenses entries, while --decorate appends symbolic references like HEAD, main, or remote tags to their respective commits.
Merging Strategies
Fast-Forward Integration
When the target branch is a direct descendant of the source branch, Git advances the pointer linearly without generating additional metadata:
$ git checkout main
$ git merge feature/api-refactor
Updating c1d2e3f..a8f2c1d
Fast-forward
config.yaml | 5 +++++
utils.py | 12 ++++++++++++
This approach maintains a perfectly linear timeline. It occurs when no divergence exists between the two branches since the last common commit.
Three-Way Merge (Recursive)
If both branches evolved independently from a shared ancestor, Git constructs a new merge commit that records both parents:
$ git checkout main
$ git merge feature/api-refactor
Merge made by the 'recursive' strategy.
database.js | 8 +++-----
router.ts | 15 +++++++++++++++
create mode 100644 middleware.js
This merge commit acts as a junction node. Git automatically selects the optimal common ancestor to compute differences, streamlining the integration process compared to manual patch application.
Resolving Divergence Conflicts
Simultaneous edits to identical line ranges trigger automatic conflict detection:
$ git checkout main
$ git merge feature/api-refactor
Auto-merging app.js
CONFLICT (content): Merge conflict in app.js
Automatic merge failed; fix conflicts and then commit the result.
Conflicted sections are annotated with explicit delimiters in the affected files:
$ cat app.js
<<<<<<< HEAD
app.js updated on main
=======
app.js modified in feature branch
>>>>>>> feature/api-refactor
Resolution requires manually editing the file to retain the desired logic, removing the delimiter markers, staging the corrected file, and finalizing the merge:
$ git add app.js
$ git commit -m "Resolve routing conflicts in app module"
Upstream Branch Association
Linking a local branch to a remote counterpart simplifies future pull and push operations by defaulting to the tracked destination.
Querying Tracking Configuraton
$ git branch -vv
feature/auth a8f2c1d [origin/feature/auth] Added OAuth middleware
* main b9e4d02 [origin/main] Updated CI pipeline
Configuring Remote Tracking
Bind a local branch to an existing remote reference using either shorthand or explicit naming:
$ git branch -u origin/feature/auth
$ git branch --set-upstream-to=origin/feature/auth
The specified remote reference must exist prior to binding; otherwise, Git returns a validation error.
Disassociating Tracking Links
Detaching the upstream relationship reverts push/pull behavior to require explicit remote specification:
$ git branch --unset-upstream feature/auth
Creating Branches with Direct Tracking
Sometimes it is more efficient to spawn a new branch that automatically inherits a remote tracking relationship upon creation:
$ git branch -t feature/auth origin/feature/auth
$ git branch --track feature/auth origin/feature/auth
This pattern eliminates separate synchronization steps and ensures immediate upstream alignment for collaborative workflows.