Basic writing and formatting syntax
- 1 Fundamentals of Git
- What is Git
- Git Internals
- 2 Get Started on Git
- Install Git
- Configuring Git
- Initializing Repository
- 3 Local Repositary
- Staging Area
- Status Command
- Commits
- ignoring files
- History of Commits
- tags
- stashing
- rebase
- Branches
- Git Branches
- fetch / pull
- diff
- merge
- Remote Repositary, Github
- SSH
- remote
- Push
- Teamwork on Github
- Fork
- Creating a pull request
- Handling a pull request
- Other Services on Github
- GitHub Pages
- Gist
Git is a distributed SCM (Source Control Management) system.
- Free and open source
- Back-up of the files
- Roll-back to a specific point
- Team development (Every developor has a full copy of the project and works in parallel.)
- Fast speed and automated efficiency
- Github, a popular git remote repository
The core of Git is a simple key-value data store.
Provide content or type and size information for repository objects:
git cat-file
Pretty-print the contents of object based on its type:
$ git cat-file -p xxxxxxx
For accessing Git Objects, all objects have a unique, 40-character, SHA-1 hash.
- The first 2 characters: the name of the directory
- The remaining 38 characters: the name of the file
The shortened version of the hash has 7-character.
3 types of Git Objects:
- Blob
- Git stores zlib compressed files (file contents) as blobs.
- Tree
- Git stores directories (folders) as trees in the file system. Git maintains 3 kinds of trees:
- Working directory, which contains
- .git folder == repository, where Git stores its objects.
- actual project files (.c, .cpp, .etc), which are original uncompressed files.
- Staging area(index)
- HEAD, which points to the most recent commit
- Working directory, which contains
- Git stores directories (folders) as trees in the file system. Git maintains 3 kinds of trees:
- Commit
- Commit objects are snapshots of the repository at a given point in time.
- Blob & Tree. Each item in a tree contains 4 pieces of data:
- Permissions for the object
- Type of object: tree or blob
- Hash of the object
- Filename
- Commit Objest. A commit contains 4 pieces of data:
- Who made the commit
- The commit message
- The hash of the parent commit. All commits, except the first, have at least one parent (parent commit).
- Commit only stores the change of the commit.
- If the contents of a file haven't changed, Git can just point to the content in a previous commit using its hash. There is no copy of the same file.
- The hash of the tree that contains the content of the commit.
-
Download
-
Echo the version of Git installed
$ git --version
-
3 different levels of config
- system level
- global level
- local level
-
Edit global config
- Via
$ git config --global ...
- Edit user name:
$ git config --global user.name "username"
- Edit user email:
$ git config --global user.email "[email protected]"
- Edit user name:
- Via
git config --global --edit
- The actual file of global config on Win32:
C:\Users\username\.gitconfig
- The actual file of global config on Win32:
- Via
-
Generate git-config Manual Page and open it in the default web browser
$ git config --help
- The file actually generated on Win32 x64:
file://.../Git/mingw64/share/doc/git-doc/git-config.html
-
Initialize an empty Repository (folder
.git
) in Working Directorycd
to Working Directory and then$ git init
- Working Directory can be created in advance by
mkdir
-
Make Working Directory and initialize Repository
$ git init "repository-name"
- Quite Mode without any message back:
$ git init -q "repository-name"
- Edit the content of this file to name the repository
- For example, adding username to local config
- Via command
$ git config --local user.name "username"
- Via directly editting this file, adding
[user] name = username
- Via command
Stating Area == pre-commit area:
- Intermediary step between untracked and tracked files.
- Or between un-added and added content that has changed.
We use git status
command to see the state of the repository:
- the changes are unstaged for commit
- the changes are staged and ready to be commited
We use git add
to track these untracked files.
- For example, to track everything that has changed:
$ git add .
Commit is to make changes which we have staged to the repository permanent. We use git commit
command to make a commit. After that, everything we stage is committed.
Options of git commit
:
-
-m
- This is a mandatory option.
- For example, to give the message associated with the commit:
$ git commit -m "Added the readme.md file"
-
-am
- For example, to add everything and commit:
$ git commit -am "Added the readme.md file"
- For example, to add everything and commit:
-
--amend
- This option is to amend a previous commit.
- For example, to add everything changed to the stage area and amend the previous commit:
$ git commit -a --amend
Delete commits of current local branch:
Undoing the Last Commit
$ git reset --soft HEAD~1
$ git reset --hard HEAD~1
The same technique allows you to return to any previous revision:
$ git reset --hard 0ad5a7a6
In order to show the history of the project as a series of commits,
we use git log
to view a history of the commits in the project:
- Which files were changed.
- When files were changed.
- Who changed files.
The log command is very customizable and can give us a lot of different output. Numberous flags to control how the information is displayed:
-
To view the log in defualt format, the most recent commit is showing first:
$ git log
-
To view the condensed log one line per commit, use oneline mode:
$ git log --oneline
-
not too much info mode (a small versio of how they changed):
$ git log --stat
-
verbose mode including the output of diff (patch?):
$ git log -p
-
Use
--pretty
to specify exactly how much info we want to show, creating a custom display:- identical to oneline mode
$ git log --pretty=oneline
- a bit more info
$ git log --pretty=short
- a bit more agian(with author and commit)
$ git log --pretty=full
- maximum
$ git log --pretty=fuller
- our own format of "pretty".
$ git log --pretty=format:"string"- For example, shortened commit hash | name of the author(author email) : commit message
$ git log --pretty=format:"%h | %an(%ae) : %s"
- On the top of the above example, do some colors with
%C
$ git log --pretty=format:"%h | %an(%Cblue%ae%Creset) : %s"
- Use --help to see what the placeholders are:
$ git log --help
- For example, shortened commit hash | name of the author(author email) : commit message
- identical to oneline mode
- latest commit mode
$ git log -1
$ git log -2
...
-
latest commit mode combined with --oneline
$ git log -1 --oneline
-
color labeled info
$ git log --decorate
-
differet branches, different commits
$ git log --graph
-
For more options, open the help file in the default browser:
$ git log --help
To ignore particular files or folders to stop Git tracking them:
- Locally, use a
.gitignore
file to specify files or folders to ignore locally. - Globally, define a excludesfile
gitignore_global.txt
in global config to ingnore files or folders globally.
- Conventionally, the ignore file on the local level is
.gitignore
. - To ignore files:
# untracked files
file_name
Thumbs.db
*.dll
- To ignore the folder and the files in the folder:
# untracked folders
folder_name
- The comments in the ignore file begin with
#
.
Use git config --global --edit
to define a global ignore file:
[core]
excludesfile = gitignore_global.txt
Branches are a fundamental feature in Git.
We start out with a master branch automatically when we initialize a repository.
-
Specifying -a to show all the branches:
$ git branch -a
-
Create a new branch:
$ git branch branch-name
-
Create a new branch and switch to it immediately:
$ git checkout -b branch-name
-
Switch to branch:
$git checkout branch-name
-
Delete a branch
- Switch back to master branch
$ git checkout master
- Delete the branch
$ git branch -d branch-name
Force to delete the branch
$ git branch -D branch_name
- Switch back to master branch
-
Branches are isolated sandboxes. Making any changes in a branch will not affect the other branches.
The fetch command brings in changes but doesn't update our current branch:
$ git fetch . master
The file FETCH_HEAD
represents what actually is fetched.
But the pull command results in a merge commit by default. It uses the fetch command internally.
Fetching and pulling are ways to get changes from one branch to another.
-
Pull a branch:
$ git pull remote-name gh-pages
-
For example, assuming we are in new-branch, we want to pull a FIX from the master branch:
git pull . master
"." means that we pull the master branch in our local repository.
then, we have a merge commit in the new-branch
$ git log --graph
Diffing is a way to view the differenence between files.
There're many 3rd party diffing tools and Git can be configured to use them.
Git's built-in default file differ. We can compare files, branches or anything that has a hash.
$ git diff
$ git diff FETCH_HEAD
$ git diff new-branch master
change the order of the branches
$ git diff master new-branch
$ git diff master...new-branch
$ git diff master new-branch --name-only
$ git diff master new-branch --stat
Merging means to take some content from one branch and merge it into another branch.
- fast-forward
- up-stream
- 'recursive' strategy
We specify the other branch we would like to merge into master branch we are currently on:
$ git merge another-branch
Merge conflicts are caused when the same file is changed in different branches.
When we try to merge the branches, we have to tell Git which version of the content we want to keep.
When "Automatic merge failed; fix conflicts and then commit the result."
remove any content we don't want to keep and run commit
to keep the history of master branch clean
Squashing multiple commits into a single commit
-i to make the rebase interactive
$ git rebase -i aefa25f
Bring changes in from other branches,
but put them under the commits we've made in the branch we're working in
First, rewinding head to replay your work on top of it...
Applying: ...
$ git rebase master
Used to mark a pariticular point in a project's history as special, such as a release.
Tags, like the branches, can point to a specific commit.
There are two types of tag:
- Light-weight or simple
- Annotated (recommended)
To show the tags the branch currently has:
$ git tag
Add a tag to the last commit:
$ git tag 0.1.0
To show the commit corresponding to a tag:
$ git show 0.1.0
actually shows:
- full hash of the commit
- short hash of the parent commit
- author
- date
- commit message
make an annotated tag by -a
and a short hash:
$ git tag -a 0.0.1 7b37a84
we need to write a tag message for annotation
$ git show 0.0.1
will show more information because it's annotated.
we can checkout the commit the tag points to:
$ git checkout 0.0.1
then the HEAD is detached from 0.0.1
never make changes when the HEAD is detached
tags are not pushed to remote repository by default
GitHub Guides A remote repository is just another copy of our repository on another computer.
we can only push to Github with a trusted computer. To make our computer trusted we should create an RSA key-pair
- Generate rsa key pair:
$ ssh-keygen
- Using the provided email as a label:
$ ssh-keygen -t rsa -b 4096 -C "[email protected]"
-t dsa | ecdsa | ed25519 | rsa
Specifies the type of of key to create.-b bits
Specifies the number of bits in the key to create.-C comment
Provides a new comment.
- default directory for storing the keys:
C:\Users\<username>\.ssh
- Using the provided email as a label:
- (optional) Use authentication agent and start ssh-agent in the background.
$ ssh-agent -s
- (optional) Add rsa key to ssh-agent.
$ ssh-add ./id_rsa
- Paste id_rsa.pub in 'New SSH key', 'SSH and GPG keys', Settings, Github to make our computer trusted.
- Check if it works.
$ ssh -T [email protected]
You've successfully authenticated, but GitHub does not provide shell access.
If password is still needed:
- Make sure to use
git clone [email protected]:username/projectname.git
to clone the repository. - Make sure that
[remote "origin"] url = [email protected]:username/projectname.git
in.git/config
for ssh repository.
$ git remote
default remote: origin
- List out all the remote.
- Set a new remote.
$ git remote add remote-name https://github.com/user/repo.git
- Verify the new remote.
$ git remote -v
use the push command to send code to a remote
$ git push
$ git add .
$ git commit -m "message"
$ git push -u remote-name master
To remove a commit you already pushed to your origin or to another remote repository
you have to first delete it locally like in the previous step
and then push your changes to the remote.
$ git push origin +master
As a contributor, we can contribute to other open-source projects.
- Fork (make a copy) the repository where to contribute
- Read CONTRIBUTING.md (optional) (tell people what they expect)
- Edit the forked repository
- Commit directly to the
master
branch of the forked repository
- Create a pull request to the original unforked repository by clicking the button
- Discuss and review teh changes in this comparison with others
As the owner, we need to deal with pull requests from other developers.
Get a notification as soon as we logined in
- Merge pull request or
- Close and comment without any action
- There are two types of Github Pages:
- User or company pages
- Project or repository pages
- We can also use a generator to create these static sites:
https://pages.github.com/
- Create a repository named as
user.github.io
- The URL will be
http//user.github.io
- Create a branch named as
gh-pages
for the repository - The URL will be
http//user.github.io/repository-name/
Gist, another service operated by Github, a pastebin-style site that is for hosting code snippets.
Gist == traditional pastebin + version control for code snippets + easy forking + SSL encryption for private pastes.
Stashing is a way to take changes in our repository and put them somewhere safe.
Useful when we need to switch branches but Git won't let us.
The stash is a stack that can take any number of stashes.
The stashes are stored in reverse chronological order.
???
restore working tree files
to reset the working directory very quickly
$ git checkout .
To make a stash to temperally put the changes to the stash like a stack
$ git stash
Use the list argument to view saved stashes
To show what we have stashed
$ git stash list
stash@{0} ... the most recent stash
stash@{1}
...
To get a little report about a stash
$ git stash show stash@{1}
To show a diff information in the little report
$ git stash show stash@{0} -p
To show the difference between two stashes
$ git diff stash@{0}..stash@{1}
To drop(remove) a stash
$ git stash drop stash@{0}
To remove all the stashes as a whole
$ git stash clear
associate a message to a stash by 'save' argument
$ git stash save "message"
To bring back the changes
To apply a existing stash to the current branchg by 'apply'
for example, apply to the most recent stash
$ git stash apply
To apply the most recent stash and drop it
$ git stash pop