Practical Git and Gitflow Snippets

This article will serve as a snippet of commands and steps with explanations that I use in my day-to-day job when working with Git and GitHub. It will also include common errors and instructions on how to connect to GitHub using a generated access token.
Common Commands
Initialize a Git Repository
git init
Initializes a new Git repository in the current directory.
Clone an Existing Repository
git clone <repo-url>
Clones a remote repository to your local machine.
Checking the Status of the Repository
git status
Displays the current state of your working directory and staging area.
Add a Remote Origin
To add a remote origin for your repository, run this command:
git remote add origin <remote-repository-URL>
Replace <remote-repository-URL>
with the URL of your remote repository (e.g., https://github.com/username/repository.git
).
Check the Remote Origin
To verify that the remote origin has been successfully added, run:
git remote -v
This will display the remote repository URLs associated with your local repository. You'll see something like:
origin https://github.com/username/repository.git (fetch)
origin https://github.com/username/repository.git (push)
Set a New Remote Origin
If you want to set a new remote origin (replace the existing one), you can use:
git remote set-url origin <new-remote-repository-URL>
Replace
Creating a New Branch
git checkout -b <new-branch>
Creates and switches to a new branch.
View Commit History
git log
Shows the commit history.
Stage Files for Commit
git add <file> # Stage a specific file
git add . # Stage all changes
Adds changes to the staging area, preparing them for commit.
Commit Changes
git commit -m "message"
Commits the staged changes with a descriptive message.
Checkout a Specific Commit or Branch
git checkout <branch-name> # Switch to a branch
git checkout <commit-hash> # Checkout a specific commit (detached HEAD)
Switches to a branch or a specific commit.
Merge Branches
git merge <branch-name>
Merges the specified branch into the current branch. This might trigger conflicts if changes are incompatible.
Resolving Merge Conflicts
When a conflict arises, Git will mark the conflicting files. Open the files and resolve conflicts manually. After fixing conflicts:
git add <file> # Stage resolved files
git commit # Commit the merge
Resolves and finalizes the merge by committing.
View Differences (Diff)
git diff # Show changes in unstaged files
git diff --staged # Show changes in staged files
Displays the differences between your working directory and the staging area or last commit.
Undo Changes in Working Directory (Discard Unstaged Changes)
git checkout -- <file> # Undo changes to a specific file
Discards local changes in a file (unstaged).
Stashing Changes (Save Changes Temporarily)
git stash
Temporarily saves changes in a stash so you can work on something else.
To apply the stashed changes:
git stash apply
Pop Stash (Apply and Remove the Stash)
git stash pop
Applies the most recent stash and removes it from the stash list.
Push Changes to Remote
git push origin <branch-name>
Pushes your local branch to the remote repository.
Pull Changes from Remote
git pull origin <branch-name>
Fetches and merges changes from the remote repository to your local branch.
Delete a Local Branch (If Not Checked Out)
git branch -d <branch-name>
Deletes the local branch, but only if it has been fully merged with the current branch (prevents data loss).
Force Delete a Local Branch (If Not Merged)
git branch -D <branch-name>
Forces the deletion of the local branch, even if it hasn’t been merged. Be careful, as this can result in losing unmerged changes.
Reset to a Specific Commit (Not Deleting Changes)
git reset <commit-hash>
Resets the HEAD to a specific commit but does not remove any changes from the working directory (this is the default "mixed" reset).
Remove the Last Commit (Soft Reset)
git reset --soft HEAD~1
Moves HEAD to the previous commit but keeps the changes staged. You can modify and recommit them.
Remove the Last Commit (Hard Reset)
git reset --hard HEAD~1
Moves HEAD to the previous commit and discards all changes (both staged and unstaged) in the working directory.
Amend the Last Commit
git commit --amend
Modify the last commit, either by editing the commit message or adding changes.
Cherry-Pick a Commit
git cherry-pick <commit-hash>
Applies the changes from a specific commit onto your current branch.
Force-Push Changes
git push --force
Pushes changes to the remote repository, even if it requires overwriting history. Be careful with this as it rewrites history.
Remove a Commit from History (Interactive Rebase)
git rebase -i HEAD~n # Where n is the number of commits to go back
Opens an editor where you can choose to drop or modify commits in your history. To permanently remove commits and rewrite history:
git push --force
Tagging a Commit
git tag <tag-name> <commit-hash>
View Stash List
git stash list
Shows a list of stashed changes.
Removing a Remote Branch
git push origin --delete <branch-name>
Deletes a remote branch.
Undo Changes in a File and Discard Staged Changes
git reset <file> # Unstage a file (but keep changes)
git checkout -- <file> # Discard changes from the working directory
Unstages a file or discards changes in the working directory.
Basic Rebase
git checkout <feature-branch> # Switch to the branch you want to rebase
git rebase <target-branch> # Rebase onto the target branch (e.g., `main` or `develop`)
This command will reapply the commits from feature-branch onto the tip of main. If there are no conflicts, it will result in a linear history.
Git rebase
applies your changes on top of another branch's commits, essentially re-writing history to make it look like your changes were made after the other branch’s changes. This eliminates the merge commits that would appear when using git merge
, giving you a cleaner, linear commit history.
So, while both git merge
and git rebase
integrate changes, rebase does so without introducing extra merge commits, making the history look more streamlined.
Delete a Commit during an Interactive Rebase
- Start the rebase:
git rebase -i HEAD~n
Replace n
with the number of commits you want to go back.
2. Mark the commit for deletion:
- In the editor that opens, locate the commit you want to delete.
- Change
pick
todrop
for the commit you want to remove. - Save and close the editor.
- Resolve any conflicts (if they arise during the rebase):
- Git will stop and notify you of conflicts.
- Fix the conflicts in the affected files.
- After resolving conflicts, stage the changes with:
git add <file>
- Continue the rebase
git rebase --continue
- Push the changes (force push is required since history has been rewritten):
git push origin <branch-name> --force
That’s it! We deleted a commit, resolved any conflicts, and pushed the changes.
Git Flow Workflow
GitFlow is a branching model for Git, created by Vincent Driessen at nvie, that defines a set of best practices for managing and releasing software projects. It provides a structured way to use Git, particularly for teams, ensuring consistent workflows and easy collaboration.
Example
A complete example demonstrating a Feature Branch Flow is as follows. Assuming we have a repo setup with a main branch.
git checkout main
git checkout -b develop
git checkout -b feature_branch
# work happens on feature branch
git checkout develop
git merge feature_branch
git checkout main
git merge develop
git branch -d feature_branch
In addition to the feature and release flow, a hotfix example is as follows:
git checkout main
git checkout -b hotfix_branch
# work is done commits are added to the hotfix_branch
git checkout develop
git merge hotfix_branch
git checkout main
git merge hotfix_branch
The overall flow of Gitflow is:
- A
develop
branch is created frommain
- A
release
branch is created fromdevelop
Feature
branches are created fromdevelop
- When a
feature
is complete it is merged into thedevelop
branch - When the
release
branch is done it is merged intodevelop
andmain
- If an issue in
main
is detected ahotfix
branch is created frommain
- Once the
hotfix
is complete it is merged to bothdevelop
andmain
How to Use a GitHub Token to Connect to a Remote Repository
To generate a GitHub token, go to:
Settings →
Developer settings →
Personal access tokens.
Here’s an example with placeholders for your GitHub token, username, and repository:
git remote set-url origin https://<YOUR_GITHUB_TOKEN>@github.com/<YOUR_GITHUB_USERNAME>/<YOUR_REPO_NAME>.git
Replace the following placeholders:
<YOUR_GITHUB_TOKEN>
with your actual GitHub token.
<YOUR_GITHUB_USERNAME>
with your GitHub username.
<YOUR_REPO_NAME>
with the name of your repository.
Make sure to keep your GitHub token secure and avoid sharing it publicly.
Some Errors and Fixes
Resolving Divergent Branches
When you see the error "You have divergent branches and need to specify how to reconcile them", follow these steps:
- Fetch the latest changes:
git fetch origin
- Rebase your branch on top of the latest updates from develop:
git rebase origin/develop
This will apply your changes on top of the latest develop branch updates.
- Push your changes:
git push origin develop
Resolving Conflicts (If Any)
If conflicts arise during the rebase:
- Fix the conflicts in the affected files.
- Stage the resolved files:
git add .
- Continue the rebase:
git rebase --continue
Contact Me
Have an opportunity, wanna collaborate on something cool or just say hello!
Send Email