移动
// 切换分支到C2的父节点C1 git checkout C2^ 复制代码
上述 ^ 命令一次只能移动一个位置,比较缓慢。接下来我们学习一个新命令。
移动分支可以直接使用 -f
选项让分支指向另一个提交。例如:
git branch -f master HEAD~3 复制代码
上面的命令会将 master 分支强制指向 HEAD 的第 3 级父提交。
如何将下图中右边的分支修改成左边的样式:
$ git checkout HEAD^ $ git branch -f bugFix HEAD^ $ git branch -f master C6 复制代码
^ 和 ~ 的组合操作
上述三条命令可以简化为下面一条命令。
作业:
git branch bugWork HEAD~^2~ 或者 git branch -f bugWork 复制代码
撤销变更
主要有两种方法用来撤销变更 —— 一是 git reset
,还有就是 git revert
。
git reset
通过把分支记录回退几个提交记录来实现撤销改动。你可以将这想象成“改写历史”。git reset
向上移动分支,原来指向的提交记录就跟从来没有提交过一样。
将HEAD 的代码重置到指定版本/tag/分支,重置分成三种,此操作非常危险,非特殊情况禁止此操作
- soft :软重置,重置位置,差异代码会暂存
- mixed :混合重置,重置位置,差异代码不会暂存
- hard :硬重置,重置位置和代码
git reset HEAD~1 复制代码
虽然在你的本地分支中使用 git reset
很方便,但是这种“改写历史”的方法对大家一起使用的远程分支是无效的哦!为了撤销更改并分享给别人,我们需要使用 git revert
。
作业:分别撤销 local
分支和 pushed
分支上的最近一次提交。共需要撤销两个提交(每个分支一个)。
记住 pushed
是远程分支,local
是本地分支 —— 这么说你应该知道用分别哪种方法了吧?
$ git reset local~ $ git checkout pushed $ git revert pushed 复制代码
作业:
$ git reset HEAD~1 $ git checkout pushed $ git revert HEAD 复制代码
作业:
// Git 中默认的是 --mixed。 git reset --hard o/master git checkout -b feature C2 git push origin feature 复制代码
上述命令为标准答案,本人通过另一种方式实现的。
git checkout -b feature git branch -f master C1 git push 复制代码
cherry-pick复制
作业:
$ git cherry-pick C3 C4 C7 复制代码
again:
$ git checkout one $ git cherry-pick C4 C3 C2 $ git checkout two $ git cherry-pick C5 C4 C3 C2 $ git branch -f three C2
stash暂存
将当前未提交的代码存放到一个暂存区当中,如果你要做以下其他任何操作,但是当前存在未提交的代码
如果开发完成,则提交后做其他操作
如果没有开发完成,则暂存后进行其他操作
其他操作完毕后,将暂存区的代码恢复到当前工作目录。恢复的方式有两种,一种是应用(apply),仅恢复代码,不清除暂存区的内容。另一种是弹出(unstash),恢复代码并清空暂存区的代码。建议使用应用(apply**)**。
暂存区内可以暂存多次代码,恢复的时候不要选错。
pull拉取
从服务器拉取代码,不指定拉取的分支时会使用当前分支的上游分支(upstream)。如果当前代 码和服务器的代码存在差异,会自动进行一次合并,如果存在冲突并且不能自动处理,会有提示要 人工解决,因此即使本地不存在任何未提交的代码,但是还是会有可能提示冲突。
git pull
相当于 git fetch + git merge
git pull origin foo
相当于:
git fetch origin foo; git merge o/foo 复制代码
还有...
git pull origin bar~1:bugFix
相当于:
git fetch origin bar~1:bugFix; git merge bugFix 复制代码
作业:
git pull origin bar:foo git pull origin master:side 复制代码
push推送
将当前代码推送到服务器上,不指定拉取的分支时会使用当前分支的上游分支
(upstream)
git commit git commit git push 复制代码
git fetch;git rebase o/master;git push 复制代码
git fetch;git merge o/master;git push 复制代码
git pull
就是 fetch 和 merge 的简写,类似的 git pull --rebase
就是 fetch 和 rebase 的简写!
进阶
git push <remote> <place> 复制代码
git push origin master
,切到本地仓库中的“master”分支,获取所有的提交,再到远程仓库“origin”中找到“master”分支,将远程仓库中没有的提交记录都添加上去,搞定之后告诉我。
摆脱 git checkout
的束缚,用 git push
实现下面的目标。
$ git push origin master $ git push origin foo 复制代码
要同时为源和目的地指定 的话,只需要用冒号 :
将二者连起来就可以了:
git push origin <source>:<destination> 复制代码
作业:
$ git push origin foo:master $ git push origin C5:foo 复制代码
Git 有两种关于 的用法是比较诡异的,即你可以在 git push 或 git fetch 时不指定任何 source
,方法就是仅保留冒号和 destination 部分,source 部分留空。
git push origin :side
删除远程分支
fetch下载
从服务器上获取代码到本地,不进行合并。
在上文学习了 git push 的参数,很酷的 参数,还有用冒号分隔的 refspecs( : )。 这些参数也适用于 git fetch
。他们的概念是相同的,只是方向相反罢了(fetch 是下载,而 push 是上传)
git fetch origin foo 复制代码
Git 会到远程仓库的 foo
分支上,然后获取所有本地不存在的提交,放到本地的 o/foo
上。
作业:
$ git fetch origin master~:foo $ git fetch origin foo:master $ git checkout foo $ git merge C6 复制代码
git fetch origin :bugFix
在本地创建一个分支
fakeTeamwork模拟团队合作
使用 git fakeTeamwork 制造远程仓库的变更,“假装”你的同事、朋友、合作伙伴更新了远程仓库,有可能是某个特定的分支,或是几个提交记录。
克隆一个远程仓库(用 git clone
),再在刚创建的远程仓库中模拟一些修改,然后在你自己的本地分支上做一些提交,再拉取远程仓库的变更。
git clone //假设成员做两次修改 git fakeTeamwork 2 //本地提交,生成 C4 git commit //更新 git pull 复制代码
作业:
思路:
- 克隆你的仓库
- 模拟一次远程提交(fakeTeamwork)
- 完成一次本地提交
- 用 rebase 发布你的工作
git clone git fakeTeamwork 1 git fetch;git rebase o/master;git push 复制代码
如果你是在一个大的合作团队中工作, 很可能是 master 被锁定了, 需要一些 Pull Request 流程来合并修改。如果你直接提交(commit)到本地 master, 然后试图推送(push)修改, 你将会收到这样类似的信息:
! [远程服务器拒绝] master -> master (TF402455: 不允许推送(push)这个分支; 你必须使用pull request来更新这个分支.) 复制代码
解决办法:新建一个分支 feature, 推送到远程服务器. 然后 reset 你的 master 分支和远程服务器保持一致, 否则下次你 pull 并且他人的提交和你冲突的时候就会有问题。
$ git reset HEAD~1 $ git checkout -b feature C2 $ git push 复制代码