@[toc]
2018-12-09,博客园
教程
【强烈推荐】GitHub项目:learnGitBranching-pcottle
整理 Git 命令如下,按第一个教程顺序整理
常用命令
初始化命令
git init
在当前文件夹初始化一个本地仓库
提交命令
git add
将改动(文件变化)添加到到暂存区(缓冲区),以待正式提交(commit)
git commit
(不建议单独使用)将暂存区的改动提交到Git,对其中文件进行一次快照,保存为一个节点
git commit -m <对提交的描述信息>
在提交变化的同时添加描述信息
git commit --amend
好像是将暂存区的修改直接提交到当前所在节点,而不是新建一个节点(提交)
有待检验
分支命令
git branch <新建分支名> [目标节点]
在目标节点新建一个分支
若不指定目标节点,则默认在当前节点(HEAD)新建分支git branch -f <指定分支名> <目标节点位置>
此命令可以将指定分支强制指向目标节点
如git branch -f master HEAD~4
命令的作用是使master强制指向HEAD所在节点的前4级节点
其中,<目标节点位置>
可以是具体的节点哈希值,也可以是相对引用的节点git branch -u <指定远程分支名> [指定本地分支名]
将指定远程分支与指定本地分支关联
如果省略[本地分支名]
,则默认将当前分支与远程分支关联。[疑问]1
切换命令
git checkout <分支名/标签名/节点哈希值等>
切换到对应的分支、标签或节点。(实际上是改变HEAD的指向,“HEAD的指向”代表当前所在位置)
git checkout -b <新建分支名>
在当前节点新建一个分支,并立即切换到这一新建分支
git checkout -b <新建分支名> <目标远程分支名>
[疑问]3在当前节点新建并切换到一个新分支,同时将其与指定的远程分支关联,用来跟踪这一远程分支
相对引用
git checkout <分支名/HEAD>^
将HEAD指向指定分支名指向节点的上一节点,即父节点。
或将HEAD指向HEAD的父节点
其中,^
符号可以一次使用多个。每使用一个代表将HEAD往上一级节点移动一次
比如git checkout master^^
命令表示将HEAD指针指向master指向节点的上两级节点(即上一级的上一级节点)git checkout <分支名/HEAD>~[数字]
作用类比于上一条命令。但通过
[数字]
可以直接指定将HEAD往前指向的节点级数
若不加[数字]
则默认上移一级,即git checkout master~
与git checkout master^
作用相同git checkout <节点>^[数字]
数字指定回溯到哪一条分支
若没有数字,则默认回溯到直接分支(即合并操作执行时HEAD所在的分支)git checkout <节点>~^2~2
支持链式操作,将多个切换命令合并为一条命令
合并命令
git merge <分支名>
(合并方法1)将<分支名>指定的分支合并到当前所在分支
即以当前分支为主,最终合并的结果(最终节点)也是由当前分支来指向【疑问】10merge
的优势在于可以保持提交历史的顺序、结构git rebase <目标分支> [移动分支]
(合并方法2)直译为“以目标分支(分支1)为基础,结合移动分支(分支2)进行梳理整合”
将[移动分支]
的提交记录整理,复制一个副本合并到[目标分支]
,得到一个线性提交记录。原提交记录依然存在。
同时将[移动分支]
指向rebase得到的分支顶端节点(有待验证)
直译过来就是“将[移动分支]
整合到[目标分支]
”
若不指定[移动分支]
,则默认移动当前分支
优势在于可以保留干净、线性的提交树
标签命令
git tag <标签名> [指定节点]
将标签名标注于指定节点
若不指定节点,则加标签于当前节点(HEAD)
查看命令
git log
列出提交记录(具体列出全部还是当前分支有待确定)
撤销变更命令[疑问]4
git reset <目标节点>
(仅适用于本地分支)将当前分支指向目标节点
即忽略目标节点之后的所有提交
但被忽略的节点所作的变更依旧存在,只是处于未加入暂存区状态git revert <节点>
(适用于远程分支)撤销指定节点的修改,即回到指定节点父节点的状态
实现方式不同于git reset <目标节点>
命令git reset [目标节点]
仅仅通过修改指向实现,git revert <节点>
是对当前节点与其父节点的差异重做而产生一个新的提交节点,得到指定节点的子节点,但是该子节点的状态与指定节点的父节点状态相同
此命令没有实际使用过,有待检验
远程命令
克隆到本地
git clone <ssh/https地址>
从远程仓端克隆远程仓库到本地
从远程仓库拉取内容
git fetch
下载远程仓库所有分支及提交记录到本地各个远程分支
git fetch <remote> <place>
类比
push
命令的参数
可以理解为仅仅是将远程仓库内容下载下来,但是并没有对本地文件作出改动。但是会更新本地仓库的远程分支指向。
区别于git pull
命令
不需要当前处于远程分支git fetch <远程仓库名称> <指定的远程分支名>
【疑问】9同时会更新本地仓库的对应的远程分支(单独的
fetch
会更新吗?)git fetch <远程仓库名称> <源节点>:<本地目标分支>
(实际很少用)<源节点>
是指远程仓库中的索引位置,<目标分支>
才是本地分支了。类比push
命令,刚好相反。
如果本地仓库不存在指定的目标分支,则Git自动在本地仓库(当前节点)创建一个同名分支,并执行操作
不更新本地的远程分支(?)git fetch <远程仓库名称> :<本地目标分支>
命令自动在本地(当前节点)创建一个本地分支
git pull <>
相当于
git fetch
与git merge
相继作用的效果
即不光下载远程内容并把本地仓库远程分支指向最新节点,同时将当前所在分支指向这一节点[疑问]5【疑问】8
git pull origin foo
相当于git pull origin foo; git merge o/foo
git pull origin bar~1:bugFix
相当于git fetch origin bar~1:bugFix; git merge bugFix
只关心提交最终合并到哪里
git pull --rebase
相当于
git fetch
+git rebase <远程分支>
向远程仓库推送内容
git push <remote> <place>
以上为
push
命令的标准表述git push <远程仓库名称> <要推送的本地分支名>
可以直译为“将本地分支A推送到远程仓库1”
向指定远程仓库推送指定的本地分支的提交记录,并更新本地仓库中与指定本地分支相关联的远程分支[疑问已解决]7
[疑问]2git push <远程仓库名称> <源节点>:<远程目标分支>
如果在远程仓库不存在指定的目标分支,则Git会在远程仓库自行创建一个新的分支
git push <远程仓库名称> :<远程目标分支>
删除指定的远程分支
进阶命令
整理提交记录
git cherry-pick <指定节点> [指定节点] ...
(cherry-pick意为“精挑细选”)可以在一条命令中指定多个节点为执行对象(好像需要是节点的哈希值)可以是提交树上任意位置的节点[疑问]6,但不能是当前节点上游的节点
命令的作用顾名思义,是选中指定节点,并按顺序将节点副本顺次附加到当前所在节点(HEAD)之后
或许这个命令可以直译为“精选”命令
交互式rebase
git rebase -i <分支名/节点/HEAD>~[数字]
使用参数
--interactive
(简写为-i
)
尝试了一下,好像只能用HEAD作为索引?(经验证,不是)
数字n代表包括HEAD所在节点向上的n个节点
打开一个rebase UI界面- 调整提交记录的顺序(通过鼠标拖放)
- 删除不想要的提交
- 合并提交
描述节点
git describe <索引>
作用是输出关于离
[索引]
最近的标签的信息
“最近”的意思仅限于同一条分支(有待验证)<索引>
指所有可以指向具体节点的值,官方表述为“任何能被 Git 识别成提交记录的引用”
若不指定具体节点,则作用于当前节点(HEAD)
注意事项
节点哈希值基于 SHA-1,共 40 位
分支名/HEAD等本质上类似一个指针,指向某个节点
具体讲,分支名指向当前分支的最新节点;而HEAD指向当前状态实际所在的节点
同时,git checkout [分支名/标签名/节点哈希值]
命令的本质是移动HEAD指针的指向本地仓库里的远程分支,或者说远程仓库分支对应的本地分支名(如果存在)不能手动移动。只有在与远程仓库同步时才能够自动修改。
疑问
既然可以用rebase UI直接对节点重排,那各个提交记录到底是记录的“变化”还是文件本身的快照啊?
如果只是变化的话,重拍之后怎么可能还可以正确应用呢?
尝试了一下,
git rebase -i [索引]
好像只能用HEAD作为索引?不必。索引均可。
对提交进行重排之后,所有后续节点都会产生相应改变?还是说因为记录的都是“变化”,所以改变内容不影响后续?
实际工作环境是否存在“本地仓库的远程分支”这一说法?
在“远程跟踪”一节提到了,确实存在。
原话如下:1
2
3当你克隆时, Git 会为远程仓库中的每个分支在本地仓库中创建一个远程分支(比如 o/master)。然后再创建一个跟踪远程仓库中活动分支的本地分支,默认情况下这个本地分支会被命名为 master。
克隆完成后,你会得到一个本地分支(如果没有这个本地分支的话,你的目录就是“空白”的),但是可以查看远程仓库中所有的分支(如果你好奇心很强的话)。这样做对于本地仓库和远程仓库来说,都是最佳选择。本地仓库有,而远程仓库没有的分支能否推送到远程端并自动创建一个新分支?
1. 如果当前没有指向具体分支,而是分离HEAD状态呢? ↩
2. 本地仓库有,而远程仓库没有的分支能否推送到远程端并自动创建一个新分支? ↩
3. 是否能够不指定“远程分支名”,从而默认关联某一远程分支 ↩
4. 没懂,看完再看一下。 ↩
5. 但是不更新在本地的远程分支?比如o/master
,不会改变? ↩
6. git cherry-pick
命令的作用对象是否可以是任意节点(除当前分支的上游节点外)? ↩
7. 若关联的本地分支与远程分支名称不一致,则在push
命令中是以远程分支名为准吗?试一试。(顺便试一试脚注的冒号用中文冒号行不行) ↩
显然,中文冒号不行
经试验,push
命令中指定的分支名以本地分支为准
故可以直译为“将本地分支A推送到远程仓库1”
8. 是否仅限于当前分支?试一试 ↩
9. 应该也是对应于push
命令,fetch
则以远程分支名为准,将指定的远程分支的记录全部拉取到本地与之相关联的分支上。试一试 ↩
单独的fetch
会更新本地仓库的远程分支吗?试一试
10. 若当前指向一个具体节点而不是某一个分支名呢?即处在分离HEAD状态,且可以更进一步,HEAD指向的节点没有其他任何分支同时指向,会发生什么? ↩
单纯移动HEAD?