Git
Tags: git, codenewbie, 100daysofcode
Published: 2020-11-20 16:41:49

<i>If you need your system to keep track of the changes done to your folders, files, or any digital sources, then the Version Control System is exactly your lookout.<br>
Git is a Version Control system that wraps up the change in the entire file system rather than mere data changes.<br>
The category of software tools helps to keep track of changes to files by monitoring the modifications done to the code. A Version Control System is used as a repository since it maintains the snapshots of the project; and a copy of work that acts as a personal work copy of the files in the project.<br>Popularly used Version Control Systems include: Centralised Version Control Systems and Distributed Version Control Systems. Git falls under the category of Distributed Version Control Systems.<br>
Before even understanding what DVCS is, let's figure out the one-liner of a Centralized Version Control System. The CVCS works on the changes directly committed to the central copy of your project. The issue of collaboration is effectively solved by DVCS, which has the server to maintain version control, hence multiple collaboration through commits on the same project is made much easier.<br>
The benefits of Version Control Systems is that it helps in managing the changes in the source code over time. Although, if the mistakes are made, you can modify the code and minimize the disruptions being made.</i>
<h2>Kick start your Git learning!</h2>
Before we start learning the git commands there are few essential terms that must be kept in mind.

<h3>Repository:</h3> 
* Nicknamed as 'repos', the Repositories are the encyclopedia of the commits which represents the working tree up to date, irrespective of the machine on which the project is running. 
* Apart from being the store-house of branches and tags, a repo also defines the HEAD from the current working tree. 
* A Repo can either be a local folder on your computer or storage space on your online host. Your files can be of your choice - text, image, code, etc. 
* Based on the servers, repositories can be divided into two types: <br>

a) <u>Bare repository</u>: These repos share the changes done by different developers, but the modification of the creation of a new version for this repo is not allowed. <br>
b) <u>Non-bare Repository</u>: These repos allow you to create any modifications to files or create a new version of the repo, similar to cloning isn't it?
* <code>git init</code>: When you're planning to start on your new project, you ought to let Git know of your plan, which is exactly what the .git file does when you run the <code>git init</code> command. It initializes a new Git repo that stores all the objects and references.

USAGE: <div class="highlight"><pre class="highlight shell"><code>git init</code></pre></div> <br>

* <code>git fetch</code>: It downloads all the latest commits from every branch and stores it in the local repo. <code>git fetch</code> never changes your working state though worked out multiple times. If you're eager to find out the local and the remote changes in the master branch then try the <code>git diff</code> command.

USAGE: <div class="highlight"><pre class="highlight shell"><code>git fetch <span class="s1">ee5df4b</span></code></pre></div>

<h3>Working tree:</h3> 
* Working tree is defined as the directory which has the associated repository. 
* You can identify a working tree if you hunt down a .git file on your filesystem. Hence it is a collection of directories, contents, and sub-directories. 
* Git repository reflects the Unix file system that begins with the root directory and consists of i-nodes that identify the files with a unique number. 
* It tracks the changes of a specific user of a repo version. When a change is committed to the git, the latter would hunt for the files in the working tree. 
* The user in the Working tree is allowed to modify, create or delete the existing files. The changes can either be committed to the git or reverted, after your changes in the working tree. <br>

* <code>git pull</code>: Now that you are aware of <code>git fetch</code> and <code>git merge</code> (scroll your way down to 'Master'), interpreting the working of <code>git pull</code> is a piece of cake. <code>git fetch</code> is executed first then the <code>git merge</code> in the working directory.<br>

USAGE: <div class="highlight"><pre class="highlight shell"><code>git pull <span class="s1"> --rebase </span></code></pre></div>

<h3>Index:</h3> 
* Having made changes to your project, you directly cannot save it in the repo from your working tree. Hence, the Index acts as a middle man to commit your changes and then store it in the records. 
* Index refers to the set of trees and files recently committed, on running the <code>git add</code> command. 
* The index is the staging area for your next commit that supports a development model, non-native to the subversion.
* In the case of subversion, the list of actions is determined based on your current working tree. 
* The list of actions, in this case, refers to the information within the Index. This is nothing but the succeeding state of HEAD, that helps you exercise control over staging in advance. <br>
* <code>git push</code>: The commits on your local branch that aren't present on your corresponding branch in the origin server will be updated using the command <code>git push</code>.

USAGE: <div class="highlight"><pre class="highlight shell"><code>git push</code></pre></div>

<h3>HEAD:</h3> 
* HEAD in Git refers to the recent commit made on the current branch awaiting the checkout which is also referred to as an 'Active' branch. 
* Git notices the active branch through the internal file <code>.git/HEAD</code> that is not advisable for manual manipulation. 
* One buzzword that we hear while knowing the HEAD is **Detached HEAD**. 
* In very few cases, the HEAD file is devoid of the branch of its reference but has an SHA-1 value. The reason for its occurrence is the sole reason to check out a specific commit, branch, or tag. This state is called Detached HEAD.<br>
<h3>Commit:</h3> 
* The changes in your working tree are saved at a particular time. Commit basically reflects an individual's change to a file in its local repository. 
* All that you have to do is, explain git of the change you want to make while running the <code>git commit</code> command.
* You can infer that git does not include a file automatically in the next commit. To resolve this situation try running the <code>git add</code> command.
* Git does not allow you to commit changes in the remote server, rather saves a new commit object in the local Git repository. 
* Your desire to change the exchange commits can be performed manually using the <code>git fetch</code>, <code>git pull</code> and <code>git push</code> commands.<br>
* <code>git commit</code>: The command creates a new commit having contents of the commit apart from the log message. The commit serves the purpose of the changes that can be undone if required. Executing a new <code>git commit</code> taking the place of the HEAD would make the previous commit its parent.

USAGE: <div class="highlight"><pre class="highlight shell"><code>git commit 
<span class="c">The '-m' option allows you to set a commit message</span> 
git commit <span class="nt"> -m</span><span class="s1"> "Commit message"</span>
<span class="c"> The '-a' option shows all the recently changed files</span>
git commit <span class="nt"> -a</span>
<span class="c"> The '--amend' option allows you recheck and change the last commit</span>
git commit <span class="nt"> --amend</span></code></pre></div>

* <code>git reset</code>: Looking to undo a commit that has already been created? <code>git reset</code> HEAD will lead you to your branch specified. It updates the stage and the working directory using the three flags (<code>--soft</code>, <code>--mixed</code> & <code>--hard</code>)besides copying the files from history to the stage.

USAGE: <div class="highlight"><pre class="highlight shell"><code>git reset <span class="s1"> HEAD^ </span></code></pre></div>

* <code>git revert</code>: The undo for git that picks all the tasks undertaken at your desired revert. If your commits have already been shared with your team, but your desire to undo the commits is your priority, then <code>git revert</code> is the best option.

USAGE: <div class="highlight"><pre class="highlight shell"><code>git revert <span class="s1"> 0e70093 </span></code></pre></div>

<h3>Master:</h3> 
* Choose to go with the name 'master'. It purely indicates the main branch where the developments are done. 
* The accepted pull requests after the individual commit are merged with the master for the complete functioning of that feature. 
* Moreover, Master is the terminology used for the branch. The remote repository will have a single local branch after cloning your project from the remote server. This local branch is called the master branch, which can be considered as the repository's default branch. 
* But when you clone a repo for the first time, Origin is the name given to the remote repo that pushes and pulls the changes.
<h3>Branch:</h3> 
* Branch refers to the line of development that is different from the main branch. Your fancy or feature can be depicted in your code without disturbing the main branch(master). 
* In such a case, the code from the master will be copied on your local system and the change would be private unless your code would enter the staging process(Commit).
* The branch is a movable pointer to one of the commits. Moving forward with the commits, operations are performed on the master branch pointing to your last commit. 
* Branching for the record is the most common feature of Version Control Systems.
<br>
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/j85x7tt534w68t734b0b.gif)<br>
* <code>git branch</code>: The command creates a new branch that points to the recently checked out commit. If you're not happy with your branch you can delete it using <code>git branch -d name</code>. Remember, when your <code>clone</code> your remote repo, the main branch of the repo is your default master.

USAGE: <div class="highlight"><pre class="highlight shell"><code>git branch <span class="s1"> myBranch </span>
<span class="c">The '-d' to delete the particular branch</span>
git branch <span class="nt">-d</span> <span class="s1">myBranch</span></code></pre></div>

* <code>git merge</code>: A new commit with two parents having the records of the changes made at both the branches are combined using the <code>git merge</code> command. This new commit would now contain the latest complete code. <br> 

<blockquote> <u><i>PRO-TIP:</u> Keep the latest version of code in the master branch.</i></blockquote> 
USAGE: <div class="highlight"><pre class="highlight shell"><code>git merge <span class="s1"> master </span>
<span class="c">Merge with the master</span></code></pre></div>

* <code>git checkout</code>: The prime importance of <code>git checkout</code> is to switch between the branches and workout a <code>git commit</code> command to notice the working. It can also copy the files from history to the working directory, in case of which the current branch wouldn't be changed.

USAGE: <div class="highlight"><pre class="highlight shell"><code>git checkout <span class="s1"> myBranch </span></code</pre></div>

<h3>Tag:</h3> 
* The name of the commit apart from the name of the person who issues the pull request and the time of the issuance is reflected in a Tag.
* Git being a Version Control System, will be able to tag specific points of importance in the history of the repository. This specific Git feature is used to mark the release points. 
* It is like an unchanged branch that doesn't have a history of commits. It serves the meaningful names to a specific version in the repository.<br>

<h3>Cherry Pick</h3>
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/n0thvpzjgevn1d2trwwn.png)
* The cherry-pick command acts like a patch on another commit by copying a commit on this other commit in the current branch.
* If you have your commits on the wrong branch or do not need the entire branch to be merged then <code>git cherry-pick <commit hash></code> is a bright option.
* To stage the all changes, run the <code>git cherry-pick -n <commit hash></code> command.
* Stuck with conflicts? Try out <code>git cherry-pick —abort</code> or <code>git cherry-pick —continue</code>.

<div class="highlight"><pre class="highlight shell"><code>
git cherry-pick <span class="nt">-n</span><span class="s1"><commit hash></span>

<span class="c">Using either of the below commands, resolves your conflicts</span>
git cherry-pick <span class="nt">-abort</span>

git cherry-pick <span class="nt">-continue</span>
</code>
</pre>
</div>

<h3>Rebase</h3>
* A rebase combines multiple branches. However, the fine line of difference between Rebase and Merge is drawn between the fact that Rebase combines the commits from the current branch to another with a linear history whereas Merge makes a single commit with two parents with a non-linear history.
* Essentially Cherry-picks in a row is its Rebase with the command <code>git rebase master</code>.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/p18gl33yu0rbrywana5g.PNG)
* <code>git rebase</code>: The commits on a particular branch move them to a new base by creating very new commits with varied IDs, without affecting the old ones.

USAGE: 
<div class="highlight"><pre class="highlight shell"><code>git rebase <span class="s1"> master</span></code></pre></div>

<blockquote> <i><u>Healthy Git tip:</u> The pushes cause a fast-forward merge on the remote repo. The rejected difference between local and remote branch can be overcome by pulling and then pushing it to the branch. </i></blockquote> 
<h1>Work your way through the Git Flow</h1>
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/lc7e8a7sdanjo12j3pnc.gif)
<a href="https://agripongit.vincenttunru.com/">Click here for the visual guide of the Git workflow</a>
<h4>Sort your PRE-REQUISITES</h4>
* After setting up Git in your local system, create a new directory.
* Open your new directory and create a new repo using the **<code>git init</code>**.

<h4>CLONE the repo</h4>
* Cloning is nothing but creating a working copy of the local repo. Try running the command **<code>git clone /path/to/repository</code>**.
* Attention: If you're using a remote server make **<code>git clone username@host:/path/to/repository</code>** your priority.
<h4>Concentrate on the WORKFLOW</h4>
* Know the trees of Git which are *Working Directory, Index and HEAD* to understand the <a href="https://gfc.io/">workflow</a>.
* Spark your knowledge on the three terms by scrolling up to the first section.
* Know that Working Directory holds your actual files.
<h4>ADD you first Git change</h4>
* Your desired changes can be added to the Index using **<code>git add <filename></code>** ; 
**<code>git add *</code>**.
* Make a commit to your HEAD **<code>git commit -m "Commit message"</code>**. Let's understand the fact that the remote repo is undisturbed.
<h4>Treat your remote repo with a PUSH</h4>
* Push the changes in the HEAD of your local working copy to your remote repo, executing **<code>git push origin master</code>**. [You can change the branch as per your needs.]
* In case of pushing your changes to the remote server execute the command <code>git remote add origin <server></code>
<h4>BRANCHING your way out</h4>
* <a href="https://learngitbranching.js.org/">Learn Git branching</a>
* Create a new branch and switch to add your feature, later enabling it to be merged with the master branch. Type-out <code>git checkout -b new_feature</code> for this purpose.
* Make a switch to master using <code>git checkout master</code> or delete your branch using <code>git branch -d new_Feature</code>.
* No worries, your branch will remain private until you run the<code>git push origin <branch></code> command to push it to your remote repo.
<h4>Make a quick UPDATE and a permanent MERGE</h4>
* The local repo has an update of the recent commit using the <code>git pull</code> that fetches and merges the remote changes.
* Make another merge to your current branch by <code>git merge <branch></code>.
* The possible conflicts to the changes auto-merged are overcome by manually handling the files and later indicating them as merged with<code>git add <filename></code>.
<h4>Find out your Commit ID</h4>
* <code>git log</code> to find out your recent repo history.
Check out the following log parameters when you:
* Do you require a Compressed log? - <code>git log --pretty=oneline</code>
* Targetting an author's commits? - <code>git log --author=bob</code>
* Want to know more about the parameters? - <code>git log --help</code>
<h4>Software release TAGS</h4>
It is a good habit and a professional approach of creating the tags for the Software releases which can be achieved by <code>git tag 1.0.0 <First_10_characters_of_the_commit_id></code>.

<h1>GIT Takeaways</h1>

Check out the tools to play around with Git.
* <a href="https://www.sourcetreeapp.com/">*Learn GIT from scratch*</a>
* <a href="https://aurees.com/">*Aurees Git Client*</a>
* <a href="https://www.gitkraken.com/">*Git Kraken*</a>
* <a href="https://git-fork.com/">*Git Fork*</a>
* <a href="https://gmaster.io/">*Git Master*</a>
* <a href="https://www.git-tower.com/mac">*Manage your DevOps lifecycle tool*</a>

<code><p><br>
<footer style="height:auto"><h3>*Follow our community for more goodies, stickers,<br>t-shirts*</h3><table><tr><td><a href="https://gitlab.substack.com/p/coming-soon">![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/hplp6opfpywirwur2vmz.png "Official Website")</a></td><td><a href="https://twitter.com/GitlabC">![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/00qhd8v9ma2t2l2xv4xh.png "Twitter")</a></td><td><a href="https://www.meetup.com/GitLab-Meetup-Coimbatore/">![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/aqq6pi897bk687d3kwwa.png "Meetup Community")</a></td><td><a href="https://www.linkedin.com/groups/8955040/">![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/8u4886rik46g1bvvrx8d.png "LinkedIn")</a></td></tr></table></footer></p></code>