Git学习笔记及理解

Author Avatar
Brian Lee 3月 05, 2018
  • 在其它设备中阅读本文章

Git学习笔记,以及一些个人理解。整理好了常用命令方便查阅。


git简介

  • git是世界上最先进的分布式版本控制系统
  • 由Linus于2005年花两周时间用C写成(我滴个龟龟,给大神跪了ORZ
  • 2008年,全球最大同性交友网站 Github上线,为开源项目免费提供Git存储

集中式VS分布式

  • ​集中式
    • 版本库集中存放在中央服务器
    • ​每次commit都需要联网
  • ​分布式
    • 每个人的电脑都是一个完整的版本库
    • ​中央服务器非必需,只是方便交换大家的修改
    • commit可在本地进行,本地有历史库,pull、push才需要联网

Git安装

  1. 安装
  2. 设置用户名和Email
    在Git Bash输入:
    $ git config --global user.name "Your Name"
    $ git config --global user.email "email@example.com"
    

创建版本库

打开所要管理的目录

如:

cd D:gitlearn

使当前目录变为Git可以管理的仓库

$ git init

生成的.git目录用于跟踪管理版本库

添加文件到版本库

$ git add <file>
$ git commit -m "description"

所有版本控制系统只能跟踪文本文件的改动,二进制文件可以由版本控制系统管理,但不能跟踪文件变化
可以多次add不同的文件,commit一次可以提交多个文件
git add实际上是将文件修改添加到暂存区
git commit实际上是将暂存区所有内容提交到当前分支


版本库信息

查看版本库状态

$ git status

查看版本库中文件

$ git ls-files

查看修改内容

工作区和暂存区的比较:

$ git diff

暂存区和分支的比较:

$ git diff --cached

工作区和版本库里最新版本的区别

$ git diff HEAD -- <file>

版本回退

查看提交日志

$ git log

在一行输出日志信息:

$ git log --pretty=oneline

精简日志信息:

$ git log --pretty=oneline --abbrev-commit

显示文件信息

$ cat <file>

回退上一版本

$ git reset --hard HEAD^

HEAD表示当前版本,上一版本为HEAD^,上上版本为HEAD^^,往上100个版本为HEAD~100

查看命令历史

$ git reflog

可通过此命令获得commit_id,以完成向某指定版本的回退

回退指定版本号

$ git reset --hard commit_id

工作区和暂存区

工作区

在电脑能看到的目录

暂存区

Git版本库(.git隐藏目录)中的stage(index)


撤销修改

丢弃工作区的修改

$ git checkout -- <file>

让文件回到最近一次git commit或者git add时的状态

丢弃暂存区修改

先将暂存区的修改撤销(unstage),重新放回工作区

$ git reset HEAD <file>

再撤销工作区修改

$ git checkout -- <file>

删除文件

直接从工作区删除文件或使用rm命令将文件删除,此时将该文件恢复:

$ git checkout -- <file>

直接从工作区删除文件或使用rm命令将文件删除,将文件从版本库中删除:

$ git rm <file>
$ git commit -m "description"

仅删除暂存区中文件:

$ git rm --cache <file>

可以是单个文件,也可以是一类文件,如*.class
删除暂存区和工作区文件:

$ git rm -f <file>

分支管理

每个人可以创建自己的分支,各自在分支上工作,开发完毕后一次性合并到原来的分支,既安全,又互不影响

创建分支

$ git branch <branchname>

切换分支

$ git checkout <branchname>

创建并切换分支

$ git checkout -b <branchname>

查看当前分支

$ git branch

该命令会列出所有分支,当前分支前面会标一个*号

合并指定分支到当前分支

$ git merge <branchname>

删除分支

删除合并过的分支
$ git branch -d <branchname>
强行删除一个未被合并的分支
git branch -D <branchname>

解决冲突

当多个分支分别有了新的提交,此时Git无法执行“快速合并”,可能产生冲突。要首先解决冲突,再提交合并

分支合并图

查看分支合并图
$ git log --graph
退出分支合并图

先按ESC,再按两次大写Z

合并时禁用Fast forward模式

$ git merge --no-ff -m "merge with no-ff" <branchname>

—no-ff参数,表示禁用Fast forward
因为本次合并要创建一个新的commit,所以加上-m参数,把commit描述写进去,这样,从分支历史上就可以看出分支信息
使用Fast forward模式,在删除分支后,会丢掉分支信息

分支策略

master稳定,仅用来发布新版本,平时不在上面干活
每个人都在自己的分支上工作,往Dev上合并,再把Dev合并到master上,在master分支发布新版本

工作现场

保存工作现场
$ git stash
查看工作现场
$ git stash list
恢复工作现场
$ git stash apply
删除stash内容
$ git stash drop
同时恢复工作现场与删除stash内容
$ git stash pop
理解工作现场的操作

对于此功能的理解,做以下步骤:

  1. 创建并切换到nowdev,在此分支下修改文件,并add,但不commit —模拟你正在此分支下工作,但工作还未完成,不能提交
  2. 此时接到修复master分支的一个bug的任务,切回master分支,查看status,发现提示有改变未commit。此变化应当是nowdev分支的,为何会出现在master分支?原因是暂存区是共用的
  3. 此时你需要返回nowdev分支,使用git stash保存工作现场,再切回master分支,查看status,发现“nothing to commit, working tree clean”,这时就可以在master上添加新分支修改bug了
  4. 修改完后,返回nowdev分支,使用git stash pop恢复现场,便可以在nowdev上继续工作了

总结:当手头工作没有完成时,先把工作现场git stash一下,然后去修复bug,修复后,再git stash pop,回到工作现场


远程仓库

创建SSH Key

$ ssh-keygen -t rsa -C "youremail@example.com"

SSH用于确认推送身份

关联远程库

$ git remote add origin git@github.com:usernamerepositoryname.git

添加后,远程库的名字为origin

查看远程库信息

$ git remote

查看更详细信息:

$ git remote -v

本地库内容推送到远程

$ git push -u origin master

实际上是把当前分支master推送到远程
由于远程库是空的,第一次推送master分支时,加上了-u参数,Git不但会把本地的master分支内容推送的远程新的master分支,还会把本地的master分支和远程的master分支关联起来,在以后的推送或者拉取时就可以简化命令
从现在起,只要本地做了提交,就可以通过命令:

$ git push origin master

把本地master分支的最新修改推送至GitHub

推送分支

$ git push origin <branchname>

从远程库克隆

$ git clone git@github.com:username/repositoryname.git

Git支持多种协议,通过ssh支持的原生git协议速度最快,使用https除了速度慢以外,还有个麻烦是每次推送都必须输入口令,但是在某些只开放http端口的公司内部就无法使用ssh协议而只能用https

从远程抓取分支

$ git pull

在本地创建和远程分支对应的分支

$ git checkout -b branch-name origin/branch-name

本地和远程分支的名称最好一致

创建本地分支和远程分支的链接关系

$ git branch --set-upstream branch-name origin/branch-name

协作步骤

  1. 尝试用git push origin branch-name推送自己的修改
  2. 若推送失败,是因为远程分支比本地更新,需先git pull,再合并
  3. 若git pull提示“no tracking information”,需创建本地分支和远程分支的链接关系
  4. 若合并有冲突,则解决冲突,并在本地提交
  5. 解决冲突后用git push origin branch-name即可推送成功

标签管理

tag就是一个让人容易记住的有意义的名字,它跟某个commit绑在一起

新建一个标签

$ git tag <tagname>

默认为HEAD

指定commit_id加标签

$ git tag <tagname> <commit_id>

创建有说明的标签

$ git tag -a <tagname> -m "description" <commit_id>

查看所有标签

$ git tag

查看标签信息

$ git show <tagname>

用PGP签名标签

$ git tag -s <tagname> -m "description" <commit_id>

需首先安装gpg(GnuPG)

推送标签到远程

推送某个标签到远程
$ git push origin <tagname>
推送全部未推送过的本地标签
$ git push origin --tags

删除标签

删除一个本地标签
$ git tag -d <tagname>
删除一个远程标签
$ git push origin :refs/tags/<tagname>

自定义Git

忽略特殊文件

需要编写.gitignore,.gitignore文件本身要放到版本库里,并且可以对.gitignore做版本管理
强制添加被.gitignore忽略的文件:

$ git add -f <filename>

检查在.gitignore何处忽略某文件:

$ git check-ignore -v <filename>

配置别名

用st表示status命令:

$ git config --global alias.st status

别的命令同理


本博客采用 CC BY-NC-SA 3.0 许可协议。转载请注明出处!
本文链接:http://brianleelxt.top/2018/03/05/git-learn/