- 工作区:就是你在电脑里能看到的目录。
- 暂存区:英文叫stage, 或index。一般存放在 ".git目录下" 下的index文件(.git/index)中,所以我们把暂存区有时也叫作索引(index)。
- 版本库:工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库。
关于这几个东西的操作不涉及push
所以你的add
命令是把你工作区的改动加到了index,也就是俗称暂存区。
然后你的commit
命令是把你暂存区的改动的文件加到了本地git版本库。
然后你的push
命令会把你本地版本库合并向你的远程git仓库
- git stash,这回把暂存区的修改存储起来
- git checkout other_branch,切换到你需要这些改动的分支
- git stash pop, 这回把存储的修改拿出来,放到这个分支的暂存区
- git log 查看你之前提交的版本日志,看看你要回到哪次commit,通常就是你push前的那一次commit,把那一长串版本号拷贝下来
- git reset --hard 你刚才拷贝的版本号,这就把HEAD指向了这个版本。
技巧二有个问题,就是你操作完之后,你用git status
查看状态会发现本地的操作tree是干净的。
这说明你还在commit之后的状态,你怎样把这个状态再撤回呢?
首先讲下git status
指令,使用这个命令的时候你基本能看到两个状态,我用iterm2的话,
可以清晰地看到你add过的文件是绿色,没有add的文件是红色。红色一般时两种,未准备,未跟踪。
这两种都可以通过add来添加。
所以,这个时候你如果没有之前没有add的文件的话,你撤回这个commit后,再使用git status
命令就会看到清一色的绿色。
最后来看这个撤回当前commit的命令为:git reset --soft HEAD^
这时你就可以去执行git status
看看状态了。
讲解一下图片中出现的命令:
- 当执行
git rm --cached <file>
命令时,会直接从暂存区删除文件,工作区则不做出改变,就是会把你commit的删掉,这时候你使用git status
时你会看到你的这个文件回到了add之前,用iterm2看会红色显示,你得重新使用add来添加它。 - 当执行
git checkout .
或者git checkout -- <file>
命令时,会用暂存区全部或指定的文件替换工作区的文件。这个操作很危险,会清除工作区中未添加到暂存区的改动。 - 当执行
git checkout HEAD .
或者git checkout HEAD <file>
命令时,会用 HEAD 指向的 master 分支中的全部或者部分文件替换暂存区和以及工作区中的文件。这个命令也是极具危险性的,因为不但会清除工作区中未提交的改动,也会清除暂存区中未提交的改动。
这个字面可能完全看不出它在干什么,所以简单解释一下:
首先比如你在分支A上提交了三次,假设三次的commit号是:1,2,3
但是如果你需要在另一个分支B上复现这三次提交怎么办?
就可以用cherry-pick把这3次的改动接到B上。比如这样:
# 先把分支切到B上
然后使用如下命令:
git cherry-pick 1 2 3
这样A上的1,2,3这三次提交会加到B上作为B的三次提交。
概念解释完了,实际有什么用呢?
一、工作中我遇见过这样的问题: 我在第一个分支A中写了一个特性,提交合并, 然后在分支B中写了另一个特性,但是在本地把develope还是master的变化往分支拉的时候,又把A的特性合道了B上, 我的本意是B分支提交的时候肯定只有它自己的特性,现在我如果要合并就戴上了A,那一定会冲突,也会乱掉。 我的做法是放弃提交合并B,我用git log把分支B的commit号记下来, 然后重新开了分支C,这个分支是干净的,然后我用cherry-pick命令把这些commit按照时间顺序加到了C上,最后提交合并了C。 这样就解决了中间不小心污染分支的问题。
二、还可能会有这样的问题: 比如你的应用已经发布了1.0版本,这个代码分支叫prod-1.0,现在正在开发2.0, 开发的分支叫做dev-2.0,但是有一天产品说,要把正在开发的某个特性提前上线, 也就是要把开发分支dev-2.0上某些提交(commit)移动到prod-1.x的版本上,那么就可以用到cherry-pick。
具体做法如下:
- 基于prod-1.0分支创建新的分支prod-1.1
git checkout -b prod-1.1 prod-1.0
- 将dev-2.0分支上的某些提交(commit, 比如c1, c2, c3)在分支prod-1.1上重演
# 做完上一步就在新的分支prod-1.1上了,然后把dev的某些提交接过来
git cherry-pick c1 c2 c3
- git merge --no-ff 分支名A 把A合并到当前分支,并且在看历史时会显示A的分叉出去的提交,可读性会更好。
- gco 分支名 = git check out 分支名 切换分支
- gc == git commit 提交改动,进入vim编辑界面,界面可看到哪些文件改动了
- gp == git push 推送远端
- glola 查看所有分支提交历史,以及各种合并信息