Git装置
linux
$ sudo yum install git
mac: http://git-scm.com/download/mac
windows: http://git-scm.com/download/win
git官网文档: https://git-scm.com/book/zh/v2
Git装置完之后,须要做最初一步配置,如果你没有做这项配置,是没有git公钥和私钥的,而上传代码到近程仓库的时候须要秘钥进行验证是否自己上传的,想要创立能够应用上面的办法:
关上git bash,别离执行以下两句命令git config --global user.name “用户名”git config --global user.email “邮箱”
config 的三个作用域
--local 只对某个仓库无效--global 对以后用户所有仓库无效--system 对系统所有登录的用户无效--list
SSH配置
- 关上git bash。
- 应用
cd ~/.ssh
能够查看是否已配置SSH。 - 执行生成公钥和私钥的命令
ssh-keygen -t rsa
并按回车3下(为什么按三下,是因为有提醒你是否须要设置明码,如果设置了每次应用Git都会用到明码,个别都是间接不写为空,间接回车就好了)。会在一个文件夹外面生成一个私钥 id_rsa和一个公钥id_rsa.pub。(可执行start ~
命令,生成的公私钥在 .ssh的文件夹外面)。 - .ssh如果不做非凡解决的话,个别是在
C:\Users\Administrator
目录下。如果看不到.ssh文件,能够应用ls -ah
指令查看暗藏文件夹即可,这是寄存秘钥的文件,关上这个文件会看到id_rsa和id_rsa.pub。id_rsa是私钥文件,id_rsa.pub是公钥文件。 - 执行查看公钥的命令
cat ~/.ssh/id_rsa.pub
。
建Git仓库
两种场景:
1.把已有的我的项目代码纳入Git治理
cd 我的项目代码所在的文件夹git init
2.建设新的我的项目间接用Git治理
cd 某个文件夹git init your_project #会在以后门路下创立和我的项目名雷同的文件夹cd your_project
mkdir 创立目录echo "" > 文件名 创立文件clear 清屏
在仓库中增加文件
1.将文件拷贝到工作目录
cp ... .
2.测试文件符合要求后增加到暂存目录
git add filesgit add -u 所有文件
3.查看文件是否被git治理
git status
4.提交暂存区的文件
git commit -m'更改理由' -am'..'从工作区间接提交
git add 更新将要提交的内容git restore 放弃工作目录中的更改git rm 移除
Git和其余版本控制系统如SVN的一个不同之处就是有暂存区的概念。
工作区(Working Directory)
就是你在电脑里能看到的目录,比方我的learngit
文件夹就是一个工作区
版本库(Repository)
工作区有一个暗藏目录.git
,这个不算工作区,而是Git的版本库。
Git的版本库里存了很多货色,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为咱们主动创立的第一个分支master
,以及指向master
的一个指针叫HEAD
。
git add
把文件增加进去,实际上就是把文件批改增加到暂存区;
git commit
提交更改,实际上就是把暂存区的所有内容提交到以后分支。
给文件重名名
git mv old new操作完后commit提交
查看版本历史,提交日志
git log -n5 --oneline 最近5条 扼要 git log --all --graph 所有分支 图像化关系
版本历史图形化工具
gitk
查看分支git branch -v创立分支git checkout -b 分支名 commitid切换分支git checkout 分支名
查看某个命令的帮忙文档
git help --web 命令 --web 在网页
.git目录
HEAD文件:指向了当初援用的分支
cat HEADref: refs/heads/master
config文件:记录了用户的信息
refs/:援用目录,蕴含了heads和tags目录
tags:标签 里程碑,我的项目开发到肯定水平,给commit打一个标签如[v1.0]
标签文件是tag类型 自身有一个40位的哈希值 ,内容蕴含了一个commit的类型的object
heads:分支,如前后端建设独立的分支,互不影响,须要集成时可合并到一个公共的分支
查看文件对象类型
cat 分支文件git cat-file -t 哈希值-p 看内容如果哈希值足以保障唯一性能够应用短的一部分
master文件为commit类型
git branch -av查看分支能够看到master分支援用指针就是heads目录中master文件的哈希值
objects/:所有文件对象
git在每次commit的时候都会生成一个tree对象、一个parent对象(如果不是第一次提交的话)、和一个commit对象,这个最顶层的tree就是对应整个工作目录,tree上面还有blob、tree对象,都是一串hash值指向对应的内容,当某个文件产生变动的时候会从新保留一次快照(hash),如果文件没有产生变动,保留的快照仍然是上次的。
涣散对象 (loose object) 会被打包到pack/目录
查看文件对象类型 为:tree
git cat-file -t 文件名+哈希值
查看内容 蕴含一个blob文件,就是提交的内容
git cat-file -p 文件名+哈希值
git对象彼此的关系
每一次提交都会创立一个commit对象,一个commit对象对应蕴含一个tree对象,tree代表了以后工夫点仓库目录构造的快照,blob指具体的文件,在git中如果两个文件内容雷同就看作一个文件,不管文件名
git拆散头指针
如果不小心通过git checkout命令切换到某个commit中(即HEAD指向某个commit),git会提醒咱们正处于拆散头指针的状态下(工作在没有分支的状况下),如果咱们做了大量的批改,然而某天咱们忽然又切换到另一个commit时,咱们的批改就有可能被git当做垃圾革除掉,因而这个动作非常危险。
拆散头指针的用途:进行尝试性的变更时
试着批改某些文件时,如果感觉批改的成果不称心,能够间接切换到别的分支,抛弃以后批改
如果咱们切换进来时,感觉以后的批改非常重要,就依照git的提醒创立一个新分支
如果某个变更(提交)是十分重要的,那么肯定要跟某个分支绑定在一起
创立新分支:git checkout -b 新分支名称 基于某个分支或者commiteg:git checkout -b newBranch master比拟某两个commit的区别git diff 第一个commit 第二个commiteg:git diff HEAD HEAD^1 (以后的HEAD指向的commit和他的父级进行比对)HEAD^ ==HEAD~ == HEAD^1 == HEAD~1HEAD^^ == HEAD^1^1 == HEAD^2
删除不须要的分支
git branch -D 分支名
批改commit的message
对最近一次commit的message做变更
git commit --amend
更改之前的message
git rebase -i 需更改commit的父级id 执行后进入编辑,把须要批改的一次message后面的'pick'改为'r'或'reword',保留退出,会跳转到批改message
合并多个间断的commit
git rebase -i 父级commitid执行后进入编辑,仅保留要合并到的commit的'pick',把须要须要合并的几个'pick'改为's'或'squash',退出保留,批改阐明
合并多个距离的commit
首先git log --graph
查看commit历史
变基git rebase -i 父commitid
进入vi
将父commitid拷贝进来并扭转程序,放在要合并的commit下面
要合并的commit的'pick'改为's'
pick acf475ed #父commits 7ac3c1cb8b92 #要合并的commit...其余
保留退出后报错:interactive rebase in progress; onto 7ac3c1c
而后执行git rebase --continue
持续变基,进入vi
怎加一个message,保留退出即可
其余参考:https://segmentfault.com/a/11...
git解决合并抵触
什么是合并抵触
在 Git 中,“合并(merging)” 是在模式上整合别的分支到你以后的工作分支的操作。你须要失去在另外一个上下文背景下的改变(这就也就是咱们所提到过的,一个无效的分支应该是建设在一个上下文工作背景上的),并且合并它们到你的以后的工作文件中来。
作为你的版本管理系统,Git 所带来的最平凡的改善就是它让合并操作变得十分轻松简略。在大多数状况下,Git 会本人弄清楚该如何整合这些新来的变动。
当然,也存在极少数的状况,你必须本人手动地通知 Git 该怎么做。最为常见的就是大家都改变了同一个文件。即使在这种状况下,Git 还是有可能主动地发现并解决掉这些抵触。然而,如果两个人同时更改了同一个文件的同一行代码,或者一个人改变了那些被另一个人删除了的代码,Git 就不能简略地确定到底谁的改变才是正确的。这时 Git 会把这些中央标记为一个抵触,你必须首先解决掉这些抵触,而后再持续你的工作。
如何解决合并抵触
当面对一个合并抵触时,咱们首先要搞明确产生了什么。例如是不是你和你的共事都同时编辑了同一个文件的同一行代码呢?是不是他删除了一个你正在编辑的文件呢?是不是你们同时增加了一个雷同文件名的文件呢?
当你应用 “git status” 时, Git 会通知你存在一个 “未合并的门路(unmerged paths)”,这只是用另外一个形式通知你,存在一个或多个抵触:
$ git status# On branch contact-form# You have unmerged paths.# (fix conflicts and run "git commit")## Unmerged paths:# (use "git add <file>..." to mark resolution)## both modified: contact.html#no changes added to commit (use "git add" and/or "git commit -a")1234567891011
就让咱们来深刻地探讨一下,如何去解决这些最常见的抵触。
当两个改变产生在同一个文件的同一些行上,咱们就要看看发生冲突的文件的内容了。Git 会十分敌对地把文件中那些有问题的区域在 “<<<<<<< HEAD” 和 “>>>>>>> [other/branch/name]” 之间标记进去。
第一个标记后的内容源于以后分支。在尖括号之后,Git 会通知咱们这些改变是从哪里(哪个分支)来的。而后有抵触的改变会被 “=======” 宰割起来。
当初,当清理文件并失去最终代码后,所有剩下的工作就是将这个后果保存起来,并且马上退出这个合并工具。这样 Git 就会晓得你曾经实现了这个操作。Git 会在后盾对那个文件主动地执行 “git add” 命令。这也标记着抵触曾经解决了。如果你不应用合并工具,而是手动在文本编辑器中清理这些抵触,你必须手动地将文件标记为已解决状态(通过执行命令 “git add ”)。
最终,当所有的抵触被解决后,你必须通过一个失常的提交操作来实现这个清理合并抵触的工作。
如何撤销一个合并
你应该始终牢记,你能够在任何工夫执行撤销操作,并返回到你开始合并之前的状态。要对本人有信念,你不会毁坏我的项目中的任何货色。只有在命令行界面中键入 “git merge –abort” 命令,你的合并操作就会被平安的撤销。
当你解决完抵触,并且在合并实现后发现一个谬误,你依然还是有机会来简略地撤销它。你只须要键入 “git reset –hard ” 命令,零碎就会回滚到那个合并开始前的状态,而后从新开始吧!
git status会有rebase in progress; onto ……这种问题? 该怎么解决?
是你之前或者刚刚用过 git rebase
,但上一次的过程还没有实现。
能够间接 git rebase --abort
来勾销目前的过程
比拟暂存区和HEAD所含文件的差别
git diff --cached
比拟工作区和暂存区所含文件的差别
git diffgit diff -- 可加具体文件名
让暂存区复原成和HEAD一样
git reset HEAD
让工作区复原为和暂存区一样
git checkout -- 文件名
勾销暂存区局部文件的更改
git reset HEAD -- 文件名
打消最近几次的提交
git reset --hard commitid(想回到的commit状态)
查看不同提交的指定文件的差别
git diff 分支名或commitid 分支名或commitid -- 指定文件
删除文件的正确做法
git rm 文件名
开发中长期加塞了紧急任务怎么解决
场景:开发中有一部分文件曾经放到了暂存区,一部分还在工作区批改当中,然而测试发现对应的分支是有问题的,须要长期修复bug
1.先把手头的工作备份到其余中央git stash
,能够用git stash list
查看
2.修复完bug提交后再复原持续
git stash apply
stash列表中寄存的文件仍会保留
git stash pop
stash列表中寄存的文件会移除
指定不须要Git治理的文件
gitHub新建仓库时会让你配置一个.gitignore
文件,针对不同的语言指定不被git治理的文件类型
只能够命名为.gitignore
如java
# Compiled class file*.class# Package Files #*.jar*.war*.tar.gz*.zip...
将Git仓库备份到本地
罕用的传输协定
哑协定与智能协定
直观区别:哑协定传输进度不可见,智能协定可见
传输速度:智能协定比哑协定块
举荐应用智能协定
备份特点:多点备份
如果要和远端的仓库进行关联的话,须要remote
git remote -v 查看git remote add 名字 地址 新建远端仓库
当本地仓库有新的分支,而远端并未增加进去时,间接push
git push 远端仓库
Git近程操作
git 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 remote
为了便于管理,Git要求每个近程主机都必须指定一个主机名。git remote
命令就用于治理主机名。
不带选项的时候,git remote
命令列出所有近程主机。
$ git remoteorigin
应用-v
选项,能够参看近程主机的网址。
$ git remote -vorigin git@github.com:jquery/jquery.git (fetch)origin git@github.com:jquery/jquery.git (push)
下面命令示意,以后只有一台近程主机,叫做origin,以及它的网址。
克隆版本库的时候,所应用的近程主机主动被Git命名为origin
。如果想用其余的主机名,须要用git clone
命令的-o
选项指定。
$ git clone -o jQuery https://github.com/jquery/jquery.git$ git remotejQuery
下面命令示意,克隆的时候,指定近程主机叫做jQuery。
git remote show
命令加上主机名,能够查看该主机的详细信息。
$ git remote show <主机名>
git remote add
命令用于增加近程主机。
$ git remote add <主机名> <网址>
git remote rm
命令用于删除近程主机。
$ git remote rm <主机名>
git remote rename
命令用于近程主机的改名。
$ git remote rename <原主机名> <新主机名>
git fetch
一旦近程主机的版本库有了更新(Git术语叫做commit),须要将这些更新取回本地,这时就要用到git fetch
命令。
$ git fetch <近程主机名>
下面命令将某个近程主机的更新,全副取回本地。
git fetch
命令通常用来查看其他人的过程,因为它取回的代码对你本地的开发代码没有影响。
默认状况下,git fetch
取回所有分支(branch)的更新。如果只想取回特定分支的更新,能够指定分支名。
$ git fetch <近程主机名> <分支名>
比方,取回origin
主机的master
分支。
$ git fetch origin master
所取回的更新,在本地主机上要用"近程主机名/分支名"的模式读取。比方origin
主机的master
,就要用origin/master
读取。
git branch
命令的-r
选项,能够用来查看近程分支,-a
选项查看所有分支。
$ git branch -rorigin/master$ git branch -a* master remotes/origin/master
下面命令示意,本地主机的以后分支是master
,近程分支是origin/master
。
取回近程主机的更新当前,能够在它的根底上,应用git checkout
命令创立一个新的分支。
$ git checkout -b newBrach origin/master
下面命令示意,在origin/master
的根底上,创立一个新分支。
此外,也能够应用git merge
命令或者git rebase
命令,在本地分支上合并近程分支。
$ git merge origin/master# 或者$ git rebase origin/master
下面命令示意在以后分支上,合并origin/master
。
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)进行合并。
如果以后分支只有一个追踪分支,连近程主机名都能够省略。
$ git pull
下面命令示意,以后分支主动与惟一一个追踪分支进行合并。
如果合并须要采纳rebase模式,能够应用--rebase
选项。
$ git pull --rebase <近程主机名> <近程分支名>:<本地分支名>
如果近程主机删除了某个分支,默认状况下,git pull
不会在拉取近程分支的时候,删除对应的本地分支。这是为了避免,因为其他人操作了近程主机,导致git pull
人不知;鬼不觉删除了本地分支。
然而,你能够扭转这个行为,加上参数 -p
就会在本地删除近程曾经删除的分支。
$ git pull -p# 等同于上面的命令$ git fetch --prune origin $ git fetch -p
git push
git push
命令用于将本地分支的更新,推送到近程主机。它的格局与git pull
命令相仿。
$ git push <近程主机名> <本地分支名>:<近程分支名>
留神,分支推送程序的写法是<起源地>:<目的地>,所以git pull
是<近程分支>:<本地分支>,而git push
是<本地分支>:<近程分支>。
如果省略近程分支名,则示意将本地分支推送与之存在"追踪关系"的近程分支(通常两者同名),如果该近程分支不存在,则会被新建。
$ git push origin master
下面命令示意,将本地的master
分支推送到origin
主机的master
分支。如果后者不存在,则会被新建。
如果省略本地分支名,则示意删除指定的近程分支,因为这等同于推送一个空的本地分支到近程分支。
$ git push origin :master# 等同于$ git push origin --delete master
下面命令示意删除origin
主机的master
分支。
如果以后分支与近程分支之间存在追踪关系,则本地分支和近程分支都能够省略。
$ git push origin
下面命令示意,将以后分支推送到origin
主机的对应分支。
如果以后分支只有一个追踪分支,那么主机名都能够省略。
$ git push
如果以后分支与多个主机存在追踪关系,则能够应用-u
选项指定一个默认主机,这样前面就能够不加任何参数应用git push
。
$ git push -u origin master
下面命令将本地的master
分支推送到origin
主机,同时指定origin
为默认主机,前面就能够不加任何参数应用git push
了。
不带任何参数的git push
,默认只推送以后分支,这叫做simple形式。此外,还有一种matching形式,会推送所有有对应的近程分支的本地分支。Git 2.0版本之前,默认采纳matching办法,当初改为默认采纳simple形式。如果要批改这个设置,能够采纳git config
命令。
$ git config --global push.default matching# 或者$ git config --global push.default simple
还有一种状况,就是不论是否存在对应的近程分支,将本地的所有分支都推送到近程主机,这时须要应用--all
选项。
$ git push --all origin
下面命令示意,将所有本地分支都推送到origin
主机。
如果近程主机的版本比本地版本更新,推送时Git会报错,要求先在本地做git pull
合并差别,而后再推送到近程主机。这时,如果你肯定要推送,能够应用--force
选项。
$ git push --force origin
下面命令应用--force
选项,后果导致近程主机上更新的版本被笼罩。除非你很确定要这样做,否则应该尽量避免应用--force
选项。
最初,git push
不会推送标签(tag),除非应用--tags
选项。
$ git push origin --tags