git diff
比较区别
1,当工作区有改动的时候,临时区为空(没有进行git add),那么diff的对比是和上次的commit的记录进行对比的。
2,当工作区有改动,临时区有东西的时候,diff是和临时区进行比较的。
git remote的相关命令
git remote命令让我们可以创建, 查看, 删除一个到其他仓储的连接。
用法
-
git remote
列出来你的仓储有哪些远程连接. -
git remote -v
和上面的命令类似, 但是他列出了每个连接的url地址. -
git remote add <name> <url>
创建一个到远程仓储的连接. 添加后你可以使用<name>做为<url>的一个别名. -
git remote rm <name>
删除一个远程连接 -
git remote rename <old-name> <new-name>
修改远程连接的别名. -
git remote set-url origin <URL>
更换远程仓库地址。把<URL>更换为新的url地址。
git pull 与 git clone的区别
从字面意思理解,都是往下拉代码,git clone是克隆,git pull 是拉。
但是,也有区别:
从远程服务器克隆一个一模一样的版本库到本地,复制的是整个版本库,叫做clone.(clone是将一个库复制到你的本地,是一个本地从无到有的过程)
从远程服务器获取到一个branch分支的更新到本地,并更新本地库,叫做pull.(pull是指同步一个在你本地版本对应的远程库内容更新的部分到你的本地库)
git pull
git pull命令的作用是,取回远程主机某个分支的更新,再与本地的指定分支合并。
完整格式:$ git pull <远程主机名> <远程分支名>:<本地分支名>
完整格式举例:比如,取回origin主机的next分支,与本地的master分支合并,需要写成下面这样,
- $ git pull origin next:master:如果远程分支是与当前分支合并,则冒号后面的部分可以省略。
- $ git pull origin next:上面命令表示,取回origin/next分支,再与当前分支合并。实质上,这等同于先做git fetch,再做git merge。
$ git fetch origin
$ git merge origin/next
在某些场合,Git会自动在本地分支与远程分支之间,建立一种追踪关系(tracking)。比如,在git clone的时候,所有本地分支默认与远程主机的同名分支,建立追踪关系,也就是说,本地的master分支自动”追踪”origin/master分支。
Git也允许手动建立追踪关系,git branch --set-upstream master origin/next
上面命令指定master分支追踪origin/next分支。如果当前分支与远程分支存在追踪关系,git pull就可以省略远程分支名。
git pull origin
上面命令表示,本地的当前分支自动与对应的origin主机”追踪分支”(remote-tracking branch)进行合并。
如果当前分支只有一个追踪分支,连远程主机名都可以省略。
get clone
远程操作的第一步,通常是从远程主机克隆一个版本库,这时就要用到git clone命令。
- $ git clone <版本库的网址>
比如,克隆jQuery的版本库。
$ git clone https://github.com/jquery/jquery.git
该命令会在本地主机生成一个目录,与远程主机的版本库同名。如果要指定不同的目录名,可以将目录名作为git clone命令的第二个参数。
- $ git clone <版本库的网址> <本地目录名>
git clone支持多种协议,除了HTTP(s)以外,还支持SSH、Git、本地文件协议等,下面是一些例子。
$ git clone http[s]://example.com/path/to/repo.git/
$ git clone ssh://example.com/path/to/repo.git/
$ git clone git://example.com/path/to/repo.git/
$ git clone /opt/git/project.git
$ git clone file:///opt/git/project.git
$ git clone ftp[s]://example.com/path/to/repo.git/
$ git clone rsync://example.com/path/to/repo.git/
- SSH协议还有另一种写法。
$ git clone [user@]example.com:path/to/repo.git/
通常来说,Git协议下载速度最快,SSH协议用于需要用户认证的场合。
分支的相关命令
-
git branch
查看有几个分支 -
git branch branchA
创建分支 -
git checkout branchA
切换分支 -
git merge branchA
合入分支代码 -
git branch -d branchA
删除分支 -
git checkout -b dev
此处其实是两步git branch dev加上git checkout dev
使用git 配置用户名和邮箱
- git config --global user.name [username]
- git config --global user.email [email]
如果你传递了 --global 选项,则Git将总是会使用该信息来处理你在系统中所做的一切操作。如果你希望在一个特定的项目中使用不同的名称或e-mail地址,你可以在该项目中运行该命令而不要--global选项。
使用git config --list
查看已设配置
- git查看用户名和邮箱地址
$ git config user.name
$ git config user.email
git log --graph
-graph标记会画出一个ASCII图展示commit历史的分支结构
处理冲突
git rebase处理冲突
假定采用的是git rebase,则处理过程为:
-
git rebase dev
将dev上的c2、c5在master分支上做一次衍合处理
git提示出现了代码冲突,此处为之前埋下的冲突点,处理完毕后 -
git add readme
添加冲突处理后的文件 -
git rebase --continue
加上--continue参数让rebase继续处理
git rebase的特点
(交互式) 使用rebase命令合并分支,解决完冲突,执行git add
.和git rebase --continue
,不会产生额外的commit。
这样的好处是,‘干净’,分支上不会有无意义的解决分支的commit;
坏处,如果合并的分支中存在多个commit,需要重复处理多次冲突。
git merge 处理冲突
(一股脑)使用merge命令合并分支,解决完冲突,执行git add .和git commit -m'fix conflict'。这个时候会产生一个commit。
注意
1、我自己尝试merge命令后,发现:merge时并没有产生一个commit。不是说merge时会产生一个merge commit吗?
注意:只有在冲突的时候,解决完冲突才会自动产生一个commit。
如果想在没有冲突的情况下也自动生成一个commit,记录此次合并就可以用:git merge --no-ff命令。
merge和rebase的区别
参考: merge和rebase的区别
补充:
- 当我们使用Git log来参看commit时,两者commit的顺序也有所不同。
- 用merge确实只需要解决一遍冲突,比较简单粗暴;用rebase有时候会需要多次fix冲突(原因在于本地分支已经提交了非常多的commit,而且很久都没有和上游合并过)
rebase和merge的使用场景
两个使用场景是不一样的,merge只是合并另外一个分支的内容,rebase也合并另外一个分支的内容,但是会把本分支的commits顶到最顶端
另外,单独使用rebase,还有调整当前分支上commits的功能(合并,丢弃,修改commites msg)
参考:https://www.zhihu.com/question/36509119/answer/67828312
git stash和git stash pop
场景:工作一半修线上bug时使用
git stash 可用来暂存当前正在进行的工作, 比如想pull 最新代码, 又不想加新commit, 或者另外一种情况,为了fix 一个紧急的bug, 先stash, 使返回到自己上一个commit, 改完bug之后再stash pop, 继续原来的工作。
pull request 功能
- code review
- communication
当你想更正别人仓库里的错误时,要走一个流程:
- 先 fork 别人的仓库,相当于拷贝一份,相信我,不会有人直接让你改修原仓库的
- clone 到本地分支,做一些 bug fix
- 发起 pull request 给原仓库,让他看到你修改的 bug
- 原仓库review 这个 bug,如果是正确的话,就会 merge 到他自己的项目中
参考:https://www.zhihu.com/question/21682976
fork功能
fork 别人的仓库到自己的github账号下,相当于拷贝一份
git revert和git reset head
git revert
git revert 是生成一个新的提交来撤销某次提交,此次提交之前的commit都会被保留
git revert <commit log string>是撤消该commit,作为一个新的commit。
git reset
现在我们启动时光穿梭机,准备把readme.txt回退到上一个版本:
首先,Git必须知道当前版本是哪个版本,在Git中,用HEAD表示当前版本,也就是最新的提交
上一个版本就是HEAD^
,上上一个版本就是HEAD^^
,当然往上100个版本写100个^比较容易数不过来,所以写成HEAD~100。
所以git reset head^
就是回退到上一个版本。
git reset的相关参数
除了在当前分支上操作,还可以通过传入这些标记来修改你的缓存区或工作目录:
--soft – 缓存区和工作目录都不会被改变
--mixed – 默认选项。缓存区和你指定的提交同步,但工作目录不受影响
--hard – 缓存区和工作目录都同步到你指定的提交
注意
- 当你传入HEAD以外的其他提交的时候要格外小心,因为reset操作会重写当前分支的历史。正如Rebase黄金法则所说的,在公共分支上这样做可能会引起严重的后果。
- 使用git reset是不影响远程分支的,一切都在本地发生。
总结:
-
HEAD
指向的版本就是当前版本,因此,Git允许我们在版本的历史之间穿梭,使用命令git reset --hard commit_id
。 -
穿梭前,用
git log
可以查看提交历史,以便确定要回退到哪个版本。 -
要重返未来,用
git reflog
查看命令历史,以便确定要回到未来的哪个版本。
git reset head
参考:https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000/0013744142037508cf42e51debf49668810645e02887691000
网友评论