NOTE
此篇文章为初步学习Git时的相关记录,主要来源廖雪峰的官方网站 Git教程。
Git简介
Git是分布式版本控制系统
Git安装
Debian:sudo apt-get install git
Ret Hat: yum install git
Git设置
$ git config --global user.name "Your Name"
$ git config --global user.email "email@example.com"
注意git config命令的–global参数,用了这个参数,表示你这台机器上所有的Git仓库都会使用这个配置,当然也可以对某个仓库指定不同的用户名和Email地址。
版本库管理
创建一个版本库非常简单,首先,选择一个合适的地方,创建一个空目录:
$ mkdir "directory name"
第二步,进入创建的空目录内,通过git init
命令把这个目录变成Git可以管理的仓库。
当前目录下多了一个.git的目录,这个目录是Git来跟踪管理版本库的,没事千万不要手动修改这个目录里面的文件,不然改乱了,就把Git仓库给破坏了。
把文件添加到版本库
第一步,用命令git add
告诉Git,把文件添加到仓库:
$ git add "file name"
第二步,用命令git commit
告诉Git,把文件提交到仓库:
$ git commit -m "提交说明"
git commit
命令,-m后面输入的是本次提交的说明,可以输入任意内容,这样就能从历史记录里方便地找到改动记录。
掌握工作区的状态
$ git status
会输出当前仓库下,对文件所做的修改。
查看修改内容
$ git diff
版本回退
HEAD指向的版本就是当前版本,Git允许我们在版本的历史之间穿梭,使用命令
$ git reset --hard commit_id。
其中,commit_id 表示版本号,也可使用HEAD^,HEAD^^,分别表示当前版本的前一个版本,当前版本的前两个版本,HEAD~100,表示当前版本往前的100个版本。
查看提交历史
$ git log
可以查看提交历史,以便确定要回退到哪个版本。
$ git log --pretty=oneline
可以精简输出。
查看命令历史
$ git reflog
可以查看命令历史,查看曾经添加过,却又撤销的版本号,可以使用git reset --hard commit_id
命令找回此版本。
撤销修改
场景1:直接丢弃工作区的修改
$ git checkout -- file
场景2:不但改乱了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改
第一步
$ git reset HEAD file
用上述命令可以把暂存区的修改撤销掉(unstage),返回到最新的版本状态,将更改重新重新放回工作区。
第二步:返回场景一
$ git checkout -- file
场景3:已经提交了不合适的修改到版本库时,想要撤销本次提交
参考版本回退,不过前提是没有推送到远程库。
删除文件
当将版本库中已经存在的文件删除后,执行命令git status
能够发现工作区,和版本库之间的不同,告诉你有哪些文件删除了。
此时,有两种方案。
1. 文件误删,想要恢复到原来的版本。
$ git checkout -- file
git checkout
其实是用版本库里的版本替换工作区的版本,无论工作区是修改还是删除,都可以“一键还原”。
2. 确实要从版本库中删除该文件.
第一步
$ git rm file
从版本库中删除文件。
第二步
$ git commit -m "删除文件说明"
提交新的版本。
添加远程库
第一步 GitHub上建立repo
Github上建立一个空的repository。这里有两个选择,一是关联本地的repository,则Github上建立的空的repsitory要与本地repo注意同名。二是,可以选择clone这个建立的空repo到本地。这里先介绍第一种。
第二步 本地库关联远程库
$ git remote add origin git@github.com:user.name/repo.git
其中user.name是你自己的GitHub账户名,repo就是你要关联的仓库名。
第三步 把本地库的所有内容推送到远程库上
$ git push -u origin master
由于远程库是空的,我们第一次推送master分支时,加上了-u参数,Git不但会把本地的master分支内容推送的远程新的master分支,还会把本地的master分支和远程的master分支关联起来,在以后的推送或者拉取时就可以简化命令。
从现在起,只要本地作了提交,就可以通过命令:
$ git push origin master
把本地master分支的最新修改推送至GitHub。
Note
千万不要使用你在GitHub上创建空repo时所指示的步骤来关联,推送本地仓库。
例如,提示:
$ git remote add origin https://github.com/user.name/repo.git
$ git push -u origin master
如果你按照上述步骤关联,推送本地库。你可能会遇到如下提示
error: The requested URL returned error: 403 Forbidden while accessing
https://github.com/user.name/repo/info/refsfatal: HTTP request failed
如果不行出现了这种问题,网上也有许多解决办法,这里提出一个。
进入本地仓库下的.git
目录,编辑config
文件,找到url那一行,将类似
更改为
或者
url=ssh://git@github.com/user.name/epo.git
上述第一种使用的是http协议,所以你在后续使用git push
的时候,会要求你输入你GitHub网站账号的密码。
而第二种则使用的是ssh协议。
从远程库克隆
利用git clone
命令从远程库克隆至本地库
$ git clone git@github.com:user.name/repo.git
或者
$ git clone https://github.com/user.name/repo.git
上述两种,一个是使用ssh协议,一个是使用http协议。
创建与合并分支
查看分支:
$ git branch
创建分支:
$ git branch <name>
切换分支:
$ git checkout <name>
创建+切换分支:
$ git checkout -b <name>
合并某分支到当前分支:
$ git merge <name>
删除分支:
$ git branch -d <name>
解决冲突
当Git无法自动合并分支时,就必须首先解决冲突。解决冲突后,再提交,合并完成。
用git log --graph
命令可以看到分支合并图
$ git log --graph --pretty=oneline --abbrev-commit
可以精简 合并图。
分支管理策略
通常,合并分支时,如果可能,Git会用Fast forward模式,但这种模式下,删除分支后,会丢掉分支信息。如果要强制禁用Fast forward模式,Git就会在merge时生成一个新的commit,这样,从分支历史上就可以看出分支信合并分支时,加上–no-ff参数就可以用普通模式合并,合并后的历史有分支,能看出来曾经做过合并,而fast forward合并就看不出来曾经做过合并。
$ git merge --no-ff -m "merge with no-ff" 分支名
Bug分支
Git还提供了一个stash功能,可以把当前工作现场“储藏”起来,等以后恢复现场后继续工作.
$ git stash
现在,用git status查看工作区,就是干净的(除非有没有被Git管理的文件),因此可以放心地创建分支来修复bug。修复完bug之后再切换至原来的分支的时候。
查看保存的工作区。
$ git stash list
stash@{0}: WIP on dev: 6224937 add merge
工作现场还在,Git把stash内容存在某个地方了,但是需要恢复一下,有两个办法:
一 是用git stash apply
恢复,但是恢复后,stash内容并不删除,你需要用git stash drop
来删除;
$ git stash apply
$ git stash drop
二是用git stash pop
,恢复的同时把stash内容也删了:
你可以多次stash,恢复的时候,先用git stash list
查看,然后恢复指定的stash,用命令:
$ git stash apply stash@{0}
删除没有合并的分支
如果创建的一个分支还没有被合并,但是并不准备继续开发了此时使用git branch -b
命令是无法删除的。要强制删除,使用
$ git branch -D 分支名
多人协作
查看远程库的信息
$ git remote
显示更详细的信息
$ git remote -v
推送分支
推送分支,就是把该分支上的所有本地提交推送到远程库。推送时,要指定本地分支,这样,Git就会把该分支推送到远程库对应的远程分支上:
$ git push origin master
如果要推送其他分支,比如dev,就改成:
$ git push origin dev
创建标签
首先,切换到需要打标签的分支上:
$ git branch <name>
然后打上标签:
$ git tag <name>
默认标签是打在最新提交的commit上的。有时候,如果忘了打标签,方法是找到历史提交的commit id,然后打上就可以了.
$ git log --pretty=oneline --abbrev-commit
$ git tag <name> <commit id>
用命令git tag
查看标签,此时只能显示出标签的名称,标签不是按时间顺序列出,而是按字母排序的。
查看标签信息
$ git show <tagname>
创建带有说明的标签,用-a指定标签名,-m指定说明文字:
$ git tag -a v0.1 -m "version 0.1 released" commit-id
标签管理
推送一个本地标签
$ git push origin <tagname>
推送全部未推送过的本地标签
$ git push origin --tags
删除一个本地标签
$ git tag -d <tagname>
删除一个远程标签
$ git push origin :refs/tags/<tagname>
如果标签只在本地,则只需要删除本地标签,如果标签已经推送到远程,要删除远程标签就麻烦一点,先从本地删除,然后,从远程删除。
忽略特殊文件
在Git工作区的根目录下创建一个特殊的.gitignore文件,然后把要忽略的文件名填进去,Git就会自动忽略这些文件。
忽略文件的原则是:
1. 忽略操作系统自动生成的文件,比如缩略图等;
2. 忽略编译生成的中间文件、可执行文件等,也就是如果一个文件是通过另一个文件自动生成的,那自动生成的文件就没必要放进版本库,比如Java编译产生的.class文件;
3. 忽略你自己的带有敏感信息的配置文件,比如存放口令的配置文件。
最后一步就是把.gitignore也提交到Git
有些时候,你想添加一个文件到Git,但发现添加不了,原因是这个文件被.gitignore忽略了:如果你确实想添加该文件,可以用-f强制添加到Git
强制添加.gitignore忽略的文件
$ git add -f App.class
或者你发现,可能是.gitignore写得有问题,需要找出来到底哪个规则写错了,可以用git check-ignore
命令检查:
$ git check-ignore -v <name>
配置别名
配置别名的基本格式为:
$ git config --global alias.unstage 'reset HEAD'
则以后执行:
$ git unstage
实际上就是执行的:
$ git unstage reset HEAD
另一个非常有用的别名配置是:
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的时候,加上–global是针对当前用户起作用的,如果不加,那只针对当前的仓库起作用。
每个仓库的Git配置文件都放在.git/config文件中。
而当前用户的Git配置文件放在用户主目录下的一个隐藏文件.gitconfig中。
别名就在配置文件的[alias]后面,要删除别名,直接把对应的行删掉即可。配置别名也可以直接修改配置文件,如果改错了,可以删掉文件重新通过命令配置。