Git and GitHub : master your important tool as a developer .

YOUSSEF ALOUANI
10 min readJun 15, 2022

--

if there’s something you should know it well in softwares it is Git .

as a team we had a lot of issueswhile dealing with git . If you are a standalone developer you won’t feel the importance of using git or understanding it well .

Version Control System :

VCS or revision control, source control, or source code management : they are a softwares that keep tracking changes that happen across a set of files .

from wiki :

vcs : class of systems responsible for managing changes to computer programs, documents, large web sites, or other collections of information. Version control is a component of software configuration management. Changes are usually identified by a number or letter code, termed the "revision number", "revision level", or simply "revision". For example, an initial set of files is "revision 1". When the first change is made, the resulting set is "revision 2", and so on. Each revision is associated with a timestamp and the person making the change. Revisions can be compared, restored, and, with some types of files, merged .

we are developers . we never get satisfied with the complixity or the design of our application we always make changes . we always add and remove features . and in alot of cases we regret the changes we made . we want to work everywhere . And no one wanna lose his work of days , weeks , months or even years .

Git System Design :

Rule 1 : “ In git Everything is a hash”

to build Version Control System you need to make sure that the system able to fill the urge need of Three key features : safeguards against content corruption, high performance, and distributed development workflows.

Git uses a Directed Acyclic Graph (DAG) for content storage as well as commit and merge histories. A DAG is a directed graph that has an infinite number of vertices and edges (connections between vertices) that contain no cycles (acyclic). Being acyclic means that there is no way to go from Node A to Node B and loop back to Node A through any number of edges. A DAG also must have topological ordering. This means that the vertices all have edges that are directed from earlier to later in the sequence .

Git use the DAG structure for content storage. Git is essentially a content-addressable filesystem made up of objects that form a hierarchy which mirrors the content’s file system tree. Git has three main primitive types it uses to represent content for a repository: trees, blobs (“Binary large objects ”), and commits.

All content is essentially stored as either tree or blob objects. A blob is a file stored in the repository and a tree object references either subtrees or blobs. You can think of the blob as the file contents while the trees are like directories. A commit object, on the other hand, has three main attributes. It points to a tree which represents a top-level snapshot of the project at the time of the commit. It also contains references to the commits that came directly before it DAG should always represent in topological order , a field for author of the commit and, optionally, a commit message.

All object primitives referenced by a 40-digit SHA hash. . By using the SHA hash as a reference identity we can get a diffrent hash for two diffrent objects and the same one for identical objects ,what Git do is calculate the diffrence efficiently. In order to safeguard against data corruption, so when git recalculate an object’s hash using the same hash function it can easily know if there’s changes or not .

before diving deep into schemas . we need to understand what every word mean in the world of VCS .

repository : A Git repository is the .git/ folder inside a project. This repository tracks all changes made to files in your project, building a history over time. Meaning, if you delete the .git/ folder, then you delete your project’s history .

#] cd .git && ls :
./COMMIT_EDITMSG

./config

./description

./FETCH_HEAD

./HEAD

./hooks

./index

./info

./logs

./objects

./refs .

objects
├── 02
│ ├── 1f10a861cb8a8b904aac751226c67e42fadbf5
│ └── 8f2d5e0a0f99902638039794149dfa0126bede
├── 05
│ └── 66b505b18787bbc710aeef2c8981b0e13810f9
├── 06
│ └── f468e662b25687de078df86cbc9b67654d938b
├── 0a
│ └── 795bccdec0f85ebd9411e176a90b1b4dfe2002
├── 0b
│ └── 2d0890591a57393dc40e2155bff8901acafbb6
├── 0c
│ └── 66fedfeb176b467885ccd1a1ec70849299eeac
├── 0d
│ └── dfac290832b19d1cf78284226179a596bf5825
├── 0e
│ └── 066e61ce93bf5dfaa9a6eba812aa62038d7875
├── 0f
│ └── a80ee6442e459c501c6da30bf99a07c0f5624e
├── 11
│ ├── 06774ed5ad653594a848631f1f2786a76a776f
│ ├── 92339da7c0831ba4448cb46d40e1b8c2bed12c
│ └── c1a7373df5a0fbea20fa8611f41b4a032b846f
.
.
.

commit : is a snapshot of the files .

commits : are structures that hold metadata about your commit message , as well as the pointers to the parent commit and the files underneath .

so when you start by typing :

git add . : git calculate and find the diffrence between files so it can update the files in the next blob .

git commit -m “update of file index.ts” : is the way that make git assing as readable message to the pointer in the repo three that contain the new blob of the last changes .

To find the object associated with a commit, simply take the commit hash you found above:

d33ab2b104e4addd0347ed3b1ca57b2e68dfc85

d3 is the folder , and 3ab2b104e4add03947ed3b1ca57b2e68dfc85 is the objectId .

by the way some times we may want to change the last commit message or add the same commit message to the next changes we can do it by :

git commit — amend -m “ the update ”

git commit — amend — no-edit

Head : most recent commit of a repo .

Branch : is a subgraph of the DAG . A branch represents an independent line of development.

while “remote branches” — which are also called “remote-tracking branches” start with refs/remotes/ and then have one more path component naming the specific remote before the part naming the branch. (Edit, April 2018: I dislike the phrase "remote branch" or "remote-tracking branch"; I think it's better to just call these remote-tracking names. But there is a lot of existing documentation that uses the other two phrases, so we need to be aware of this usage.)

For instance, you are no doubt familiar with refs/remotes/origin/master, but if you have a remote named bob you might also have refs/remotes/bob/hacks/feep that tracks Bob's hacks/feep.

A local branch name refs/heads/branch has the distinguishing feature that git checkout will put you "on" that branch by default, by writing that name into the special HEAD reference; and once it you are set up this way, new commits (created by git commit, git merge, git cherry-pick, etc.) cause the new commit's SHA-1 to be written into the branch-file. (The new commit has as its parent, or one of its parents, the old tip-of-branch.)

we can create a branch by typing this command :

git checkout -b <new-branch> <existing-branch>

to switch between branches :

git checkout <branch-name>

to clone specific branch

git clone -b ‘branch name’ ‘repo-hostname’ .

the merging :

The reality of development is that it’s a messy business; on the surface, it’s simply a linear progression of logic, a smattering of frameworks, a bit of testing — and you’re done. If you’re a solo developer, then this may very well be your reality. But for the rest of us who work on code that’s been touched by several, if not hundreds, if not thousands of other hands, it’s inevitable that you’ll eventually want to change the same bit of code that someone else has recently changed.

Merging is Git’s way of putting a forked history back together again. The git merge command lets you take the independent lines of development created by git branch and integrate them into a single branch.

Git merge will combine multiple sequences of commits into one unified history. In the most frequent use cases, git merge is used to combine two branches. In these scenarios, git merge takes two commit pointers, usually the branch tips, and will find a common base commit between them. Once Git finds a common base commit it will create a new "merge commit" that combines the changes of each queued merge commit sequence.

Merge conflict :

error: failed to push some refs to ‘https://github.com/account/git-er-done.git' hint: Updates were rejected because the remote contains work that you do hint: not have locally. This is usually caused by another repository pushing hint: to the same ref. You may want to first integrate the remote changes hint: (e.g., ‘git pull …’) before pushing again. hint: See the ‘Note about fast-forwards’ in ‘git push — help’ for details

As a human, it’s fairly easy to see how two people modifying the same line of code in two separate branches could result in a conflict, and you could even argue that a halfway intelligent developer could easily work around that situation with a minimum of fuss. But Git can’t reason about these things in a rational manner as you or I would. Instead, Git uses an algorithm to determine what bits of a file have changed and if any of those bits could represent a conflict.

imagine you are in a team of 4 developers everyone of you works on a diffrent feature on the same application for that everyone of you have his own branch after 30 days of we work . all features should be at the same branch a branch called the alpha-dev .

to do that you need to merge .

you decide to do : git pull , cause you think that git is smart more than what it is . so you get this error :

CONFLICT (content): Merge conflict in index.ts Automatic merge failed; fix conflicts and then commit the result

you need to do it by yourself . by

First, you need to return to the previous state of your working environment. Right now, you’re mid-merge, and you only have two choices at this point: Either go forward and resolve the merge, or roll back and start over. Since you want to look at this merge conflict from a different angle, you’ll roll back this merge and start over.

Reset your working environment with the following command:

git reset --hard HEAD

This reverts your working environment back to match HEAD, which, in this case, is the latest commit of your current branch, zIntegration.

If you are just starting git those are all what You need .

GIT commands Tutorial :

CREATE

Sets the author name and email address respectively to be used with your commits.

git config –global user.name “[name]”

git config –global user.email “[email address]”

Clone an existing repository.

$ git clone ssh://user@domain.com/repo.git

Create a new local repository.

$ git init

Create a new empty branch for a new project

You can create a branch as an orphan:

git checkout — orphan <branchname>

This will create a new branch with no parents. Then, you can clear the working directory with:

git rm — cached -r .

Or Delete everything in the orphan branch

git rm -rf .

Remove a file (or folder)

git rm -r [file-name.txt]

LOCAL CHANGES

Changed files in your working directory

$ git status

Changes to tracked files

$ git diff

Preview changes before merging

git diff [source branch] [target branch]

Add all current changes to the next commit

$ git add .

Add some changes in <file> to the next commit

$ git add — p <file>

Commit all local changes in a tracked file

$ git commit -a

Commit previously staged changes

$ git commit

Change the last commit
Don’t amend published commits!

$ git commit — amend

COMMIT HISTORY

Show all commits, starting with the newest

$ git log

Show changes over time for a specific file

$ git log -p <file>

Who changed what and when in <file>

$ git blame <file>

View changes (detailed)

git log — summary

View the change history of a file

For this I’d use: gitk [filename]

Or to follow filename past renames: gitk --follow [filename]

BRANCHES & TAGS

List all existing branches

$ git branch -av

Switch HEAD branch

$ git checkout <branch>

Create a branch from a branch

$ git checkout -b <brnach-name>

Create a new branch based on your current HEAD

$ git branch <new-branch>

Create a new tracking branch based on a remote branch

$ git checkout — track <remote/branch>

Delete a local branch

$ git branch -d <branch> or $ git branch -D <branch>

Mark the current commit with a tag

$ git tag <tag-name>

UPDATE & PUBLISH

List all currently configured remotes

$ git remote -v

Show information about a remote

$ git remote show <remote>

Add new remote repository, named <remote>

$ git remote add <shortnames> <url>

Download all changes from <remote>, but don’t integrate into HEAD

$ git fetch <remote>

Download changes and directly merge/integrate into HEAD

$ git pull <remote> <branch>

Publish local changes on a remote

$ git push <remote> <branch>

Delete a branch on the remote

$ git branch -dr <remote/branch>

Publish your tags

$ git push — tags

MERGE & REBASE

Merge <branch> into your current HEAD

$ git merge <branch>

Rebase your current HEAD onto <branch>
Don’t rebase published commits!

$ git rebase <branch>

Abort a rebase

$ git rebase — abort

Continue a rebase after resolving conflicts

$ git rebase — continue

Use your configured merge tool to solve conflicts

$ git mergetool

Use your editor to manually solve conflicts and (after resolving) mark file as resolved

$ git add <resolved-files>
$ git rm <resolved-file>

UNDO

Discard all local changes in your working directory

$ git reset — hard HEAD

Discard local changes in a specific file

$ git checkout HEAD <file>

Revert a commit <by producing a new commit with contrary changes)

$ git revert <commit>

Reset your HEAD pointer to a previous commit
… and discard all changes since then

$ git reset — hard <commit>

…and preserve all changes as unstaged changes

$ git reset <commit>

… and preserve uncommitted local changes

$ git reset — keep <commit>

Git stash

Stores all the modified tracked files

git stash save

Restores the most recently stashed files

git stash pop

Lists all stashed changesets

git stash list

Discards the most recently stashed changeset

git stash drop

Remove all stashed entries

git stash clear

--

--

YOUSSEF ALOUANI
YOUSSEF ALOUANI

Written by YOUSSEF ALOUANI

junior software engineer , the performance if it was a person , intrested in microservices architecture and System Design . I believe in sharing Knowledge

No responses yet