上面我们得到了项目的git仓库之后,我们就会对这个项目进行开发,并且使用git来进行管理,那么接着来看看如何使用git进行管理和操作。
假设我们已经使用git clone
获取到了一个git仓库的本地拷贝,下面,我们在这个项目的基础上进行一些开发操作,对一些文件作出了修改,在完成开发操作之后,我们需要提交本次更新到本地仓库中。
在工作目录下,所有文件只有两种状态:已跟踪或未跟踪
已跟踪的文件是本地项目中已经存在的文件。这些文件可能呈现未更新,已修改或者已放入暂存区这几种状态。
未跟踪的文件一般就是在本地新创建的文件。
初次克隆某个仓库时,工作目录中的所有文件都属于已跟踪文件,且状态为未修改。
在编辑过某些文件之后,Git 将这些文件标为已修改。我们逐步把这些修改过的文件放到暂存区域,直到最后一次性提交所有这些暂存起来的文件,如此重复。所以使用 Git 时的文件状态变化周期如图所示。
下面我们来看看具体的命令操作:
检查当前文件状态
前面已经介绍了文件的状态,下面看看如何确定哪些文件当前处于什么状态,可以用 git status
命令。如果在克隆仓库之后立即执行此命令,会看到类似这样的输出:
$ git status
# On branch master
nothing to commit (working directory clean)
上面这种状态就是未更新状态,说明所有已跟踪文件在上次提交后都未被更改过。此外,上面的信息还表明,当前目录下没有出现任何处于未跟踪的新文件,否则 Git 会在这里列出来。最后,该命令还显示了当前所在的分支是 master,这是默认的分支名称,实际是可以修改的
现在让我们用 vim 在项目中创建一个新文件 README,保存退出后运行 git status
会看到该文件出现在未跟踪文件列表中:
$ vim 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)
在状态报告中可以看到新建的README文件出现在“Untracked files”下面。未跟踪的文件意味着Git在之前的快照(提交)中没有这些文件;也就是这是新创建的文件。Git 不会自动将之纳入跟踪范围,除非你明明白白地告诉它“我需要跟踪该文件”,因而不用担心把临时文件什么的也归入版本管理。
跟踪新文件
使用命令 git add
开始跟踪一个新文件。所以,要跟踪 README 文件,运行:
$ git add README
此时再运行 git status
命令,会看到 README 文件已被跟踪,并处于暂存状态:
$ git status
On branch master
Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: README
#
只要在 “Changes to be committed” 这行下面的,就说明是已暂存状态。如果此时提交,那么该文件此时此刻的版本将被留存在历史记录中。在 git add
后面可以指明要跟踪的文件或目录路径。如果是目录的话,就说明要递归跟踪该目录下的所有文件。
暂存已修改文件
如果我们对项目中的某一个已经跟踪过文件进行修改,那么这个文件所属的状态就会变成已修改状态。
现在我们修改下之前已跟踪过的文件 benchmarks.rb,然后再次运行 status 命令,会看到这样的状态报告:
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: README
#
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
#
# modified: benchmarks.rb
#
文件 benchmarks.rb 出现在 “Changes not staged for commit” 这行下面,说明已跟踪文件的内容发生了变化,但还没有放到暂存区。要暂存这次更新,需要运行 git add
命令。现在让我们运行 git add
将 benchmarks.rb 放到暂存区,然后再看看 git status
的输出:
$ git add benchmarks.rb
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: README
# modified: benchmarks.rb
#
另外,需要说明的一点是,已经暂存的文件如果被修改了,它的状态就会变成已修改状态,所以修改完毕之后,需要再次通过git add
命令将它添加为到暂存状态。
忽略某些文件
有些文件是我们并不想加入也无需被添加到 Git 管理中,同时也不希望他出现在未跟踪列表中。 “.gitignore” 文件可以达到这个效果。
.gitignore 有全局和局部两种:
1、通过修改全局配置 git config
中的 excludesfile 指定全局忽略文件。设置方法:
$git config --global core.excludesfile ~/.gitignore
2、忽略文件默认为当前目录的 .gitignore ,但它只作用于当前目录下。
文件 .gitignore 的格式规范如下:
所有空行或者以注释符号 # 开头的行都会被 Git 忽略。
可以使用标准的 glob 模式匹配。
匹配模式最后跟反斜杠(/)说明要忽略的是目录。
要忽略指定模式以外的文件或目录,可以在模式前加上惊叹号(!)取反。
所谓的 glob 模式是指 shell 所使用的简化了的正则表达式。星号(*)匹配零个或多个任意字符;[abc] 匹配任何一个列在方括号中的字符(这个例子要么匹配一个 a,要么匹配一个 b,要么匹配一个 c);问号(?)只匹配一个任意字符;如果在方括号中使用短划线分隔两个字符,表示所有在这两个字符范围内的都可以匹配(比如 [0-9] 表示匹配所有 0 到 9 的数字)。
查看已暂存和未暂存的更新内容
要查看尚未暂存的文件更新了哪些部分,不加参数直接输入 git diff
,此命令比较的是工作目录中当前文件和暂存区域快照之间的差异,也就是修改之后还没有暂存起来的变化内容。
若要看已经暂存起来的文件和上次提交时的快照之间的差异,可以用 git diff --cached
命令。(Git 1.6.1 及更高版本还允许使用 git diff --staged
,效果是相同的,但更好记些。)
请注意,单单 git diff
不过是显示还没有暂存起来的改动,git diff --cached
显示的是暂存起来的文件跟上次提交之间的改动。所以有时候你一下子暂存了所有更新过的文件后,运行 git diff
后却什么也没有,就是这个原因。
提交更新
当所有文件的改动都被暂存起来之后,下一步就是提高更新了。在此之前,请一定要确认还有什么修改过的或新建的文件还没有 git add
过,否则提交的时候不会记录这些还没暂存起来的变化。所以,每次准备提交前,先用 git status
看下,是不是都已暂存起来了,然后再运行提交命令 git commit
:
$ git commit
这种方式会启动文本编辑器以便输入本次提交的说明。这个文本编辑器就是我们在git的安装与配置 里面配置的那个文本编辑器。
另外也可以用 -m
参数后跟提交说明的方式,在一行命令中提交更新:
$ git commit -m "Fix benchmarks for speed"
需要注意的是,提交的是已经暂存的内容,未纳入暂存范围的文件将不能被提交。
跳过使用暂存区域
Git 提供了一个跳过使用暂存区域的方式,只要在提交的时候,给 git commit
加上 -a
选项,Git 就会自动把所有已经跟踪过的文件暂存起来一并提交,从而跳过 git add
步骤:
$ git commit -a -m 'added new benchmarks'
需要注意的是它实际上是把处于跟踪状态的文件进行提交,如果文件不处于跟踪状态,它是不会被提交的。
移除文件
要从 Git 中移除某个文件,就必须要从已跟踪文件清单中移除(确切地说,是从暂存区域移除),然后提交。可以用 git rm
命令完成此项工作,并连带从工作目录中删除指定的文件,这样以后就不会出现在未跟踪文件清单中了。
如果只是简单地从工作目录中手工删除文件,运行 git status
时就会在 “Changes not staged for commit” 部分(也就是未暂存清单)看到:
$ rm grit.gemspec
$ git status
# On branch master
#
# Changes not staged for commit:
# (use "git add/rm <file>..." to update what will be committed)
#
# deleted: grit.gemspec
#
这样就需要运行 git rm
记录此次移除文件的操作:
$ git rm grit.gemspec
$ git status
# On branch master
#
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# deleted: grit.gemspec
#
这样提交的时候,该文件就不再纳入版本管理了。
如果删除之前修改过并且已经放到暂存区域的话,则必须要用强制删除选项 -f
另外一种情况是,从暂存区域移除跟踪但不删除文件,即从跟踪状态转为未跟踪状态,用--cached
选项即可:
git rm --cached readme.txt
修改最后一次提交
如果已经执行了git commit
,但是想在之前的提交上追加一些内容,这个时候就应该在修改之后就应该使用下面命令提交:
$ git commit --amend
启动文本编辑器后,会看到上次提交时的说明,编辑它确认没问题后保存退出,就会使用新的提交说明覆盖刚才失误的提交。
如果刚才提交时忘了暂存某些修改,可以先补上暂存操作,然后再运行 --amend
提交:
$ git commit -m 'initial commit'
$ git add forgotten_file
$ git commit --amend
取消已经暂存的文件
如果我们不小心将一些文件加入到暂存区域,但是想要撤销,可以使用下面操作,benchmarks.rb是文件名。
git reset HEAD benchmarks.rb
使用上面命令之后,benchmarks.rb文件就会从暂存状态回到未暂存的状态。
取消对文件的修改
如果我们对一个文件进行了修改但是还是没有加入到暂存区域,想要取消对文件的修改可以使用下面命令。
git checkout -- benchmarks.rb
git查看提交历史
使用命令查看提交历史
在提交了若干更新之后,又或者克隆了某个项目,想回顾下提交历史,可以使用 git log
命令查看。
$ git log
commit ca82a6dff817ec66f44342007202690a93763949
Author: Scott Chacon <schacon@gee-mail.com>
Date: Mon Mar 17 21:52:11 2008 -0700
changed the version number
commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
Author: Scott Chacon <schacon@gee-mail.com>
Date: Sat Mar 15 16:40:33 2008 -0700
removed unnecessary test code
commit a11bef06a3f659402fe7563abf99ad00de2209e6
Author: Scott Chacon <schacon@gee-mail.com>
Date: Sat Mar 15 10:31:28 2008 -0700
first commit
默认不用任何参数的话,git log
会按提交时间列出所有的更新,最近的更新排在最上面。每次更新都有一个 SHA-1 校验和、作者的名字和电子邮件地址、提交时间,最后缩进一个段落显示提交说明。
git log
有许多选项可以帮助你搜寻感兴趣的提交,接下来我们介绍些最常用的。
我们常用 -p 选项展开显示每次提交的内容差异,用 -2 则仅显示最近的两次更新,在做代码审查,或者要快速浏览其他协作者提交的更新都作了哪些改动时,就可以用这个选项。
使用图形化工具查阅提交历史
在项目工作目录中输入 gitk 命令后,就会启动图所示的界面。这个命令就相当与git log
命令。