Thursday, July 15, 2021

Git - introduction

Revert the change
- Rollback file changes
- Commit Amend
- Commit Revert
- Delete untracked files

1. Roll back changes



===================

checkout
- you want to download a file from server to your client system (workspace).
you get a file from repo.
- modify the file and upload to remote server (repo) is checkin.

all the record who,what,when modified is recorded (metadata).



Server (repo)
Client (Workspace)
  - Workspace1
  - workspace2

why they use git compare to other tool?

Git
- cameout if linux development community
- Linux Torvalds - 2005
- Initial goals
  - speed
  - supported for non -linear development (thousands of paraller parallel branches)
  - Fully distributed
  - Able to handle large projects like linux efficiently

Distributed vs Centralized

Centralized model (CVS,Subversion,perforce)
Distributed model (Git, mercurial)


Central VCS Server
- Computer A
- Computer B

* network issue/latency

- Git takes snapshots
- Git uses checksums
  commit ID(SHA-1 Hash)
  Tree object: ID -> snapshot of the filesystem
  Author: Bill Johnson
  Commit Message: Initial Commit

Workspace is a folder where you will be working. This is going to be your local repository.
Inside your workarea, you are going to have three areas.

  Working area
  Staging area
  repo

When you do checkout, all the files are stored in working directory.
This is where you create and save the files.
But the process work little differently.
In git, you don't directly checkin. You checkout, modify the code/files in your working directory and then you are going to take the code into a new area called staging area. This is where git will take a snapshot.

From the staging area, you will be actually doing checkin. Now, content will be saved into repo (local).

Now, repository as well as staging area is hidden area for you. It is infact, not a folder but a virtual space that is available logically. This how it is created internally.


All the commits are stored in repository. The place you will be working is working directory.

First you create a file in working directory -> to modify you move the file to staging area and finally save on repo.

When file is first created, it is untracked file. There is no information about the file in repository thats why it is untacked file.

When file is put into repository, file is tracked file. what that mean? - that mean file is traceable by git.

When there is no difference between a file in Workspace and repo then the file is unmodified file. Once you modified the file, the difference between repository file and what you have been changed. This file is called modified file.

when you try to put this file in staging area, the file is called staged file.
When you try to store, you try to store in repository. Now, content on repo and the workspace is same or unmodified file.

Life cycle of a file is that a very new file, that is not available at repository is untracked file.
When you do checkout all the files are unmodified. When you make changes they are modified. When you put into staging area, they are staged.
From stage, you are going to commit.


what is github?
- it is a site for online storage of git repositories.
- Many opensource project use it including linux kernel
- You get a free repo for personal use or project. You can have private repo with some fee.

==========================================

Git workflow

go to github.com and create an accoutn
-> create a new repository
name: myrepo2020 (name of the project product)
public
create repository

now you will get code

copy the path.

central repo: https://github.com/<myrepo>/myrepo2020.git


download client for your PC

search for git-scm

downlod for windows (git-bash)

install and open it.
you will see it like a linux command prompt.

$ ls
$ which git
$ git --version

Basic configuration
- need username, email
$ mkdir classroom/git; cd classroom/git

$ git config --global user.name "Jay K."
$ git config --global user.email "jay@jayk.com"
$ git config --global push.default "Simple"

With this we will create local copy of workspace. For this you need central repository.

make a copy of
$ git clone <source-central-repo> <dest-local-repo>
$ git clone https://github.com/<myrepo>/myrepo2020.git
it will create myrepo2020 on the current directory.
$ ls
you will see the repo.

or,

$ git clone https://github.com/<myrepo>/myrepo2020.git workspace2030

it will create new folder workspace2030 @current directory.

execute the following command
$ echo "First line"> 1.java
$ git status

you see untracked files

put the file in repo, then you will have tracked file.

now, store the file in repo. You can not put file directory in repo. You have to first put the file in staging area and then store in repo permanently.

you have two commands
add- adding file to staging area, creates a copy of file

$ git add <filename> -> adds single file
$ git add * -> adds all files that are modified.

$ git status

no commit yet, changes are ready to be commited.

that mean files are in staging area and ready to save.

$ git commit -m "First change for testing purpose"
-m - message -> what changes you made.


when you do commit,
it will take user name from global config file.
time stamp from machine and detail what it got from snapshot.



$ git status
now file is unmodified.


Now, lets go ahead and modify the file again,

$ echo "Line 2">> 1.java
$ git status

modified
file is modified.

$ cat 1.java

now first you stage the file

$ git add 1.java
$ git status
file is added to staging area

what if you have to modify multiple files
say

$ echo "first line" > 2.java

we have 2.java file.
$ git status
it shows now, there is 1.java file which is modified and 2.java which is untracked.

untracked file is not available in repository.

$ git add . -> all modified file will be added to staging area,

$ git status

Now, lets commit
$ git commit -m "Second commit with set of changes"

$ git status

as a user you keep modify and add to repo.

$ ls

when you run ls, you will not see repository. As we discussed earlier, its a hidden foler.

How to see the repo?
====================

in the current directory, there is a hidden directory .git.
this is where commits are available. You are not supposed to modify manually.
$ ls -la

$ cd .git' ls -la


$ git log
gives you detail about commit

40 digit commit id.
author
date

every commit, you will get unique commit id.

when you run git log you will see latest commit id on the top

to find latest commit id, you can give the number

$ git log -3 -> displays 3 commits

$ git log --online -> gives small output without id and author

$ git log --online -l

$ git show <commit_ID>

git show c54333> -> give 6 letters from commit id.


we learned we have repo, we downloaded and committed.

$ mkdir test
$ git status
$ touch test/file1
$ git status
$ git add .
$ git commit -m "Testing .."


whatever we made changes locally, it is not available on central repository.
to update or share the changes you made locally, you can push.

$ git push

how to changes are tracked? with commit id.

what git will do when you run git push?
git will try to take the commit ids which are not available on central repo but available on local repo. only those commits are going to be pushed.


transaction details are commit ids.

coming back to our workspace, we can see the commit id by running
$ git log --online

you see three changes, three commit id

What happend when you run git push

- it will take all 3 commit ids and going to push to central repository.

first it will try to connect to central repository, if you have not set up already, will prompt for user name and password.

once you supply username/pw, info is pushed to central repo.

go to your online repo repo, you will see the files

now, come back and push again
$ git push

it will say everything up-to-date.

as of now, your local and repote repo are on sync.


How does it know where to push the change?
inside your .git, you have config file

$ cat .git/config

when you run git push, it will read the config file and push to the repo.


There might be multiple user working. They might also clone...
and modify on local repo.

$ mkdir classroom/lab1; cd classroom/lab1
$ git clone https:/github.com/<user-name>/repo-name.git workspace01

all the modification on local repo is only available locally.

$ echo "First line" > 4.java
$ git stauts
untracked
$ git add .
$ git commit -m "added"

$ git log --oneline

displays commit ids.

now to uplod to central repo
$ git push

now, it will only push the one that are changes.

look at the message

go to repote repo and review the changes.


go back to old workspace
but now central repo is updated but this is not updated.
you need to update first that mean pull from central repo

this mean commit id available from central repo, you will be downloading.
$ git log --oneline
$ git pull
update mean -> update with whatever you have on central repo.

$ git log --oneline


review
Configuration
$ git config --global user.name "Jay K"
$ git config --global user.email "jay@jay.com"
$ git config --global push.default "Simple"

User/developer workflow
----------------------
$ git clone <source-central-repo> <dest-local-repo>
$ git clone https:/github.com/<user-name>/repo-name.git myworkspace
$ git status
$ touch myfile; echo "Hello">myfile
$ git status
$ git add <file> or git add .
$ git status
$ git commit -m "mesage"
$ git log -num -ineline
$ git show <commitid>
$ git push
$ git pull

======================
Branch


You will have three areas

- Working directory
- Staging area
- Repo

We put on staging area, comit and commit remains in repo area. We will push from repo to remote repo.


In fact there is a layer in branch and file content will be on branch before commiting to repo ->

What is branch?
Like a bank branch, where you go to get the money.

In side a repository there is a branch. All the commit you go will also be available on branch.
You can create multiple branches where you will have multiple copy of your data.

When you create a repo, by default, branch is also created which is a master branch.

also on centrol repo, there is also a master branch and it is created when repo is created.

When you clone the repo, everything from remote repo is copied over.

When is it userful?
===================

Branch is copy of currently available files/directory.

You can choose what branch you would like to work on.
Branches are independent. If you make change in one branch, it will not be replacated automatically.

You have to tell git what branch you want to work on.
Git shows the content from the branch you are in.

when you list the content from current branch, in fact what it does is it removes the contents from working directory and displays from the branch.


checkout
-> checkout is a process of taking out the content from repository and brining it into your working directory. Checkout is also a process of taking the content from a branch in a repository.
When there is only one branch, you don't have to use checout but if you have multiple branch, you have to specify it.

Lets say we have two branches
- andriod
- IOS

if we checkout IOS, content from IOS will be displaied on working dirctory. same way if you checkout andrioid branch, you will see the content from android.


If you want you can create branch in central repository and if anyone clones, they will receive the latest content from central repository. So, if you clone the repo from central repo, your newly created branch is also copied.

if your local repo, you can create as many repo as you want but your peer can't get the updated information until you sync with remote repo.

How to find out available branches?
-----------------------------------

$ git branch

it will show all the branches including you are currently working.

$ git log
you will see record of commit

How to create branch?
=====================
branch comes from tree. branch has parent branch. so to create a branch, you need to have a branch already existed.

so we already have master branch by default.

lets say we have three commit ids, c1, c2, c3
content of files on each commit may be different.

Note: You will get unique commit id when you do commit

$ git branch
* master
$ git branch IOS
creating a branch called IOS
$ git branch -> list

How to move from one branch to another?
---------------------------------------
$ git checkout IOS
it will basically removes the content from working directory temporarily and displays the content from IOS branch.

$ git branch
you will see
* IOS
the first one on the list is the working branch.

$ touch fileinIOS
$ git add .
$ git comit -m "added new file"
$ ls
$ git log --oneline

Now, switching to new branch.
$ git checkout <Branch_Name>
$ git checkout master
$ git branch
you wil lsee * in front of branch.

$ ls
$ git log --oneline
$ touch NewfilAdded
$ git add .
$ git commit -m "new added to master branch"
$ ls
$ git log --oneline

$ git checkout IOS
$ ls

review the output between two branches.

git push
Note: commit is stored in repository inside branch.
if there is no new commit ID, there is nothing to push to remote repo.


we commit from master to remote repo.

What happens when a branch which ia available on our local repo?
---------------------------------------------------------------

We created an IOS repo, how do we sync to repo?

when you run push, it will check on repo and if it does not exists and the content is new, data will be pushed.


you need to have flexibility to modify ...

if you want to push from local repo to remote, think about the branch.

how to push from one branch to another?
=======================================
if you want to push from one branch to another branch, there is a concept called merge.

moving content from one branch to another.

$ git merge <Source_Branch> <Destination_Branch>

whatever commit available on source will be available to destination branch.

To merge, you have to first go to destination branch.

$ git checkout master
$ git log --oneline
$ git merge IOS <specify_branch -> by default, it will pick the current one)

merge command commit change, by default it will open vi.

$ ls
$ git log --oneline

you will see new commit ID.

what happens if latest commit is deleted.
------------------------------------------
use git log to check ...who did merge.


if you see upto date, that means there is not new commit id on source branch.

when  you do merge, the content from source branch will be copied to dest branch.

what if same file exists on both source and destination?


$ echo "Master" > fileinIOS
$ git add .
$ git commit -m "adding master line to the file"

$ cat fileinIOS

$ git log --online -2 # list only latest 2 commit

lets checkout to IOS branch
$ git checkout IOS
$ ls
$ cat fileinIOS

nothing is displayed.

$ echo "IOS" > fileinIOS
$ cat fileinIOS
go to master

$ git checkout  master
$ git merge IOS

you see a conflict error.

$ git status

$ cat fileinIOS
<<<<<<< HEAD
MASTER
=======
IOS
>>>>>>> IOS

You will see the content from source and destination branch.

with arrow >>>>>> is the content from source

with reverse (left) arrow <<<<<<< means destination branch.



you have to verify the choose or edit the file and do the commit
Remove all confusing content.

$ vi fileinIOS
$ git add .
$ git commit -m "Adding after conflict resolution"
$ ls
$ cat fileinIOS
Master
IOS


Choose commit ID
$ git cherry-pick <commitID>

only one commit id from source id it merged to destination branch.

rather than merging everything, if you want to merge specific commit id, you have to do it manually one by one.

$ gitch checkout IOS
$ ls
$ git log --oneline

$ git add .
$ git commit -m "Added 01"
$ git log --oneline -2# Display only 2 commit id.
$ git touch hello2.txt
$ git add .
$ git commit -m "hello 2"
$ ls
$ git log --oneline -3

Create another commit with another file
$ touch hello3.txt
$ git add .
$ git commit -m "hello3"
$ git log --oneline -4

Now we have three different commit id.
rather than merging everything, we can choose one by one.

go to master branch and start the merge
$ git checkout master

$ git cherry-pick ab45dcf
$ ls

review the output. You see, it didn't copy everything.
$ git cherry-pick <commit-id2>

$ ls

once done, you can push

$ git push

your local repo master to central repo master is on sync.

selective merge vs complete merge.


we transfer/sysn the data from local master branch to repote master branch on central repo.
=====================================
=====================================




unit test
- test of your code whether its is working or not.

how to undo the change?
one file or multiple file?

make a backup of the file before you undo that change.
- how do you do it?

There is an option called stash.

when you have a change in a working directory and want to take a backup, as well as undo the changes you have done together, you can use the command stash.

-> Stash basically undo the changes and take a backup of changes what you have done.

Where the backup is stored?
----------------------------
- inside the repo in object location.


lets see how it can be done.

Lets go to wp0
$ cd mp0; git pull
$ ls
$ git log --online -2 # list last 2 commit id
$ cat 1.java
$ cat 2.java
$ echo "File3">> 3.java
$ echo "File4">> 4.java

$ git status

now, take a backup and undo the change
$ git stash
$ git status    # now you see


Where is the backup available?
------------------------------
$ git stash list
you will see commitID,


now lets do the change again

$ echo " Content 2.0">>2.java
$ echo "Content 1.1>> 4.java
$ git status

$ cat 2.java
$ cat 4.java

now, if you run stash, you see the result?
$ git stash
$ git status

content has been removed

$ cat 2.java
$ cat 4.java

you will see new contents are removed.

What is the point of backup and undo?
------------------------------------
- if you just want to undo, then you don't need backup.
- You are taking a backup, whether the change is good change or not. and going back is easy.

how do you know what is the back you have done and what are the changes available.

this is why we need to understand the stash list output

stash@{0}: WIP on IOS: f544555 doinint 03
stash@{1}: WIP on IOS: f544555 doinint 03
 
when you run 'git stash- git stores the content in array.

array is a sequence of values you are going to keep.
lets see you want to store something in memory

block|block|block
index0|index1|index2
hello0 hello1 hello2
they will have index and the first value willbe the index of 0. and index increases....

based on this what change you want. For eg, you can access the position value.
index of 0 will give hello0. 1 is pointed to 1 and hell2 is pointed to 3.


How do you get?
---------------
-  you have to first choose particular index and then, stash as follow
$ git apply stash@{Index-NO}
$ cat 2.java
$ cat 4.java
$ git stash apply stash@{1}
$ git status
$ cat 2.java
$ cat 4.java
now you see the content files.

Note: when you run stash apply command, you can not apply on modified file. Because when you took stash or backup, it will take a backup from reference of your file. By undoing it, it wil go back to previous location.
so, whenever you run apply, the files in your working directory should be on unmodified state. If its already modified, it will not know what reference to apply.

$ git stash apply stash@{0}
aborting. ..

$ git add .
$ git commit -m "add stashed file"

Now changes are permanently stored in local repository.


$ git stash list
you will still see the backup. do not remove until you are going to commit the changes.

after the commit, you can remove it.

$ stash clear  # removes all backups.


Reset - undo
$ git log --onliner

head -> what is it?

branch is ponted to some <Head>reference

because of HEAD, you can work on branch.

head reference is always pointed to latest commit_id.


if you modify something and you try to check in, it will create noew commit and head reference automatically moves. Head reference are pointed to commit_ID, you will see the correspoding content.

now, lets go to workspace

$ cat 2.java
$ cat 4.java

we see two lines on both files including all changes.

now you see different output. it includes all the content before you stash.


Undo'ing in git? - in three aras (Undoing from snapshot)
git reset

1. soft -> try to undo only from repository reference
2. mixed mode -> undo from repo and stagiing area
3. hard mode -> undo from all the areas, you do the hard mode. (from repo + staging area + working directory)

most of the time, you use hard mode.

$ git undo
$ git reset --soft/mixed/hard

$ git staus
$ git log --online 2    # look at the head reference
$ cat 2.java
$ cat 4.java

$ echo "new line">>2.java
$ cat 2.java

$ git add .
$ git status

$ git reset --soft
$ $ cat 2.java
$ git status

 

midex mode - undo the staging area
$ git reset --mixed # it will not do anythig on working directory but undo the staging area.

unstaged.
$ sit status

$ cat 2.java

so in mixed mode, it undo from staging area.

$ git add .
$ git status

you se the changes
$ git reset --hard
you can only see two lines..

it says head reference is moded to main


you use reset on either staging area or working directory.


default mode is mixed mode.

when you want to use reset?
------------------------------
- when you want only undo and that also before you are going to do the commit, temp files or whatever you have , you will be using mixed mode.


$ git status
$ git log --oneline
reord current commit id

$ echo "dummy line" >> 2.java
$ cat 2.java
$ git add .
$ git commit -m "adding dummy line"
$ git log --oneline -2

in git, you can not remove a commit id.

how do you undo manually?
you go back to 2.java file and remove the added content and add and push.

how do you to undo using git? - git revert <commit-id>
-----------------------------
$ git revert <commit-id>

what revert will do is -> it will go back to previous commit id, take the content, apply it now.
when you have apply, it is a change. since content is removed, this file is modified.
it will create a commit_id.

any change you do is ontop of commit id. you can not just delete the commit id.


$ git revert <previous_commit_id>

this will apply the change and do the commit.


add a message when editor opens and save

$ git log --oneline -4


undo using reset.

undo a commit through revert when there is an issue with commit.
it will not delete the commit. It will keep the old commit and it will create a new commit with old content.


How to go back to old commit id?
--------------------------------
say your co-worker did revert to your change and when you come back next day, you see your commit has been reverted. There might be mis-understanding on your code and  your co-worket reverted or code it self might be with errors.


go back and see and test it if your code really had an issue,..

to go to older commit id, you have to move HEADer to your commit id
use git checkout
$ git checkout <commit_ID>
$ git checkout eas2abc4
head is pointed to new commit id
$ cat 2.java

you can review the code and where the mistake is

what you can do it, on  your latest commit-id, you can do the revert which will undo the last commit.

say your commit ids are
ff123s2 -> latest commit id
jak4534

we will use latest commit id and revert

$ git checkout jak4534
$ git log --oneline -3
now you see head reference is pointed to different commit id.
34 is wher ehead is pointed to.

now, we have to go to latest commit ID.

Note: Transaction are incremental based on previous (Commit ID).
git checkout is to move around diferent commit id.

if you already have commited, and if you want to undo the commit then you are going to do a revert.
if you want to go back between different commit id then you can choose checkout and keep moving.

$ git log --online -3
jak4534 -> latest commit id
ff123s2
you see latest commit id is changed.head reference is pointing to different one.

is it the latest commit id?
No

Head reference has been moved.

What is the latest commit ID?
-----------------------------
we know latest commit id is ff123s2

now, if you want to work on that, you have to go back to that commit id.

how do you go there?
$ git checkout <latst commit id>

now, say you don't know the commit id?

git log shows the commit id from the head reference currently where it is pointing everything below it.

now, you have to know couple of more stuffs.

we use checkout command for branching as well.

so what is the difference?
--------------------------
for branch, we say 'git checkout <branchname>' to switch between one branch to another barnch.

here, we saying 'git checkout <commit ID>' jumping from one commit id to another commit id.

now, lets go into little depth.

You are working in repository, in side the repo, you are working in a branch.

where in the branch you are working?
actually pointing to commit id where you are working.

when  you say where you are working, you should specify
-> particular repo
-> partucular branch
-> partucular commitID

its like a room inside a building -> floor and -> room -> cubicle...


BRANCH+CommitID -> by default you will be on latest commit id

when you do 'git checkout branch_Name' without commit_ID, you will always go to latest commit id of the branch.

go to latest commitID

$ git checkout IOS

head position has been moved to latest commit ID.

$ cat 2.java

$ git log --oneline -4

$ git checkout master
$ git log --oneline -3









============================





review
Configuration
$ git config --global user.name "Jay K"
$ git config --global user.email "jay@jay.com"
$ git config --global push.default "Simple"

User/developer workflow
----------------------
$ git clone <source-central-repo> <dest-local-repo>
$ git clone https:/github.com/<user-name>/repo-name.git myworkspace
$ git status
$ touch myfile; echo "Hello">myfile
$ git status
$ git add <file> or git add .
$ git status
$ git commit -m "mesage"
$ git log -num -ineline
$ git show <commitid>
$ git push
$ git pull


$ git branch
$ git checkout <New_Branch>
$ git checkout IOS
$ git checkout andrioid
$ touch Myfile
$ git merge <Source_Branch> <Destination_Branch>
$ git cherry-pick <commitID>

$ git stash
$ git stash list
$ git apply stash@{Index-NO}
$ git stash clear

stash@{0}: WIP on IOS" fs83ud789 doitnow 03
stash@{1}: WIP on IOS" fs83ud789 doitnow 03

idea22|idea11
index0 index1 index2 ...


git reset --soft (repository reference)
git reset --mixed (repo+stagingarea)
git reset --hard(repo+SA+Working directory)

git revert <commitid>
git checkout <commitid>

BRANCH+CommitID
      latest - commitID
CURRENT - BRANCH


Stashing commited changes
1. Create shash, remove changes from working directory
$ git stash

2. List stash available for ther epository
$ git stash list

3. Reapply the changes, remove stash
$ git stash pop

4. Apply a specific stash from repo
$ git stash apply stash@{num}

5. Remove stash from repo
$ git stash clear


Resetting changes
1. Revert uncommitted changes
$ git reset <file>

2. Move only to HEAD pointer
$ git reset --soft

3. Move the HEAD pointer and reset the staging area (Default):
$ git reset --mixed

4. Move HEAD pointer, resets staging area and working tree to the new HEAD
$ git reset --hard


Reverting changes
1. Rever a commit
$ git revert <commit>

2. Checkout specific commit
$ git checkout <commit_id>

3. Delete a file
$ git rm <file>

4. Remove untracked file
$ git clean -n (-n is for dry run)
$ git clean -f (force delete)

5. Discard changes in working directory
$ git checkout --<files>

https://youtu.be/Yey0dFnB4nk



No comments:

Post a Comment

Git branch show detached HEAD

  Git branch show detached HEAD 1. List your branch $ git branch * (HEAD detached at f219e03)   00 2. Run re-set hard $ git reset --hard 3. ...