目录
基本概念
GIT & SVN 的区别
工作流程
协议
head和版本号
配置基本信息
局部配置
全局配置
基本命令
git clone
git add
git commit
git push
git fetch
git merge
git pull
状态检查命令
git status
git log
git reflog
逆向操作命令
git rm
git restore -S
git reset —soft
git reset —mixed
git reset —hard
git checkout -f
本地仓库整理命令
git commit -amend
git rebase
git stash
git clean
分支操作命令
查看分支
创建分支
合并分支
删除分支
GIT WORK FLOW
Git 是分布式的,SVN 不是:这是 Git 和其它非分布式的版本控制系统,例如 SVN,CVS 等,最核心的区别。
Git 把内容按元数据方式存储,而 SVN 是按文件:所有的资源控制系统都是把文件的元信息隐藏在一个类似 .svn、.cvs 等的文件夹里。
Git 分支和 SVN 的分支不同:分支在 SVN 中一点都不特别,其实它就是版本库中的另外一个目录。
Git 没有一个全局的版本号,而 SVN 有:目前为止这是跟 SVN 相比 Git 缺少的最大的一个特征。
Git 的内容完整性要优于 SVN:Git 的内容存储使用的是 SHA-1 哈希算法。这能确保代码内容的完整性,确保在遇到磁盘故障和网络问题时降低对版本库的破坏。
workspace:工作区
staging area:暂存区/缓存区
local repository:版本库或本地仓库
remote repository:远程仓库 别名: origin
GIT 使用4种协议: 本地协议(local)、HTTP协议、SSH协议、GIT协议
本地协议(暂不讨论,本公司中这部分主要使用cooper)
SSH 协议 同时支持读写操作的网络协议
Git 协议 网络协议 只读 不能写操作
HTTP 协议 :(不在服务器端运行Git) 网络协议 只读 不能写操作
SSH公钥获取:
判断是否已经存在:
cat ~/.ssh/id_rsa.pub
生成SSH-key:
ssh-keygen -o -t rsa -C "[email protected]" -b 4096
head : 当前检出记录的符号引用
版本号: sha1 哈希算法下的40位字符串, 但是我们在操作中,只使用前7位即可
git config user.name
git config user.email
git config —local -l
git config —global user.name
git config —global user.email
git config -l
从远程仓库下载一个项目。
workspace 保存文件到 staging area
git commit -m
将 staging area 保存文件到 local repository
git commit -amend
把当前暂存区里的内容合并到上一次commit里,而且还可以修改上一次提交的message信息.
之后需要使用 git push –fore 强制推送修改后的commit
local repository 推送文件到 remote
git push <远程主机名> <本地分支名>:<远程分支名>
将本地分支推送到远程分支,若不存在远程分支创建远程分支并关联
git push --set-upstream origin
删除指定的远程分支
git push origin :master # 等同于 git push origin --delete master
存在冲突
调用git pull去拉取分支下来,然后会在冲突的文件里记录冲突的内容,手动去解决冲突,然后 再git commit 和 git push。
将远程仓库所包含的分支的最新commit - id 记录到本地文件
git merge 操作是区分上下文的。当前分支始终是目标分支,其他一个或多个分支始终合并到当前分支。所以,当需要将某个分支合并到目标分支时,需要先切到目标分支上。
git merge --abort
当合并的过程中,由于冲突难解决,你想放弃合并,回到未合并之前的状态;
将远程仓库所包含的分支拉到本地,并进行合并
相当于git fetch + git merge
检查本地仓库状态
按条数
$ git log -3
按日期
$ git log --after="2018-7-1" # 2018年7月1好之后的所有日志 $ git log –-before="2014-7-1"
按作者
$ git log --author="Dounin"
按照提交信息 $ git log --grep=“issue” # 按照提交本中是否包含issue的日志
按文件 $ git log -- ./src/http/modules/ngx_http_xslt_filter_module.c
按照内容 $ git log -S “ngx_free” # 即所有文件中包含了 ngx_free字符串的修改
按照范围 $ git log
和git log 类似, 但是不遍历HEAD的祖先。它是HEAD所指向的一个顺序的提交列表:它的undo历史。reflog并不是repo(仓库)的一部分,它单独存储,而且不包含在pushes,fetches或者clones里面,它纯属是本地的。
git rm —cached
git rm
用来删除git add 添加到暂存区的文件
本地仓库 回退到暂存区
本地仓库 回退到工作区
本地仓库直接删掉该记录
使用暂存区数据覆盖工作区
把当前暂存区里的内容合并到上一次commit里,而且还可以修改上一次提交的message信息.
之后需要使用 git push –fore 强制推送修改后的commit
When performing a Rebase operation, Git extracts the changes on the base branch from the common ancestor of both branches, then points the base branch to the latest commit of the base branch, and finally applies the extracted changes after the latest commit of the base branch.
当执行rebase操作时,git会从两个分支的共同祖先开始提取待变基分支上的修改,然后将待变基分支指向基分支的最新提交,最后将刚才提取的修改应用到基分支的最新提交的后面。
rebase,变基,可以直接理解为改变基底。feature分支是基于master分支的B拉出来的分支,feature的基底是B。而master在B之后有新的提交,就相当于此时要用master上新的提交来作为feature分支的新基底。实际操作为把B之后feature的提交存下来,然后删掉原来这些提交,再找到master的最新提交位置,把存下来的提交再接上去(新节点新commit id),如此feature分支的基底就相当于变成了M而不是原来的B了。
commit 合并
先使用git log 找到commit 的hash 值
利用git rebase –i 【4cbeb4248f7】, -i后面的参数表示不要合并的commit的hash值
pick 的意思是要会执行这个 commit squash 的意思是这个 commit 会被合并到前一个commit
执行完git pull --rebase之后如果有合并冲突,使用以下三种方式处理这些冲突:
git rebase --abort 会放弃合并,回到rebase操作之前的状态,之前的提交的不会丢弃;
git rebase --skip 则会将引起冲突的commits丢弃掉(慎用!!);
git rebase --continue 合并冲突,结合"git add 文件"命令一起用与修复冲突,提示开发者,一步一步地有没有解决冲突。(fix conflicts and then run "git rebase --continue")
对上述冲突的处理
1、使用 $git rebase --abort
执行之后,本地内容会回到提交之间的状态,也就是回到以前提交但没有pull是的状态,简单来说就是撤销rebase。
2、使用 $git rebase --skip
git rebase --skip 引起冲突的commits会被丢弃,对于本文应用的例子来说开发者A对c.sh文件的commit无效,开发者A自己修改的部分全部无效,因此,在使用skip时请慎重。
执行:$ vim c.sh
查看本地c.sh文件提交内容,展示如下图所示,执行语句之后开发者A的修改无效。
3、使用 $git rebase --continue
执行完$git pull --rebase 之后,本地如果产生冲突,手动解决冲突之后,用"git add"命令去更新这些内容的索引(index),然后只要执行:
$ git rebase --continue 就可以线性的连接本地分支与远程分支,无误之后就回退出,回到主分支上。
stash的原理: 将本地没提交的内容(git commit的内容不会被缓存 但git add的内容会被缓存)进行缓存并从当前分支移除,缓存的数据结构为堆栈,先进后出。
重点:
stash 只会操作被git追踪的文件
git stash list,返回缓存的列表
git stash pop,将堆栈中最新的内容pop出来应用到当前分支上,且会删除堆中的记录,
如果pop出来的内容有冲突,git会中断此次pop并告知你需要进行冲突解决
git stash apply, 与pop相似,但他不会在堆栈中删除这条缓存,适合在多个分支中进行缓存
git stash drop/git stash clear,git stash drop [名]删除单个缓存 举例git stash drop stash@{0} git stash clear全清
git stash show, git stash show [名]显示与当前分支差异 举例git stash show stash@{0} 加上-p可以看详细差异
git stash branch, 指定或最新缓存创建分支
如果是有些内容已经存在工作区了,但是尚未提交到暂存区,即是untracked的内容,那么我们可以使用git clean命令来删除这些文件.
git clean –f :删除当前目录下所有没有track过的文件,他不会删除.gitignore文件里面指定的文件夹和文件,不管这些 文件有没有被track过。 git clean -f
git branch
git branch
git checkout -b
git checkout
git merge
git push origin master 推送到远端分支
git branch -d
git push origin -d
第一步:根据需求,从master拉出新分支,不区分功能分支或补丁分支。
第二步:新分支开发完成后,或者需要讨论的时候,就向master发起一个pull request(简称PR)。
第三步:Pull Request既是一个通知,让别人注意到你的请求,又是一种对话机制,大家一起评审和讨论你的代码。对话过程中,你还可以不断提交代码。
第四步:你的Pull Request被接受,合并进master,重新部署后,原来你拉出来的那个分支就被删除。(先部署再合并也可。)