✨ Mastering Git Commands: From Basic to Advanced ✨
Introduction:
Git is a powerful version control system that's fundamental for modern software development. Whether you're new to Git or looking to advance your skills, mastering a range of Git commands is key to effective code management. This blog takes you through the essential Git commands, from simple operations like committing and branching to more advanced topics such as rebasing and cherry-picking. By the end, you'll have a comprehensive understanding of Git and the confidence to use it effectively in your projects.
How to commit, push, and pull from GitHub : Scenario:
🔹Login to any EC2 instance
🔹Create one directory and go inside it
🔹git init -> is used to initialize a new Git repository for a project. It sets up the necessary files and data structures that Git needs to start tracking changes to your project's files
🔹touch myfile ->creates an empty file
🔹git status ->shows the status of repo, files, working dir data, commit, etc
🔹git add . ->adds code from working dir to staging path
🔹git commit –m “My first commit” -> To save
🔹git log -> shows details on who has committed the code along with commit-id, email id and time of commit, etc
🔹git show -> shows what has been committed
🔹git remote add origin -> copies the code from local to remote i.e., GitHub
🔹git push –u origin master
Commit: Save Changes Locally
What: Record changes to your files in your local repository.
How: Use git add . to stage changes, then git commit -m "Your message" to save them.
Push: Share Changes to GitHub
What: Send your commits to GitHub for others to see.
How: After committing, use git push to upload your changes to your GitHub repository.
Pull: Get Changes from GitHub
What: Bring updates made by others on GitHub to your local repository.
How: Use git pull to fetch and merge changes from the GitHub repository to your local copy.
gitignore:
To ignore some files while committing
create one hidden file .gitignore and enter the file format which you want to ignore, for example, vi .gitignore
.css
.java
In the above file, gitignore will exclude executing CSS and java files respectively git add .gitignore
git commit –m “exclude .css & .java files”
git status
◼️Purpose: It tells Git which files or directories to ignore when tracking changes. ◼️Usage: Create a file named .gitignore in the root directory of your repository.
◼️Syntax: Each line in the .gitignore file specifies a pattern to match files or directories to ignore. You can use wildcards and negation to specify patterns.
By using .gitignore, you can keep your repository clean and focused on the important files while ignoring irrelevant or generated files.
How to create a Branch:
To create a new branch in Git, you can use the git branch command followed by the name of the new branch. Then, you can switch to the newly created branch using git checkout.
🔸git branch -> shows on which branch we are currently in
🔸git branch <branch_name> -> creates a branch with the given name
🔸git checkout <branch_name> -> This command switches your working directory to the new branch you just created.
🔸git checkout -b <branch_name> -> This command creates a new branch named <branch_name> and switches your working directory to it in one step.
🔸git branch –d <branch_name> -> deletes branch name
🔸git branch –D <branch_name> -> forceful delete
MERGE:
To merge changes from one branch into another in Git, you can use the git merge command. Here's how to do it:
💠Checkout the Target Branch: First, ensure you are on the branch where you want to merge changes. Use the git checkout command to switch to the target branch:
👉git checkout <target_branch>
💠Merge the Source Branch: Once you are on the target branch, use the git merge command followed by the name of the source branch you want to merge into the target branch:
👉git merge <source_branch>
This command will merge the changes from the source branch into the target branch. 💠Commit the Merge: After resolving any conflicts, commit the merge to complete the process:
👉git commit -m "Merge <source_branch> into <target_branch>"
Replace <source_branch> and <target_branch> with the actual branch names.
GIT CONFLICT:
When a file contains different content in separate branches, merging them may lead to conflicts. In such cases, conflicts must be resolved by addressing the differences between the branches. Once resolved, the changes should be staged with the add command and committed using commit. Even if it shows conflict, Merge should have happened already, so after editing file merge is not needed again.
GIT STASHING:
Git stashing allows you to temporarily store changes in your working directory without committing them to the repository. This is useful when you need to switch to a different branch or work on a different task without committing unfinished changes.
Suppose you are implementing a new feature for your product, your code is in progress and suddenly a escalation comes, you have to keep aside your new feature and work for few hours. You cannot commit your partial code and also cannot throw away your changes. So you need some temporary storage where you can store your partial changes and later on commit it.
⚡To stash an item (only applies to modified files not new files)
⚡To stash items list -> git stash list
⚡To apply stashed items -> git stash apply stash@{0}, Then you can add & commit
⚡To clear the stash items -> git stash clear
⚡To apply the changes and remove them from the stash -> git stash pop
git reset:
git reset is a powerful command that is used to undo local changes to the state of a git repo.
To reset staging area:
◼️git reset <file-name>
◼️git reset
To reset the changes from both staging area and working directory at a time.
◼️git reset –-hard
git revert:
The revert command helps you undo an existing commit.
It doesn’t delete any data in this process instead git creates a new commit with the included files reverted to their previous state. So, your version control history moves forward while the state of your file moves backward.
reset -> before commit, revert -> after commit
suppose you have a Git repository with the following commit history:
d8f72c2 (HEAD -> main) Added feature A
a12b4e9 Fixed bug in feature B
6f3c1a7 Implemented feature B
92a0f5d Initial commit
Now, let's say you want to undo the changes introduced by the commit with the message "Fixed bug in feature B" (commit a12b4e9).
To revert this commit, you can use the following command:
git revert a12b4e9
After running this command, Git will create a new commit that undoes the changes made by the specified commit. You can then push this new commit to the repository to apply the reversal of changes.
The commit history after reverting the specified commit would look like this:b8f56d1 (HEAD -> main) Revert "Fixed bug in feature B"
d8f72c2 Added feature A
a12b4e9 Fixed bug in feature B
6f3c1a7 Implemented feature B
92a0f5d Initial commit
Now, the changes introduced by the commit "Fixed bug in feature B" have been reverted, and the commit history reflects the reversal.
Tags:
Tag operation allows giving meaningful names to a specific version in the repository . ➡️To apply tag: git tag –a <tagname> -m <message> <commit-ID>
➡️To see the list of tags: git tag
➡️To delete a tag: git tag –d <tagname>
How to remove untracked files:
➡️git clean –n -> dry run
➡️git clean –f -> forcefully
git clone:
git clone is a command used to create a copy of an existing Git repository. It copies the entire repository, including all files, commit history, and branches, to your local machine. This is useful when you want to start working on a project that is hosted on a remote Git repository, such as GitHub, GitLab, or Bitbucket.
git clone <repository_URL>
git clone command, Git will create a new directory with the same name as the repository (unless you specify a different name), and it will copy all the files and commit history from the remote repository into this directory.
git fetch:
Use git fetch to download changes from the remote repository without merging them into your current branch. This allows you to inspect the changes before merging. syntax: git fetch [remote_name]
eg: git fetch origin
git pull:
Use git pull to download changes from the remote repository and automatically merge them into your current branch. This is a convenient way to update your local branch with the latest changes from the remote repository.
Syntax: git pull [remote_name] [branch_name]
e.g: git pull origin main
git pull = git fetch + git merge
git cherry-pick:
git cherry-pick is a powerful Git command used to apply the changes introduced by a specific commit onto the current branch. This command allows you to selectively choose commits from one branch and apply them to another, independent of the commit history.
◼️Syntax: git cherry-pick <commit>
<commit>: Specifies the commit you want to apply onto the current branch.
How it works:
🌟Select the commit: You specify the commit you want to cherry-pick by providing its unique commit hash.
🌟Apply changes: Git takes the changes introduced by the specified commit and applies them directly onto the current branch.
🌟Create a new commit: Git automatically creates a new commit with the same changes as the cherry-picked commit, but with a new commit hash.
Use Cases:
🌟Feature Back porting: When you want to apply a specific feature or fix from one branch to another without merging the entire branch.
🌟Fixing Bugs: If a bug is fixed in a separate branch and you want to apply the fix to the main development branch.
🌟Reordering Commits: To rearrange commits or cherry-pick specific changes into a different order.
Example:
Suppose you have two branches, main and feature, and you want to cherry-pick a commit from feature into main.
🌟Find the commit hash: Use git log to find the commit hash of the commit you want to cherry-pick.
Cherry-pick the commit:
◼️git checkout main
◼️git cherry-pick <commit_hash>
🌟Resolve conflicts (if any): If there are conflicts between the cherry-picked changes and the existing code in the main branch, resolve them manually.
Commit the changes: After resolving conflicts, commit the cherry-picked changes: ◼️git commit
Finish: You have successfully cherry-picked the commit from feature into main. Notes:
Cherry-picking creates a new commit with the same changes as the original commit but with a new commit hash. Therefore, it does not maintain the commit history of the original branch.
Be cautious when cherry-picking commits, as it can lead to conflicts or unintended changes in the codebase.
It's a good practice to document the reasons for cherry-picking commits in the commit message to maintain clarity in the project history.
git bisect:
Git bisect streamlines bug hunting by systematically narrowing down the commit that introduced a bug.
Mark one commit as "good" (where the bug doesn't exist) and another as "bad" (where the bug appears).
Git navigates through commits, testing each one, until it identifies the exact commit where the bug was introduced.
💡git bisect start -> Starts bisecting
💡git bisect bad -> mark bad commit
💡git bisect good ->mark good commit
💡git bisect reset ->finishes bisecting
How to Use:
Identify Known States:
Determine a commit where the bug is present (bad).
Identify a commit where the bug is not present (good).
Start Bisecting:
Initiate the bisecting process using git bisect start.
Mark Known States:
Mark the bad commit: git bisect bad.
Mark the good commit: git bisect good .
Automated Testing:
Git will automatically check out commits for testing.
After testing each commit, mark it as good or bad based on whether the bug is present.
Continue Bisecting: Git will continue narrowing down the range of commits until it identifies the exact commit introducing the bug.
Finish Bisecting: Once Git identifies the bad commit, reset the bisecting process using git bisect reset.
git rebase:
Git rebase is a command used to integrate changes from one branch onto another by reapplying commits on top of the destination branch. This helps in maintaining a clean and linear commit history.
Syntax: git rebase <base_branch>
How it Works:
Identify Base Branch: Specify the branch you want to rebase onto (<base_branch>). Rewind: Git rewinds your current branch to the point where it diverged from the base branch.
Apply Commits: Git applies the commits from the base branch onto your current branch, one by one.
Reapply Changes: Your local commits are then reapplied on top of the new commits from the base branch, creating a linear history.
Example Usage:
Suppose you're working on a feature branch feature and want to integrate changes from the main branch:
git checkout feature
git rebase main
This command will rewind your feature branch to the point where it diverged from main, apply the commits from main onto feature, and then reapply your local commits on top.
Benefits:
🔸Maintains a clean and linear commit history.
🔸Avoids unnecessary merge commits, leading to a more organized repository
🔸Helps in integrating changes from one branch onto another seamlessly.
Caution:
🔸Use rebase for local branches; avoid it on shared branches to prevent conflicts.
🔸Be cautious when rewriting commit history, especially in shared repositories.
git reflog:
Displays a log of all reference changes (e.g., commits, checkouts) in the repository, even if they're not in the commit history.
Syntax: git reflog
git submodule:
Manages Git sub modules within a repository, allowing you to include external repositories as part of your project.
Syntax: git submodule add <repository_URL>
git filter-branch:
Rewrites Git commit history by applying various filters, such as removing files, modifying commit messages, or squashing commits.
Syntax: git filter-branch [options] [--] [] [--]
Example: git filter-branch --tree-filter 'rm -f ' HEAD
git blame :
Shows the revision and author of each line in a file, helping to identify who introduced specific changes.
Syntax: git blame
Example: git blame myfile.txt
**
Some more commands:**
💠git log -1 -> shows the latest commit
💠git log -2 -> shows the latest 2 commits
💠git log –oneline -> displays all the commits in a single line
💠git log –grep “ ignore” -> if we forget commit-id, can grep and get the commit-ids
💠git --version -> displays git version
git config --global username "xyz":
✨This command sets your username to "xyz" for all Git repositories on your system. ✨The --global flag ensures that this configuration is applied globally, affecting all repositories.
✨This username is typically associated with your commits to identify who made the changes
git config --globaluser.email"xyz@gmail.com":
✨This command sets your email address to "xyz@gmail.com" for all Git repositories on your system.
✨Like the previous command, the --global flag ensures that this configuration is applied globally.
✨Your email address is another piece of information associated with your commits, allowing Git to identify you as the author of the changes.
📂Happy Versioning📂
Subscribe to my newsletter
Read articles from Sakeena Shaik directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Sakeena Shaik
Sakeena Shaik
🌟 DevOps Specialist | CICD | Automation Enthusiast 🌟 I'm a passionate DevOps engineer who deeply loves automating processes and streamlining workflows. My toolkit includes industry-leading technologies such as Ansible, Docker, Kubernetes, and Argo-CD. I specialize in Continuous Integration and Continuous Deployment (CICD), ensuring smooth and efficient releases. With a strong foundation in Linux and GIT, I bring stability and scalability to every project I work on. I excel at integrating quality assurance tools like SonarQube and deploying using various technology stacks. I can handle basic Helm operations to manage configurations and deployments with confidence. I thrive in collaborative environments, where I can bring teams together to deliver robust solutions. Let's build something great together! ✨