Play with Git

Introduction to git

Git installation

  1. Go to https://git-scm.com/download/win and download the required installer based on your Windows.

  2. Once the download is done just double-click on the installer and follow the steps.

  3. Once the installation is completed, open the git bash window or command prompt and execute "git --version" to check the installation is successful.

     ubiswas@LPWLTL1404 MINGW64 ~
        $ git --version
        git version 2.35.1.windows.2
    

Git configuration Levels

What will be the minimum configuration that we need to start with git? The answer can be found by executing the below command :

git commit -m "initial version"

we can see the current configuration by executing the below command:

git config --list

Starting with Git

Creating a git repository

  1. Open the git bash or command prompt and execute the command to create a repository folder

     ubiswas@LPWLTL1404 MINGW64 ~
        $ mkdir newRepo
    

it will create a folder named newRepo and then go to that folder and execute the command

ubiswas@LPWLTL1404 MINGW64 ~
$ cd newRepo

ubiswas@LPWLTL1404 MINGW64 ~/newRepo
$ git init
Initialized empty Git repository in C:/Users/ubiswas/newRepo/.git/

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
$

You have created the git repository successfully.

Git workflow

Tracking File changes in git

  1. Open the git bash window or the command prompt then go to the repository.

  2. Add a file to the working directory by executing the below command

     ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
        $ touch a.txt
    

    it will create a.txt file in the working directory but not in staging area, can be checked by executing

     ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
        $ ls
        a.txt
        ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
        $ git ls-files --stage
        ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
        ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
        $ git status
        On branch master
    
        No commits yet
    
        Untracked files:
          (use "git add <file>..." to include in what will be committed)
                a.txt
    
        nothing added to commit but untracked files present (use "git add" to track)
    
        ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
    

    a.txt file is in the working directory but not in the staging area.

  3. Now add the file to the staging area then commit to store it to the local repository by executing the below command:

     ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
        $ git add .
    
        ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
        $ git commit -m "added a.txt file"
        [master (root-commit) 925757a] added a.txt file
         1 file changed, 0 insertions(+), 0 deletions(-)
         create mode 100644 a.txt
    
        ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
        $ git ls-files --stage
        100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0       a.txt
    
        ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
        $
    

Reverting to earlier commits

Modify the a.txt file and add a new line by executing the below commands

  ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
  $ vi a.txt

  ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
  $ cat a.txt
  Line 1 added to the file.

  ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
  $ git status
  On branch master
  Changes not staged for commit:
    (use "git add <file>..." to update what will be committed)
    (use "git restore <file>..." to discard changes in working directory)
          modified:   a.txt

  no changes added to commit (use "git add" and/or "git commit -a")

  ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
  $ git add .
  warning: LF will be replaced by CRLF in a.txt.
  The file will have its original line endings in your working directory

  ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
  $ git commit -m "updated a.txt file"
  [master 6d0d1ec] updated a.txt file
   1 file changed, 1 insertion(+)

  ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
  $ git log --oneline
  6d0d1ec (HEAD -> master) updated a.txt file
  925757a added a.txt file

As we can see two commit has been created for the file a.txt. Now if we want to revert to the first commit ( 925757a) then we can do it simply by executing the below command

  ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
  $ git log --oneline
  6d0d1ec (HEAD -> master) updated a.txt file
  925757a added a.txt file

  ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
  $ git checkout 925757a a.txt
  Updated 1 path from 65a4574

  ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
  $ git status
  On branch master
  Changes to be committed:
    (use "git restore --staged <file>..." to unstage)
          modified:   a.txt


  ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
  $ git commit -m "moved back to the version 1"
  [master 51775d8] moved back to the version 1
   1 file changed, 1 deletion(-)

  ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
  $ git status
  On branch master
  nothing to commit, working tree clean

  ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
  $ cat a.txt
  ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
  $ git log --oneline
  51775d8 (HEAD -> master) moved back to the version 1
  6d0d1ec updated a.txt file
  925757a added a.txt file

Deleting files in git

We can delete git files in two ways

Delete a file from the staging area only not from the working directory by running the below command:

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
  $ git rm --cached a.txt
  rm 'a.txt'

  ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
  $ git ls-files --stage

  ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
  $ ls
  a.txt

  ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
  $ git status
  On branch master
  Changes to be committed:
    (use "git restore --staged <file>..." to unstage)
          deleted:    a.txt

  Untracked files:
    (use "git add <file>..." to include in what will be committed)
          a.txt


  ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
  $

We can restore the file to the staging area by running the command below:

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
  $ git restore --staged a.txt

  ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
  $ git ls-files --stage
  100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0       a.txt

  ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
  $ ls
  a.txt

  ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
  $ git status
  On branch master
  nothing to commit, working tree clean

Delete the file from both the working directory and staging area by executing the below command:

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
  $ git rm a.txt
  rm 'a.txt'

  ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
  $ ls

  ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
  $ git ls-files --stage

  ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
  $

Ignoring files in git

We can ignore files in git by using the .gitignore file.

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
$ touch .gitignore
ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
$ cat .gitignore
*mb

added a filter to ignore .mb file to the stage and commit. Now add a new file as example.mb to the working directory and check the status.

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
$ touch example.mb

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
$ git status
On branch master
nothing to commit, working tree clean

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
$ ls
a.txt  example.mb

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
$

it is not tracking the example.mb file as it is ignored inside the .gitignore file. now remove the filter from the .gitignore file for the .mb file.

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
$ vi .gitignore

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
$ cat .gitignore
*json

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   .gitignore

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        example.mb

no changes added to commit (use "git add" and/or "git commit -a")

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
$

Now git tracking the file example.mb.

Renaming files in git

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
$ ls
a.txt  example.mb

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
$ git mv a.txt aa.txt

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        renamed:    a.txt -> aa.txt


ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
$ git commit -m "renamed a.txt file to aa.txt"
[master 071e43b] renamed a.txt file to aa.txt
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename a.txt => aa.txt (100%)

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
$ ls
aa.txt  example.mb

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
$

Branching in git

The branch is nothing but a separate working directory, it normally creates to keep the master branch intact.

To create a branch need to execute the command "git branch <branch name>" from the git bash. Below is an example to create a branch named 'feature-one'

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
$ git branch
* master

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
$ git branch feature-one

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
$ git branch
  feature-one
* master

But with this command, we just created the branch but did not go to this branch yet. To go to the newly created branch we need to execute the command 'git checkout <branch name>'. Example:

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
$ git checkout feature-one
Switched to branch 'feature-one'

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (feature-one)
$ ls
aa.txt  example.mb
ubiswas@LPWLTL1404 MINGW64 ~/newRepo (feature-one)
$ git branch
* feature-one
  master

Now we are in the 'feature-one' branch and the * mark is pointing to the currently active branch

Merging in git

Let's create a new file named 'feature1.txt' inside the 'feature-one' branch and modify an existing file then merge this branch to the master branch.

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (feature-one)
$ touch feature1.txt

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (feature-one)
$ ls
aa.txt  example.mb  feature1.txt

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (feature-one)
$ vi feature1.txt

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (feature-one)
$ cat feature1.txt
Line 1 is added from the feature1.branch


ubiswas@LPWLTL1404 MINGW64 ~/newRepo (feature-one)
$ vi aa.txt

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (feature-one)
$ cat aa.txt
Added this line from feature-one branch.
ubiswas@LPWLTL1404 MINGW64 ~/newRepo (feature-one)
$ git add .
warning: LF will be replaced by CRLF in aa.txt.
The file will have its original line endings in your working directory
warning: LF will be replaced by CRLF in feature1.txt.
The file will have its original line endings in your working directory

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (feature-one)
$ git commit -m "BR: added a new file feature1.txt and updated existing aa.txt fiel"
[feature-one 4af6b4f] BR: added a new file feature1.txt and updated existing aa.txt fiel
 2 files changed, 3 insertions(+)
 create mode 100644 feature1.txt

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (feature-one)
$ git status
On branch feature-one
nothing to commit, working tree clean

Now switch to the master branch again and execute the below command to merge the 'feature-one' to the master.

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (feature-one)
$ git checkout -
Switched to branch 'master'

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
$ git log --oneline
071e43b (HEAD -> master) renamed a.txt file to aa.txt
442d23b added a example.mb file
6dcc757 updated gitignore file with filiter
1aa2bc7 added gitignore file
51775d8 moved back to the version 1
6d0d1ec updated a.txt file
925757a added a.txt file

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
$ git merge feature-one
Updating 071e43b..4af6b4f
Fast-forward
 aa.txt       | 1 +
 feature1.txt | 2 ++
 2 files changed, 3 insertions(+)
 create mode 100644 feature1.txt

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
$ git log --oneline
4af6b4f (HEAD -> master, feature-one) BR: added a new file feature1.txt and updated existing aa.txt fiel
071e43b renamed a.txt file to aa.txt
442d23b added a example.mb file
6dcc757 updated gitignore file with filiter
1aa2bc7 added gitignore file
51775d8 moved back to the version 1
6d0d1ec updated a.txt file
925757a added a.txt file

Resolving conflict while merging

Conflict generally occurs when multiple people modify the same files from different branches even from the same branch. Then when try to merge or commit a conflict occurs.

To generate conflict let's modify the same file from the master and feature-one branches. Example: feature1.txt file

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
$ ls
aa.txt  example.mb  feature1.txt

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
$ vi feature1.txt

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
$ cat feature1.txt
Line 2 is added from the feature1.branch


ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
$ git add.
git: 'add.' is not a git command. See 'git --help'.

The most similar command is
        add

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
$ git add .

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
$ git commit -m "updated feature1.txt file from amster"
[master bdbfa60] updated feature1.txt file from amster
 1 file changed, 1 insertion(+), 1 deletion(-)

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
$ git checkout fetaure-one
error: pathspec 'fetaure-one' did not match any file(s) known to git

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
$ ls
aa.txt  example.mb  feature1.txt

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
$ cat feature1.txt
Line 2 is added from the feature1.branch


ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
$ git checkout feature-one
Switched to branch 'feature-one'

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (feature-one)
$ ls
aa.txt  example.mb  feature1.txt

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (feature-one)
$ cat feature1.txt
Line 1 is added from the feature1.branch


ubiswas@LPWLTL1404 MINGW64 ~/newRepo (feature-one)
$ vi feature1.txt

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (feature-one)
$ git add .

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (feature-one)
$ git commit -m "BR: update feature1.txt from feature-one branch "
[feature-one c68b83f] BR: update feature1.txt from feature-one branch
 1 file changed, 1 insertion(+), 1 deletion(-)

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (feature-one)
$ git checkout -
Switched to branch 'master'

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
$ git merge feature-one
Auto-merging feature1.txt
CONFLICT (content): Merge conflict in feature1.txt
Automatic merge failed; fix conflicts and then commit the result.
ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master|MERGING)
$

Git suggests fixing the conflicts manually. in this case, lets open the feature1.txt file

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master|MERGING)
$ vi feature1.txt

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master|MERGING)
$ cat feature1.txt
Line 333 is added from the feature1.branch


ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master|MERGING)
$ git status
On branch master
You have unmerged paths.
  (fix conflicts and run "git commit")
  (use "git merge --abort" to abort the merge)

Unmerged paths:
  (use "git add <file>..." to mark resolution)
        both modified:   feature1.txt

no changes added to commit (use "git add" and/or "git commit -a")

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master|MERGING)
$ git add .

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master|MERGING)
$ git commit -m "Me"
[master 9fb1dea] Me

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
$ git status
On branch master
nothing to commit, working tree clean

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
$ git log --oneline
9fb1dea (HEAD -> master) Me
c68b83f (feature-one) BR: update feature1.txt from feature-one branch
bdbfa60 updated feature1.txt file from amster
4af6b4f BR: added a new file feature1.txt and updated existing aa.txt fiel
071e43b renamed a.txt file to aa.txt
442d23b added a example.mb file
6dcc757 updated gitignore file with filiter
1aa2bc7 added gitignore file
51775d8 moved back to the version 1
6d0d1ec updated a.txt file
925757a added a.txt file

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
$

Stashing in git

Stashing means saving the current progress and reverting to the last commit without interrupting the current work. That means saving the current progress from one branch and then moving to another branch (last successful commit)to do some other stuff.

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (feature-one)
$ vi a.txt

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (feature-one)
$ cat a.txt
Line 1 is added.
Line 2 is added.
Lin 3 is in inprogress....

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (feature-one)
$ git stauts
git: 'stauts' is not a git command. See 'git --help'.

The most similar command is
        status

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (feature-one)
$ git status
On branch feature-one
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   a.txt

no changes added to commit (use "git add" and/or "git commit -a")

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (feature-one)
$ git checkout master
error: Your local changes to the following files would be overwritten by checkout:
        a.txt
Please commit your changes or stash them before you switch branches.
Aborting

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (feature-one)
$ git stash save "Br: staging the line 3 progress"
warning: LF will be replaced by CRLF in a.txt.
The file will have its original line endings in your working directory
Saved working directory and index state On feature-one: Br: staging the line 3 progress

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (feature-one)
$ git status
On branch feature-one
nothing to commit, working tree clean

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (feature-one)
$ git checkout -
Switched to branch 'master'

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
$

Now after completing the stuff from the master branch we can back to the feature-one branch and check the files. Noticed a.txt file shows the content up to the last successful commit.

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
$ git checkout -
Switched to branch 'feature-one'

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (feature-one)
$ git log --oneline
cc78cb4 (HEAD -> feature-one) Br: added a line 2
89db9e6 (master) added initial version

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (feature-one)
$ ls
a.txt

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (feature-one)
$ cat a.txt
Line 1 is added.
Line 2 is added.

Now perform the below command to get the progress that was stashed earlier

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (feature-one)
$ git stash list
stash@{0}: On feature-one: Br: staging the line 3 progress

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (feature-one)
$ git stash apply
On branch feature-one
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   a.txt

no changes added to commit (use "git add" and/or "git commit -a")

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (feature-one)
$ cat a.txt
Line 1 is added.
Line 2 is added.
Lin 3 is in inprogress....

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (feature-one)
$ echo "Changes in Line 3 is DONE" >> a.txt

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (feature-one)
$ git add .
warning: LF will be replaced by CRLF in a.txt.
The file will have its original line endings in your working directory

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (feature-one)
$ git commit -m "Fixed the Line 3 progress "
[feature-one 8a03028] Fixed the Line 3 progress
 1 file changed, 2 insertions(+)

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (feature-one)
$ git status
On branch feature-one
nothing to commit, working tree clean

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (feature-one)
$ cat a.txt
Line 1 is added.
Line 2 is added.
Lin 3 is in inprogress....
Changes in Line 3 is DONE

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
$ git stash show
 a.txt | 1 +
 1 file changed, 1 insertion(+)

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
$ git stash list
stash@{0}: On feature-one: Br: staging the line 3 progress

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
$ git stash clear

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
$ git stash list

ubiswas@LPWLTL1404 MINGW64 ~/newRepo (master)
$

Rebasing in git

Rebasing is the process of moving one branch to the commit of another branch.

Git and GitHub

what is GitHub

Creating Github repository by HTTPS

Creating Github repository by SSH

Pulling remote changes to local

Pushing local changes to remote