What is version control?
Version control is a system (VCS) that records changes to a file or set of files over time so that you can recall specific versions later.
A Version Control System is a very wise thing to use. It allows you to revert selected files back to a previous state, revert the entire project back to a previous state, compare changes over time, see who last modified something that might be causing a problem, who introduced an issue and when, and more. Using a Version Control System also generally means that if you screw things up or lose files, you can easily recover.
The major difference between Git and any other VCS is the way Git thinks about its data. Conceptually, most other systems store information as a list of file-based changes. These other systems think of the information they store as a set of files and the changes made to each file over time (called as delta-based version control).
With Git, every time you commit, or save the state of your project, Git basically takes a picture of what all your files look like at that moment and stores a reference to that snapshot. More clearly, if files have not changed, Git doesn’t store the file again, just a link to the previous identical file it has already stored. Git thinks about its data more like a stream of snapshots.
This makes Git more like a mini filesystem with some incredibly powerful tools built on top of it, rather than simply a VCS.
- Developers can work together from anywhere in the world.
- Developers can see the full history of the project.
- Developers can revert to earlier versions of a project.
Git has integrity. That means it uses a mechanism such that everything in git is check summed before it stored and then referred by SHA-1 hash. This 40-character string calculated based on the contents of file or directory in Git.
Git has three states that file could reside in:
- Modified — the state that file has changed but still haven’t committed to database.
- Staged — the state that file has marked as modified file in its current version to go into next commit snapshot.
- Committed — the state that fila has stored safely in local database.
This leads to three main section of a Git project,
- Working tree: A single checkout of one version of the project. These files are pulled out of the compressed database in the Git directory and placed on disk to use or modify.
- The staging area: This is a file, generally contained in your Git directory, that stores information about what will go into next commit. Its technical name in Git parlance is the “index”.
- Git directory: The place where Git stores metadata and object database for project. This is what is copied when clone repository from another computer.
First — Time Setup
After installing Git to your operating system, there are few things to customize on Git environment. Git comes with a tool called “git config” that lets us get and set configuration variables that controls all aspects of how Git looks and operates. These variables can be stored in three different places.
- “[path]/etc/gitconfig file”: Contains values applied to every user on the system and all their repositories. If the option –system to “git config”, it reads and writes from this file specifically. Because this is a system configuration file, that need administrative or superuser privilege to make changes to it.
- “~/.gitconfig or ~/.config/git/config file”: Values specific personally to you, the user. You can make Git read and write to this file specifically by passing the --global option, and this affects all of the repositories you work with on your system.
- Config file in the Git directory (that is, .git/config) of whatever repository currently using: Specific to that single repository. You can force Git to read from and write to this file with --local option, but that is in fact the default. Unsurprisingly, you need to be located somewhere in a Git repository for this option to work properly.
After installing Git, first thing is to set user name and email address once. This is important because every Git commit uses this information.
If option is --global, then Git will always use that information for any operation on that system. If there any specific projects that need to override this system with a different name and email address, you can run the command without the --global option.
Git will create a branch called “master” when creating a new repository with “git init”. If you want set “main” as the default branch name as a different name for initial branch use as follows.
If you want to check configuration settings, use the “git config --list” command to list all settings.
There may be same key from different files. So, if you want to check specific key’s value type following command. git config <key>:
There are three equivalent ways to get manual page help for any Git commands.
Even offline, these commands could access anywhere. There are more available options for a Git command. Like:
Here I hope to cover the basic command that do vast majority things eventually with Git.
Getting a Git Repository
There are two ways of obtaining a Git repository.
- A local directory that is currently not under version control can turn into a Git repository. First, go to the project’s directory.
First, go to the project’s directory. For windows,
This creates a new subdirectory named “.git” that contains all of your necessary repository files — a Git repository skeleton. At this point, nothing in your project is tracked yet.
After that, you could start tracking files and do commit to Git by “git add” and “git commit” commands.
2. Clone an existing Git repository from elsewhere.
“git clone <url>” command use to get a copy of an existing Git repository which may need your contribution. By this command Git receives a full copy of nearly all data that the server has. Every version of every file for history of the project is pulled down by default running “git clone”.
Example:- Clone the Git linkable library called libgit2
This creates a directory named “libgit2”, initializes a “.git” directory inside it, pulls down all the data for that repository and checks out a working copy of the latest version.
If you want to create a directory with different name other than repository had, you can use new directory name as an additional argument.
This do the same thing as the previous one, but the target directory is called “mylibgit”.
Recording Changes to the Repository
At this point, there should be Git repository on local machine and want to make changes and commits of changes into repository. There are two states to files in working directory of repository: Tracked or Untracked. Tracked files are that were in the last snapshot. Untracked files are everything else that not in last snapshot.
At the moment you clone a repository, all files will be tracked and unmodified. Because still files weren’t untouched. As you edit files, Git sees them as modified, because you’ve changed them since your last commit. As you work, you selectively stage these modified files and then commit all those staged changes, and the cycle repeats.
Checking the Status of your Files
“git status” command uses to determine states of files. If you run this command just after a clone output will show like this:
This means none of your tracked files are modified and Git also doesn’t see any untracked files. Finally, the command tells you which branch you’re on and informs you that it has not diverged from the same branch on the server.
Let’s say you add a new file to your project, a simple README file. If the file didn’t exist before, and you run “git status”, you see your untracked file like so:
Here you can see new README file is untracked, because it’s under the “Untracked files” heading in your status output. Basically, untracked means that Git sees a file that didn’t have in the previous commit. So let’s track the file.
Tracking New Files
In order to begin track a file use the command “git add”.
Then after running “git status” command again, you can see that README file is now tracked and staged to be committed.
Now it’s staged because it’s under the “Changes to be committed” heading. Here “git add <files>” command takes a path name for a file or a directory. If it’s a directory, the command adds all the files in the that directory recursively.
Staging Modified Files
If you change a previously tracked file called “CONTRBUTING.md” and then run “git status” command again, output will look like this:
The “CONTRIBUTING.md” file appears under a section named “Changes not staged for commit” which means that a file that is tracked has been modified in the working directory but not yet staged. “git add” command is used to begin tracking new files, to stage files, to do other things like marking merge-conflicted files as resolved.
Let’s run “git add” now to stage the “CONTRIBUTING.md” file, and then run “git status” again.
Now both files are staged an will go into next commit.
At this point suppose you have to change a little bit in “CONTRIBUTING.md” before you commit. Then you made the change and run GIT status one more time.
As the output, “CONTRIBUTING.md” file is listed as both staged and non-staged. this turns out that git stages a file exactly as it is when you run the “git add” command. It means that, if you modify a file after run “git add”, you have to run git add again to stage the latest version of the file.
Often, they will have a class of files that you don’t want Git to automatically add or even show as being untracked. These are generally automatically generated files such as log files or files produced by build system. In such cases, you can create a file listing patterns to match them named “.gitignore”.
The first line tells Git to ignore any files ending in “.o” or “.a” — object and archive files that may be the product of building your code. The second line tells Git to ignore all files whose names end with a tilde (~), which is used by many text editors such as Emacs to mark temporary files. You may also include a log, tmp, or pid directory; automatically generated documentation; and so on. Setting up a “.gitignore” file for your new repository before you get going is generally a good idea so you don’t accidentally commit files that you really don’t want in your Git repository.
The rules for the patterns you can put in the “.gitignore” file are as follows:
- Blank lines or lines starting with # are ignored.
- Standard glob patterns work, and will be applied recursively throughout the entire working tree.
- You can start patterns with a forward slash (/) to avoid recursivity.
- You can end patterns with a forward slash (/) to specify a directory.
- You can negate a pattern by starting it with an exclamation point (!).
Glob patterns are like simplified regular expressions that shells use.
An asterisk (*) matches zero or more characters, [abc] matches any character inside the brackets (in this case a, b, or c), a question mark (?) matches a single character, and brackets enclosing characters separated by a hyphen ([0–9]) matches any character between them (in this case 0 through 9). You can also use two asterisks to match nested directories; a/**/z would match a/z, a/b/z, a/b/c/z, and so on.
Here is another example “.gitignore” file:
Viewing Your Staged and Non-staged Changes
Though “git status” command shows which files were changed, it didn’t show what exactly changed in the file. Although “git status” answers those questions very generally by listing the file names, “git diff” shows you the exact lines added and removed — the patch, as it were.
Let’s say you edit and stage the “README” file again and then edit the “CONTRIBUTING.md” file without staging it. If you run your “git status” command, you once again see something like this:
To see what you’ve changed but not yet staged, type “git diff” with no other arguments:
That command compares what is in your working directory with what is in your staging area. The result tells you the changes you’ve made that you haven’t yet staged.
If you want to see what you’ve staged that will go into your next commit, you can use “git diff — staged”. This command compares your staged changes to your last commit:
It’s important to note that “git diff” by itself doesn’t show all changes made since your last commit — only changes that are still non-staged. If you’ve staged all of your changes, “git diff” will give you no output.
Committing Your Changes
When your staging area is set up the way you want it, you can commit your changes. Remember that anything that is still non-staged — any files you have created or modified that you haven’t run “git add” on since you edited them — won’t go into this commit. They will stay as modified files on your disk. In this case, let’s say that the last time you ran “git status”, you saw that everything was staged, so you’re ready to commit your changes. The simplest way to commit is to type “git commit”:
Alternatively, you can type your commit message in line with the commit command by specifying it after a -m flag, like this:
Now you’ve created your first commit! You can see that the commit has given you some output about itself: which branch you committed to (master), what SHA-1 checksum the commit has (463dc4f), how many files were changed, and statistics about lines added and removed in the commit.
Remember that the commit records the snapshot you set up in your staging area. Anything you didn’t stage is still sitting there modified; you can do another commit to add it to your history. Every time you perform a commit, you’re recording a snapshot of your project that you can revert to or compare to later.
Here we discussed a pinch of details of Git version control system. Thank you for your reading. Hope you get little idea about Git.