- What is Git?
- A Short History of Git
- Git Config
- Use https instead of git to push / clone
- Create and Initialize Repository
- First commit => HEAD
- Show the working tree status
- Push to GitHub
- Manage set of tracked repositories
- Pull in upstream changes
- Pull VS Fetch & Merge
- Push tags
- Replace local changes
- Git Tips
- Git Resources
What is Git?
Git is a fast, scalable, distributed revision control system with an unusually rich command set that provides both high-level operations and full access to internals.
A Short History of Git
As with many great things in life, Git began with a bit of creative destruction and fiery controversy. The Linux kernel is an open source software project of fairly large scope. For most of the lifetime of the Linux kernel maintenance (1991–2002), changes to the software were passed around as patches and archived files. In 2002, the Linux kernel project began using a proprietary DVCS system called BitKeeper.
In 2005, the relationship between the community that developed the Linux kernel and the commercial company that developed BitKeeper broke down, and the tool’s free-of-charge status was revoked. This prompted the Linux development community (and in particular Linus Torvalds, the creator of Linux) to develop their own tool based on some of the lessons they learned while using BitKeeper. Some of the goals of the new system were as follows:
- Simple design
- Strong support for non-linear development (thousands of parallel branches)
- Fully distributed
- Able to handle large projects like the Linux kernel efficiently (speed and data size)
Since its birth in 2005, Git has evolved and matured to be easy to use and yet retain these initial qualities. It’s incredibly fast, it’s very efficient with large projects, and it has an incredible branching system for non-linear development.
git config - Get and set repository or global options
Git comes with a tool called git config that lets you get and set configuration variables that control all aspects of how Git looks and operates. These variables can be stored in three different places:
- /etc/gitconfig file: Contains values for every user on the system and all their repositories. If you pass the option--system to git config, it reads and writes from this file specifically.
- ~/.gitconfig file: Specific to your user. You can make Git read and write to this file specifically by passing the --global option.
- config file in the git directory (that is, .git/config) of whatever repository you’re currently using: Specific to that single repository. Each level overrides values in the previous level, so values in .git/config trump those in /etc/gitconfig.
Set git push policy
Defines the action git push should take if no refspec is given on the command line, no refspec is configured in the remote, and no refspec is implied by any of the options given on the command line. Possible values are:
nothing - do not push anything.
- matching - push all branches having the same name in both ends. This is for those who prepare all the branches into a publishable shape and then push them out with a single command. It is not appropriate for pushing into a repository shared by multiple users, since locally stalled branches will attempt a non-fast forward push if other users updated the branch. + This is currently the default, but Git 2.0 will change the default to simple.
- upstream - push the current branch to its upstream branch (tracking is a deprecated synonym for this). With this, git push will update the same remote ref as the one which is merged by git pull, making push and pull symmetrical. See "branch.<name>.merge" for how to configure the upstream branch.
- simple - like upstream, but refuses to push if the upstream branch's name is different from the local one. This is the safest option and is well-suited for beginners. It will become the default in Git 2.0.
- current - push the current branch to a branch of the same name.
The simple, current and upstream modes are for those who want to push out a single branch after finishing work, even when the other branches are not yet ready to be pushed out. If you are working with other people to push into the same shared repository, you would want to use one of these.
NOTE: per repository git config settings are stored in .git/config
Use https instead of git to push / clone
It's easier to clone/pull/fetch and push via HTTPS if you are behind proxy.
This adds the following in ~/.gitconfig
Refer to => http://git-scm.com/docs/git-config
Any URL that starts with this value will be rewritten to start, instead, with <base>. In cases where some site serves a large number of repositories, and serves them with multiple access methods, and some users need to use different access methods, this feature allows people to specify any of the equivalent URLs and have Git automatically rewrite the URL to the best alternative for the particular user, even for a never-before-seen repository on the site. When more than one insteadOf strings match a given URL, the longest match is used.
Any URL that starts with this value will not be pushed to; instead, it will be rewritten to start with <base>, and the resulting URL will be pushed to. In cases where some site serves a large number of repositories, and serves them with multiple access methods, some of which do not allow push, this feature allows people to specify a pull-only URL and have Git automatically use an appropriate URL to push, even for a never-before-seen repository on the site. When more than one pushInsteadOf strings match a given URL, the longest match is used. If a remote has an explicit pushurl, Git will ignore this setting for that remote.
Create and Initialize Repository
git init - Create an empty git repository or reinitialize an existing one
Create an empty git repository or reinitialize an existing one
git add - Add file contents to the index (staging area)
It is common to recursively add all files in a new project by specifying the current working directory like below:
Add all file contents to the index (staging area)
Since Git will recursively add all files under a directory specified, if you give it the current working directory, it will simply start tracking every file there. In this case, a git add . would have done the same thing as a "git add *", but that's only because we don't have subdirectories which the * would not recurse into.
First commit => HEAD
HEAD => points to the last commit you have made
git commit - Record changes to the repository (records snapshots of an index / staging area)
git rm - Remove files from the working tree AND from the index/staging area
NOTE: By default, a git rm file will remove the file from the staging area entirely and also off your disk (the working directory). To leave the file in the working directory, you can use git rm --cached .
git rm --cache => Remove files from the index ONLY - leave the file in the working directory
Show the working tree status
git status - show the working tree status
view the status of your files in the working directory and staging area
This is equivalent to
Delete a branch. The branch must be fully merged in its upstream branch, or in HEAD if no upstream was set with --track or --set-upstream.
Delete a branch irrespective of its merged status.
Push To Remote branch
Someone else needs to get updated repo (commits)
Tracking Remote Branches
Create a local branch to track origin new branch
Same branch name
To set up a local branch with a different name than the remote branch, you can easily use the first version with a different local branch name
Now, your local branch sf will automatically push to and pull from origin/serverfix.
Deleting Remote branches
Push to GitHub
git push - push your new branches and data to a remote repository
Push to github
NOTE: Use -u for the first push.
For every branch that is up to date or successfully pushed, add upstream (tracking) reference, used by argument-less git-pull and other commands. For more information, see branch.<name>.merge in git-config.
More git push examples
Find a ref that matches master in the source repository (most likely, it would find refs/heads/master), and update the same ref (e.g. refs/heads/master) in origin repository with it. If master did not exist remotely, it would be created.
A handy way to push the current branch to the same name on the remote.
Push the current branch to the remote ref matching master in the origin repository. This form is convenient to push the current branch without thinking about its local name.
Manage set of tracked repositories
git remote - list, add and delete remote repository aliases
Octopress use case, need to update Octopress (to the latest commits) - git remote add
If current working directory is cloned from terrywang.github.com repository, initially the .git/config looks like below
Add the remote octopress repository using git add
Check what's been added
git pull - fetch from a remote repo and try to merge into the current branch
To merge another branch into your active branch (e.g. master), use
in both cases git tries to auto-merge changes. Unfortunately, this is not always possible and results in conflicts. You are responsible to merge those conflicts manually by editing the files shown by git.
After changing, you need to mark them as merged with
before merging changes, you can also preview them by using
Push new octopress version to remote source branch
Octopress update done.
Pull in upstream changes
When a repository is cloned, it has a default remote called origin that points to your fork on GitHub, not the original repository it was forked from. To keep track of the original repository, you need to add another remote named upstream
NOTE: A remote is a repository stored on another computer, in this case on GitHub's server. It is standard practice (and also the default when you clone a repository) to give the name origin to the remote that points to your main offsite repository (for example, your GitHub repository).
Git supports multiple remotes. This is commonly used when forking a repository.
Pull in changes from upstream
If the original repository forked (your project from) gets updated, the changes can be added the fork by running the following
Pull VS Fetch & Merge
There are two ways to get commits from a remote repository or branch: git fetch and git pull. While they might seem similar at first, there are distinct differences you should consider.
IMPORTANT: When you use git pull, git tries to automatically do your work for you. It is context sensitive, so git will merge any pulled commits into the branch you are currently working in. One thing to keep in mind is that git pull automatically merges the commits without letting you review them first. If you don't closely manage your branches you may run into frequent conflicts.
NOTE: If the project has tags that have NOT been merged to master, you should do: git fetch upstream --tags
Fetch & Merge
NOTE: When you git fetch, git retrieves any commits from the target remote that you do not have and stores them in your local repository. However, it does not merge them with your current branch. This is particularly useful if you need to keep your repository up to date but are working on something that might break if you update your files. To integrate the commits into your local branch, you use git merge. This combines the specified branches and prompts you if there are any conflicts.
Use case - keep forked repositories up-to-date with upstream
NOTE: This is the recommended way to keep the master branch in the forked repository up-to-date with upstream.
Get latest commits and new tags from upstream
Push tags to the forked project repository
NOTE: git push --mirror will push all branches and tags to remote repository.
Use case - use git rebase to squash multiple commits into 1 singe commit (especially useful for GitHub Pull Requests).
Commits to be squashed
Use interactive rebase to squash the last 3 commits
A new editor screen, Vim in this case will be opened, see below
Save and quit by using :wq 2 and 3 will be merged into 1.
NOTE: squash can only be backwards, squash latest commits to the one before them.
After rebasing, another Vim screen will show up (for editing commit message!)
Comment or delete what is NOT wanted. Save and it’s done!
NOTE: man git-rebase for more.
Use git stash to quickly save some changes that you are NOT ready to be committed or saved, but want to come back later.
git-stash - Stash the changes in a dirty working directory away
Add the current changes to the stack (revert to HEAD)
After fetching and merging with remote repository (or just pull)
Apply the changes
NOTE: If you want to remove the item from the stack when applying, use git stash pop instead.
An example from manpage:
Pulling into a dirty tree
When you are in the middle of something, you learn that there are upstream changes that are possibly relevant to what you are doing. When your local changes do not conflict with the changes in the upstream, a simple git pull will let you move forward.
However, there are cases in which your local changes do conflict with the upstream changes, and git pull refuses to overwrite your changes. In such a case, you can stash your changes away, perform a pull, and then unstash, like this:
Replace local changes
In case you did something wrong (which for sure never happens ;) you can replace local changes using the command
this replaces the changes in your working tree with the last content in HEAD. Changes already added to the index, as well as new files, will be kept.
If you instead want to drop all your local changes and commits, fetch the latest history from the server and point your local master branch at it like this
Every time files are modified, updated, run
- git status
- git log
- git reflog
then add them by using git add or git rm (git rm --cached) before commit. Finally run git push to github.
git reflog - Manage reflog information
git cherry-pick - Apply the changes introduced by some existing commits
NOTE: it is extremely helpful when accidentally git reset --hard, this command can help you find the commit hash, use git cherry-pick to back to the future!
Set HTTP Proxy
Disable SSL certification verification
OR specify the certification path
tig - text-mode interface for git
gitk - Git repository browser
Push to multiple git repos (GitHub + Heroku)
Modify .git/config file in working directory
The "heroku" and "github" remotes are generated by git and are created in the setup instructional steps of each service respectively. I went ahead and manually added the remote "origin" and just copied the url variable from the other remotes. You'll now be able to push to both by calling "git push origin" and then you can fetch from each one as individually needed.
- Git Documentation
- Git Reference
- GitHub Help https://help.github.com/
- git - the simple guide - 1 page
- A Visual Git Reference http://marklodato.github.io/visual-git-guide/
- Cheat sheets http://teach.github.com/articles/git-cheatsheets/
- slides http://teach.github.com/articles/course-slides/
- Presentations http://training.github.com/resources/presentations/
- Git Resources - github:training
- Pro Git http://git-scm.com/book
- The Git Community Book http://alx.github.com/gitbook/
- Git Tutorial and Training by Atlassian
- Slides by @ihower
Yet Another Introduction to Git http://www.slideshare.net/ihower/git-coscup2013
Git Tutorial http://www.slideshare.net/ihower/git-tutorial-13695342
Git and GitHub http://www.slideshare.net/ihower/git-and-github-7306407
- Git by ihower http://ihower.tw/git/
- 5 Useful Git Tips http://adit.io/posts/2013-08-16-five-useful-git-tips.html