Git命令

本文讲述了git一些常用的命令原理。参考《pro git》

初识Git

  在早期开发项目中,对于项目的管理与协作时非常困难的事情,因此版本控制系统应运而生,git和Mercurial,Bazaar 还有 Darcs 一样都是分布式的版本控制系统。客户端每次对远程仓库中提取的并不是新版本的文件快照,而是把原始的代码仓库完整的镜像下来。这么一来,任何一处协同工作用的服务器发生故障,事后都可以用任何一个镜像出来的本地仓库恢复。
  git对差异文件的处理上,并不care文件数据具体差异的地方,而是把变化的文件作快照后,记录在一个微型的文件系统中。每次提交更新时,他会纵览所有文件的指纹信息并对文件做一个快照,然后保存一个指向这次快照的索引,为了提高性能,对于没有变化的文件,git不会再次保存,而只是对上一次保存的快照做一次连接。
工作方式如图:

  对于任何一个文件,在git中都有三种状态:已提交,已修改和以暂存。对于这三种状态的查询和如何到达这三种状态,后面会讲。

git基础

本地仓库的初始化与提交过程

 &emsp先从最基础的地方说起,先使用git,首先要做的就是建立本地仓库,在一个文件夹下执行:

1
2
3
4
5
6
7
8
9
10
11
git init
```
之后会看到目录中生成了,git目录,git使用的所有资源和数据都保存在这个目录中,这就表示已经初始化为一个git本地仓库。然后使用:
```bash
git add --all
git add add README
git add *.c
```
  就可以把你想要跟新的文件添加到暂存区,并且跟踪这部分文件,这也是的两个功能。
```bash
git add

1
2
git rm --cached filename //取消跟踪filename文件
$ git reset HEAD filename //取消暂存区的文件

然后:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
git commit -m '注释'
```
就可以提交到本地仓库,此时即是以提交状态。
如果你想查询文件在git中的状态可以使用:
```bash
git status
On branch master
Initial commit
Untracked files:
(use "git add <file>..." to include in what will be committed)
.idea/
pom.xml
test.iml
nothing added to commit but untracked files present (use "git add" to track)
```
&emsp;&emsp;可以看到,使用 git status之后出现的提示部分, initial commit 和 untracked files就说明此本地仓库已经初始化并提交,而且未跟踪,如果你想要跟踪这些文件可以使用 git add 命令,这些也都在提示中,这可以看出git的人性化了吧。
为了跟好的理解git中文件状态的周期变化,给出下图:
![](http://ww3.sinaimg.cn/large/006tKfTcjw1f6ioxx5051j310o0gotae.jpg)
&emsp;&emsp;当你想从别人或者自己的仓库中复制整个项目时,使用:
git clone git://github.com/test/test.git
这里使用的服务器是github的服务器,当然你也可以改成自己公司的git服务器。
### 忽略某些文件
&emsp;&emsp;当你不想将一些没用的文件加入项目管理,可以创建一个.gitignore的文件,此文件中可以写出忽略文件的格式,这里遵从glob格式,也就是正则表达式。
*.[oa] //表示以.o或者 .a结尾的都会被忽略
*~//表示以~结尾的都会被忽略
### 移除文件
从暂存区移除文件可以使用:
```bash
git rm test.txt

最后提交的话就不会纳入此版本管理了。

移动文件

这个功能与其说是移动不如说是改名:

1
2
3
4
5
git mv file_from file_to
git mv readme.txt readme #等价于下面三条命令
mv readme.txt readme #移动数据
git rm readme.txt #删除原来的文件
git add readme #将改名后的文件移动到暂存区

取消更改

1
2
git reset HEAD filename //取消已经暂存的文件,取消跟踪但是不会删除更改,只是commit不会提交此文件了
git checkout --filename //取消已经更新但是未暂存的文件,将未暂存的修改删除。

修改commit信息

1
git commit --amend

版本回退

当你做的修改已经提交或者未提交时,需要回退到上一个版本

1
2
3
git reset --hard HEAD^ #回退到当前版本的上一个版本
git reset --hard HEAD^ #回退到当前版本的上上个版本
git reset --hard <提交版本号> #回退到此版本号所代表的版本

如果回退之后 又想回到未来 除非你有未来的版本号 git log是打不出未来版本号的,使用git log -g 或者git reflog就可以显示出来

远程仓库

  远程仓库是指托管 在网络上的项目仓库,可能会有好多个,其中有些你只能读,另外有些可以写。同他人协作 开发某个项目时,需要管理这些远程仓库,以便推送或拉取数据,分享各自的工作进展。管 理远程仓库的工作,包括添加远程库,移除废弃的远程库,管理各式远程库分支,定义是否 跟踪这些分支 。
查看远程仓库

1
git remote -v #查看原称仓库的详细信息

了解了远程仓库后就要添加远程仓库了:

1
git remote add origin(shortname) git://github.com/paul/test.git

  这条命令就添加了远程仓库,刚开始学习git的时候,在这里郁闷了很长时间,以为添加了远程仓库就能在服务器上面添加仓库,但是事实并不是这样,其实远程仓库并不是实际服务器上的仓库,而是服务器上的仓库的别名,可以看到 shortname 可以是任意的名字 可以代表后面的一大串url,这对我们以后向远程仓库push很方便,起码不用谢url了,git默认的仓库名字是origin。
从远程仓库抓取项目文件可以使用:

1
git fetch origin

向远程仓库推送,使用:

1
git push origin master

这里的origin 好似远程仓库的名字,也就是代表了那一串url,master时git默认的主分支。
远程仓库的重命名和删除。

1
2
git remote rm origin //删除远程仓库
git remote pb paul //将pb重命名为paul

git分支

  分支在团队协作中时非常重要的,对同一个项目有多条线一起对项目进行修改,每次修改不同的部位,最后将这些分支合并为master。
这里列举一个分支的应用:

  1. 开发某个网站。
  2. 为实现某个新的需求,创建一个分支。
  3. 在这个分支上开展工作

假设此时,你突然接到一个电话说有个很严重的问题需要紧急修补,那么可以按照下面的方式处理:

  1. 返回到原先已经发布到生产服务器上的分支。
  2. 为这次紧急修补建立一个新分支。
  3. 测试通过后,将此修补分支合并,再推送到生产服务器上。 4. 切换到之前实现新需求的分支,继续工作。

如图;修补bug的分支为iss53

创建分支

1
git branch testing

创建分支前:

创建分支后:

每个分支在更新中是独立的。

切换分支、删除本地分支与分支合并

1
2
3
git checkout testing
git branch -d testing #删除本地分支,在当前分支下不能删除当前本地分支
git merge hotfix #把hotfix分支合并到master分支

合并时会出现两种情况:
1.当master位于hotfix的直接上游时,此时会出现“ fast forword”提示,这是一种简单的合并。
如图: 合并前

合并后

2.当不是直接上游时:

此时git会根据 c4 和c5的公共祖先进行一次三方计算,并创建一个新的commit对象:

合并后的分支状态(将计算出的c6作为master的源点):

分支冲突

  当分支发生冲突时,git并不会过早的合并,而是提醒你发生冲突的文件,可以手动人工的方式协商冲突的文件,已达到最好的效果。

显示提交记录

1
git log #其中出现的版本号在版本回退中很重要

总结

  最后用一幅图来将形象化: