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
- Downloads the entire repository to a new gir repository
- Adds the remote pointing it to the clone url
- 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
- Fetch (or sync) our local repository with the remote one – git fetch
- 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.