git 是什么?
git是一个免费、开源的分布式版本控制系统,可以快速、高效地处理无论大或小的任意工程。
git 容易学习,体积小、性能快如闪电,以其低成本的本地分支,方便快捷的缓存区域,具有多个工作流的特点超越了诸如Subversion, CVS, Perforce, ClearCase等SCM工具。
充分了解git以及git工作的基本原理,对于高效使用git并提高工作效率十分有帮助。
git 的特点
快照,而非差异(Snapshots, not differents)
强大的分支管理
几乎所有的操作都是基于本地的(Nearly every opertation is local)
数据的完整性(Git has integrity)
git 通常只会添加数据 (Git generally only adds data)
三个状态(The three states)
分布式
免费开源
以下着重理解两点:
快照,而非差异(Snapshots, not differents)
git 与其他工具最大的区别就是它对于数据的思考方式。大部分工具基于一系列文件的变化存储信息。记录的是基于每个文件的每一次改动。
git 将数据看做一系列微型文件的快照(a set of snapshots of a miniature filesystems),你在本地的每一次提交或者暂存,git会将在那一刻的所有文件进行快照记录,并保存一份对该快照的引用。为了高效起见,如果文件没有发生改变,git 不会再次存储文件,只是保存一个指向以前一模一样的文件的链接。git 对待数据的方式更像是对待一个快照流。
用图片来看一下二者的区别:
三个状态(The three states)
驻留的文件在git看来有三种状态:commited, modified, staged. 即提交、修改和缓存。这样就形成了git工程的三个目录:工作目录,缓存区,git目录。如下图所示:
git目录是Git用来存放工程的元数据和对象数据库的,是Git最重要的部分。克隆git仓库时,会拷贝此目录。
工作目录是工程的一个单一检出版本。这些文件从git目录的压缩数据库中拉取出来并放置到你的本地磁盘中。
缓存区是一个通常包含在Git目录中的文件,保存你下一步要进行提交的信息。它有时被称为'index'。
git 常用命令
git命令十分丰富,这里简要地将常用的git命令分为四类:
本地仓库相关
远程仓库相关
版本管理相关
分支管理相关
安装好git以后,首先要进行一下全局的设置:
$ git config --global user.name "yuqy"
$ git config --global user.email "[email protected]"
*注:
$ git config -l //可以查看设置
$ git config --replace-all //可以替换旧的设置
本地仓库相关命令
本地仓库初始化操作:
$ mkdir git-share
$ cd git-share
$ git init
Initialized empty Git repository in /Users/yqy/git-share.git/
本地工作目录添加至缓存:
$ git add iwjw.js
缓存区提交至本地Git仓库:
$ git commit -m "add first file"
-m是注释,用于添加对于此次提交的说明。
以上两步将文件提交到了git仓库,若想简化步骤,可以使用:
$ git commit -ma "modify file"
检查文件状态:
$ git status
那么如何撤销本地仓库的相关操作呢?
撤销本地工作目录的修改:
$ git checkout iwjw.js
撤销缓存区的修改:
$ git reset HEAD iwjw.js
撤销git目录的修改:
$ git revert iwjw.js
远程仓库相关命令
可以在github上创建一个仓库,例如,这里创建好了的一个仓库,地址为:http://www.github.com/yuqy/gi...
首先,本地仓库关联至远程仓库:
$ git remote add orgin https://www.github.com/yuqy/git-share.git
本地仓库推送至远程仓库:
$ git push -u origin master
从远程仓库克隆到本地:
$ git clone https://www.github.com/yuqy/git-share.git
查看远程仓库:
$ git remote -v
删除远程仓库:
$ git remote rm origin
修改远程仓库:
$ git remote set-url xxx
从远程仓库拉取代码:
$ git fetch
$ git merge orgin/master
可以用$ git pull
简化以上两条命令
本地仓库推送到远程仓库: $ git push origin master
本地仓库的某分支提交到远程仓库的某分支:
$ git push localbranch:remotebranch
本地新建的分支推送到远程:
$ git push orgin localbranch
版本管理的相关命令
查看历史:
$ git log
$ git log --pretty=format:'%h %add | %s%d[%an] --graph --date=short '
获得旧版本(版本回退):
$ git checkout 3b7e6fc
这是,3b7e6fc是哈希值前7位。
给版本打标签:
git tag v1
移除标签:
$ git tag -d v1
查看标签:
$ git tag
分支管理相关命令
查看分支:
$ git branch
查看远程分支:
$ git branch -r
创建分支:
$ git branch br1
创建并切换分支:
$ git checkout -b br1
从某个提交处切换分支:
$ git checkout -b br2 5e6a24e
切换分支:
$ git checkout master
合并分支:
$ git merge master
解决冲突:
在合并分支的时候往往会遇到冲突,打开文件,常常可以看到:
<<<<<<< HEAD
alert(1)
=======
alert(2)
>>>>>> master
其中HEAD与=====
之间表示是当前版本的内容,====
与master之前表示是合并过来的分支的内容。解决冲突就是在两个版本中选择一个版本,删除另外一个。
删除分支:
$ git branch -d br1
$ git branch -D br1
-d,若分支没有被合并,通常会提醒,因此删除不了,-D是强制删除,
衍合:
$ git rebase master
衍合与合并的区别:
衍合将重写提交树,(可能会影响他人的分支合并)
场合:希望得到精确的提交历史线时可以使用衍合
有用的git技巧
别名
$ git config --global alias.co checkout
或者修改.gitconfig文件
比较
$ git diff
修改上一次的提交
$ git commit --amend -m "add one line"
储藏未提交的修改
$ git stash
查看所有的储藏列表
$ git stash list
将某个储藏应用到工作目录
$ git stash apply stash@{0}
将最后一次储藏应用到工作目录
$ git stash pop
清空所有储藏
$ git stash clear
cherry-pick(遴选)
从不同的分支中检出一个单独的commit , 并把它和你当前的分支合并
类似于打补丁,例如,修复一个所有分支都有的bug这样的场合可以适用。
$ git cherry-pick 8ea36d5
git blame 查找问题的利器
$ git blame -L 2,+4 iwjw.js
-L: 从指定行开始
+4: 要显示的行数
git reflog 对commit的跟踪
$ git reflog
git GUI Clients
参考:
git-scm
推荐使用免费的,在windows,mac上都可使用的source tree软件。
Source Tree中的操作和git命令的对应关系
source tree是非常好用的git gui 工具,它的每个操作和git命令是有对应关系的:
抓取就相当于git fetch,
拉取就相当于git pull,
推送就相当于git push,
暂存(储藏)就相当于git stash,
遴选就相当于git cherry-pick,
右键审查选定的修改日志就相当于git log
右键审查选定项目相当于git blame
右键提交回滚就相当于git revert
source tree里面还可以在视图里对提交进行搜索。
source tree 在提交时最有用,因为图形化界面能最直观地体现你本次要提交的内容,能避免提交错误信息,例如你打的Log和alert. 也就是这个时候,git diff 最弱。
个人觉得,平常的合并和拉取可以用git命令,因为使用命令的速度比较快,但是在提交时、解决冲突以及需要搜索时source tree的图形化界面有助于你对提交内容和待解决的冲突进行审查和取舍。
References
[1] www.git-scm.com
[2] git 教程--廖雪峰的官方网站