To understand Git fundamentals, it is a good approach to put aside your general thought about GIT that is coming from CVS or SVN background. The major difference between Git and other version control systems is about how they process the information for recording the changes underneath.
CVS, SVN, perforce etc store the record as delta based version control, each version has its own delta which helps to compare the file in their respective system.
However, Git understands the data change in a different way. With Git every time you commit or save the state of project, it basically takes a picture of what all your file look like at that moment and stores a reference to that snapshot, if nothing has changed it does not store the file again but provide a link to the previous identical file it has already stored.
Git is fast because its almost every operation is local. Unlike CVS, SVN we do not need network to compare the history of files, we have all history in our local disk. For the new changes that has been made and pushed by another developer you have to fetch it from server. However, you have a local copy of your project which you can use to commit to, for e.g if you're not connected to internet you can commit your changes to the local repo and push the changes afterwards.
Git maintain its integrity of data by using SHA-1 Hash. Git check-summed the information of file and store it in its database. The SHA-1 Hash is hexa decimal characters and based on the file or the directory structure. In this way, Git clears the doubts of getting the courrpt files.
Git generally only Adds the data, this means when we commit any change in a project the Git database add the data about the change.
Git has three main states that you file can reside in these are:
Committed, Modified and Staged.
Committed means the changes are committed and data is stored in you local database.
Modified means you have made the changes but they are not yet in the database.
Staged means that you have marked your modified files in their current version to go into your next commit snapshot
GIT BRANCHING
Some people refer Git's branching technique is its "one of kind" feature. For some of you like me who do not have much idea about branching, consider this simple definition that "Branching means you diverge from the main line of development and continue to do work without messing with that main line". In many VCS it is a heavy process because for that branch it is usually we have to copy entire workset. In Git it is incredibly a lightweight process and switching back forth between the branches generally as fast.
Branch in Git is just a SHA1 hexadecimal file with the information of the commit object which has the reference/pointer to the tree of files that has changed and a pointer to all the previous commits. Well, to digest this we have to take a step back and understand what happens actually behind the scenes when a $git commit is execute.
Consider you have a directory that contains three files and you are committing it. Firstly, staging these files will compute checksum for each file which Git refers as Blobs and stores those tree objects. Secondly, Git will create a tree object that will hold the metadata information of the saved three blobs and a pointer to them. Thirdly, one commit object that holds the information of the committer, message and pointer to that tree so that it can recreate the snapshot in later time if needed.
if you make changes and commit again it will store the pointer to the commit that came before it
A branch in Git is just a lightweight movable pointer to one of these commits. The default branch name in Git is MASTER. As you start making commits you are given a master branch that points to last commit you have made. When you create a new branch you create it by running the command $git branch testing. This creates a new pointer to the same commit you are currently on.
HEAD lets you know on which branch you are currently on, it mostly confuse with other concept of CVS but in Git, it means the current branch pointer. You are on master branch it did not switch you to the testing.
You can easily see this by running a simple git log command that shows you where the branch pointers are pointing. This option is called --decorate.
$ git log --oneline --decorate
To switch to testing branch you need to run command $git checkout testing this will move the HEAD to testing. This is necessary because you should not make changes directly to the master branch, lets say you make a change and commit it, now you can see the benefit:
This shows that your testing branch moved forward and the master reports to the same commit, we can switch between branches and do relative work by using the same checkout command.
To have a history of all the commits run $ git log --oneline --decorate --graph --all
if you have multiple branches and you are also doing commit work then you will have a divergent history which can be seen by the above command.
For the reason a branch in Git is just a 40 character SHA-1 checksum of the commit it points to it is cheap and quick to create and destroy the branches.
REfrences: git-scm.com/book/en/v2/Getting-Started-Git-Basics
Git Tools.
Git CMD, Git Bash and Git GUI difference
Git provides above three tools for one purpose USING THE GIT, they all can do same operations but these three were created with intention of users capability,
If the user are more familiar with Linux commands and want to use the git feature with some of the standard unix commands those users can start using git with this tool.
If the user is more comfortable with Windows command line and like to do git operations by command line interface Git CMD comes into the picture.
However, Git GUI provides minimum features of Git and are in favors of those users who really do not like typing commands and want to do some basic operation without any typos.
All in all those tools do the same magic in the end and one series of steps for a task can be done by any one or all of them.
Difference between Git Pull and Git Fetch:
It is obvoius for a new commer to see lot of options with similar meanings and get confuse. Git Pull and Fetch are among them untill you read the following paragraph.
Git Fetch: Use when you want to download the changes from the remote repository but not yet sure to merge those changes into your working copy. Or you can say it fetches all the commits from the target branch that do not exist in your current branch and stores them in your local repo but does not integrate them.
Git Pull: it downloads the changes like the Git Fetch and merge them. So, your working copy gets updated without calling merge separately.