after git installation, you'll need to check if Git is installed. In the terminal type:
git --version
git config --global user.name "your-name"
git config --global user.email "your-email"
To check if Git is already configured you can type:
git config --list
-
fundamentals
-
Installing git VCS
-
Working with git
-
Setting remote for the local repo.
- tracking branches
-
Cloning a remote repo and working with it.
-
Rewriting History
-
pull requests
most used words
- git: an open source, distributed version-control system.
- GitHub: a platform for hosting and collaborating on Git repositories.
- HEAD: representing your current working directory, the HEAD pointer can be moved to different branches, tags, or commits when using git switch.
- commit: a Git object, a snapshot of your entire repository compressed into a SHA.
- fork: a replica of a repository on on your GitHub, and it is owned by a different user.
- clone: a local version of a repository, including all commits and branches.
- remote: a common repository on GitHub that all team members use to exchange their changes.
- pull request: a place to compare and discuss the differences introduced on a branch with reviews, comments, integrated tests, and more.
Git Objects:
- commit object - A small text file.
- Annotated tag - A permanent reference to a specific commit.
- Tree - Directories and file names in a project.
- Blob - The content of a file in the project.
typically a user interacts with only commit and tag and let the Git
deal with tree and blob.
important notes:
- Repository -
- working dir -
- Staging area -
- remote -
- Git ID's - commit_Id is a "40 character hexadecimal string" also known as hash, checksum, SHA / SHA1.
đź’ˇ tip: Does git use SHA-1 or sha256?
At its core, the Git version control system is a content addressable filesystem. It uses the SHA-1 hash function to name content. The length of a SHA1 hash is 160 bits or 20 bytes. In this application it is represented by 40 characters in hexadecimal form. SHA-1 was cracked by google reaserchers and is considered unsafe for storing passwords.
you can use >> git hash-object filename
command to generate SHA1 hash code for any file.
- git models the relationship of commits with a DAG (Directed Acyclic Graph).
- the directed nature is implied by the vertical order of the commits, with most recent commit on top.
- their is no circular loop in graph, all the commits ("child nodes") are directed from bottom to top.
- branch occurs when a commit has more than one child. ex: look at commit_id 6068
- merge occurs when a commit has more than one parent. ex: look at commit_id 4c58
HEAD pointer
points to the most recent commit on a branch.
>> git init
initializes git vcs in current directory
>> git init myproject
creates a new folder named myproject and initializes git vcs in it.
- first command set remote for local repository
- second command selected the remote branch to push to
syntax: >> git clone source destination
>> git clone https://github.com/LearnWebCode/welcome-to-git.git “welcome page”
clones the welcome-to-git project in directory named welcome page.
>> git clone https://github.com/awesome projectdir
clones the project named awesome in directory named projectdir.
>> git clone https://github.com/awesome
clones the project named awesome in directory named awesome.
đź’ˇ tip: Difference between fork and clone
Fork : when we want to make a replica of other github user's repository to our github profile, we fork their repository.
Clone : when we want to work in our local machine on a copy of forked repository( or any repository on our github profile) we clone it.
>> git status
The git status command will display a lot of information depending on the state of your files, the working directory, and the repository.
- tell us about new files that have been created in the Working Directory that Git hasn't started tracking, yet
- files that Git is tracking that have been modified and etc etc.
>> git log
flags:
--oneline "shows all commits 1/line with SHA and commit message"
- lists one commit per line.
- shows the first 7 characters of the commit's SHA.
- shows the commit's message.
--stat "shows stats"
- displays the file(s) that have been modified.
- displays the number of lines that have been added/removed.
- displays a summary line with the total number of modified files and lines that have been added/removed.
--patch or -p “show what lines were added and what were removed”
- displays the files that have been modified
- displays the location of the lines that have been added/removed
- displays the actual changes that have been made
>> git log --author="sajid"
will show all logs for commits made by sajid.
>> git log --graph --decorate –all
the default git log displays the SHA, the author, the date, and the message.
>> git log --oneline --graph --decorate -all
shows the graphical representation of all the commits made till now.
The git diff command can be used to see changes that have been made but haven't been committed, yet.
- the files that have been modified
- the location of the lines that have been added/removed
- the actual changes that have been made
>>git diff
compare and shows the difference between working-copy(modified & unstaged) and the copy in repo.
>>git diff --staged
compares and shows difference between staged file and copy in repo.
tag is a reference/label attached to a specific commit.
the tags are used to mark a time line in history, as v1.0,beta,v1.1 or some similiar names.
- they are of two types
Light Weight
- simple reference to a commit.
Annotated Tag
- A full git object that references a commit.
- Includes tag author name, tag date, tag message, the commit ID.
>> git tag
shows the list of all the tags in the repository, if present.
>> git tag tagname
the commit that HEAD points to (i.e the most recent commit in current branch) will be tagged with the provided tag name.
>> git tag -a tagname -m "your message here"
-a denoted the tag is annoted basically annotted tags have message and big description as compared to light weight tag's (tags with out -a)
syntax: >> git tag -a tagname <commit_SHA>
>> git tag -a version1 a242f45
note: the >> git push
command alone can not automatically transfer tags to the remote repository
- to transfer a single tag, use
>> git push <remote> <tagname>
. - to transfer all the tags, use
>> git push <remote> --tags
.
>> git tag -d tagname
>> git tag --delete tagname
deletes the tag from your local repo , to delete the tag from global(github,or other hosting) use command >> git push tag -d tagname
(-d is short for --delete).
branch occurs when a commit has more than one child. see graph
benifits -
- team members can isolate their work so that it don't impact others untill the work is ready.
- this allows to experiment with changes to the project, while at the same time team retains a stable version of the project.
- if you have an idea for a change, you can create a branch and test your idea. later you can merge it in production or throw out your branch.
- branches allow to support multiple versions of the project simultaneously.
branches can be -
- Topic - A feature, a bug fix, a hotfix, a Configuration Change...
- Long Lived - master, develop, relese...
master is the default name of the main branch in the repository.
>> git branch
list all the branches name, present in repository. the branch that has *
in front of it is current active branch. for example, * main
means main is active.
>> git branch branchName
it will create a new brach from the commit HEAD is pointing at, with the label(here branchName) you provided.
note: git branch sidebar will create a branch named sidebar, to switch to the branch you just created you'll need another command >> git checkout branchName
.
>> git checkout -b branchname
this command allows to create and switch to a new branch all in one command.
>> git branch branchName commit_SHA
goes to commit with "commit_SHA" and start a new branch from there with branch label as the branchName.
>> git checkout branchname
use this command to switch to the branch with branchName specified.
checkout command -
- makes the HEAD pointer point to the label of branch checked-out to.
- updates the working tree with the files from the checked-out branch.
- A detached head reference points directly to a commit.
checking out to a commit leads to detached HEAD state,
you probably checkout to a commit to review "history/condition" during that commit,
you probably would have used something like>> git checkout A12BE17
.
you will have to again checkout to the branch to makeHEAD
point to latest commit in branch.
>> git branch -d nameofbranch
branch labels are commonly deleted after a topic branch has been merged.
branches are used to do development or make a fix, after a branch's changes have been merged, you probably won't need the branch anymore. you can delete it using above command.
- if you try deleting a branch label with unmerged work, git will not let you do that it responds with
the branch is not fully merged
. - however, you can force delete an unmerged branch using
-D
flag. for example>> git branch -D branchName
. - if you delete branch with out merging, the commit's are left without a branch and are called dangling commits. Git will periodically garbage collect deleting older dangling commits.
what if you accidentally deleted a branch label?
- you can use the
>> git reflog
command. - git reflog returns a local list of recent HEAD commits. this list is in the local .git directory, but not in the repository. so this only works locally.
- you can find the dangling commit in that list and start a branch again from the SHA of that commmit.
Que: git switch branchName and git checkout branchName ?
Did you forget to create a new branch, and made your changes in the wrong branch? use.
>> git switch -c "new-branch"
- Merging combines the work of independent branches.
- Usually, this involves merging a topic branch, into a base branch, such as the master branch.
- The base branch is usually a longer running branch than the topic branch.
there are four types of merges:
- Fast-forward merge
- Merge commit
- Squash merge
- Rebase
- moves the base branch label to the tip of the topic branch.
- by default git first tries the fast-forward merge when merging two branches.
- A fast forward merge is possible only if no other commits have been made to the base branch since the topic branch was created.
- If any commits have been added to the base branch, it will not allow you to perform a fast-forward merge.
- the benifit of fast-forward merge is that
no new commit
is needed to merge the two branches.
performing a Fast-forward merge
- first checkout to master branch
>> git checkout master
- use git merge, git attemps a fast forward merge by default.
>> git merge branchName
- delete the previous branch after it is merged
>> git branch -d branchName
note: after a branch is merged its branch label can be deleted, this prevents a continuous increase in the number of merged branch labels as the project grows.
Dealing with an ever increasing number of feature branch labels can be confusing.
whether or not you should delete the branch label's after a merge is a decision that your team should make.
If you'd like to retain the knowledge of where the feature work occured, you can include this information in the feature's commit messages. Or you can add a tag that permanently marks the feature work.
- merge commit happens automatically, if two branches can't be merged in fast-forward fashion.
- combines the commits at the tip of the branches to be merged and places the result into a
new merge commit
.
performing a merge commit
1. >> git checkout master
2. >> git merge branchName
,accept or change commit message.
3. >> git branch -d branchName
- one can force a merge commit even if fast-forward merge is possible.
force a merge commit
1. >> git checkout master
2. >> git merge
--no-ff
branchName
,accept or change commit message.
3. >> git branch -d branchName
????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
squash merge
& Rebase
, they rewrite commit history.
??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
- git automatically merges two changes if they don't overlap/override each other.
- A merge conflict arises when two separate branches( that we want to merge ) have made edits( commit after changing ) to the same line in a file.
- during a merge conflict Git is unable to automatically resolve differences in code between two commits.
- when Merge conflict occurs
git edits the files with conflict markers and place them in working tree.
now a person needs to make decision, (which changes to keep). - fix, add and commit the conflicting files.
Resolving Merge Conflicts
1. >> git checkout master
2. >> git merge branchName
,in case of conflict, Automatic merge failed; fix conflicts and then commit the result.
3. fix changes in file that is causing conflict
4. stage changes, and commit them
5. >> git branch -d branchName
what are merge stratergies and what is recursive stratergy ?
Answer:
- If remote branch is ahead of local branch, On git pull changes are fetched in tracking branch and merged into local branch using fast forward merge strategy.
- Initially remote branch is ahead of the local branch, then local branch commited some changes without fetching changes from remote branch, after that local branch run git pull, here those changes will be merged using recursive strategy.
- tracking branch is a local branch referencing to the remote branch.
- tracking branch name start with
<remote name>/<branch name>
, ex:origin/master
. - if you clone a repository you'll have a default tracking branch
- visible using flag
--all
in command>> git branch --all
.
fig: there is only one remote branch ie. main and HEAD(tracking branch pointer) is pointing to that.
- to make a local branch track changes from other than default branch
- to view commits on default remote tracking branch, use
origin
in command>> git log
origin
--oneline
.
- to change the default remote tracking branch, use
>> git remote set-head <remote> <branch>
.
fig: there are 2 remote branches master
, develop
. initially default was set to master
, now HEAD is set to reference develop
branch
- verfying if we are insync(upto date) with tracking branch.
Note: >> git log --all
gives the logs of all the local and tracking branches.
- clone - copies a remote repository.
- Fetch - retrieves new objects and references from the remote repository.
- pull - Fetches and merges commits locally.
- push - Adds new Objects and references to the remote repository.
- retrieves new objects and references from the remote repository.
- updates the tracking branches only.
- to reflect fetched changes into working dir and local branch, you'll have to merge tracking branch with local branch.
- combines the
>> git fetch
and>> git merge FETCH_HEAD
into one command>> git pull
.- new objects and references are fetched, then the tracking branch is merged into the current local branch. automatically in one go.
- by default git applies fast-forward merge if possible, if not possible it creates merge commit.
- when executing pull command we can specify the merging options using one of following flags-
--ff
- (default) fast-forward merge if possible, if not possible then creates merge commit.--no-ff
- include a merge commit.--ff-only
- cancel instead of doing a merge commit.--rebase
- ??????????????????????????????
- to push changes from local branch into remote branch, use
>> git push
. - initially you have to use
>> git push [-u] <repository> <branch>
to set up default remote branch to push to.-u
means (--set-upstream). - ex:
>> git push -u origin master
, after setting up upstream you can just use>> git push
and it will always push to remote branch you set for upstream. - alternatively you can specify which branch to push to. ex:
>> git push origin develop
.
You can use git commit --amend to make a modification to the last commit you made. This will alter the commit history of your project, so it is recommended that you don't use git commit --amend if you have already pushed your commits to the remote.
You can also use git commit --amend to rewrite the most recent commit to include files in your staging area.
git revert creates a new commit with changes that are the opposite of the commit that is functionally being 'undone'
- git rebase turn a Recursive Merge into a Fast-Forward Merge