您的位置:首页 > 其它

git学习笔记

2015-10-11 15:14 351 查看
Git的官方网站:http://git-scm.com概念:
工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库。
Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD。
为什么Git比其他版本控制系统设计得优秀,因为Git跟踪并管理的是修改,而非文件。安装:
msysgit是Windows版的Git,从http://msysgit.github.io/下载,然后按默认选项安装即可。安装完成后,在开始菜单里找到“Git”->“Git Bash”,蹦出一个类似命令行窗口的东西,就说明Git安装成功!安装完成后,还需要最后一步设置,在命令行输入:
$ git config --global user.name "Your Name"
$ git config --global user.email "email@example.com"
git config命令的--global参数,用了这个参数,表示你这台机器上所有的Git仓库都会使用这个配置,当然也可以对某个仓库指定不同的用户名和Email地址。
$ git config --global color.ui true #可以配置让Git显示颜色$ git config --list 显示$ git config -e [--global] 编辑创建版本库:git initgit init [project-name] 新建一个目录,将其初始化为git代码库把文件添加到版本库:(提交修改和提交新文件是一样的)
git add readme.txt
git commit -m "wrote a readme file"
例子:
$ git add file1.txt
$ git add file2.txt file3.txt
$ git commit -m "add 3 files."$ git add . [b]将项目的所有文件添加到仓库中[/b][b]$ git commit -m "wrote a readme file"[/b]$git commit -a 提交自上次commit之后的变化$git commit -v 显示diff信息查看文件修改:
如果git status告诉你有文件被修改过,用git diff可以查看修改内容。
git status:命令可以让我们时刻掌握仓库当前的状态
git diff:顾名思义就是查看difference,显示的格式正是Unix通用的diff格式。
$git diff HEAD -- readme.txt #交后,查看工作区和版本库里面最新版本的区别版本回退:
穿梭前,用git log可以查看提交历史,以便确定要回退到哪个版本:
$ git log #一大串类似3628164...882e1e0的是commit id(版本号)
$ git log --pretty=oneline #看得眼花缭乱的可以加上--pretty=oneline参数
$ git reset --hard HEAD^ #回退到上一个版本,HEAD表示当前版本,上一个版本是HEAD^,上上一个版本HEAD^^,往上100个版本HEAD~100
现在,你回退到了某个版本,关掉了电脑,第二天早上就后悔了,想恢复到新版本怎么办?
要重返未来,用git reflog查看命令历史,以便确定要回到未来的哪个版本:
$ git reflog
$ git reset --hard 3628164 #版本号没必要写全,前几位就可以了,Git会自动去找。当然如果Git找到多个版本号,就无法确定是哪一个了撤销修改:
$ git checkout -- readme.txt #只能撤销工作区的修改
命令git checkout -- readme.txt意思就是,把readme.txt文件在工作区的修改全部撤销,这里有两种情况:
一种是readme.txt自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态;
一种是readme.txt已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。
总之,就是让这个文件回到最近一次git commit或git add后的状态。$ git reset HEAD readme.txt #撤销暂存区
用命令git reset HEAD file可以把暂存区的修改撤销掉(unstage),重新放回工作区。git reset命令既可以回退版本,也可以把暂存区的修改回退到工作区。当我们用HEAD时,表示最新的版本。回退场景:
场景1:当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改时,用命令git checkout -- file。
场景2:当你不但改乱了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改,分两步,第一步用命令git reset HEAD file,就回到了场景1,第二步按场景1操作。
场景3:已经提交了不合适的修改到版本库时,想要撤销本次提交,参考版本回退一节,不过前提是没有推送到远程库。删除文件:
直接在文件管理器中把没用的文件删了,或者用rm命令删了
选择1:确认删除
$ git rm test.txt
$ git commit -m "remove test.txt"
选择2:删错了,把误删的文件恢复到最新版本
$ git checkout -- test.txt$ git rm --cached [file] 停止追踪指定文件,保留在工作区删除分支:
git push origin :branch-name
冒号前面的空格不能少,原理是把一个空分支push到server上,相当于删除该分支使用git远程仓库GitHub:
1、设置SSH:
第1步:创建SSH Key。在用户主目录下,看看有没有.ssh目录,如果有,再看看这个目录下有没有id_rsa和id_rsa.pub这两个文件,如果已经有了,可直接跳到下一步。如果没有,打开Shell(Windows下打开Git Bash),创建SSH Key:
$ ssh-keygen -t rsa -C "youremail@example.com"
如果一切顺利的话,可以在用户主目录里找到.ssh目录,里面有id_rsa和id_rsa.pub两个文件,这两个就是SSH Key的秘钥对,id_rsa是私钥,不能泄露出去,id_rsa.pub是公钥,可以放心地告诉任何人 。第2步:登陆GitHub,打开“Account settings”,“SSH Keys”页面:然后,点“Add SSH Key”,填上任意Title,在Key文本框里粘贴id_rsa.pub,点“Add Key”,你就应该看到已经添加的Key文件的内容说明:
GitHub允许你添加多个Key。假定你有若干电脑,你一会儿在公司提交,一会儿在家里提交,只要把每台电脑的Key都添加到GitHub,就可以在每台电脑上往GitHub推送了。
如果你不想让别人看到Git库,有两个办法,一个是交点保护费,让GitHub把公开的仓库变成私有的,这样别人就看不见了(不可读更不可写)。另一个办法是自己动手,搭一个Git服务器,因为是你自己的Git服务器,所以别人也是看不见的。这个方法我们后面会讲到的,相当简单,公司内部开发必备。2、(本地库)添加到远程库
你已经在本地创建了一个Git仓库后,又想在GitHub创建一个Git仓库,并且让这两个仓库进行远程同步。
第1步:登陆GitHub,然后,在右上角找到“Create a new repo”按钮,创建一个新的仓库,在Repository name填入learngit,其他保持默认设置,点击“Create repository”按钮,就成功地创建了一个新的Git仓库第2步:在本地的learngit仓库下运行命令git remote add origin git@server-name:path/repo-name.git(关联一个远程库):
$ git remote add origin git@github.com:michaelliao/learngit.git #远程库的名字就是origin。[b]$ git pull origin master 上传github之前,要先pull一下[/b]第3步:把本地库的所有内容推送到远程库上
$ git push -u origin master #推送成功后,可以立刻在GitHub页面中看到远程库的内容已经和本地一模一样
由于远程库是空的,我们第一次推送master分支时,加上了-u参数,Git不但会把本地的master分支内容推送的远程新的master分支,还会把本地的master分支和远程的master分支关联起来,在以后的推 送或者拉取时就可以简化命令此后:每次本地提交后,只要有必要,就可以使用命令git push origin master推送最新修改3、从远程库克隆(到本地)
要克隆一个仓库,首先必须知道仓库的地址,然后使用git clone命令克隆。Git支持多种协议包括https,但通过ssh支持的原生git协议速度最快。
第1步:首先,登陆GitHub,创建一个新的仓库,名字叫gitskills,勾选Initialize this repository with a README
第2步:在本地执行$ git clone git@github.com:michaelliao/gitskills.gitgit clone默认会把远程仓库整个给clone下来; 但只会在本地默认创建一个master分支。如果远程还有其他的分支,此时用git branch -a查看所有分支
git chechout mastergit chechout <branch#1>
git chechout <branch#2># ...git chechout <branch#i># 如此遍历所有的分支直至i,这样远程所有的代码和提交信息都会下载到本地克隆某一特定分支: git clone -b <branch name> [remote repository address]创建与合并分支:
$ git checkout -b dev #git checkout -b <name> 创建dev分支,然后切换到dev分支
相当于:
$ git branch dev #git branch <name>
$ git checkout dev #git checkout <name>$ git branch #列出所有分支,当前分支前面会标一个*号$ git checkout master #切换回master分支$ git merge dev #git merge <name> 合并指定分支到当前分支。此刻即把dev分支的工作成果合并到master分支上,Fast-forward表示快速合并$ git branch -d dev #git branch -d <name> 合并完成后就可以放心地删除dev分支因为创建、合并和删除分支非常快,所以Git鼓励你使用分支完成某个任务,合并后再删掉分支,这和直接在master分支上工作效果是一样的,但过程更安全$ git branch -r 列出所有远程分支$ git branch -a 列出所有本地和远程分支$ git branch -d [branch-name] 删除分支$ git branch -dr [remote/branch] 删除远程分支$ git push origin --delete [branch-name]$ git branch -m devel develop 重命名本地分支devel为develop
解决冲突:
当Git无法自动合并分支时,就必须首先解决(手工)冲突。解决冲突后,再提交,合并完成。
用git log --graph命令可以看到分支合并图:$ git log --graph --pretty=oneline --abbrev-commit
详见视频:http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000/001375840202368c74be33fbd884e71b570f2cc3c0d1dcf000分支管理策略:
通常,合并分支时,如果可能(无冲突发生),Git会用Fast forward快速合并模式,但这种模式下,删除分支后,会丢掉分支信息。如果要强制禁用Fast forward模式,Git就会在merge时生成一个新的commit,这样,从分支历史上就可以看出分支信息
$ git merge --no-ff -m "merge with no-ff" dev #--no-ff参数,表示禁用Fast forward
$ git log --graph --pretty=oneline --abbrev-commit #能看到分支历史
在实际开发中,我们应该按照几个基本原则进行分支管理:
首先,master分支应该是非常稳定的,也就是仅用来发布新版本,平时不能在上面干活;
干活都在dev分支上,也就是说,dev分支是不稳定的,到某个时候,比如1.0版本发布时,再把dev分支合并到master上,在master分支发布1.0版本;你和你的小伙伴们每个人都在dev分支上干活,每个人都有自己的分支,时不时地往dev分支上合并就可以了。BUG分支:
每个bug都可以通过一个新的临时分支来修复,修复后,合并分支,然后将临时分支删除。
当你接到一个修复一个代号101的bug的任务时,很自然地,你想创建一个分支issue-101来修复它,但是,等等,当前正在dev上进行的工作还没有提交,怎么办?
1、保存工作现场
$ git stash #Git还提供了一个stash功能,可以把当前工作现场“储藏”起来,等以后恢复现场后继续工作
$ git status #现在,用git status查看工作区,就是干净的(除非有没有被Git管理的文件)2、确定要在哪个分支上修复bug
假定需要在master分支上修复,就从master创建临时分支:
$ git checkout master
$ git checkout -b issue-101
修改BUG并提交(add和commit)3、切换到master分支,并完成合并,最后删除issue-101分支
$ git checkout master
$ git merge --no-ff -m "merged bug fix 101" issue-101
$ git branch -d issue-1014、回到dev分支干活
$ git checkout dev
$ git status
工作区是干净的,刚才的工作现场存到哪去了?用git stash list命令看看:$ git stash list
$ git stash pop #恢复的同时把stash内容也删了
相当于:
$ git stash apply #恢复后,stash内容并不删除
$ git stash drop #删除stash内容
$ git stash list #再看不到任何stash内容了$ git stash apply stash@{0} #可以多次stash,恢复的时候,先用git stash list查看,然后恢复指定的stashFeature分支:
软件开发中,总有无穷无尽的新的功能要不断添加进来。每添加一个新功能,最好新建一个feature分支,在上面开发,完成后,合并,最后,删除该feature分支。
一个新任务开发代号为Vulcan的新功能:
$ git checkout -b feature-vulcan
5分钟后,开发完毕:
$ git add vulcan.py
$ git status
切回dev,准备合并:
$ git checkout dev
此时,接到上级命令,因经费不足,新功能必须取消,虽然白干了,但是这个分支还是必须就地销毁:
$ git branch -d feature-vulcan #销毁失败
$ git branch -D feature-vulcan #销毁成功,如果要丢弃一个没有被合并过的分支,可以通过git branch -D <name>强行删除多人协作:
当你从远程仓库克隆时,实际上Git自动把本地的master分支和远程的master分支对应起来了,并且,远程仓库的默认名称是origin。
$ git remote #查看远程库的信息
$ git remote -v #查看远程库的信息,显示更详细的信息。如果没有推送权限,就看不到push的地址
$ git push origin master #推送分支,就是把该分支上的所有本地提交推送到远程库。推送时,要指定本地分支哪些分支需要推送,哪些不需要呢?
master分支是主分支,因此要时刻与远程同步;
dev分支是开发分支,团队所有成员都需要在上面工作,所以也需要与远程同步;
bug分支只用于在本地修复bug,就没必要推到远程了,除非老板要看看你每周到底修复了几个bug;
feature分支是否推到远程,取决于你是否和你的小伙伴合作在上面开发。本地新建的分支如果不推送到远程,对其他人就是不可见的;
在本地创建和远程分支对应的分支,使用git checkout -b branch-name origin/branch-name,本地和远程分支的名称最好一致;
从本地推送分支,使用git push origin branch-name,如果推送失败,先用git pull抓取远程的新提交;
建立本地分支和远程分支的关联,使用git branch --set-upstream branch-name origin/branch-name,否则git pull失败;
从远程抓取分支,使用git pull,如果有冲突,要先处理冲突。标签管理:
发布一个版本时,我们通常先在版本库中打一个标签,这样,就唯一确定了打标签时刻的版本。将来无论什么时候,取某个标签的版本,就是把那个打标签的时刻的历史版本取出来。所以,标签也是版本库的一个快照。其实它就是指向某个commit的指针。
$ git checkout master #首先切换到需要打标签的分支上
$ git tag v1.0 #命令git tag <name>就可以打一个新标签,默认标签是打在最新提交的commit上的
$ git tag #查看所有标签
如果忘了打标签,比如,现在已经是周五了,但应该在周一打的标签没有打,怎么办?
找到历史提交的commit id,然后打上就可以了:
$ git log --pretty=oneline --abbrev-commit
$ git tag v0.9 6224937 #对add merge这次提交打标签,它对应的commit id是6224937
$ git tag #再查看所有标签,注意,标签不是按时间顺序列出,而是按字母排序的
$ git show v0.9 #用git show <tagname>查看标签信息
$ git tag -a v0.1 -m "version 0.1 released" 3628164 #可以创建带有说明的标签,用-a指定标签名,-m指定说明文字
$ git tag -s v0.2 -m "signed version 0.2 released" fec145a #可以通过-s用私钥签名一个标签
$ git tag -d v0.1 #删除标签(本地)
$ git push origin v1.0 #推送某个标签到远程git push origin <tagname>
$ git push origin --tags #一次性推送全部尚未推送到远程的本地标签$ git pull origin --tags #一次拉取所有远程标签到本地
如果标签已经推送到远程,要删除远程标签:
$ git tag -d v0.9 #先从本地删除
$ git push origin :refs/tags/v0.9 #然后从远程删除。命令git push origin :refs/tags/<tagname>可以删除一个远程标签撤销:git checkout [file] 恢复暂存区的指定文件到工作区git checkout [commit] [file] 恢复某个commit的指定文件到工作区git checkout . 恢复上一个commit的所有文件到工作区取标签版本:git checkout tag_name (先克隆远程库)这时候git会提示你当前处于一个“detached HEAD" 状态,因为tag相当于是一个快照,是不能更改它的代码的,如果要在tag代码的基础上做修改,你需要一个分支:git checkout -b branch_name tag_name (先克隆远程库)这样会从tag创建一个分支,然后就和普通的git操作一样了自定义Git:
1、忽略特殊文件:
有些时候,你必须把某些文件放到Git工作目录中,但又不能提交它们,比如保存了数据库密码的配置文件啦,等等,每次git status都会显示Untracked files ...,有强迫症的童鞋心里肯定不爽。忽略某些文件时,需要编写.gitignore;.gitignore文件本身要放到版本库里,并且可以对.gitignore做版本管理。已有gitignore-master文件供直接使用。忽略文件的原则是:
1)忽略操作系统自动生成的文件,比如缩略图等;
2)忽略编译生成的中间文件、可执行文件等,也就是如果一个文件是通过另一个文件自动生成的,那自动生成的文件就没必要放进版本库,比如Java编译产生的.class文件;
3)忽略你自己的带有敏感信息的配置文件,比如存放口令的配置文件。2、配置别名
$ git config --global alias.st status #告诉Git,以后st就表示status。--global参数是全局参数,也就是这些命令在这台电脑的所有Git仓库下都有用
$ git config --global alias.co checkout #同理
$ git config --global alias.ci commit
$ git config --global alias.br branch
$ git config --global alias.unstage 'reset HEAD'
$ git config --global alias.last 'log -1' #显示最后一次提交信息
$ git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"
或者修改配置文件:
每个仓库的Git配置文件都放在.git/config文件中
当前用户的Git配置文件放在用户主目录下的一个隐藏文件.gitconfig中Git批处理脚本:
方法1:
先在 git bash 里执行:
alias blog='git add .; git commit -m "blog update"'; git push origin gh-pages
以后要更新博客时,直接执行 blog方法2:
在 git bash 里执行
git config --global alias.blog '!git add . && git commit -m "blog update" && git push origin gh-pages'
或者
编辑 .git/config 文件,加上这么一段:[alias]
blog = !git add . && git commit -m 'blog update' && git push origin gh-pages
以后要更新博客时,执行 git blog参考文档:
廖雪峰的Git教程:http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000github教程: http://www.worldhello.net/gotgithub/
git命令:
$ git reset --keep <commit>Publish your tags
$ git push --tagsGet help on the command line
$ git help <command>FQA:git删除master分支后重建:如果用:
git branch -D master;//删除本地master分支
git push origin :master;//删除远程master分支会发现删除不了,因为在本地您处在master分支,在远程master为默认分支。解决之道:
1.先建立自己的分支。
git branch temp;
git push origin temp:temp;//将temp分支提交到远程分支上。2.在github上将master分支设置成不是default的分支,这里就要选择temp分支了,因为只有两个分支。
github操作,点击后面的settings,选择不是master的分支为默认。
git删除master分支后重建3.再使用删除:
git branch -D master;//删除本地master分支
git push origin :master;//删除远程master分支这样就完成删除了。4.如果你还想在将master分支做为默认的分支,再建一个叫master的分支,然后类似操作(将内容提交到master分支上,push到远程的github上,进入settings中设置master为默认的分支即可。)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: