git基操
一.git 简介
区块解释
- 工作区:就是你现在写代码的地方,
- 暂存区:在工作区修改的记录保存的地方
- 本地版本库: 暂存区通过
commit
命令,将暂存区的东西生成commit,可以推送到远端- 远端版本库: 服务器上和本地版本库一模一样的仓库
注:
工作区和暂存区通信,暂存区和本地版本库通信,本地版本库和远端版本库通信
工作区不能和远端直接进行通信,暂存区也不能和远端直接进行通信
fast forward
顾名思义:就是最快的前进方式
解释:git 默认的merge方式.将dev分支合并到master分支时,master分支的指针直接指向dev的commit
优点:快
缺点:当删除dev分支后,会丢掉分支信息
解决办法:(不常用)使用git merge --no-ff dev
,这样的话master会生成一个新的commit,不会直接使用dev的commit
HEAD(
对应的文件存储在./git/HEAD ref: refs/heads/master
)
- 有一个分支master,master的指针指向该分支的最新commit,HEAD指向master,也就是说HEAD是指向指针的指针
当然:HEAD指针不仅可以指向分支,也可以指向tag和commit.
内部实现:
- tag的内部是commit,可用
git cat-file
查看- 分支的内部其实也是commit
所以,HEAD其实指向的都是commit
branch(
对应的文件存储在./git/branchs
)
- branch其实是由commit组成的一条链表,每个链表都有自己的tree和parent commit,都可以通过父节点找到上一个commit
- 新建dev分支,就是新建一个dev指针指向最新commit,然后HEAD再指向dev
- 切换分支其实就是把HEAD从master更新到dev
git 后悔药
git restore <文件>...
解释:该文件还没有加入到暂存区,使用该命令可以丢掉你在工作区的改动git checkout --file
--作用对象为工作区
解释:该文件已经加入到暂存区,现在你在工作区对该文件进行修改,但还没有执行git add
操作,这时可以使用该命令将暂存区的内容替换工作区的内容,也就是说删掉基于该暂存的内容改动(没有执行git add
操作是重点)git reset HEAD --file
--作用对象为暂存区
解释:当你执行完git add
后,可以使用该命令丢弃掉基于上个暂存的的暂存内容,并将丢掉的这部分暂存恢复到工作区演示:stage为暂存区,现在workspace工作区test.md +加了 love字段
第一种情况:执行git checkout --file
,那么会将stage的内容替换到workspace中,也就是删除掉了love字段
第二种情况:执行git add test.md
将love加入暂存区,那么可以使用git reset HEAD --file
丢掉love这个暂存,并将丢掉的暂存恢复到工作区,也就是说工作区回到了添加love这个字段的状态
二.git config设置
-
git config --global user.name 'lyk'
设置姓名 -
git config --global user.email 'lyk@163.com'
设置邮箱 -
git config --global --list
查看已经设置的内容
注:
其中--global
可以替换为--local
--system
, 他们用法一样,作用域不一样.
--local
只针对某个git仓库
--global
针对当前用户的所有仓库
--system
针对系统所有的登录用户有效
如果多次设置产生冲突,那么有效顺序为--local
>--global
>--system
可以在.git/config文件下找到我们通过命令行命令设置的姓名、邮箱等
三.git 常用命令
-
git help --web log
查看帮助
本地
-
git init
创建仓库(包含.git),使用 ls -ah可以查看隐藏文件 -
git add 需要添加的文件
添加文件到git的暂存区 -
git commit -m "修改的内容"
提交到git暂存区,需要填写你修改了哪些东西 -
git commit -am "修改的内容"
== add.+commit的集合(简写而已) -
git commit --amend
修改最近一次commit提交的内容 -
git rebase -i commit的id
修改某次commit提交的内容(可以合并多个commit) -
git status
查看git的状态 -
git blame 文件
查看文件的修改记录 -
git mv 旧文件名 新文件名
git mv 命令用于移动或重命名一个文件、目录、软连接。 -
git diff
工作区和暂存区的不同 -
git diff 被修改的文件
查看文件被修改的地方 -
git diff commit1
工作区和commit(版本库)的不同,commit可以换成HEAD -
git diff commit1 commit2 --文件
对比两个commit的不同之处(可以针对某几个文件) -
git diff branch1 branch2
对比两个分支的不同之处(其实分支也是commit) -
git diff HEAD HEAD^
或者git diff HEAD HEAD~1
对比当前commit和其父commit之间不同 -
git diff --cached
对比暂存区和HEAD(即上一个commit)的不同,默认HEAD,可换成commitID -
git log
查看当前分支提交的日志 -
git log --oneline
快速查看当前分支日志 -
git log refs/remotes/origin/master
查看远程分支日志 -
git log -3
查看3跳日志 -
git log -a
或者git log --all
查看所有分支的提交日志 -
git log --graph
图形化结构查看当前分支日志 -
git log --oneline --graph
组合命令,快速并且图形化结构查看当前分支日志 -
git reset HEAD
清除暂存区的内容,恢复到和HEAD的内容一样 -
git reset HEAD -- 文件
清除暂存区某个文件的内容,恢复到和HEAD的内容一样 -
git reset --hard HEAD^
分支退回到上个版本(git reset --hard HEAD~100,退回到100个版本) -
git reset --hard 版本id
分支退回到指定的版本 -
git reflog
记录你每一次操作HEAD的命令日志 -
git revert??????
-
git checkout ."
或者"git checkout -- <file>
用git暂存区全部或指定的文件替换工作区的文件。这个操作很危险,会清除工作区中未添加到暂存区的改动。 (就是丢弃工作区的相对于暂存区的修改,也就是基于该暂存区的修改) -
git rm 文件
将文件从工作区已跟踪文件清单中移除,相当于rm + git add
如果想撤销的话, -------------
1step(先使用git reset HEAD 文件
删除rm操作这个新的暂存内容,并将改暂存内容恢复到工作区),然后
2step(使用git checkout --文件
将暂存区的内容替换到工作区,也就是取消了rm操作) -
git rm -f <file>
如果删除之前修改过并且已经放到暂存区域的话,则必须要用强制删除选项 -f -
git rm --cached <file>
直接从git暂存区删除文件,工作区则不做出改变 -
git cherry-pick 4c805e2
将commit嫁接到当前分支 -
git stash
保存工作区的修改 -
git stash list
查看stash列表 -
git stash pop
恢复工作区的修改, 从stash列表中移除最近的stash -
git stash apply
恢复工作区的修改, 不移除, 依然保留该stash -
git stash apply stash@{0}
恢复指定的stash到工作区中 -
git stash drop stash@{0}
从stash列表中移除指定stash -
git cat-file -t
查看git文件的类型 -
git rerere
可以重放commit之前的操作(rebase时可以使用)
远程仓库
-
git remote add origin git@github.com:xx.git
关联远程仓库(origin是远端的名字,不一定叫origin, 以后就可以用origin这个简写代替git仓库地址) -
git push -u origin master
把本地分支提交到远程master -
git clone git@xx.git
克隆远程仓库 -
git remote -v
查看远程仓库信息 -
git fetch
从远程拉取分支 -
git pull
等于git fetch+merge
,从远程抓取分支并和本地的分支合并 -
git push origin src:dest
git push的非缩写版本,src代表本地分支,dest目标远程分支 -
git pull origin src:dest
git pull的非缩写版本,src代表远程分支,dest代表本地分支(和push相反)
分支
-
git branch
查看本地分支,分支前面带*代表当前分支 -
git branch -a
查看所有的分支,包括本地和远程的分支 -
git branch -vv
查看本地分支,并附带最后一条commit记录 -
git branch 分支
创建分支 -
git checkout 分支
切换分支 -
git checkout -b 分支
创建并切换分支 -
git checkout --track origin/分支
创建并切换分支,分支名与远端一样(上个命令的简写,但是不能自定义分支名) -
git checkout -b 新分支 基于的分支(可以是远端分支)
基于某个分支上创建新的分支,并切换到新分支 -
git merge 分支
合并某分支到当前分支 -
git merge --allow-unrelated-histories 分支
强制合并没有关联的两个分支 -
git branch -d 分支
删除某分支 -
git branch -D 分支
强制删除某分支 -
git push origin 空格:远程分支名称
删除远程分支(空格替换远程分支,相当于删除) -
git push origin --delete 远程分支名称
删除远程分支
标签
-
git tag v1.0
默认打在最新的commit -
git tag v2.0 67786678
给某一次commit打标签 -
git tag -a v1.0 -m 注释
打标签&加上提示 -
git tag
查看标签 -
git tag -d
删除本地标签 -
git push origin 空格:refs/tags/v1.0
删除远程标签 -
git push origin --delete tag v1.0
删除远程标签 -
git show v1.0
查看标签信息 -
git push origin v1.0 v2.0
将标签推送到远端,可以同时推送多个 -
git push origin --tags
将所有标签推送到远端 -
git push origin refs/tags/v1.0:refs/tags/v1.0
推送tag完整写法
四.安装gitk
使用gitk图形化界面来查看git
brew update
brew install git
brew install git-gui
使用方法:gitk
或者gitk --all
使用gitk -a &
可以开启多线程,这样终端和wish都可以使用
六. git 技巧
组合搜索
github组合搜索:搜索自己想要的仓库时,可以在搜索内容例如deepfeak
加上文件名称,
例如deepfeak in:readme
, --------------------------------------搜索出来的是仓库
例如:从文件名中搜索想要的字段deepfeak filename:readme.txt
,--搜索出来的是code
例如:筛选星数deepfeak stars>:100
,
或者直接使用高级搜索
远端的pull request设置
可以在github上设置pull request的选项
如果设置为merge
,则自动合并分支
如果设置为aquash and merge
,则自动整个多个commit为一个commit并cheery-pick到合并的分支
如果设置为rebase and merge
,则将多个commit用cheery-pick到合并的分支(如果多个commit有冲突,设置为rebase则有可能merge失败.所以还是squash更安全一点)
- squash和rebase都可以使merge操作变成线性的,但是rebase保留了多个commit,而squash只保留了整合后的一个commit
七.git 问题
-
分离头指针的问题
解释:HEAD指针和目前你的工作区的内容不一致就会出现detached HEAD
state(例如在master上使用git checkout -commit
)
解决办法:使用git branch newBranch 3d4fed
创建一个以3d4fed commit为基准的新分支newBranch,最后merge到master分支上
- 如果已经丢失,可用
git reflog
查看提交记录,参考:https://www.jianshu.com/p/91a0f8feb45d
- git对比svn?
git本地存在版本库,而svn是集中式的管理系统,只有服务器有版本库. - gitlab和github都支持CI/CD(持续继承,持续交付)功能,类似jinkens.
- git submodule的用处
我觉得可以搞搞组件化,以后可以试试 0.0