Introduction
Git (/ɡɪt/) is a distributed version control system (VCS) for tracking changes in computer files and coordinating work on those files among multiple people. It is primarily used for software development, but it can be used to keep track of changes in any files. More often it is used for source code management.This blog is divided in two parts.
1. Setting up git on local machine, and running commands locally
2. This part covers git in depth and practical scenario(remote) is covered.
Download and Install
- Go to git-scm.com/downloads, download executable for required operating system.Check version of your Git bash
$ git --versionConfiguring Username and email
$ git config --global username "vikasmishra12345"$ git config --global user.email "vikasmishra@gmail.com"
To see if all setting are configured
$ git config --list {use clear command to clear screen}
To see any specific settings,
$ git config user.email
To see all commands
$ git help
or $git help command name
Creating First Repository
To see, where git is currently looking, type
$ pwd
And, to change to custom folder
$ cd ..
$ cd User/Desktop/GitExample
Now to make folder a git project
$ git init
Git will reply
Initialized empty Git repository in .git/
You’ve now initialized the working directory—you may notice a new directory created, named ".git".
This is an architecture of local only, ie. it commits changes into local repository and when we do it in remote repository i.e.github then further command are used
Commit changes
First check if there is any file in our project , type ls and to see hidden files ls -la
Note -To see content inside .git, type
$ ls -la .git
Inside .git folder, there is config folder which stores all changes made in project at one place
Now add some files inside folder manually. And to commit we need to follow two steps.
Next, tell Git to take a snapshot of the contents of all files under the current directory (note the .), with git add:
$ git add . {Adds all changes made in folder. This is to let git know that we made changes. Unless we add any file, that file is not tracked by git. Also we can add specific file using command
$ git add abc.txt }
You can permanently store the contents of the index in the repository with git commit.To keep track of changes we need to commit these changes, commit command is used.
$ git commit -m "Any message"
Add command moves changes from local to staging area(also called index). Commit command moves changes from index to repository. It stores SHA-1 hash values of changes made. It does not save changed file but changed set(i.e.whole change as 1 set)
After we commit, in the following way git stores all commit history. Once commit cannot be unchanged. It ensures complete data integrity. Only changes are made in new or in the last data where HEAD is pointing.
To skip staging area and commit into repository. Note-: It pushes all changes in project to repository.
$ git commit -am "Pushing changes directly to repository"
$ git commit -a
After we commit, in the following way git stores all commit history. Once commit cannot be unchanged. It ensures complete data integrity. Only changes are made in new or in the last data where HEAD is pointing.
To skip staging area and commit into repository. Note-: It pushes all changes in project to repository.
$ git commit -am "Pushing changes directly to repository"
$ git commit -a
View History & Status
To view commit history, we use log command$ git log
or
$ git log -p
$ git log --oneline
To view changes made on you project, we use status command. lets make some changes in one of our file and also add some new file in our project. Status commad help us to see difference in three tier ie. repository,staging index, working directory.
$ git status {tells any change made within local copy in workspace}
View Specific Changes
To view difference between local and staging area.{In actual diff command compares repository and local, but when we run add command then file is moved to staging area. Hence no changed file present at local. Now no change present between local and repository, hence it seems as if comparing local and staging area. }
$ git diff
$ git diff abcd.txt {Compares staging and working directory}
To view difference between staging area and repository
$ git diff --staged abcd.txt
Deleting Files
To delete file simply use rm command.
$ git rm abcd.txt
$ git commit -m "Deletion point" {This makes changes in repository}
Moving & Renaming Files
Here, move and rename are synonymous. For both purpose we use mv command:
$ git mv ActualFile RenameFile { we can give complete address as well }
$ git commit -m "File renamed"
Undoing Changes
To checkout file from repository(local)
$ git checkout -- "checking out from repository"
To unstage File from staging area. It replaces file from staging index with repository.
$ git reset HEAD abcd.html
Checking out older Version from Repository
$ git checkout commitId {this can be obtained from git log command, we can type Id partially}
To checkout specific file, file name can be given. No need to type complete commit Id we can type partially in above two example. This commits to staging index. It does not make any change in working repository
$ git checkout abcd73e -- index.html
$ git reset HEAD index.html
$ git commit --amend -m "Make change comment"
To undo commit made in repository, we make changes in HEAD only always. For this we use revert command.
$ git revert 37ebhgsdhshd4578ss
It resets current head to specified state. Remember save commit state of head pointer for any future references. We can move head both forward and backward direction. Hence to go in past state or to revert back to previous state, use reset state.
Suppose, we have some untracked files in our directory, then use clean command:
$ git clean -f {Removes all untracked from working directory}.
In order to ignore tracking of some file, we need to create .gitignore file {for windows create file manually and save as '.gitignore' with type as 'All files'} in our working directory and need to add whatever file we want it to ignore.
$ git add .gitignore
$ git commit -m "Add ignoring file"
Make entry of all files and directory to be ignored are to be put in .gitignore file. for example
Generally following entries are ignored and its entry is made in .gitignore file.
Following are link to get detail info about 'to be ignored file'
In order to view commit,
$ git ls-tree branchName
Note-:blob generally refers to file and tree refers to directory. Tree inside tree is known as tree-ish
We can also compare two commit using SHA value of 2 commits
$ git diff xzwdg2334sd..wqrsfed12m
Branching
In order to create branch, use branch command
$ git branch {to view all branches}
$ git branch newBranchName {to create new branch}
In order to change branch name use:
$ git checkout branchName {To switch from one branch to another}
$ git checkout -b branchName {creation and switching in one step}
$ git diff oneBranch..anotherBranchName {to see difference in two branches}
To rename branch,
$ git branch -m existing_Name new_Name
To delete branch, can only be deleted from other branch only(not same)
$ git branch -d branch_to_delete
Merging
To view merge branches in current branch:
$ git branch --merge
To delete branch, can only be deleted from other branch only(not same)
$ git branch -d branch_to_delete
Merging
To view merge branches in current branch:
$ git branch --merge
To merge changes from one branch to another use merge command, first checkout branch where changes are to be merged
$ git merge branch_name {here branch name refers from where changes are to be merged into current checkout branch}To abort merging in case of conflict
$ git merge --abort
Stashing
In order to save our work without adding or commit in staging or in repository, we use stash. It temporarily stores in stash area.
$ git stash list {enlist all stash items}
$ git stash save "any comment" {to save in stash}
$ git stash show -p stash@{0} {to view particular stash}
$ git stash pop stash@{0} {to bring stash item in current directory and also removing it from stash are}
$ git stash drop stash@{0} {delete stash item}
Finally, gitk command show graphical representation of changes:
$ gitk
Cloning
To clone project in our folder, we use clone command
$ git clone fromCopylocation toCopylocation
Git In Detail
Local Repositories
git (locally) has a directory (.git) which you commit your files to and this is your 'local repository'. This is different from systems like svn where you add and commit to the remote repository immediately.
git stores each version of a file that changes by saving the entire file. It is also different from svn in this respect as you could go to any individual version without 'recreating' it through delta changes.
git doesn't 'lock' files at all and thus avoid the 'exclusive lock' functionality for an edit (older systems like pvcs come to mind), so all files can always be edited, even when off-line. It actually does an amazing job of merging file changes (within the same file!) together during pulls or fetches/pushes to a remote repository such as github. The only time you need to do manual changes (actually editing a file) is if two changes involve the same line(s) of code.
Branches
Branches allow you to preserve the main code (the 'master' branch), make a copy (a new branch) and then work within that new branch. When you've finished, you merge the changes made in the branch back in to the master repository. Many organizations use branches for each piece of work whether it is a feature, bug or chore item. Other organizations only use branches for major changes such as version upgrades. With a branch you control and manage the branch, whereas with a fork someone else controls accepting the code back in.
Broadly speaking there are two main approaches to doing branches. The first is to keep most changes on the master branch, only using branches for larger and longer-running things like version changes where you want to have two branches available for different needs. The second is whereby you basically make a branch for every feature request, bug fix or chore and then manually decide when to actually merge those branches into the main master branch. Though this sounds tedious, this is a common approach and is the one that I currently use and recommend because this keeps the master branch cleaner and it's the master that we promote to production, so we only want completed, tested code, via the rebasing and merging of branches.
The standard way to bring a branch "in" to master is to do a
merge
. Branches can also be rebase
d to 'clean up' history. It doesn't affect the current state and is done to give a 'cleaner' history. Basically the idea is that you branched from a certain point (usually from master). Since you branched 'master' itself has moved forward. So it would be cleaner if all the changed you have done in a branch are played against the most recent master with all its changes. So the process is: save the changes; get the "new" master, and then reapply the changes again against that. Be aware that rebase, just like merge, can result in conflicts that you have to manually resolve (edit).
One 'guideline' to note: Only rebase if the branch is local and you haven't pushed it to remote yet! This is mainly because rebasing can alter the history that other people see which may include their own commits.
Tracking branches
These are the branches that are named origin/branch_name (as opposed to just branch_name). When you are pushing and pulling the code to/from remote repositories this is actually the mechanism through which that happens. For example when you
git push
a branch called 'building_groups', your branch goes first to origin/building_groups and then that goes to the remote repository (actually that's an over-simplification but good enough for now). Similarly if you do a git fetch building_groups
the file that is retrieved is placed in your origin/building_groups branch. You can then choose to merge this branch into your local copy. Our practice is to always do a git fetch and a manual merge rather than just a git pull (which does both of the above in one step).
Fetch
ing new branches.
Getting new branches: At the initial point of a clone you will have all the branches. However, if other developers add branches and push them to the remote there needs to be a way to 'know' about those branches and their names in order to be able to pull them down locally. This is done via a
git fetch
which will get all new and changed branches into the locally repository using the tracking branches (e.g. origin/). Once fetch
ed, one can git branch --remote
to list the tracking branches and git checkout [branch]
to actually switch to any given one.Merging
Merging is the process of combining code changes from different branches, or from different versions of the same branch (for example when a local branch and remote are out of sync.). If one has developed work in a branch and the work is complete, ready and tested, then it can be merged into the
master
branch. This is done by git checkout master
to switch to the master
branch, then git merge your_branch
. The merge will bring all the different files and even different changes to the same files together. This means that it will actually change the code inside files to merge all the changes. When doing the checkout
of master
it's also recommended to do a git pull origin master
to get the very latest version of the remote master merged into your local master. If the remote master changed, i.e. moved forward
, you will see information that reflects that during that git pull
. If that is the case (master changed) you are advised to git checkout your_branch
and then rebase
it to master so that your changes actually get "replayed" on top of the "new" master. Then you would continue with getting master up-to-date as shown in the next paragraph.
If there are no conflicts then master will have the new changes added in. If there are conflicts, this means that the same files have changes around similar lines of code that it cannot automatically merge. In this case
git merge new_branch
will report that there's conflict(s) to resolve. You 'resolve' them by editing the files (which will have both changes in them), selecting the changes you want, literally deleting the lines of the changes you don't want and then saving the file. The changes are marked with separators such as ========
and <<<<<<<<
Once you have resolved any conflicts you will once again
git add
and git commit
those changes to continue the merge (you'll get feedback from git during this process to guide you). When the process doesn't work well you will find that git merge --abort
is very handy to reset things.Forks
There are two main approaches to collaboration in git repositories. The first, detailed above is directly via branches that people pull and push from/to. These collaborators have their ssh keys registered with the remote repository. This will let them push directly to that repository. The downside is that you have to maintain the list of users. The other approach - forking - allows anybody to 'fork' the repository, basically making a local copy in their own git repository account. They can then make changes and when finished send a 'pull request' (really it's more of a 'push' from them and a 'pull' request for the actual repository maintainer) to get the code accepted.
This second method, using forks, does not require someone to maintain a list of users for the repository
This second method, using forks, does not require someone to maintain a list of users for the repository
When you 'fork' - in the github web browser gui you can click on - you create a copy ('clone') of the code in your github account. It can be a little subtle first time you do it, so keep making sure you look at whose repository a code base is listed under - either the original owner or 'forked from' and you
Clones
As indicated in the section on github, a clone is a copy of a repository. When you have a remote repository you issue the git clone command against its URL and you then end up with a local copy, or clone of the repository. This clone has everything, the files, the master branch, the other branches, all the existing commits, the whole shebang. It is this clone that you do your adds and commits against and then the remote repository itself is what you push those commits to. It's this local/remote concept that makes git (and systems similar to it such as Mercurial) a DVCS (Distributed Version Control System) as opposed to the more traditional CVS's (Code Versioning Systems) such as SVN, PVCS, CVS, etc. where you commit directly to the remote repository.
Pull
$git pull
Incorporates changes from a remote repository into the current branch. In its default mode, git pullis shorthand for git fetch followed by git merge FETCH_HEAD.
Git Aliasing
For this I have the following aliases in my ~/.bash_aliases file (which is called from my ~/.bashrc file for each terminal session:
# git
alias gst='git status' # Warning: gst conflicts with gnu-smalltalk (when used).
alias gb='git branch'
alias gco='git checkout'
alias gcob='git checkout -b '
alias ga='git add '
alias gc='git commit'
alias gg='git grep ' # A great very FAST search option, easier then `find`
Basic Troubleshooting/Useful Tips
Finally, 6 key lifesavers:
1) You mess up your local branch and simply want to go back to what you had the last time you did a git pull:
git reset --hard origin/master # You will need to be comfortable doing this!
2) You start making changes locally, you edit half a dozen files and then, oh crap, you're still in the master (or another) branch:
git checkout -b new_branch_name # just create a new branch
git add . # add the changes files
git commit -m"your message" # and commit them
3) You mess up one particular file in your current branch and want to basically 'reset' that file (lose changes) to how it was the the last time you pulled it from the remote repository: git checkout your/directories/filename
This actually resets the file (like many git commands it is not well named for what it is doing here).
4) You make some changes locally, you want to make sure you don't lose them while you do a git reset or rebase: I often make a manual copy of the entire project (cp -r ../my_project ~/
) when I am not sure if I might mess up in git or lose important changes.
5) You are rebasing but things gets messed up:
git rebase --abort # To abandon interactive rebase and merge issues
6) Add your git branch to your PS1 prompt (see https://unix.stackexchange.com/a/127800/10043), e.g.
Basic differences
Git clone vs Git pull
Git clone is the equivalent of these three commands:
git init
git remote add origin [url]
git pull origin master
Git pull is the equivalent of these commands:
git fetch
git merge origin/master
The 'origin' here is the name of a 'remote'
Git clone vs checkout
git clone is to fetch your repositories from the remote git server.
git checkout is to checkout your desired status of your repository (like branches or particular files).
E.g., you are currently on master branch and you want to switch into develop branch.
git checkout develop_branch
E.g., you want to checkout to a particular status of a particular file
git checkout commit_point_A -- <filename>
Git push vs commit
Basically git commit
"records changes to the repository" while git push
"updates remote refs along with associated objects". So the first one is used in connection with your local repository, while the latter one is used to interact with a remote repository.
In short, basically git commit puts your changes into your local repo, while git push sends your changes to the remote location.
ForK vs Clone
Fork
- A copy to your remote repo (cloud) that links it to Joe's
- A copy you can then clone to your local repo and F*%$-up
- When you are done you can push back to your remote
- You can then ask Joe if he wants to use it in his project by clicking pull-request
Clone
- a copy to your local repo (hard drive)
GitHub
github (a remote repository) is a remote source that you normally push and pull those committed changes to if you have (or are added to) such a repository, so local and remote are actually quite distinct. Another way to think of a remote repository is that it is a .git directory structure that lives on a remote server.
Commonly used git commands
In order to wrap the text in git bash use, minus with shift+S and return. To move forward use F key and B for backward. Space bar to see rest of result.
To use it sign up on https://github.com/
How to fetch from remote branch
go to master branch of that applicatipon
git fetch
git checkout -b Branch_X origin/Branch_X
git branch
git pull
How to merge multiple commit message in one commit(squashing)
git log —oneline
git reset --hard Head~5
git merge --squash HEAD@{1}
git commit -m 'comments here'
git log --oneline
https://www.youtube.com/watch?v=cEGIFZDyszA&index=1&list=PL6gx4Cwl9DGAKWClAD_iKpNC0bGHxGhcx
ReplyDeletehttps://git-scm.com/docs/gittutorial
ReplyDeletehttps://help.github.com/articles/adding-a-remote/
ReplyDeleteThanks to Admin for Sharing such useful Information. I really like your Blog. Addition to your Story here I am Contributing 1 more Similar Story Common used Git Commands Checklist for Developers.
ReplyDeleteBrilliant blog I visit this blog it's incredibly awesome. Curiously, in this blog content formed doubtlessly and sensible. The substance of information is helpful.
ReplyDeleteWorkday Online Training