原理
对于一个使用5年svn的人来说,突然使用git,确实不太习惯,而且他们的设计方式上有很大的不同。
他们最大的不同有2点:
- svn没有分支
- svn没有本地仓库
分支
在svn中,没有分支,都是保存一个一个文件,这些文件是平行存放的。而在git中,你进入一个仓库,要切换到你需要的分支中。那么这些文件的存储也比svn要复杂,据我观察,大概是只存储不同分支代码的不同部分。
- git branch develop 创建develop分支
- git checkout develop 切换到develop分支
本地仓库
对于svn而言,就只有一个仓库,就是中心仓库,所有开发者的都提交到这个仓库。git则不同,所有开发者在本地有自己的仓库,可以提交自己的更新,在需要的时候再推送到远程仓库。举例:
当切换一个分支后,就可以修改代码和提交更新了,假设修改了main.go这个文件。
- git add main.go 增加代码到暂存区,类似于svn add
- git commit -m’fix a bug’ 提交更新到本地仓库
- git push 提交更新到远程仓库
可以看出,与svn不同,多了第三步推送到远程仓库。在svn中,第二步就可以提交到远程仓库。所以,这里就是本地仓库的作用。因为git是分布式的,有自己的本地仓库,所有的更新可以不提交到中心仓库,每个开发者可以离线工作,不依赖于中心仓库。
所以更新代码需要2个过程:
- 代码更新到本地仓库
- 代码更新到远程仓库
撤销
有几个关于撤销的操作。
撤销add
git add了一个不需要的文件main.exe,需要撤销。
- git reset HEAD main.exe 撤回main.exe文件
- git reset HEAD 撤回所有add的文件
撤销commit
注意此时,还没有git push到远程仓库。
git commit 了一个不需要的文件,需要撤回上一个git commit 操作。
git reset --soft HEAD^ 修改的代码依然在文件中
如果需要撤回多个git commit,操作如下:
git reset --soft commit_id
这里需要查看你需要回滚到哪个commit id,使用git log查看。
撤销push
这里指已经推送到远端的commit,如何撤销?需要两步:
- git reset --hard HEAD^ 或者 git reset --hard commit_id
- git push origin HEAD --force
注意,这里使用了–hard 参数,一经回滚,原来的代码的就消失了,不会留在原来的文件中,使用是要注意。
关于HEAD
HEAD可以理解为一个指针,指向当前分支的最新commit。
删除
- git rm main.exe 删除文件
- git mv main.exe mian.exe_bak 文件重命名
对比
关于对比,这里需要明确几个概念。
- 工作区 当前编辑的代码文件
- 暂存区 暂存编辑后的更新
- 本地仓库 本地的代码仓库
- 远程仓库 远程的代码仓库
举例:当修改main.go之后,使用git diff 命令,可以看到修改的内容。然后使用git add main.go,修改就保存了暂存区,再使用git diff就没有任何内容了,因为此时工作区和暂存区内容一致了。所以,引申出2个对比:
- 工作区和本地仓库对比
- 暂存区和本地仓库对比
总结如下:
- git diff 查看工作区和暂存区(git add)的变化
- git diff --cached 查看暂存区(git add)和上一次commit版本变化
- git diff HEAD 查看工作区和上一次commit版本的变化
- git diff master develop main.go 比较master develop分支下的main.go的不同
修改message
有时候刚刚提交的日志描述不准确,需要修改。
git commit --amend 修改上一个提交的log
有时候需要合并多次提交的log:
git rebase -i commit_start commit_end
即这个commit区间内的commit的合并成一个commit,如果commit_end缺省的话,默认是HEAD.
其他常用操作
- git status 查看状态
- git log 查看提交记录
- git branch 查看当前所在分支
- git clone 克隆仓库
- git show commit_id 查看一个提交的详细记录
- git remote -v 查看远端地址