GIT concepts and cheetsheet

Git does not take care of the access control so we need to additional software for that and that’s where hosted solutions like GitHub and BitBucket come in and also self-managed solutions like Gitosis and Gitorious come in.

Help

git help –  provides help on all commands

git help commandName –  provides help on specific command

Config

git config - - global user.name “username”

git config  - - global user.email abc@xyz.com

git config - - global color.ui true –  Get pretty colors on the output of our command line

git config - - global core.editpr emacs –  use emacs for interactive commands

git config - - global merge.tool opendiff –  uses opendiff for merging conflicts

git config user.email “email” –  sets the email for the current repository

 

Starting a Repository

mkdir store –  create directory

cd store –  change to directory

git init –  Initialize the empty repository in the local system

or 

we could directly create a repository in the current folder
git init sample-dev-proj

and then navigate to the repository
cd sample-dev-proj

Never need to go in the directory but that’s where the data is stored.

Git Workflow

Creating a file – It will be untracked initially

Add file to staging area – Is getting ready for taking the snapshot of the file.

Commit – Taking a snapshot of the files that we have put on stage

git status – tells you what has changed since the last commit. It also tells the branch we are on as of now.

git add filename1 filename2 – will add the specific file to staging area

git add - - all – will add all the files to the staging area

git commit -m “Describe the changes done” – will add the snapshot at the top of the timeline and adds the commit message which describes the work that has been done.

This takes the snapshot of the stage and this gets added to our timeline

git log – lists the commits that we have had with details

Keep commit messages in present tense and not the past tense

Different ways to add files

git add <list of files> – adds the list of files

git add - - all – add all files

git add *.txt –  adds all text file in current directory

git add docs/*.txt –  adds all txt file sin the docs directory

git add docs/ –  adds all the files in the docs directory

git add “*.txt” –  adds all text files in the entire project

Git Diff

git diff –  Shows the unstaged differences since the last commit.

Red color shows the removed line and green color shows the line that was added.

git diff - - staged –  shows the differences between the staged files.

Unstaging files

git reset HEAD <filename> –  unstages the particular file

HEAD – refers to the last commit in the current branch

Discard modifications

git checkout - - <filename> –  blows all the changes since the last commit

Skip staging and Commit

git commit –a –m <filename> –  This will add changes of the file and commit it.

However this will not add the untracked files.

Undoing a commit

 

git reset - - soft HEAD^ –  resets into staging. ^ sign indicates that it moves to the commit one before the current one. Now I can make changes and re-commit.

git reset - - hard HEAD –  blows away the last commit and all changes

git reset - - hard HEAD^ –  blows away the last commit

Should not be used after the push

Adding to a commit

git add <filename>

git commit - - amend –m “Commit message” –  Adds the file to the last commit

This new commit message overrides the previous commit messages

Sharing the repository

Adding a Remote

git remote add <remote name> <repository address> –  Adds a new remote repository with name origin. It’s a convention to name it as origin as this is place where most of the people will be working from.

git remote –v –  shows the repositories

Remotes are like bookmarks

Pushing to Remote

git push <remote name> <branch name> –  push the local branch master to the remote repository origin.

We could password cashing to avoid typing the user name and password again and again.

https://help.github.com/articles/set-up-git

github.com has history and commit options which provide the info similar to git log

git pull –  will go to github and get the current changes and get it down to the local system and then sync it up with the local repository

Remove a remote

git remote rm <remote name>

Cloning and Branching

Cloning a Repository

git clone <repository address> –  creates a local repository with the same name as the actual repository

git clone <repository address> <local repository name> –  creates a local repository with specified name

Steps

  1. Downloads the entire repository to a new gir repository
  2. Adds the remote pointing it to the clone url
  3. Checks out the initial branch likely master and set the head
git remote –v lists all the remote branches

Branching Out

git branch <branch name> –  will create a new branch from master

git checkout <branch name> –  To move to that specified branch

git branch → See local branches

git branch --all → See all branches including remote

Working on a branch

echo “Schrodinger” > cat.txt –  creates a text file and inside it puts the word Schrodinger

Now when add this file and commit it then this file is added to our current branch and not the master branch.

ls –  Lists all the files in the current directory

Merge a Branch

Move to the branch you want to merge it with.

git checkout master

then

git merge <branch name to merge>

* Fast forward merge means that when we merge a branch there is no file merge required as the master branch did not change in the time while we made the changes.

Delete a branch

git branch –d <branch name>

NON Fast Forward Merge

git checkout –b <branch name> –  Creates a branch and then checks it out

Some commit done on both master and feature branch

Now when we move back to master from the feature branch and try to merge we are taken into the Vi editor and it asks us to do a merge commit.

Vi Commands

j –  down             k–  up                    Esc –  leave mode                            :wq –  save and quit

h–  left                  l –  right                i –  insert mode                 :q! –  cancel and quit

We can modify the message

When git does a merge commit then there a commit a commit at the top. If we see the git log it says that there has been a merge commit. At this point the 2 branches became one branch

Collaboration

Someone already pushed a new version of source code after you pulled but before you push. So now if you try to push your code it will be reject as you are behind the commit at this point of time.

Understanding Pull

git pull
  1. Fetch (or sync) our local repository with the remote one –  git fetch
  2. Merges the origin/master(repository on the server) with master –  git merge origin/master

So this has merged the local master branch with the code from branch but the origin/master is not aware of this merge commit

So we need to do a Push

git push

Updates origin/master be at the same state as our local repository

Merge commits are not considered to be good as they pollute the repository
We have 2 people editing the same file and one of them has committed the file back to github and other person now wants to commit the same file.

git pull

Pull will sync the repository and then tries to merge but the merge will not be successful. So we need to edit the file and do a merge commit.

When we jump into the file we will see something like a diff of the local version and the server version

So we need to manually edit the file to fix it.

The

git commit –a –  Leave off the message as we do not want to go back to the editor and list the commit message and will even list the committed files that we fixed.

Then

git push –  To sync the origin/master to the local master

Remote Branches

  • When you need other people to work on your branch
  • You might want to back up a branch if it’s going to there for long
git checkout –b <branch name>–  creates and switches to a new local branch

git push origin <branch name> –  links the local branch to the remote branch for tracking.

We make some changes on the branch and when we do a commit and a push the also pushes the changes from the local branch to the remote branch

We can see the list of all the branches in github

Now when someone else does a pull from remote then it will show that a new branch is be added to the remote.

But if check the local branches it will still not be available

git branch

but we see the remote branches we will be able to see the new remote branch

git branch –r

so we could do the

git checkout <remote branch name> –  Sets up the tracking for the remote branch from origin

So now you could make the changes and push it.

git remote show

Shows

  • All the remote branches whether they are tracked or not.
  • Shows all the local branches and what remote branches they merge with.
  • Local branches configured for git push. Also shows the local branches that are out of date.

Removing a Branch

git push origin :<branch name> –  Deletes the remote branch

git branch –d <branch name> –  Deletes the local branch

If there are commits on this branch that have not been merged it will ask to either commit those changes

git branch –D <branch name> –  force delete branch

Push on Deleted Remote Branch

git commit –m –a “Commit message”

git push –  Message comes up saying everything up to date because there is no remote to push to.

git remote show origin  –  shows the branches available and stale/deleted remote branches

git remote prune origin –  clean up the deleted remote branches references

Prune

We would have 2 copies of a remote branch locally. One is brach that we work with and the other one is a read-only copy of the remote branch. We could check that by running

git branch --all

Once we are done working with a brach we delete the branch but we might also want to remove the read-only copy of the branch maintained by git as well. We could do that by using the Prune command which removes all unreachable objects from the database.

git pull —prune

We could also use gc which automatically calls prune

git gc

Tags

A tag is a reference to commit. It is mostly used for the release versioning.

git tag –  list all the tags

git checkout tagname –  checks out the code at commit

git tag –a <tagname> -m “Tag description”

git push –tags –  Pushes the tags otherwise the tags will stay local

Rebase

Merge commits are not so great so we want to skip them. So Someone already pushed a new version of source code after you pulled but before you push. So now if you try to push your code it will be reject as you are behind the commit at this point of time.
So instead of git pull and git push we could do git fetch and git rebase

git fetch –  Goes to github and pulls down any changes but does not merge them

Rebase does the following steps.

  • Moves the changes form master which are not in origin/master to a temporary area.
  • Then it runs all the origin master commits one by one
  • Then it runs all the commits in the temporary area onto the master one by one.

So the merge happens without any merge commit.

Local Branch Rebase

git checkout admin –  switches to admin branch

git rebase master –  First runs the master commits and then it runs the additional admin commits onto the admin branch

git checkout master –  move to the master branch

git merge admin –  does a fast forward commit as the changes have been taken care of

We have 2 people editing the same file and one of them has committed the file back to github and other person now wants to commit the same file.

git fetch – fetches the commits of the branch in the repository

git rebase –  Takes the commits from master and moves them to a temporary area. Then it runs all the origin master commits. Then it runs the temporary area commits one at a time. And this will lead to a conflict

So need to fix the merge conflict and then run git rebase – – continue

git rebase - - skip –  Skips the patch

git rebase  - - abort –  Checkout the original branch and stop rebasing

once we are done with the editing of the file we do a

git add filename

git rebase - - continue –  continues applying the commits

History

git log –  Shows the list of the logs of the recent commits.

It shows

  • SHA
  • Author
  • Date Commit message
git config - - global color.ui true –  Emphasis the commit hash

git log - - pretty=oneline –  Displays one commit per line starting with SHA and then the commit message

git log - - pretty=formt: “%h %ad- %s [%an]” –  You can have specific format for the log

%ad – author date

%an – author name

%h – SHA hash

%s – subject

%d – ref names

* Run git help log for more options

Aliases for log output formats

git log  - - global alias.mylog \ “log - - pretty=format: %h %s [%an] - - graph”

To use this log formatting just use

git mylog

git config - - global alias.lol \ “log - - graph - - decorate - - pretty=oneline - - abbrev-commit - - all”

Shows the graphical output

git log - - online –p  –  provides the information of what was added and what was deleted.

git log - - online - - stat –  Shows how many insertions and deletions were made in each file in each commit.

git log - - online - - graph –  Shows visual representation of branch merging into master

Date and Time Ranges for Log

git log - - until=1.minute.ago –  Show log until 1 minute ago

git log - - since=1.day.ago –  shows log since days specified

git log - - since=1.hour.ago

git log - - since=1.month.ago - - until=2.weeks.ago –  Since and until

git log - - since=2000-01-01 - - until=2012-12-21 –  since an until

Uncommited Changes

git diff HEAD –  Does the same thing as git diff i.e. compares with the last commit

Comparing with earlier commits

git diff HEAD^ –  compares with parent of last commit

git diff HEAD^^ –  compares with grandparent of last commit

git diff HEAD~5 –  compares with the code 5 commits ago

git diff HEAD^ . . HEAD –  compares the second most recent to the most recent

git diff sha1 . . sha2 –  compares between different SHA’s

We could also use abbreviated sha’s available in github

git diff master <branch name> –  diff between two branches

* Can use time based diff just like logs

Blame

git blame <file name> - - date short –  shows the SHA’s and the commit ids and the difference between the various commits

Excluding files and folder

To exclude a folder we need to put the folder name inside the .git/info/exclude file and then we will not that folder anymore.

So we can exclude

Specific file –  tutorial.mp4

Specific file type –  *.mp4

Specific directory –  experiments/

.log files in log directory –  logs/*.log

Excluding From All Copies

.getignore –  To ignore the file not only from the local repository but also from the all the repositories

Removing a File from the repository

git rm filename –  removes the file from the local file system and is untracked

and then we commit

git commit –m “Removed file” –  The file finally removed

Untracking File

git rm - - cached filename –  stops watching for the changes of the file. It is deleted  only from the repository and not from the file system.

Aliases

git config - - global alias.st status –  git st = git status

git config - - global alias.co checkout –  git.co = git.checkout

git config - - global alias.br branch –  git br = git branch

git config - - global alias.ci commit –  git ci = git checkout

 

Data types in git

blob, tree commit, tag

git checkout <commitid> –  used to go to the history in any time.

Git takes snapshot and not the diff. So it takes the snapshot of the database at any point in time.

Difference Since some date

git diff "@{yesterday}"

git whatchanged --since="2 weeks ago"

 

Reset author on previous commit

git commit --amend --author "New Author Name <newmail@example.com>"

Reset author on all commits

$ git filter-branch --commit-filter 'if [ "$GIT_AUTHOR_NAME" = "Old Author Name" ];then export GIT_AUTHOR_NAME="New Author Name";export GIT_AUTHOR
_EMAIL=test@example.com; fi; git commit-tree "$@"'

Any questions, comments and feedback are most welcome.