git 常用操作
本地操作
关于工作区和版本库
- 工作区,就是我们在本机上Git目录,我们直接修改文件的时候,所有的修改都只是在工作区。
- 暂存区(stage或者index),是版本库中的一部分。工作区中的修改需要通过git add添加到暂存区,这些修改在暂存区中等待被提交到版本库中形成版本。
- 分支,是版本库中的重要部分。初始情况下Git为我们自动创建了第一个分支master,我们之后创建的分支,以及所有分支里的所有提交形成的版本记录都保存在这里。
- HEAD指针,也是版本库中的重要部分。初始情况下它指向master,HEAD所指向的版本就是当前版本,也就是最新的提交。
用户名和邮箱地址的作用
用户名和邮箱地址是本地Git客户端的一个变量,不随git库而改变。
每次commit都会用用户名和邮箱纪录。
github的contributions统计就是按邮箱来统计的。
查看用户名和邮箱地址:
$ git config user.name
$ git config user.email
修改用户名和邮箱地址:
$ git config --global user.name "username"
$ git config --global user.email "email"
把当前目录变成Git可以管理的仓库
$ git init
查看仓库当前状态
$ git status
查看提交日志
$ git log 显示从最近到最远的提交日志
$ git log --graph 查看分支合并情况
$ git log --pretty=oneline 一行显示
$ git log --graph --pretty=oneline 一行显示分支合并情况
$ git log --graph --pretty=oneline --abbrev-commit 以简短的commit_id一行显示分支情况
abbreviation 缩写 缩写词
Git的commit id不是1,2,3…递增的数字,而是一个SHA1计算出来的一个非常大的数字,用十六进制表示.
查看不同difference
$ git diff #是工作区(work dict)和暂存区(stage)的比较
$ git diff --cached #是暂存区(stage)和分支(master)的比较
显示的格式正是Unix通用的diff格式
版本回退
工作区修改撤销
$ git checkout -- readme.txt
这里有两种情况:
一种是readme.txt自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态;
一种是readme.txt已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。
总之,就是让这个文件回到最近一次git commit或git add时的状态。
暂存区的撤销
针对已经 add到暂存区的情况
$ git reset HEAD readme.txt
把暂存区的修改回退到工作区,然后在执行工作区修改撤销
针对已经 add 和commit到分支上的情况
$ git reset --hard HEAD^
在Git中,用HEAD表示当前版本,上一个版本就是HEAD^,上上一个版本就是HEAD^^,
当然往上100个版本写100个^比较容易数不过来,所以写成HEAD~100。
也可以根据commit_id 跳到指定的版本
$ git reflog 查看命令历史 找到commit_id
$ git reset --hard commit_id 前往指定版本
提交文件到本地分支
#把文件添加到添加到暂存区stage
$ git add readme.txt
#把暂存区的所有内容提交到当前分支
$ git commit -m "wrote a readme file"
-m 后面输入提交说明
每次修改,如果不add到暂存区,那就不会加入到commit中
git commit只负责把暂存区的修改提交
文件删除
$ rm test.txt #删除工作区test.txt文件
如果误删 可以通过
$ git checkout -- test.txt 找回被删文件
删除仓库里的文件
$ git rm test.txt
如果误删 可回退版本 回退后本地仓库回到原来状态
文件储藏
测试文件 提交到本地仓库时 然后在git rm 仓库里还有没有这个文件
问题:
commit 后没有版本号
解:没有执行过add的原因
远程操作
or create a new repository on the command line
用命令行创建一个新仓库
git init
git add README.md
git commit -m "first commit"
git remote add origin https://github.com/julysiji/learnGit.git
git push -u origin master
or push an existing repository from the command line
用命令行推到现有的仓库
git remote add origin https://github.com/julysiji/learnGit.git
git push -u origin master
问题:
每次push 都需要重新输入账号密码才可以
解决:
删除之前的ssh 秘钥重新生成
删除之前填在github里面的ssh key
把新生成的ssh key 填入github
执行
$ git remote rm origin
$ git remote add origin git@github.com:用户名/库名.git
在执行
推送master分支到 名称是origin的远程仓库
$ git push -u origin master
时会跳出警告:
The authenticity of host 'github.com (xx.xx.xx.xx)' can't be established.
RSA key fingerprint is xx.xx.xx.xx.xx.
Are you sure you want to continue connecting (yes/no)?
SSH连接在第一次验证GitHub服务器的Key时需要确认GitHub的Key的指纹信息是否真的来自GitHub的服务器
输入yes回车
接着会再弹一个警告
Warning: Permanently added 'github.com' (RSA) to the list of known hosts.
Git输出一个警告,告诉你已经把GitHub的Key添加到本机的一个信任列表里了
OK解决
远程克隆
github 支持两种格式
ssh协议下
$ git clone git@github.com:julysiji/gitSkills.git
https协议下
https://github.com/michaelliao/gitskills.git
master分支是一条线,Git用master指向最新的提交,再用HEAD指向master,就能确定当前分支,以及当前分支的提交点
分支的创建合并和删除
$ git checkout -b dev 创建并切换到分支dev
也可以分为两步进行操作
$ git branch dev 创建分支dev
$ git checkout dev 切换到分支dev
切换到master 切换分支时需要把当前分支的改动 add后commit
$ git merge dev 合并dev 分支到master分支
合并分支时,Git会用Fast forward模式,但这种模式下,删除分支后,会丢掉分支信息.
如果要强制禁用Fast forward模式,Git就会在merge时生成一个新的commit
这样从分支历史上就可以看出分支信息.
准备合并dev分支,请注意--no-ff参数,表示禁用Fast forward
$ git merge --no-ff -m "merge with no-ff" dev
合并分支时 冲突的时候需要 修改后 进行add commit 然后在合并
$ git branch -d dev 删除dev分支
如果不想修改后再删除 也可以 直接强行删除
$ git branch -D dev
$ git merge --no-ff -m "merge with no-ff" dev
准备合并dev分支,请注意--no-ff参数,表示禁用Fast forward:
bug分支 工作区备份
当正在支线上进行的工作还没法提交 但是 必须在两个小时内修复一个bug 怎么办?
Git还提供了一个stash功能 可以把当前工作现场“储藏”起来 等以后恢复现场后继续工作
$ git stash
确定要在哪个分支上修复bug 假定需要在master分支上修复 就从master创建临时分支并修复bug
$ git stash list
显示Git栈内的所有备份,可以利用这个列表来决定从那个地方恢复。
恢复指定的stash
$ git stash apply stash@{0}
恢复有两个办法:
一是用git stash apply恢复 但是恢复后 stash内容并不删除
你需要用git stash drop来删除
另一种方式是用git stash pop 恢复的同时把stash内容也删了
多人协作
查看远程信息
$ git remote
查看远程详细信息
$ git remote -v
推送分支
$ git push origin master 推送master主分支到远程仓库origin
$ git push origin dev 推送dev分支到远程仓库origin
假设另外一个协同操作者从远程仓库clone
默认情况下只能看到master分支
$ git clone git@github.com:julysiji/gitSkills.git
如果需要在分支dev操作 需要创建远程分支到本地
$ git checkout -b dev origin/dev
当协同者push过分支后 本地自己push分支的时候会被拒绝提交提示有冲突
解决办法也很简单 Git已经提示我们 先用git pull把最新的提交从origin/dev抓下来
然后在本地合并 解决冲突 再推送 当我们执行
$ git pull
时也失败了,原因是没有指定本地dev分支与远程origin/dev分支的链接
根据提示 继续执行
$ git branch --set-upstream-to=origin/dev
多人协作常用模式
1.首先 可以试图用git push origin branch-name推送自己的修改
2.如果推送失败 则因为远程分支比你的本地更新 需要先用git pull试图合并
3.如果合并有冲突 则解决冲突 并在本地提交
4.没有冲突或者解决掉冲突后 再用git push origin branch-name推送就能成功
如果git pull提示“no tracking information”则说明本地分支和远程分支的链接关系没有创建 用命令git branch --set-upstream-to=origin/branch-name。
标签创建:
首先切换到需要打标签的分支上git tag <name>就可以打一个新标签
$ git tag v1.0
根据commit_id 打标签
$ git reflog 查看commit_id
$ git tag v0.9 6224937
$ git tag 查看tag 标签
$ git show v0.9 查看标签信息
创建带有说明的标签,用-a指定标签名,-m指定说明文字
$ git tag -a v0.1 -m "version 0.1 released" 3628164
还可以通过-s用私钥签名一个标签:
$ git tag -s v0.2 -m "signed version 0.2 released" fec145a
tag的删除 标签都只存储在本地 不会自动推送到远程 所以打错的标签可以在本地安全删除
$ git tag -d V1.0
推送某个标签到远程,使用命令
$ git push origin V1.0
一次性推送全部尚未推送到远程的本地标签
$ git push origin --tags
如果标签已经推送到远程,要删除远程标签就麻烦一点,先从本地删除
$ git tag -d V1.0
然后,从远程删除。删除命令也是push
$ git push origin :refs/tags/V1.0
git log 查看commit的历史
git show <commit-hash-id>查看某次commit的修改内容
git log -p <filename>查看某个文件的修改历史
git log -p -2查看最近2次的更新内容
http://www.jianshu.com/p/ed1f4bdbfb51
http://www.jianshu.com/p/40441281adc3
https://yq.aliyun.com/articles/3103