Git学习笔记
Git是一个开源的分布式版本控制系统,用来记录版本修订情况的变化,可多用户共享开发过程,以便于敏捷高效地开发项目。
GitHub是一个用Git做版本控制的项目托管平台,用来存放开源或闭源(需要收费)的项目,GitHub基本使用方法参考官网的 Hello World项目,讲的很详细了这里不再赘述。
创建版本库
开始的开始,要用 git init
命令创建一个版本库(又名仓库)以供版本维护并与远程平台(GitHub)建立关联,命令运行后会在该目录下生成.git隐藏文件,这个隐藏文件存放了版本库所有的管理信息。其中config文件存放着远程服务器的url等信息,可以用git config --list
命令查看详细信息。
$ mkdir new_dir && cd new_dir
$ git init
配置信息
配置GitHub的注册名称和邮箱,这些信息在版本库建立关联时作为登录信息使用。
$ git config --global user.name "your_username"
$ git config --global user.email "your_email"
工作区 & 暂存区 & 版本库
-
工作区(working directory)
运行git init
命令所在的目录,也是本地版本库所在目录,未经git add
的工作区内容处于未缓存状态 -
版本库(repository)
本地版本库指在工作区需要管理的文件,远程版本库指在GitHub上相对应同步的文件,使用Git的目的即在于在两个版本库之间建立关联,进行同步管理,版本库所有的管理信息都存在. git文件中 -
暂存区(stage/index)
工作区与本地版本库间的中转站,用来缓存工作区中修改的内容,暂存区存在的意义在于git add
提交工作区修改的部分内容,而原子操作的一次性提交交由git commit
处理,这样便于版本回溯和管理
Git工作示意图:
添加 & 提交
git add
命令用于将对应修改的文件添加到暂存区,这时暂存区中的目录树被更新
$ git add <new_file>
$ git add .
#添加当前目录中所有改动过的文件到暂存区
git commit
命令用于将暂存区中做出的所有修改 提交到本地版本库分支,这时HEAD指向的分支(一般为master主分支)被更新,HEAD可以理解成指向当前分支的指针。"comment"为对本次提交的说明,参数-m如果不加,bash会默认打开vim编辑器强制要求输入注释内容。
$ git commit -m "comment"
git log
命令用于查看历史提交记录,参数–pretty=oneline可使显示更为清晰可观。每次提交对应一个ID号:comment id,HEAD指向的就是最近一次的comment id,上一个版本可记为HEAD^,上十个版本为HEAD~10,可用git reset
切换到任意的提交版本。
git reflog
命令用于查看所有版本库分支的操作记录
$ git log
$ git log --pretty=oneline
#将打印信息单行显示
$ git reflog
git status
命令用于查看当前仓库状态,shell会提示哪些文件需要add,哪些文件需要commit,如果这些步骤都完成,会提示"nothing to commit,working tree clean"
$ git status
git diff
用于查看区别
$ git diff
#查看工作区和暂存区的区别
$ git diff --cached
#查看暂存区和版本库之间的区别
$ git diff HEAD
#查看工作区和版本库HEAD分支之间的区别
$ git diff <filename>
#查看工作区和暂存区相应文件的区别
替换 & 撤销
git rm
命令用于删除文件
$ git rm filename
#删除工作区文件
$ git rm -- cacehd
#删除暂存区文件,工作区不受影响
git checkout
命令会用暂存区文件替换工作区相应文件,可用于切换branch或恢复工作树文件。这个操作会清除工作区中未添加到暂存区的改动,慎用。
$ git checkout .
#用暂存区所有文件替换工作区所有文件,即撤销所有文件在上一次commit后的更改
$ git checkout -- <filename>
#用暂存区文件替换工作区相应文件,即撤销该文件在上一次git add后的更改
$ git checkout -b <new_dir>
#创建并切换到new_dir分支
$ git checkout <branch>
#切换并更新HEAD指向branch分支,以及用branch的目录树代替工作区和暂存区
git reset
命令用于替换暂存区或工作区目录树。其替换模式分为–softer、–mixed、–hard三种,具体区别如图:(图片来源于网络)
- –soft只进行步骤1,仅回退commit的提交信息,暂存区和工作区不受影响
- –mixed是默认方式,进行步骤1、2,回退commit的提交信息和暂存区内容,工作区不受影响
- –hard最彻底,进行步骤1、2、3,回退commit的提交信息、暂存区以及工作区内容,这个操作会清除工作区中未添加到暂存区的改动,慎用。
$ git reset HEAD
#用HEAD分支指向的目录树替换暂存区目录树,工作区不受影响
$ git reset HEAD --<filename>
#用HEAD分支指向的目录树中的文件替换暂存区中的相应文件,工作区不受影响
$ git reset --hard HEAD or git reset --hard #用HEAD分支指向的目录树替换暂存区和工作区目录树
$ git reset --hard HEAD^ or HEAD~1
#用前一次提交版本的目录树替换暂存区和工作区目录树
$ git reset --hard ac87fb72
#用commit id为ac87fb72...版本的目录树替换暂存区和工作区目录树
关于Branch
GitHub版本库默认有一个master的分支,当我们需要添加不同功能时,可以新建不同分支,由不同用户同步进行开发,最后通过合并确定为最终版本。
git branch
命令用来对branch进行操作
$ git branch
#查看本地版本库分支
$ git branch -r
#查看远程版本库分支
$ git branch -a
#查看所有分支
$ git branch <new_dir>
#创建名为new_dir的分支
保存工作现场
git stash
命令用来保存工作现场,用以处理在当下工作未完成情况下,临时需要处理其他任务,这时将正在进行的工作现场暂时压进堆栈保护起来,待以后恢复使用。
$ git stash
#保护当前工作现场
$ git stash list
#查看保存工作现场记录
$ git stash apply [stash@{n}]
#恢复(序号为n的)保存现场
$ git stash drop [stash@{n}]
#删除(序号为n的)保存现场
$ git stash pop [stash@{n}]
#恢复并删除(序号为n的)保存现场
SSH密钥配置
访问GitHub仓库有两种方式:一种是通过HTTPS协议,这种方法在git push时每次都要输入username和password,效率较低;另一种则是通过SSH协议,GitHub支持SSH多用户登录,这需要事先在PC端及GitHub上配置SSH KEY,每一个PC终端对应一个SSH KEY。
SSH KEY配置过程:
首先在bash中用ssh-keygen
指令生成密钥,参数-t rsa
表示密钥类型采用RSA加密,-C
表示提供一个新注释
$ ssh-keygen -t rsa -C "emailname@example.com"
命令执行后会提示输入"Enter passphrase",可以选择不设置,这样在git push时效率更高,在Windows中默认会在"/c/Users/用户名/"(Linux在"~/")下生成.ssh文件,其中存放id_rsa和id_rsa.pub文件。
然后再把生成的SSH key添加到GitHub上,要把id_rsa.pub中内容全部复制,包括最后一个换行符。
最后用ssh
命令测试是否配置成功,注意第一次用SSH登录时bash会有提示,选择continue就行了
$ ssh -T git@github.com
远程版本库操作
GIt可以整合多个远程版本库文件到本地版本库进行合并、修改,然后push到其中一个远程版本库,这意味着Git可以有多个远程版本库,但通常只有一个本地版本库。
git remote
命令用于管理一组跟踪的存储库,参数-v可以显示远程版本库名称与url的对应关系。
$ git remote -v
#查看远程版本库分支
$ git remote add <name> <url>
#将远程版本库<url>名称为<name>
$ git remote remove <name>
注意origin只是远程版本库默认命名,同一个url的版本库可以对应多个不同名称,但同一个名称只能添加一次url,否则在执行git remote add
命令时会出现"remote origin already exists",若想用该命令重复添加url,必须先将该名称的版本库remove,另外该url中的版本库.git必须已经在GitHub上存在,否则也会出现"remote origin already exists",也就是说我们无法在Git上完成新建远端版本库的操作。
以上这些对版本库的操作可以在.git/config文件中修改完成。
git fetch
命令用于将远程版本库的更新,同步至本地版本库,前提是本地存在与远程一致的版本库,否则并不会在本地建立新分支,比如本地只有master分支,而远程有master、legacy等分支,那么git fetch
后只会同步远程master分支的更新,而不会在本地新建legacy分支。注意fetch所取回的更新,在本地主机上要用”远程主机名/分支名”的形式读取,比如origin主机的master分支,就要用origin/master读取。
$ git fetch <远程主机名> <分支名>
$ git fetch [origin]
#将远程主机origin所有分支的更新都同步到本地版本库,不加主机名则默认为origin
$ git fetch origin master
#将远程主机origin的master分支的更新同步至本地版本库
$ git checkout -b <new_dir> origin/master
#基于远程分支origin/master的基础上新建本地分支new_dir
git pull
命令用于将远程版本库分支与本地版本库分支合并,相当于运行git fetch
和 git merge
指令
$ git pull <远程主机名> <远程分支名>:<本地分支名>
$ git pull origin next:master
#要取回origin版本库的next分支,与本地master分支合并时":master"可以省略
equal:
$ git fetch origin next
#获取远程origin下的next分支
$ git merge origin/next
#在当前分支上,合并远程origin/master分支
git push
命令用于将本地版本库的变动推送到远程版本库,-u参数表示将本地版本库master分支与远程版本库指定分支建立追踪关系,此后若追踪关系不变,则命令可以简化为git push
。
$ git push <远程主机名> <本地分支名>:<远程分支名>
$ git push -u origin master:next
#将本地master分支push到远程next分支,当远程分支为master时,":master"可省略
标签管理
git tag
命令用于创建,列出,删除或验证使用GPG签名的标签对象,标签信息保留在本地commit版本库中。Git使用的标签有两种类型:轻量级标签(lightweight)和附注型标签(annotated)。轻量级标签信息固定,含附注型签包含自身的校验信息、标签名、电子邮件地址和日期,以及标签说明,标签本身也允许使用GPG(GNU Privacy Guard ) 来签署或验证,一般建议使用含附注型的标签,以便保留相关信息。
默认建立标签为轻量级标签,参数-a表示创建附注型标签,参数-m "my first version"表示标签说明,否则会启用vim编辑器强制输入。
$ git tag
#列出所有标签
$ git tag [-a] v1.0 -m "my first version"
#创建[附注型]标签,版本号为v1.0
$ git show v1.0
#显示v1.0标签的具体信息
$ git tag -d v1.0
#删除v1.0标签
$ git tag -a v1.2 7fbhdxxx
#后期追加标签,7fbhdxxx为commit id的前几位
$ git push origin v1.0
#将v1.0标签推送到远端版本库origin分支
$ git push origin --tags
#将所有标签推送到远端版本库origin分支
克隆远程库
git clone
应该是操作最简单、实用性最强的Git命令了,只需知道目标版本库的url即可轻松拷贝源码到本地目录。这里注意通过SSH协议拷贝源码同样需要注册SSH KEY,因此在拷贝他人源码时一般采用HTTPS协议访问。
$ git clone https://github.com/CaptainRB/TEXT_EXAMPLE.git <new_filename>
$ git clone git@github.com:CaptainRB/TEXT_EXAMPLE.git <new_filename>
注:更多详细命令及用法参阅Git bash -h / --help帮助手册或查阅资料
附:Git学习资源推荐 易百Git教程