Author: Charles Zhu
Summary: git 错误理解
SVN下的项目管理
在使用SVN进行版本管理的时候,我喜欢完成一个功能后进行提交。因为SVN设计的项目大多是在Linux系统,由于缺少较好的IDE,通常会先使用svn status
查看修改的文件,然后逐一确认,最后使用 svn ci -a -m \"commit content\"
进行提交。
git下的误区
大多数情况下,我一直按照SVN的方式处理git项目。我也一直感觉使用git commit -a
很爽,直到有一天发现git的log显示…
接下来我们来做一些操作:
$ git init
$ echo "this is a init text" >> 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)
很显然,我们需要先“添加” 文件到版本库(注意这个add在git中不是添加到版本库),然后进行提交:
$ git add .
$ git commit -m "init commit"
接下来修改文件:
$ echo "add a line" >> hello.txt
$ git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: hello.txt
no changes added to commit (use "git add" and/or "git commit -a")
仔细看log,它提示我们先进行add操作再进行commit(如果确定要提交的情形下),但是等一下,add操作不是已经做了吗?难道add的含义不是添加文件到版本库以便进行追踪?
git add到底是什么意思
我们先接着上面继续操作:
$ git add hello.txt
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: hello.txt
这时的log和之前相比,没有了add的建议操作,为了更明显显示这种区别:
$ echo "difference" >>hello.txt
$git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: hello.txt
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: hello.txt
或者用-s参数:
$git status -s
MM hello.txt //在shell中2个M的颜色显示不一样
这里可以明白,git中的add操作和svn中的add操作是完全不一样的意思。
在git中, 执行add操作后是把文件加入版本库的暂存区,而commit针对的内容就只是暂存区。
而 git commit -a
其实会先执行add操作再提交暂存区的内容,所以这样做是一个非常不好的实践,因为add到暂存区的操作实际是需要我们严格控制的。至于git上为什么要有这样的设计,那么需要知道 reset
命令。这个下次再讲。
反思
很早就知道“暂存区”的概念,可是一直没有深入。git 的 add
和 commit
一直使用,可是却没有想到背后的涵义。所谓 “知其然不知其所以然”,实是大忌!
Comments