Git
几乎是我们在学习期间都会用到的一个分布式版本控制软件,这给我们提供了极大的便利,也十分符合现在的开源精神,所以,作为一个计算机的学习者,掌握Git
的基本用法几乎时百利而无一害。而这篇文章则主要记录一些基本操作,但是这些基本操作在日常使用中几乎时完全足够了。
基于本地的Git管理
- 创建本地的版本库
$ mkdir testGit # 创建工作文件夹
$ cd testGit # 进入该文件夹
$ pwd # 查看当前路径 /e/GitRepository/test/testGit
$ git init # 通过该命令把当前目录变成Git可以管理的仓库
通过执行git init
命令,就把所创建的testGit
目录变成了一个git版本库,此时目录下会多出一个.git目录,该目录用来管理版本库,不要轻易修改
- 添加文件至暂存区
$ touch example.txt # 创建一个txt文件
$ git add example # 将该文件加入到暂存区
Tip: 在git中,工作目录
,暂存区
和HEAD
是几个很重要的概念,与之相对应的文件状态分别为未跟踪
和已跟踪
,其中,已跟踪的文件状态又分为:未修改,已修改,已暂存,在本文最后会详细说明。
- 提交文件至HEAD
$ git commit example.txt -m "备注信息xxx" # 将暂存区的文件提交到HEAD,[-m]为提交备注
$ git commit --amend -m "新备注xxx" # 修改前一次的备注
- 查看工作区状态
$ git status
- 查看日志
$ git log
$ git log --graph --pretty=oneline --abbrev-commit # 以图形化显示日志
- 移除
$ rm example.txt # 只移除工作区文件,需要重新add -- commit
$ git rm example.txt # 同时移除工作区和已暂存文件
- 撤销
$ git checkout --example.txt # 在未提交至暂存区时,撤销前一次工作区的修改
$ git reset HEAD example.txt # 撤销前一次添加至暂存区的文件,回到未跟踪状态
- 忽略文件
未暂存的文件或者未提交的文件,使用状态查询的时候系统会频繁提示,如果有一些文件是你想要忽略的文件,比如.tmp文件,可以采用如下方式添加至忽略文件中。
$ vim .gitignore # 在该版本库下建立gitignore文件
*.tmp # 采用正则表达式,过滤掉你要忽略的内容,如前表示过滤掉所有.tmp文件
- 版本回退
$ git reset --hard HEAD # HEAD表示当前,HEAD^表示前一个,HEAD^^表示前前一个,也可以用HEAD~2表示前前个,以此类推。
$ git log
commit 6a593658be7db38e919931d19d3a96946b4281ba
Author: zhengyajun <zhengyajun_email@163.com>
Date: Sun Jan 22 10:57:33 2017 +0800
$ git reset --hard 6a593 # 这是另一种方法,6a593是上述log文件中id前几位
如果再你回退到哪个版本后,后悔了,可以采用如下方式追回:
$ git reflog # 查看你最近对版本库的操作,里面有记录版本号
$ git reset --hard xxx # 同上一样回退至指定版本
- 分支的建立
$ git checkout -b testBranch # 创建并切换至分支testBranch
$ git branch testBranch # 创建分支testBranch
$ git checkout testBranch # 切换至分支testBranch
$ git branch # 查看当前分支,当前分支带有星号
- 分支的合并
$ git merge testBranch # 默认采用快速合并的方式(只有指针移动,不记录)
$ git merge -no-ff -m "备注信息xxx" # 不采用快速合并的方式
- 分支的删除
$ git branch -d testBranch
TIP: 在进行分支合并时,如果你分别对两个需要被合并的分支都进行了修改,那么在合并时就会提示冲突
,而此时用git statu也可以看到冲突状态,解决冲突的办法是用任意编辑器打开冲突文件,文件冲突部位会显示<<<<<<<
; =======
;>>>>>>>
.这几种符号,分别代表两个分支的不同内容,根据需要手动修改,去掉符号,之后手动add => commit
,提交合并即可成功。这样的冲突合并可以用$ git log --graph --pretty=oneline --abbrev-commit
查看到。
- 挂起和恢复
git
提供一个功能,在工作未完成又不想提交时(以免为自己或者协作者埋雷),可以采用如下命令,将目前的工作环境 “挂起”,等忙完以后再回到该分支继续工作。
$ git stash # 挂起工作环境
$ git stash list # 查看被挂起的工作
$ git stash apply # 恢复但是不删除stash,还可以查看
$ git stash pop # 恢复并删除
$ git stash apply/pop stash@{0} #恢复list中的指定stash@{0}
- 创建和管理标签
前面有提到的commit id
是一串经过哈希算法算出的156
位的十六进制,尽管我们可以使用前几位代替,但是,当你的版本库里面拥有众多的文件时,你还是希望有更简单的表示方法,git
提供了很方便的标签操作,标签默认打在你当前所在分支的最新commit
上面:
$ git tag v1.0 # 创建一个名字叫v1.0的标签
$ git tag # 查看
如果要为之前的commit版本打标签,则可以在后面加上对应版本的commit id:
$ git tag v0.1 6a593 # 为commit id为6a593开头的版本打上标签v0.1
$ git tag -a v0.1 -m "备注信息" 6a593 # 添加明文备注,同前
$ git tag -s v0.1 -m "备注信息" 6a593 # 添加密文备注【PGP加密】
删除标签:
$ git tag -d tag_name # 删除标签
- 配置别名
虽然在git
中我们可以使用tab键进行补全,但是,对于一些常用命令,我们还是会希望输入简略字母就可以,比如branch
只输入br:
$ git config --global alias.br branch # global表示全局有效,不加仅对当前仓库有效
每个仓库的Git
配置文件放在.git/config
文件中,用户的配置文件在用户主目录下的.gitconfig
文件中,可以通过修改配置文件来修改或者删除。
基于远程的Git管理
- 添加和移除远程库:
$ git remote # 查看当前库的远程仓库,本地库默认无,从远端克隆的库默认为origin
$ git remote -v # 查看远程仓库的详细信息
$ git remote add [Remote_name] https://github.com/zhengyajun/test.git # []内为名字,任取。
# git支持多种协议,推荐使用https,ssh需要额外配置,会在后文提到。
- 从远程克隆版本库:
$ git clone https://github.com/zhengyajun/test.git # 同上,github提供ssh和https,初学推荐https
- 从远程抓取数据:
$ git fetch [Remote_name] [Branch_name] # []内为要抓取的远程主机名,默认origin,只抓取不合并,此时以分支‘origin/master’呈现
$ git checkout -b newBranch origin/master # 利用抓取的数据构建一个新的分支
$ git merge origin/master # 在本地分支上合并远程分支,以远程库为origin为示例,以下同
$ git rebase origin/master # 功能同merge,不同在于不记录分支的改变
$ git pull [Remote_name] [Branch_name] # 抓取并自动合并文件
- 向远程推送数据:
$ git push -u [Remote_name] [Branch_name] # 选择推送的远程主机和分支,第一次推送时加上参数[-u]会自动关联本地和远程的分支,方便后续使用
# 推送的前提是你对远程库拥有写权限
- 远程推送标签:
$ git push origin v1.0 # 推送某一个标签
$ git push origin -tags # 推送全部标签
- 远程删除标签
$ git push origin:refs/tags/v0.9 # 删除标签v0.9
###文中提到的几个基本概念和命令###
Git
中的几个基本操作:
### 基于linux:
$ cd xxx # 切换至xxx目录,一般使用路径指示,常用: .表示当前目录;..表示上一级目录;~家目录;-前一工作目录;/根目录
$ ls -al # -al表示显示当前目录所有文件,包括隐藏文件
$ mkdir xxx # 创建xxx目录
$ rmdir xxx # 删除xxx目录
$ rm xxx # 删除xxx文件
$ vim xxx # 文本编辑器
$ touch xxx # 创建一个xxx空文件
$ grep “xx” fileName # 在fileName中寻找xx,并显示该行
$ cat xxx # 文本编辑器和查看器,主要用于查看
$ head -n 3 fileName # 查看fileName的前三行 == cat fileName | head -n 3
$ tail -n 3 fileName # 查看fileName的后三行 == cat fileName | tail -n 3
### 基于windows:
$ echo .>test.txt # 创建一个test.txt文件
$ echo xxx > test.txt # 在test.txt覆盖写入xxx
$ echo xxx >> test.txt # 在test.txt追加写入xxx
$ clip<abc/e/xxx.txt # 复制xxx.txt文件
$ dir # 同linux ls
$ notepad xxx # 用默认的文本编辑工具打开xxx,通常是记事本,不建议使用,建议使用vim
- ssh配置:
$ git config --global user.name "xxx" # 设置用户名
$ git config --global user.email xxx@xx.com # 设置邮箱,同你github网站上的邮箱:https://github.com
$ ssh -keygen -t rsa -C "xxx@xx.com" # 参数[-t]表示选择加密方式,[-C]表示备注信息
# 生成的文件会在~/.ssh中,我们需要复制其中的id_rsa_pub,可以用记事本打开或者直接复制
$ clip<~/.ssh/id_rsa_pub
# 复制后,登陆Github网站,右上角设置中 => 添加ssh => 粘贴id_rsa_pub,成功即可完成ssh配对。
- 工作区,暂存区,
HEAD
以及未跟踪,已跟踪(未修改,已修改,已暂存)
工作区就是我们在未进行git
操作的环境,通过add
操作,把工作目录的文件添加至暂存区(index/stage
),而我们通过commit
把暂存区的文件提交至HEAD
而文件的类型是:我们把未添加至暂存区的文件状态称为未跟踪
状态,添加以后则是已跟踪
。已跟踪
的状态分为:未修改
,已修改
,已暂存
,这个不做过多叙述。
关于这一部分的概念网上有很多图解,如果有不明白,百度会一看就明,这是很重要的概念,一定要理解。
- 指针
Git
的速度之所以很快,很大程度取决于它是记录修改而不是记录文件,所谓的记录修改,很多是用指针来完成的
HEAD
其实是一个指向master
的最新commit
的指针,当有新提交时,便指向最新commit
,同理,在分支切换中也是同理,都是指针的变动,所以,当两个分支都变动时,合并会冲突,因为不能简单的通过指针的变动来完成,需要手动解决。