2017.9.14
Git学习笔记
Git
Git是一个免费并且开源的分布式版本控制系统,最初由林纳斯·托瓦兹(Linus Torvalds)创作,于2005年以GPL发布。最初目的是为更好地管理Linux内核开发而设计。如今,Git已成为最受开发者欢迎的版本控制系统。
自从用了Git,修改文件再也不用命名成file1,file2,file2改进版,file最终版…
注意:
所有的版本控制系统,只能跟踪文本文件的改动,比如TXT文件,网页,所有的程序代码等等。而图片、视频这些二进制文件,没法跟踪文件的变化,也就是只知道图片从100KB改成了120KB。Git跟踪并管理的是修改,而非文件。
Notes
1.创建版本库
创建一个空目录,然后通过
git init
命令把这个目录变成Git可以管理的仓库:
$ mkdir learngit$ cd learngit$ git initInitialized empty Git repository in /Users/michael/learngit/.git/
2.添加和提交
把一个文件放到Git仓库只需要两步:
- git add <file>...: 将文件添加到仓库
- git commit -m "message": 将文件提交到仓库
工作区有一个隐藏目录.git,是Git的版本库,其中最重要的就是称为
stage
(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支
master
,以及指向
master
的一个指针叫
HEAD
。
git add
之前若需撤销修改,用
git checkout -- <file>...
命令。
git add
实际上就是把文件修改添加到暂存区,逆操作是
unstage
:
git reset HEAD <file>...
。
git commit
实际上就是把暂存区的所有内容提交到当前分支,逆操作是
git reset --hard HEAD^
。
3.版本回退
- git status: 查看仓库当前的状态
- git diff: 查看具体修改内容
- git log: 查看版本变化的历史纪录
- git reset --hard HEAD^/commit id: 回退到指定版本
使用
git log
命令时,一大串类似
3628164...882e1e0
的是
commit id
(版本号)
$ git logcommit 3628164fb26d48395383f8f31179f24e0882e1e0Author: Michael Liao <askxuefeng@gmail.com>Date: Tue Aug 20 15:11:49 2013 +0800append GPL
在Git中,用
HEAD
表示当前版本,上一个版本就是
HEAD^
,上上一个版本就是
HEAD^^
,当然往上100个版本写100个
^
比较容易数不过来,所以写成
HEAD~100
,也可指定
commit id
。
$ git reset --hard HEAD^HEAD is now at ea34578 add distributed$ git reset --hard 3628164HEAD is now at 3628164 append GPL
Git的版本回退速度非常快,因为Git在内部有个指向当前版本的HEAD指针,当你回退版本的时候,Git仅仅是改变HEAD指针的指向。
4.远程库(Github)
由于本地Git仓库和GitHub仓库之间的传输是通过SSH加密的,在使用Github之前,需先进行以下设置:
- 创建SSH Key:$ ssh-keygen -t rsa -C "youremail@example.com"
- 用户主目录下里找到.ssh目录,里面有id_rsa和id_rsa.pub两个文件,登陆GitHub,打开“SSH Keys”页面:在Key文本框里粘贴id_rsa.pub文件的内容。
添加远程库
如果本地库有内容,而远程库没有内容,则在Github上“Create a new repo”,然后将本地仓库与之关联,这样就可以把本地仓库的内容推送到GitHub仓库了。
$ git remote add origin git@github.com:michaelliao/learngit.git$ git push -u origin master
修改远程库
:
格式:
git remote set-url origin xxxx xxxx代表自己的本地仓库路径
例子:
git remote set-url origin git@gitee.com:CinccLiBF/clom.git
从远程库克隆
如果远程库有内容,而本地库没有内容,则直接从远程库克隆。
$ git clone git@github.com:michaelliao/gitskills.git
从远程库pull
如果远程库与本地库都有内容,并且存在冲突,则本地库无法向远程库
push
,解决办法很简单,先用
git pull
把最新的提交从
origin/master
抓下来,然后,在本地合并,解决冲突,再推送。
$ git pullfix conflicts...$ git push origin master
5.分支管理
每次提交,Git都把它们串成一条时间线,这条时间线就是一个分支。创建版本库时自动创建
master
主分支。创建新的分支dev时,Git新建了一个指针叫
dev
,指向
master
相同的提交,再把
HEAD
指向
dev
,就表示当前分支在
dev
上。当
dev
上的工作完成了,直接把
master
指向
dev
的当前提交,就可以把
dev
合并到
master
上。
- git branch: 查看分支
- git branch <name>: 创建分支
- git checkout <name>: 切换分支
- git checkout -b <name>: 创建+切换分支
- git merge <name>: 合并某分支到当前分支
- git branch -d <name>: 删除分支
- git branch -D <name>: 强行删除没有被合并过的分支
master分支应该是非常稳定的,也就是仅用来发布新版本,平时不能在上面干活;干活都在dev分支上,也就是说,dev分支是不稳定的,到某个时候,比如1.0版本发布时,再把dev分支合并到master上,在master分支发布1.0版本;小伙伴们每个人都在dev分支上干活,每个人都有自己的分支,时不时地往dev分支上合并就可以了。所以,团队合作的分支看起来就像这样:
Git还提供了一个
stash
功能,可以把当前工作现场“储藏”起来,等以后恢复现场后继续工作。
# 保存工作现场$ git stashSaved working directory and index state WIP on dev: 6224937 add mergeHEAD is now at 6224937 add merge# 查看工作现场列表$ git stash liststash@{0}: WIP on dev: 6224937 add merge# 恢复工作现场方法1$ git stash pop# 恢复工作现场方法2$ git stash apply stash@{0}...$ git stash drop
6.自定义Git
忽略特殊文件
在Git工作区的根目录下创建一个特殊的.gitignore文件,然后把要忽略的文件名填进去,Git就会自动忽略这些文件。
# MacOS X:.DS_Store# Python:*.py[cod]*.so# My Config:*.txt
配置别名
例如,用
git st
表示
git status
命令,
git br
表示
git branch
命令…:
$ git config --global alias.st status$ git config --global alias.co checkout$ git config --global alias.cm commit$ git config --global alias.br branch$ git config --global alias.unstage 'reset HEAD'$ git config --global alias.last 'log -1'$ git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"...
配置Git的时候,加上
--global
是针对当前用户起作用的,如果不加,那只针对当前的仓库起作用。每个仓库的Git配置文件都放在.git/config文件中。而当前用户的Git配置文件放在用户主目录下的一个隐藏文件.gitconfig中:
$ cat .gitconfig[alias] co = checkout ci = commit br = branch st = status[user] name = Your Name email = your@email.com
配置别名也可以直接修改这个文件,如果改错了,可以删掉文件重新通过命令配置。