git-logo
What is GIT?
GIT is a distributed version control system for tracking changes in source code during any development. Here each developer has their code on their local system. Whenever they want they can push the code into Github or Git Server

SVN and GIT
SVN is a centralised repository. Everyone use to connect to central repo and code there. If there is any network issue between server and client, developers cannot do anything using SVN.

What are the areas or stages in GIT?
1. Workspace Area : What ever files we add/create are initially in the Workspace Area.
2. Staging/Index Area (git add)
3. Local Repository (git commit -m)
4. Remote (git push)
atozit-git-work-flow

Initially files when created are in workspace area. To add them to staging we use “ git add -a or git add . Or git add <filename> “ commands. When the files are in Staging or index area means that they are ready to commit. Once the files are in Staging area, they can be put into local repository using “git commit <file1> -m “comment about the committee” . So the files are into local repository.

What is a git repository?
Git repository is a folder or directory which is initialized using "git init" command which creates a '.git' sub-directory which has all the elements to track the code changes.

What is git branching?
Series of commits is called a branch. A branch is a collection of directories and files. Default branch is master. When we create a branch from master, all code will be copied to the new branch and there we do required modifications like feature1 and if everything is fine, we can merge it back to master or continue as separate branch.
git branch : this command displays all the branches in alphabetical order.
*  before a branch represents current active branch where we are into
git branch <newbranch name” will create a new branch.
git branch -b <newbranch name will create the new branch and also switches to that branch.
If we want to merge, we need two branches at least. It will merge all files and directories from source branch to target branch(master in this case). The command is : git merge feature1. For this go to master branch and do the “git merge feature1” . This merges all files from feature1 branch to the master branch.
So to merge two branches, go to the target branch(like master) and give the command as git merge <branch to be merged>
To delete a branch, use “git branch -d <branch name>” from other branch. You shouldn’t be in the same branch when deleting.
git branch -D <branch name>; -D is force deletion of a branch
Master branch also can be deleted from other branch
Git branch commands:

Branching Commands

Explanation

Git branch

Display all branches in alphabetical order

Git branch <new branch>

Create new branch

Git checkout -b <new branch>

Create and change to the new branch

Git diff <branch1> <branch2>

Difference between branches

Git merge <branchname>

Merge into the current branch

Git branch -d <branchname>

Delete this branchname

Git branch -D <branchname>

Delete this branch forcibly


DAY 1
GIT Commands:
* git init : to initialise a git repo
* git clone: To clone the exact copy of a repository. eg: git clone https://github.com/vjrid8/repo.git will create a directory with name repo in your system and fetches all files.
* git clone <remote repo path> <custom name> will create a directory with name "custom name" in your local system and fetched files into it.
* git config --global user.name “your-user-name”
* git config --global user.mail “xyz@mail.com”
* git config --list
* git status => displays status of our files; if they are red, they are in workspace, If they are green, ready to commit and are in staging/index area;
* git commit -m “label”
* git commit -am <label” => to add files to index and commit in single command. Its like git add -a and git commit. Only old files which are already committed or in staging area can be added and committed using this. New fresh files cannot be added and committed.
* git log => will display the commits
* git status <sha code/commit ID> will display details of that commit
* git status pop
* git add -f <filename> to add a file to index area even though its ignored with “.gitignore” file
* git add will add files to staging. to undo this or unstage files, use git rm --cached <file>
*
Suppose we added files to staging. Theses files will be in unmodified state. now again you modified the, they are in modified state. if you again git add <that file> it will be in staging. to undo this, use git restore --staged <file>
* git checkout <branchname> will change the branch into the given branch name
* git branch will display in which branch we are into
* git log —oneline will display git commits in one liner.
* git log -5
* git log -1 to display about the last commit
* git show sha1code
* git remote add origin <repo URL>
* git push -u origin master => -u is upstream; master is the branch

Earlier we have several version control systems in place but none of them is as famous as SVN or GIT.

All version control systems works from central repository.

History:
1. Source Code Control system(SCCS)-1972
2. Revision Control System - 1982
3. Concurrent Version Control System(CVS) 1986-1990)
4. Apache Subversion(SVN) - 2000 Opensource
5. BitKeeper SCM -2000 - Distributed version control system - Proprietary
6. GIT - Linus Torvols - 2005

All repositories work as pull the code from central repository, make changes and submit the changes back to the central repository.

But in GIT, different users(or teams of users) maintain their own repos, instead working from a central repo. 
Changes are stored as "Change Sets" or "Patches". 
Means tracks changes, not versions
Different from CVS and SVN, which track versions

Installation:
Download it from http://git-scm.com

Configuration Files:
System:
    /etc/gitconfig
    /Program Files/Git/etc/gitconfig
User:
    ~/.gitconfig
    $HOME/.gitconfig - in windows
Project:
    my_project/.git/config

git config --system => to configure system wide  
git config --global => to configure user configuration
git config => to configure project configuration

Ex: git config --global user.name "vjrid4"
git config --global user.email "vjrid4@gmail.com"

To list the configurations:
git config --list
git config user.name

DAY 2
Task: How to push local directory contents to github.com

STEP 1: git init => which will initialize the local directory as a Git repo.
STEP 2: git add . =>Stage the files in the current directory to new repo
STEP 3: git commit -m "First Commit" => commits the tracked changes and prepares them to be pushed to a remote repo. To remove this commit and modify the file, use 'git reset --soft HEAD~1' and commit and add the file again.
Label can be 50 char long as best practice with ticket number or bug fix..
STEP 4: to set remote github repo, copy the repo URL and execute command as 'git remote add origin https://github.com/vjrid4/devops.git'
STEP 5: To display remote URL, you can use 'git remote -v'
STEP 6: Now push the changes to remote git repo using command 'git push origin master'

git log: what changes are commited
git log
git log -n <number of commits>
git log -n 1
git log --since=2012-06-15
git log --until=2012-06-15
git log --author='vjrid4'
git log --grep='Init'

GIT Workflow:
Typically git workflow starts adding a file to the working copy. Then move it to staging index using git add <file.txt> and then commit changes using git commit -m <about this commit>

Add/Edit a File (Working copy)
git add <file.name> (Staging Index)
commit -m (Repository)

Hash Values#
How git refers to each commit or changes made to a repository or sets of changes made to a repository. Change sets are snapshots those are the changes made.
checksum algorithms convert data into a simple number
same data always equals same checksum
data integrity is fundamental
changing data would change checksum

Git uses SHA-1 hash algorithm to create checksums
its a 40 character hexa string which is a commit ID which we can see in git log.

Each commit number is mapped to a snapshot as discussed above. also each commit has parent, author and message details along.

The HEAD pointer:
point to a commit. Point to tip of the current branch in repository.
last state of repo, what was last checked out
points to parent of next commit

HEAD is like tape recorder head. Wherever head is recording starts from there. As same in git, if we commit changes, HEAD is at current repo and this HEAD is the parent for next commit. Means changes will start from here till next commit. so head is always point to recent commit.

there is a file in each repo in .git\HEAD. if we display the file, it displays  refs/heads/master. If we go to that path, and display master, it gives the commit ID which is head.

Making changes to files:
go to current working copy direcotry
git status
git status gives us the difference between working directory, staging Index and repository.
If add new files and execute git status, it displays new files which are added and asks to add them to staging o commit changes to repository.
so git status is a very good command to know what are the changes we made from last commit and what are at staging Index and what are at working copy.

git diff:
Gives the difference
git diff <file name> gives changes made to pirticualr file.
git diff --staged [ in earlier versions(>1.7), its git diff --cached ]
git diff by default gives changes made to your working directory. It doesnt list the changes from staging. To get the differences made to staging, use the command git diff --staged.

git rm <file to be deleted> => git remove a file
======
If we delete a file from the working directory, we need to tell git to delete it from repo also using git rm command. If we directly use git rm to delete a file, it deletes permenantly without moving it to trash. Instead of “git rm”, if we delete a file using linux rm command, we can get that file back using “git checkout <filename>”

Git rm is equal to rm <file> and commit -am <commit message>.

Git rm will delete file from working directory, staging area and local repo. So it can’t be restored or recovered.

Moving and Renaming Files:
Renaming: there are two ways to do this. First is do it from operating system and tell git to remove the old file. Second way is directly from git using git mv original.file newnamed.file

If we use mv command to rename a file, it will delete the existing file and creates a file with new name. So when we check the status, it says the file is deleted from working directory and a new file is added to working directory. So we need to add these to staging and then we have to commit.

So to overcome the above complex issue, we can use git mv command. It will directly renames the file and adds the file to the staging. So only commit is enough in this case.

tracked and untracked files:
Untracked files are just files created in working directory. when you say "git status", these files are shown in RED Color means they were not yet added to Staging.

Tracked files are the files added to Staging using "git add <file(s)>

git commit --amend --reset-author is the command to fix the author issues.
git push --set-upstream origin master

Working with a Real Project:
git init in new directory where repo is initialized
git add .
git commit
git diff
git status
git log
git commit -am <Add to staging and commit using single command>

Undoing Changes:
git can undo changes made to our working directory or staging directory.

git status
file has been modified
git diff = shows what has changed
git checkout index.html
git checkout <fileto be restored>
git checkout <branchname>
git checkout -- index.html => -- represents to stay on current branch and restore file index.html.

how to undo changes to staging index.
===================================
undo staging..
git reset HEAD <filename> to unstage.

Undoing commits to repository:
git commit ammed -m  "revert last commit"

How to undo changes from a previous commit:
Find the HASH from git log in which you made changes to that pirticular file or branch and execute git checkout <commit code/SHA> -- <file/branch name>
git checkout <
git revert <commit code/SHA>

Git ignore:
If we are developing, there are some unwanted files generated. For example, If we are developing a ‘C/C++” program, lot of obj files will be generated. If we want omit them adding to index area or local repository, we have two option. One is we can implement the same at system level using “/etc/gitignore” file or at directory level, you can create a file under directory like “.gitignore”. Include the files which you want to ignore like 

*.php
*.log
*.obj
*.exe
!index.php => as we gave *.php to ignore, but want to override the file index.php with “!” Mark .
[abc].php

Now git add . And git commit -m “git ignore file added”


Delete Git Log History:
It will be in 3 ways. They are soft, mix and Hard type of removal

** git reset —soft <SHA1  Commit code>. => files will be removed from local repository
** git reset —mix <SHA1  Commit code>   => files will be removed from staging area and local repository
** git reset —hard <SHA1  Commit code> => files will be removed from working directory, staging area and local repository.

So we must take care while working with git reset command, as it will also remove the files related to the commits. So when we do a reset, HEAD will point to the <SHA1 commit code>. Prior to the SHA1 commit code will be deleted.

GIT PUSH ISSUES:
permission Denied to push:
1. change git remote using: git remote add origin git@github.com:vjrid8/atozit.in.git
2. If there are any previous wrong git remote URLs, remove them using: git remote rm
3. Now generate the key pair on your system using ssh-keygen -t rsa and this will create a key pair like id_rsa and id_rsa.pub in your ~/.ssh folder. copy contents of id_rsa.pub and paste them in the SSH and GPG keys section on your github account by clicking new SSH key.
4. Now you will be able to push the code to github.com

"git remote -v " command displays remote URLS

GITIGNORE:
How to ignore files in the git working directory from git?
create a file in working directory with name ".gitignore" and add the files to it.
.gitignore file will ignore blank lines in it and comments can be added by prefixing # in the file
include files that you want to ignore line by line as below:
file1.txt
*.txt
!project.txt => exception from *.txt to leave this project.txt
folder/



Learn & Learn