背景
用过几年的svn,在svn中修改了代码都是直接提交到远程仓库里去,这样如果你的开发机器域远程仓库网络断了你就没法提交了。
而git 有本地工作去,本地仓库,及其与本地仓库对应的远程仓库。所以即使远程仓库网络断了你照样可以提交到本地仓库。
所以git把以前必须要联网操作远程仓库的操作下放到本地仓库,比如合并分支就是在本地仓库里分别下载master和issue分支然后在本地合并。
公司用git来管理代码,有时对一些命令背后的原理不是很懂,比如git stash,git add,git checkout。这篇文章对我工作过程中遇到的疑问进行整理。
暂存区
暂存区顾名思义就是暂时存放代码的区域,当我代码没有写完我可以通过git add ./ 存放到暂存区中,等待以后git commit到当前本地分支。
git stash 同样是提交到暂存区,经常有这样的事情发生,当你正在进行项目中某一部分的工作,里面的东西处于一个比较杂乱的状态,而你想转到其他分支上进行一些工作。问题是,你不想提交进行了一半的工作,否则以后你无法回到这个工作点。
-- 创建分支
shawndeMacBook-Pro:git_example shawn$ git branch 2017年06月07日
shawndeMacBook-Pro:git_example shawn$ git checkout 2017年06月07日 -- 切换到分支
Switched to branch '2017年06月07日'
shawndeMacBook-Pro:git_example shawn$ vi read.md
shawndeMacBook-Pro:git_example shawn$ git stash
Saved working directory and index state WIP on 2017年06月07日: 7055f9d rq
HEAD is now at 7055f9d rq
shawndeMacBook-Pro:git_example shawn$ git checkout master
Switched to branch 'master'
shawndeMacBook-Pro:git_example shawn$ cat read.md
first edit readme.md
shawndeMacBook-Pro:git_example shawn$ git checkout 2017年06月07日
Switched to branch '2017年06月07日'
shawndeMacBook-Pro:git_example shawn$ cat read.md
first edit readme.md
shawndeMacBook-Pro:git_example shawn$ git stash apply
On branch 2017年06月07日
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: read.md
no changes added to commit (use "git add" and/or "git commit -a")
shawndeMacBook-Pro:git_example shawn$ cat read.md
first edit readme.md
sencond edit readme.md -- 注意:从这里看出 git stash 一定要调用git stash apply才能返回以前工作现场
git add ./ 与 git stash 区别就是,返回原来现场必须调用git stash来返回现场。
因为我们提交代码过程就是 git add ./ -> git commit -> git push,git add 做的操作对所有的分支有影响,如下命令:
shawndeMacBook-Pro:git_example shawn$ vi read.md
shawndeMacBook-Pro:git_example shawn$
shawndeMacBook-Pro:git_example shawn$ git status
On branch 2017年06月07日
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: read.md
no changes added to commit (use "git add" and/or "git commit -a")
shawndeMacBook-Pro:git_example shawn$ git add ./
shawndeMacBook-Pro:git_example shawn$ git checkout master
M read.md
Switched to branch 'master'
shawndeMacBook-Pro:git_example shawn$ git checkout 2017年06月07日
M read.md
Switched to branch '2017年06月07日'
shawndeMacBook-Pro:git_example shawn$ cat read.md
first edit readme.md
sencond edit readme.md
third edit readme.md
shawndeMacBook-Pro:git_example shawn$ git checkout master
M read.md
Switched to branch 'master'
shawndeMacBook-Pro:git_example shawn$ cat read.md
first edit readme.md
sencond edit readme.md
third edit readme.md -- 注意:在master做的分支也可以看到 '2017年06月07日' 分支做的操作
shawndeMacBook-Pro:git_example shawn$
git checkout
从字典里查看checkout 的意思如下:to depart from a place; record one’s departure from work,也就是說這是一個切換並且記錄現在的情況的指令,使用checkout的時候最重要的是不會修改master的位置。说白了checkout 不会修改内容,只会修改头指针也就是把工作目录替换成其他的分支,本身master等其它分支内容没有变。
比如原理的版本链路如下:
- A - B - C (HEAD, master)
check out B之后会变成
-A -B(head) -C(master).
如果这时候我新开一个分支 C,check out (new branch) -b
-A -B -C (master)
|
- new branch (head) //指针到了 new branch这里
从这里看出check 做的操作都是局限在本地仓库后,一般我们都是在本地打new branch 做开发然后合并到master上去然后在push 到远程 origin(origin与master对应)。
git 分支合并请参考如下链接:
https://git-scm.com/book/zh/v1/Git-%E5%88%86%E6%94%AF-%E5%88%86%E6%94%AF%E7%9A%84%E6%96%B0%E5%BB%BA%E4%B8%8E%E5%90%88%E5%B9%B6
注意一点的是:
git merge命令用于合并指定分支到当前分支。合并后,再查看readme.txt的内容,就可以看到,和dev分支的最新提交是完全一样的。
注意到上面的Fast-forward信息,Git告诉我们,这次合并是“快进模式”,也就是直接把master指向dev的当前提交,所以合并速度非常快。