Installation and configuration
- First thing first, you can easily install git in all 3 mainstream OS, Windows, Linux, OSX.
Get windows installer on https://git-for-windows.github.io/.
Note that in Windows, the official git tool was called "git for windows" as well as msysgit. They‘re aimed at the same thing.
- Git provide a command tool named git config for environment configuration.
You should configure some basic information at least for better using experience.
Editor & Merge tool will be need other stand alone tools, e.g. gvim, kdiff3, etc.
Here we do not configure external editor but get the kdiff3 right here http://sourceforge.net/projects/kdiff3/files/latest/download?source=files.
- User Information
$ git config --global user.name "John Doe"
$ git config --global user.email [email protected]
- Editor
$ git config --global core.editor gvim
- Merge tool
Say we‘re using kdiff3 in windows for Comparison and merge branch.
$ git config --global merge.tool kdiff
$ git config --global mergetool.kdiff3.path "your path to kdiff3.exe"
- PS: the configuration could be list using below commands:
$ git config --list
Or if you need to check the value of a configuration, use:
$ git config user.name
- As sometimes you will need to clone a remote repository, and you‘re trying to use the SSH way for remote operations. It‘s time for some SSH stuffs.
- Check whether your ssh keys exists:
$ ls ~/.ssh
There should be text files similar to below, which contains the public key & end with your email.
id_dsa.pub
id_rsa.pub
- Generate your new ssh keys:
$ ssh-keygen -t rsa -b 4096 -C "[email protected]"
- Ensure ssh-agent is enabled:
# start the ssh-agent in the background
$ ssh-agent -s
# Agent pid 59566 - Add your SSH key to the ssh-agent:
$ ssh-add ~/.ssh/id_rsa
- Add your SSH key to your account, copy the whole public key and paste to your remote Git repository server such as GitHub, GitLab, etc.
$ clip < ~/.ssh/id_rsa.pub
- PS: This ssh way using your private key to identify your user information, it was used when the repository URL happened to be something similar to git://example.com/repo.git.
- Check whether your ssh keys exists:
Dance at local
- Initialize a new git repository or clone a remote repository
- Initialize locally
Change directory to your local project and then:
$ git init
$ git add *.cpp
$ git add README
$ git commit -m ‘initial project version‘
- Clone repository
$ git clone git://github.com/example/project.git [directory name]
This will create a directory using your [directory name] or the remote project name (If no directory name specified).
- Initialize locally
- Git status
There‘re 3 different status here includes changed, staged, committed.
- Untracked
By default, if you create, modified some files in your local repository, these files will get a untracked status, nothing is record in Stage Area.
$ gvim README
$ git status
# On branch master
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# README
nothing added to commit but untracked files present (use "git add" to track)
- Stage
Now you‘re going to track & stage these files, you can use git add to finish this.
These files will be committed together when you commit your changes next time.
$ git add README
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: README
Note that you can use git diff to compare your changes all the time.
$ git diff
This will compare your unstaged file with your staged area.
- Commit
You‘re ready to finish a period of development, now let‘s get a version clean and ready.
$ git diff --staged
This will compare your staged changes with the last time you committed.
$ git commit -m "Example message"
If all the needed files were tracked already, then you can also use below command to commit your changes directly without Stage files:
$ git commit -a -m "Example message"
- Untracked
- Remove files
- To remove files from git, you‘ll need command to complete this task. This is because your file records were in the staged area, and this command will help you to remove it from the Stage Area.
After deleting files, the status will become "Changed but not updated".
- Then you can use:
$ git rm filesToBeRemoved
- To just untrack some files but not remove them, you can use:
$ git rm --cached filesToBeUntracked
After that, you can just add the missing rule to the .gitignore file.
- Glob could also be used, note the \ symbol will help to achieve this feature recursively:
$ git rm \*.log
- To remove files from git, you‘ll need command to complete this task. This is because your file records were in the staged area, and this command will help you to remove it from the Stage Area.
- Rename files
- Using git mv
$ git mv filename1 filename2
- Using git rm & git add, this is important when you‘re renamed some files already but haven‘t yet remove the records in git stage area.
$ mv README.txt README
$ git rm README.txt
$ git add README
- Using git mv
- Amend the last commit
- Using --amend param, the last commit will be together with the new operations.
$ git commit -m ‘initial commit‘
$ git add forgotten_file
$ git commit --amend
- Unstage file & Discard changes:
$ git reset HEAD benchmarks.rb
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: README.txt
#
# Changed but not updated:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: benchmarks.rb
#
Firstly the file benchmarks.rb was to be committed just like the README.txt above, but now it become a unstaged file which needed other steps.
- You can add it back to staged status or checkout to discard the changes.
$ git checkout -- benchmarks.rb
However, this is a dangerous command because it will really discard your changes, unlike some more friendly commands, i.e. stashing.
- Using --amend param, the last commit will be together with the new operations.
Remote repository
- Show me the verbose
$ git remote -v
#origin git://example.com/project.git
#peter git://hello.com/project.git
#lan //dell-pc/d/path/project.git
- Add remote repository
- Using git remote add to configure a new repository.
$ git remote add alias git://github.com/paulboone/ticgit.git
Once you have your remote repositories, you can specify you‘ll choose which repository to fetch data:
$ git fetch peter
Unpacking objects: 100% (44/44), done.
From git://github.com/paulboone/ticgit
* [new branch] master -> peter/master
* [new branch] ticgit -> pter/ticgit
- Using git remote add to configure a new repository.
- Push local commits to remote repository
- This is a straight forward command, if the branch doesn‘t exist in remote, the new branch will be created automatically:
$ git push [remote-name] [branch-name]
- This is a straight forward command, if the branch doesn‘t exist in remote, the new branch will be created automatically:
Branch Model
This is the most widely used part in git. Efficient, Clear, and works great.
- Create a new branch
$ git branch testing
- In your local, there‘s always a HEAD pointer point to a specified version of your working branch. That is:
- As the image says, master & testing were the two branches exist. HEAD now point to master. Because git branch will not change the working branch anyway.
- Now you‘re going to check out the new branch for working:
$ git checkout testing
The HEAD pointer has been redirected. And now the checkout command was used to switch branches, instead of discard changes.
- After switch and commit different things in both branches, they might look like:
This model explains why we should use branch to control our development, and how easily it is to use.
- Basic workflow of development based on git
- Firstly you‘ve decided to work on a new feature or a bug fix, say #iss53.
$ git branch iss53
$ git checkout iss53
- Now you have below model look like:
- Some work have been done, the progress moved on:
$ git commit -m "Add something"
- But there‘re some urgent fix should be done now, you‘ll switch back to complete the hotfix:
- $ git checkout master
- $ git branch hotfix
$ git checkout hotfix
#Switched to a new branch "hotfix"
When the hotfix has been committed, it looks like:
- Now we merge the hotfix to master and push it to remote server:
- Things were moving smoothly and the hotfix can be deleted safely, and the iss53 could be keep developing again.
$ git branch -d hotfix
#Deleted branch hotfix (3a0874c).
$ git checkout iss53
$ git commit -m "other features"
- When the iss53 has been finished, just merge the iss53 into master:
$ git checkout master
$ git merge iss53
Even though the process of merge was different from the hotfix one, the git decided how to merge these two branches itself. Finding the Common ancestor, merge the commits, and create a new commit (which is a special commit named "Merge commit").
- What if there‘re conflict occurred when merging? At the moment, all the conflict files will be listed as "Unmerged files".
$ git mergetool
merge tool candidates: kdiff3 tkdiff xxdiff meld gvimdiff opendiff emerge vimdiff
Merging the files: index.html
Normal merge conflict for ‘index.html‘:
{local}: modified
{remote}: modified
Hit return to start merge resolution tool (opendiff):
After that, the status will become modified again and could be committed now.
- Actually, you can also merge the master branch into your #iss53 anytime, if other‘s important changes are needed. And then push the local branch to the remote repository, create a merge request. Waiting for someone who has a write access right to merge your branch into master. This is an acceptable workflow as well.
$ git checkout iss53
$ git fetch origin
$ git merge origin/master iss53
$ git push origin iss53
This kind of process could be completed easier via rebase:
$ git checkout iss53
$ git rebase master
$ git push origin iss53
The rebase command will generate a clearer development history:
- Tracking branch
- A local branch checkout from remote server was called a tracking branch.
$ git checkout -b localfix origin/serverfix
Branch localfix set up to track remote branch refs/remotes/origin/serverfix.
Switched to a new branch "localfix "
The branch name can be the same as branch on server side.
$ git push origin serverfix:localfix or
$ git push origin serverfix (if the name were the same)
- A local branch checkout from remote server was called a tracking branch.