取得项目的 Git 仓库,第一种是在现存的目录下,通过导入所有文件来创建新的 Git 仓库。第二种是从已有的 Git 仓库克隆出一个新的镜像仓库来。
初始化新仓库
$
git init
如果当前目录下有几个文件想要纳入版本控制,需要先用 git add 命令告诉 Git 开始对这些文件进行跟踪,然后提交:
$
git add
*.c
$ git add README
$
git commit -m 'initial project version'
从现有仓库克隆
克隆仓库的命令格式为 git clone [url]。比如,要克隆 Ruby 语言的 Git 代码仓库 Grit,可以用下面的命令:
$
git clone git://github.com/schacon/grit.git
如果希望在克隆的时候,自己定义要新建的项目目录名称,可以在上面的命令末尾指定新的名字:
$
git clone
git://github.com/schacon/grit.git
mygrit
Git 支持许多数据传输协议。之前的例子使用的是
git://
协议,不过你也可以用
http(s)://
或者
user@server:/path.git
表示的 SSH 传输协议。
记录更新到仓库
请记住,工作目录下面的所有文件都不外乎这两种状态:
已跟踪或
未跟踪。已跟踪的文件是指本来就被纳入版本控制管理的文件,在上次快照中有它们的记 录,工作一段时间后,它们的状态可能是未更新,已修改或者已放入暂存区。而所有其他文件都属于未跟踪文件。它们既没有上次更新时的快照,也不在当前的暂存 区域。初次克隆某个仓库时,工作目录中的所有文件都属于已跟踪文件,且状态为未修改。
在编辑过某些文件之后,Git 将这些文件标为已修改。我们逐步把这些修改过的文件放到暂存区域,直到最后一次性提交所有这些暂存起来的文件,如此重复。所以使用 Git 时的文件状态变化周期如图 2-1 所示。
检查当前文件状态
[nathan@javarepor testing]$
git status
# On branch master
nothing to commit (working directory clean)
# On branch master
nothing to commit (working directory clean)
vim 编辑一个新文件 README,保存退出后运行 git status
[nathan@javarepor testing]$
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)
# 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)
使用命令 git add 开始跟踪一个新文件
[nathan@javarepor testing]$
git add README
[nathan@javarepor testing]$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: README
#
[nathan@javarepor testing]$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: README
#
忽略某些文件
创建一个名为
.gitignore
的文件,列出要忽略的文件模式
看一个 .gitignore 文件的例子:
# 此为注释 – 将被 Git 忽略
*.a # 忽略所有 .a 结尾的文件
!lib.a # 但 lib.a 除外
/TODO # 仅仅忽略项目根目录下的 TODO 文件,不包括 subdir/TODO
build/ # 忽略 build/ 目录下的所有文件
doc/*.txt # 会忽略 doc/notes.txt 但不包括 doc/server/arch.txt
查看已暂存和未暂存的更新
git status 的显示比较简单,仅仅是列出了修改过的文件,如果要查看具体修改了什么地方,可以用 git diff 命令。
比较的是工作目录中当前文件和暂存区域快照之间的差异
$
git diff
diff --git a/benchmarks.rb b/benchmarks.rb
index 3cb747f..da65585 100644
--- a/benchmarks.rb
+++ b/benchmarks.rb
@@ -36,6 +36,10 @@ def main
@commit.parents[0].parents[0].parents[0]
end
+ run_code(x, 'commits 1') do
+ git.commits.size
+ end
+
run_code(x, 'commits 2') do
log = git.commits('master', 15)
log.size
看已经暂存起来的文件和上次提交时的快照之间的差异
[nathan@javarepor testing]$ git add README
[nathan@javarepor testing]$ git diff --staged
diff --git a/README b/README
index 577fcb1..59d51aa 100644
--- a/README
+++ b/README
@@ -1 +1,2 @@
this is git demo
+add new line
[nathan@javarepor testing]$ git diff --staged
diff --git a/README b/README
index 577fcb1..59d51aa 100644
--- a/README
+++ b/README
@@ -1 +1,2 @@
this is git demo
+add new line
提交更新
$
git commit -m
"Story 182: Fix benchmarks for speed"
记住,提交时记录的是放在暂存区域的快照,任何还未暂存的仍然保持已修改状态,可以在下次提交时纳入版本管理。每一次运行提交操作,都是对你项目作一次快照,以后可以回到这个状态,或者进行比较。
跳过使用暂存区域
Git 提供了一个跳过使用暂存区域的方式,只要在提交的时候,给 git commit 加上-a 选项,Git 就会自动把所有已经跟踪过的文件暂存起来一并提交,从而跳过 git add 步骤:
git commit -a -m
'added new benchmarks'
移除文件
要从 Git 中移除某个文件,就必须要从已跟踪文件清单中移除(确切地说,是从暂存区域移除),然后提交。可以用
git rm
命令完成此项工作,并连带从工作目录中删除指定的文件
如果只是简单地从工作目录中手工删除文件,运行 git status 时就会在 “Changed but not updated” 部分
[nathan@javarepor testing]$
rm tem.txt
[nathan@javarepor testing]$ git status
# On branch master
# Your branch is ahead of 'origin/master' by 2 commits.
#
# Changed but not updated:
# (use "git add/rm <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# deleted: tem.txt
#
no changes added to commit (use "git add" and/or "git commit -a")
[nathan@javarepor testing]$ git status
# On branch master
# Your branch is ahead of 'origin/master' by 2 commits.
#
# Changed but not updated:
# (use "git add/rm <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# deleted: tem.txt
#
no changes added to commit (use "git add" and/or "git commit -a")
[nathan@javarepor testing]$
git rm tem.txt
rm 'tem.txt'
rm 'tem.txt'
[nathan@javarepor testing]$
git status
# On branch master
# Your branch is ahead of 'origin/master' by 2 commits.
#
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# deleted: tem.txt
#
# On branch master
# Your branch is ahead of 'origin/master' by 2 commits.
#
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# deleted: tem.txt
#
最后提交的时候,该文件就不再纳入版本管理了。如果删除之前修改过并且已经放到暂存区域的话,则必须要用强制删除选项
-f(译注:即 force 的首字母),以防误删除文件后丢失修改的内容。
另外一种情况是,我们想把文件从 Git 仓库中删除(亦即从暂存区域移除),但仍然希望保留在当前工作目录中。换句话说,仅是从跟踪清单中删除。比如一些大型日志文件或者一堆.a 编译文件,不小心纳入仓库后,要移除跟踪但不删除文件,以便稍后在 .gitignore 文件中补上,用 --cached 选项即可:
git rm --cached
readme.txt
删除所有log/ 目录下扩展名为 .log 的文件。注意到星号 * 之前的反斜杠 \
$ git rm log/\*.log
递归删除当前目录及其子目录中所有 ~ 结尾的文件
$
git rm \*~
移动文件
git mv README.txt README
撤消操作
修改最后一次提交
重新编辑提交说明
git commit --amend
如果刚才提交时忘了暂存某些修改,可以先补上暂存操作,然后再运行 --amend 提交:
$
git commit -m 'initial commit'
$
git add forgotten_file
$
git commit --amend
上面的三条命令最终只是产生一个提交,第二个提交命令修正了第一个的提交内容。
取消已经暂存的文件
git reset HEAD benchmarks.rb
取消对文件的修改,如果觉得刚才对 benchmarks.rb 的修改完全没有必要,该如何取消修改,回到之前的状态
git checkout -- benchmarks.rb
这条命令有些危险,所有对文件的修改都没有了,因为我们刚刚把之前版本的文件复制过 来重写了此文件。所以在用这条命令前,请务必确定真的不再需要保留刚才的修改。