Git Tutorial

Git Tutorial

·

13 min read

Git is a free and open-source version control system used to track changes in computer code, documents, and other digital content. In This tutorial I will demonstrate the Git command good to know

Setup the git environment in the device

To see the commits of a project

git log 
#or
git log --oneline #to show in onle
git log -n 10 --oneline # to show last 10 commits
git log -n 10 --oneline --parents

To see in the form of the graph:

git log --graph
 git log --oneline --decorate --graph --parents
# use this to show in the better way

This to show the tree in better way: In this we can two or three commit ideas for each .In two => first is the child and next is its parent , But in Three => 1. child ,2. far parent, 3. near parent

It is a good idea to introduce yourself to Git with your name and public email address before doing any operation. The easiest way to do so is:

git config  --add --global user.name "Your Name Comes Here"
git config --add --global user.email you@yourdomain.example.com

You can see your config details using

git config --list
# or
cat ~/.gitconfig

we can edit using

 nvim ~/.gitconfig

we can set the default branch name to the master using

git config --global init.defaultBranch master

Git Remote options

check for the remote

git remote -v

Remove the remote using its name:

git remote remove origin

Replace with the name of the remote you want to delete (e.g., origin).

add remote

git remote add origin https://github.com/username/repository.git

Verify the remote

git remote -v

update the Repo

git push origin main
git pull origin main

Initialize the repository

follow the step to create a new projects

make a directory

mkdir foldername
cd foldername

initialize the empty repository

git init it will create the .git folder

the files can in one of this states untracked , staged and committed

create a file in projects vim content.md after making changes save it

git status  
# will show the status

we can add a file , and it will start tracking by the git

git add filename # to add a file

we can use add . to add all files after this the files will come to the staging place where ready for the next step

you can always revert using the command

git restore --staged filename

now you can commit [commit is snapshot ] git store an entire snapshot of files on peer-commit level

git commit -m "commit message"

ya, you are done. now you can see the details of commit using the hash

 git cat-file -p 3bb9b920d97fc1ab5ae2c3e3cd38eb316850bb0e
# it will show all the details

Terminology: tree → representation of the folders | | blob → store the file

Config

to see the local file or the project config

cat .git/config

we can add some key-value pairs local

git config --list --local

we can add key value pairs using add

git config --add --local cms.ceo Ceoname
git config --add --local cms.cto ctoname

Remove the cms.ceo configuration:

git config --unset --local cms.ceo

To Remove all the key-value configuration:

git config --unset-all --local cms.ceo

we can add some key-value pairs local

git config --list --local

To Get the Value we can use this

git config --get cms.ceo
# Ceoname

Branch

To create a branch

git branch <branchname>

To see all branch

git branch

to change the branch

git switch <branchname>
#or
git checkout <branchname>

to delete a branch

git branch -d <branchname>

Merge

You might think what is the need of the different branch and merging them. It will differentiate with your code with other and can merged finally

now you might have active branch with some code edit ,now do this

Managing branches

A single Git repository can maintain multiple branches of development. To create a new branch named experimental, use

 git branch experimental

If you now run

git branch

you’ll get a list of all existing branches:

  experimental
* main

The experimental branch is the one you just created, and the master branch is a default branch that was created for you automatically. The asterisk marks the branch you are currently on; type

 git switch experimental

to switch to the experimental branch. Now edit a file, commit the change, and switch back to the master branch:

(edit file)
git commit -a
git switch master

Check that the change you made is no longer visible, since it was made on the experimental branch and you’re back on the master branch.

You can make a different change on the master branch:

(edit file)
git commit -a

at this point the two branches have diverged, with different changes made in each. To merge the changes made in experimental into master, run

git merge experimental

If the changes don’t conflict, you’re done. If there are conflicts, markers will be left in the problematic files showing the conflict;

 git diff

will show this. Once you’ve edited the files to resolve the conflicts,

git commit -a

will commit the result of the merge. Finally,

gitk

will show a nice graphical representation of the resulting history.

At this point you could delete the experimental branch with

 git branch -d experimental

This command ensures that the changes in the experimental branch are already in the current branch.

Fast Forward Merge

A fast-forward merge in Git is a type of merge where the branch being merged in (e.g., feature) is simply moved forward to point to the commit at the tip of another branch (e.g., main). This can happen when there is a direct path from the current branch to the target branch, meaning no divergent commits exist.

When does a Fast-Forward Merge occur?

  • When no additional commits have been made on the base branch (e.g., main) since the feature branch was created.

  • The commits in the feature branch are a linear progression from the base branch.

Rebase

Never ever run this on main branch

Rebase Working (Step by Step)

Scenario

We have the following branch structure:

  1. main branch is the primary branch.

  2. feature branch was created from main and has diverged.

  3. We want to:

    • Rebase feature onto the latest main to integrate changes.

    • Visualize the changes using git log --graph.


Initial Setup

Start by creating a repository and setting up the branches.

# Create a new repository
git init rebase-example
cd rebase-example

# Create the main branch with initial commits
echo "File A" > fileA.txt
git add fileA.txt
git commit -m "A: Initial commit"

echo "File B" > fileB.txt
git add fileB.txt
git commit -m "B: Add fileB.txt"

# Create and switch to the feature branch
git checkout -b feature
echo "File C" > fileC.txt
git add fileC.txt
git commit -m "C: Add fileC.txt"

echo "Update File C" >> fileC.txt
git add fileC.txt
git commit -m "D: Update fileC.txt"

# Switch back to main and make more commits
git checkout main
echo "File D" > fileD.txt
git add fileD.txt
git commit -m "E: Add fileD.txt"

echo "Update File B" >> fileB.txt
git add fileB.txt
git commit -m "F: Update fileB.txt"

Visualize the Current Branch Structure

Run the following command to see the branch structure:

git log --oneline --graph --all

Output:

* F: Update fileB.txt (main)
* E: Add fileD.txt
| * D: Update fileC.txt (feature)
| * C: Add fileC.txt
|/
* B: Add fileB.txt
* A: Initial commit

Here:

  • main has the commits A -> B -> E -> F.

  • feature has the commits C -> D.


Rebase feature onto main

Rebase feature onto main to apply its changes on top of main.

# Switch to feature branch
git checkout feature

# Rebase onto main
git rebase main

During the rebase:

  • Git rewinds the feature branch (removes C and D temporarily).

  • It replays C and D on top of F.


Visualize After Rebase

Run the log command again:

git log --oneline --graph --all

Output:

* D: Update fileC.txt (feature)
* C: Add fileC.txt
* F: Update fileB.txt (main)
* E: Add fileD.txt
* B: Add fileB.txt
* A: Initial commit

Now:

  • feature commits are directly on top of main.

  • The history is linear.


Handle Conflicts (If Any)

If there are conflicting changes between main and feature, Git will pause the rebase process.

  1. Git will show the conflicting file(s).

  2. Fix the conflict manually in the file(s).

  3. Stage the resolved file(s):

     git add <file>
    
  4. Continue the rebase:

     git rebase --continue
    

Summary of Commands

Here’s a quick reference:

  1. Visualize History:

     git log --oneline --graph --all
    
  2. Rebase a Branch:

     git checkout <branch>
     git rebase <target-branch>
    
  3. Interactive Rebase:

     git rebase -i <base-branch>
    
  4. Handle Conflicts:

    • Fix conflicts in files.

    • Stage the resolved files:

        git add <file>
      
    • Continue the rebase:

        git rebase --continue
      
    • Abort the rebase:

        git rebase --abort
      

To change the commit message use this

git commit --amend

or you can also do this

git reset --soft HEAD~1

Git Diff

It is use to compare but not to perform the action

use to see the Git difference with the staged on the and older one

git add .
git diff --staged

we can see the difference of the two hash

git diff hashofone hashoftwo

Git Stash

Stash is a way to save your changes in a temporary location. It is useful when you want to make changes to a file but don’t want to commit them yet. You can then come back to the file later and apply the changes.

Conflicting changes will not allow you to switch branches without committing the changes. Another alternative is to use the git stash command to save your changes in a temporary location.

Terminal window

git stash

This command saves your changes in a temporary location. It is like a stack of changes that you can access later.

Naming the stash

You can also name the stash by using the following command:

Terminal window

git stash save "work in progress on X feature"

View the stash list

You can view the list of stashes by using the following command:

Terminal window

git stash list

Apply the stash

You can apply the stash by using the following command:

Terminal window

git stash apply

Apply the specific stash

You can apply the specific stash by using the following command:

Terminal window

git stash apply stash@{0}

Here stash@{0} is the name of the stash. You can use the git stash list command to get the name of the stash.

Applying and dropping the stash

You can apply and drop the stash by using the following command:

Terminal window

git stash pop

This command applies the stash and drops it from the stash list.

Drop the stash

You can drop the stash by using the following command:

Terminal window

git stash drop

Applying stash to a specific branch

You can apply the stash to a specific branch by using the following command:

Terminal window

git stash apply stash@{0} <branch-name>

Clearing the stash

You can clear the stash by using the following command:

Terminal window

git stash clear

Git Reflog

This is used to see the detailed history

git reflog

This will show you the history of your commits. You can use the number at the end of each line to access the commit that you want to view.

Git Revert, Reset, and Reflog: A Practical Guide

Here’s a polished explanation with examples suitable for a blog post:


Understanding Git Revert, Reset, and Reflog: A Practical Guide

Git provides powerful tools to manage your commit history and undo changes. Let’s break down some key functionalities and how they can be used effectively:


1. Changing Commit Messages

If you made a typo or need to clarify your commit message, Git allows you to amend it.

Example: Fixing a Typo in the Commit Message

git commit -m "Intial commit with typo"  # Typo in "Initial"

To fix it:

git commit --amend -m "Initial commit with typo fixed"

This command updates the message of the last commit. You can verify the change with:

git log --oneline

2. Removing Specific Commit Code Changes

There are two primary ways to undo changes in Git:

  • git revert: Creates a new commit that reverses the changes introduced by a specific commit.

  • git reset: Moves the branch pointer to a previous commit, potentially removing changes.

Using git revert to Undo Specific Changes

If you have the following history:

* 123456 Add feature X
* abcdef Initial commit

To undo "Add feature X":

git revert 123456

This creates a new commit that undoes the changes made in 123456. The history now looks like this:

* 789abc Revert "Add feature X"
* 123456 Add feature X
* abcdef Initial commit

This method is safe for shared branches because it doesn't rewrite history.


3. Resetting to Go Back in the Past

git reset moves the branch pointer to a specific commit and optionally modifies the working directory or staging area.

Example: Using git reset

Assume the following commit history:

* f12345 Added feature Y
* abcdef Initial commit

To reset to abcdef:

git reset --soft abcdef  # Keeps changes staged

To discard changes entirely:

git reset --hard abcdef  # Deletes changes permanently

This is useful for local cleanups but should be used cautiously on shared branches.


4. Reflog: Navigating History Like a Time Traveler

Git tracks all movements of HEAD using the reflog, allowing you to recover lost commits or move back to previous states.

Example: Recovering from a Reset

Let’s say you mistakenly reset to an earlier commit:

git reset --hard abcdef

You can use git reflog to view your recent actions:

git reflog

Sample output:

abc1234 HEAD@{0}: reset: moving to abcdef
f12345  HEAD@{1}: commit: Added feature Y

To return to the latest commit:

git reset --hard f12345

Advanced Workflow: Combining Revert, Reset, and Reflog

Scenario:
You accidentally merged a feature branch, realized some commits were incorrect, and want to:

  1. Remove specific commits.

  2. Rewrite history.

  3. Recover lost commits if needed.

Step 1: Revert Specific Commits

git revert <commit-hash>

Step 2: Reset to an Earlier Commit

git reset --soft <commit-hash>  # Keep changes staged

Step 3: Recover with Reflog

If you reset too far or lose commits:

git reflog
git reset --hard <desired-commit>

Visualizing History with --graph

After making changes, use this command to visualize your commit history:

git log --oneline --graph --all

Sample Output:

* abc1234 (HEAD) Reverted "Add feature X"
* 123456 Add feature X
* abcdef Initial commit

Conclusion

With revert, reset, and reflog, Git gives you full control over your repository’s history:

  • Use revert to safely undo changes in shared branches.

  • Use reset for local cleanup and to rewrite history (be cautious).

  • Use reflog to recover lost commits and navigate your history.

  • using the reflog hashid we can revert it back