暮鼓集 行走集
原作于2016年07月21日
下载并安装Git
https://git-scm.com/
运行git bash
建立第一个git库
$ cd git_training
$ git init
Initialized empty Git repository in /.git/
可以在当前目录(git_training)下发现多出了一个隐藏的子目录,名为.git,其中存放着git库的全部数据。
检查状态
$ git status
On branch master
Initial commit
nothing to commit (create/copy files and use "git add" to track)
请牢记git status这个命令,以后我们会反复用到它。这里,git status告诉我们在主(master)分支上,没有什么可以commit的。
新增一个文件,再次检查状态
在目录下新增文件hello.txt
$ git status
On branch master
Initial commit
Untracked files:
(use "git add <file>..." to include in what will be committed)
hello.txt
nothing added to commit but untracked files present (use "git add" to track)
可以看到git报告有一个Untracked文件hello.txt,同时提示使用git add来track。
请注意,Git将文件的状态分为四种
- staged: 文件已准备好,等待commit
- unstaged: 文件发生了改变,但是还未准备好commit
- untracked: 文件没有被Git Track,通常是新增的文件
- deleted: 文件已经被删除,等待从Git库中删除
将文件加入缓存区(staging area)
$ git add hello.txt
$ git status
On branch master
Initial commit
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: hello.txt
Git提示hello.txt的状态变成了Changes to be committed,这标明文件已经在缓存区,但仍然不在Git库中。
除了使用git add来缓存单个文件的改动,还可以使用git add -A . 来加入当前目录下的所有文件, -A 确保及时文件被删除也会包括进来。
我们也可以用git add *.txt这样的通配符来加入一批文件。不过批量添加文件时,必须特别小心,建议务必使用git status来检查是否有不相关的文件被加入缓存区。
可以使用git reset 将文件从缓存区中移除。
提交改动
$ git commit -m "Add hello"
[master (root-commit) c173d96] Add hello
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 hello.txt
一次提交/commit是Git库的一个快照,它记录了我们对文件的改动情况。
查看日志
$ git log
commit c173d962fcc4ea5e30f44e7e49845a7287474b04
Author: Jie Zhuang <[email protected]>
Date: Tue Jan 24 16:20:27 2017 +0800
Add hello
可以使用git log –summary来查看更多信息,比如每一次的commit中,哪些文件被新增,哪些被删除。
指定远程库
远程库的意义在于为项目提供了一个网络协作的平台,也是项目的一个安全备份。
$ git remote add origin [email protected]:jiezhuangcn/git_training.git
origin是我们为远程库指定的一个名称,通常我们会称为origin。
git_training.git是我在github中建立的一个库,你可以建立自己的库,并确保你可以访问。
推送(PUSH)到远程库
这类似于vss/cvs/svn这些传统工具的签入check in。
$ git pull origin master
Branch master set up to track remote branch master from origin.
从远程库拉取(PULL)更新
在协作开发中,多位开发者使用同一个远程库来协同开发,其他成员也会将他们的改动推送到远程库。
我们经常需要将这些更新拉取下来,这类似于vss/cvs/svn这些传统工具的签出check out。
$ git pull origin master
Updating 3852b4d..3e70b0f
Fast-forward
world.txt | 1 +
1 file changed, 1 insertion(+)
create mode 100644 world.txt
有时,在pull时,我们正在修改自己的文件,因为还没有完成所以不想提交,这时可以使用git stash来暂存改动,在pull完成后,再使用git stash apply将暂存的改动应用到工作区。
比较改动
让我们在hello.txt中加一行hello。
$ git diff
diff --git a/hello.txt b/hello.txt
index e69de29..b6fc4c6 100644
--- a/hello.txt
+++ b/hello.txt
@@ -0,0 +1 @@
+hello
\ No newline at end of file
git diff可以比较工作区与缓存区文件的不同。
如果这时git add hello.txt,git diff将不会有输出。
与最后一次Commit进行比较
git diff还可以用于比较工作区与最后一次commit的内容。
$ git diff HEAD
diff --git a/hello.txt b/hello.txt
index e69de29..b6fc4c6 100644
--- a/hello.txt
+++ b/hello.txt
@@ -0,0 +1 @@
+hello
\ No newline at end of file
HEAD是一个指针,记录着所有不同的commit的位置,默认的HEAD指向最近一次commit。这样我们可以直接使用HEAD,而不必去查询最近一次commit的SHA字串。
除此之外,git diff可以用来比较缓存区与最后一次commit的内容。
$ git diff --staged
因为这时缓存区与最后一次commit内容相同,所以输出为空。可以尝试增加一些文件,add到缓存区后,再比较一下。
Check out文件
使用以下命令将文件更改回到最后一次提交时的状态:git checkout - 。
继续并摆脱自上次提交以来对octocat.txt的所有更改
$ git checkout -- hello.txt
为什么必须使用“ – ”,似乎没有它也可以工作。 这是因为git checkout 还可以切换branch。 如果你碰巧有一个名为hello.txt的分支,它将checkout出文件,而不是切换到相同名称的分支。
创建分支
当我们需要新增功能或者修复Bug时,通常会创建一个分支(副本),而原先的Git库默认分支,一般称为主分支(master)。
我们可以将改动提交到新建的分支,当完成工作后,这个分支可以合并到主分支。
$ git branch work
切换分支
使用git checkout 命令切换分支。 现在尝试切换到work分支:
$ git checkout work
可以使用git checkout -b new_branch来同时创建一个分支并切换到这个分支。
合并分支
现在,在work分支中删除所有的文件。
$ git rm .
然后切换回主分支
$ git checkout master
将work合并到主分支
$ git merge clean_up
Updating 3852b4d..ec6888b
Fast-forward
1 deletions(-)
delete mode 100644 hello.txt
如果我们不是在work中删除了所有文件,而是修改一些文件,在合并时,就会发生冲突。解决冲突并不麻烦,我会在进阶里讲解,也可以参考Pro Git一书。
删除分支
我们已经完成了work分支的工作并将它合并到了主分支,所以不再需要work分支了,让我们来删除它。
git branch -d work
Deleted branch work (was ec6888b).
如果我们尚未将分支合并到主分支,但是已经不想要这个分支了,我们会想到删除分支,但是这时会发现git branch -d bad_feature不能完成删除。这是因为-d不会允许您删除尚未合并的内容。
添加–force或-f选项,或使用-D来强行删除。
完成
现在你已经学习完了Git的基本操作,想了解更多的内容,你可以参考以下这些文档。
- Git进阶
- Git Reference
- Pro Git