git本质上一个分布式的文件系统。它把远端的仓库clone到本地,在本地可以做离线式的提交,合并。然后在合适的时机,推送到远端仓库。
对于每个文件的提交,git并没有保存差异内容,而是全镜像的保存。如果文件没有改动的话,那么只保存了上一个版本的指针。
git 配置
git的环境变量存放在三个地方,分别如下:
- /etc/gitconfig:所有用户通用的配置,可以放到这里。通过命令 git config --system访问到
- ~/gitconfig文件:用户目录下的配置只适用于该用户。通过命令 git config --global访问到
- 当前项目下的git目录配置文件(即.git/config文件),这里的配置只针对当前项目有效
每一个级别的配置都会覆盖上层的相同配置。可以通过 git help <verb>命令来查看使用帮助。
命令别名
可以用 git config 为命令设置别名。
1 2 3 4 5 |
git config --global alias.co checkout git config --global alias.br branch git config --global alias.ci commit git config --global alias.st status git config --global alias.last 'log -1 HEAD' |
初始化git仓库
如果有现有仓库的话,直接通过 git clone命令。如果是初始项目的话,可以 git init命令。
有些文件无需纳入git管理,可以在项目跟目录下创建.gitignore文件,列出忽略的文件模式即可。
比如忽略vim编辑产生的中间态文件,可以写入 *.sw[op]。
.gitignore文件需要注意两点:
- 匹配模式最后跟反斜杠(/)说明要忽略的是目录
- 要忽略指定模式以外的文件或者目录,可以在模式前加上感叹号(!)取反
文件对比
git diff命令比较的是工作目录中当前文件和暂存区域快照之间的差异,也就是修改之后还没有暂存起来的变化内容。
若要查看已经暂存起来的文件和上次提交时的快照之间的差异,可以用 git diff --staged。
文件提交
一般情况下,使用 git add 命令把文件存入暂存区域,然后通过 git commit提交。可以使用 git commit -a,git自动会把所有已经跟踪过的文件暂存起来一并提交,从而调过git add步骤。
如果从暂存区域移除文件,或者说移除跟踪但不删除文件,用 git rm —cached即可。
有时提交完成后才发现漏掉了几个文件,或者提交信息写错了,想要撤销刚才的提交操作,–amend 选项可以重新提交。
查看提交历史
git log -p 显示每次提交的内容差异,用-n显示最近的n次提交。
--pretty 选项可以指定使用不同的格式展示提交历史,其中使用format,可以自定义格式。
查看提交范围
双点
这种语法主要是让git区分出可从一个分支中获得而不能从另一个分支中获得的提交。
git log master..experiment这句的意思是”所有可从experiment分支中获得而不能从master分支中获得的提交”。实际上可以查看分支上有哪些提交还没有合并到master分支上。
三点
这个可以指定被两个引用中的一个包含但又不被两者同时包含的分支。 git log master...experiment。一个常用的参数是 —left-right, 它会显示每个提交到底处于哪一侧分支。
撤销操作
提交后发现漏掉了几个文件,或者提交信息写错了,想要撤销刚才的提交操作,可以使用 git commit --amend重新提交。
远程仓库使用
使用 git remote -v查看远程的仓库地址。
默认情况下, git clone 命令本质上就是自动创建了本地的master分支用于跟踪远程仓库中的master分支。所以一般运行 git pull 目的都是从原始clone的远端仓库抓取数据后,合并到工作目录中当前分支。
git remote show origin 显示远端仓库地址的详细信息。
使用标签
在某个时间点上的版本打上标签。通过 git tag -a 标签名称 -m '标签说明' 创建含附注的标签。
切换标签可以通过 git checkout 标签名称 。切换至标签下,如果有文件提交,这里是没有意义的。需要切换到分支下才能保存提交。标签只是一个标记而已。
分支
使用 git branch 查看所在的分支。
git保存着一个名为HEAD的特别指针,它是一个指向正在工作中的本地分支的指针。
- 新建分支 git branch 分支名称。此时并没有切换到新建的分支上。
- 切换分支 git checkout 分支名称。分支切换后,HEAD指针也指向了最新的分支上。
- 推送至远程仓库 git push origin test1:test2 test1:本地分支名称 test2:远程仓库分支名称。如果本地分支和远程分支名称一致,只写一个即可。
把一个分支整合到另一个分支的方法有两种:merge(合并)和rebase(衍合)。
rebase的原理是回到两个分支(你所在的分支和你想要衍合进去的分支)的共同祖先,提交你所在分支每次提交时产生的差异,把这些差异分别保存到临时文件里,然后从当前分支转换到你需要衍合入的分支,依序施用每一个差异补丁文件。衍合能产生一个更为整洁的提交历史。回看衍合过的分支的历史记录,看起来更清楚:仿佛所有修改都是先后进行的,尽管实际上他们原来是同时发生的。
衍合风险
永远不要衍合那些已经推送到公共仓库的更新。
在衍合的时候,实际上抛弃了一些现存的commit而创造了一些类似但不同的新commit。如果把commit推送到某处然后其他人下载并在其基础上工作,然后用git rebase重写了这些commit再推送一次,你的合作者就不得不重新合并他们的工作。
获取远程分支 git fetch origin origin:远程仓库名称。
有时在分支的多个commit对象中,只需要挑拣出部分合并。可以通过 git log 找出合并的对象,通过 git cherry-pick xxxxx进行合并。
储藏工作
有时候在分支开发进行中,需要切换到另一个分支紧急修复问题。使用 git checkout xxx 切换分支时,可能提示:
1 2 3 4 |
error: Your local changes to the following files would be overwritten by checkout: README Please, commit your changes or stash them before you can switch branches. Aborting |
这说明两个分支间有冲突,无法完成切换。可以使用 git stash命令来储藏目前的变更。
1 2 3 4 5 6 |
[bruceding@localhost project]$ git stash Saved working directory and index state WIP on test: bacd928 modify 2 HEAD 现在位于 bacd928 modify 2 [bruceding@localhost project]$ git status 位于分支 test 无文件要提交,干净的工作区 |
可以看到使用 git status 时,分支已经时干净的了。这样可以进行分支切换了。
使用 git stash 之前,如果时新增的文件,最好先通过 git add 加入到暂存区。
工作完成后,还可以切换回来,通过 git stash apply 来还原储藏。也可以通过 git stash pop还原,同时,储藏条目也会被删除。
真是时光荏苒!
受教了!呵呵!