Git–分布式版本控制系统
注:只能针对文本内容,不能解析word、视频、音频等二进制内容。
一、安装git
https://git-scm.com/downloads windows 版本,默认选项安装。
安装完成后,在git bash关联账户。
$ git config --global user.name "xxxxxx"
$ git config --global user.email "xxxxx@xx.com"
本机器全局设置用户名和email。
配置文件在当前系统用户家目录下C:\Users\xxxxxx.gitconfig。
特定项目使用其他用户名和email,去掉–global选项重新配置即可,新的配置保存在该项目的.git/config文件里。
二、创建版本库
1. 创建并初始化版本库
创建版本库(repository),在这个目录下的文件可以由Git监管,做版本控制。
$ mkdir git_repository
$ cd git_repository/
$ pwd
/f/git_repository
$ git init
Initialized empty Git repository in F:/git_repository/.git/
/f/git_repository (master)
其中.git目录用来跟踪管理版本库。
2. 添加文件到版本库
文本文件需要放入到工作区目录或子目录下!
git add <file>
添加到暂存区git commit
提交到版本库【保存快照】
$ git add hellogit.txt
$ git commit -m "hellogit"
-m: 提交说明
三、版本操作
1. 版本库状态
查看版本库状态
$ git status
查看与之前提交后的改动:git diff <file>
$ git diff hellogit.txt
2. 撤回到上一个版本
查看版本历史记录git log
,从最近提交到最早提交。
$ git log
仅显示版本号和描述
$ git log --pretty=oneline
9f4a74f1de984d9e32a2a72b3fd4b42ad1e486bf (HEAD -> master) second
fe100c24747f02f812a5156b60e3d5d36bac0512 hellogit
注:HEAD -> master
中的HEAD
表示当前版本指向哪个分支,上一个版本是HEAD^
,上上个是HEAD^^
,之前第10个版本是HEAD~10
。
版本退到之前版本
$ git reset --hard HEAD^
版本从之前版本回到之后版本的方法
(1)根据git log
查找的版本号。
$ git reset --hard 9f4a74f1de984d9e32a2a72b3fd4b42ad1e486bf
(2)使用git reflog
查找出所有的版本历史轨迹。
$ git reflog
$ git reset --hard 版本号
3. 工作区、暂存区、版本库
工作区:操作的目录git_repository。
暂存区:.git
目录下的index
文件(stage/index)。
版本库:工作区下的.git
目录。
git add <file>
操作是将文件修改添加到暂存区index
文件;git commit
将暂存区所有内容提交到当前分支中。
git init
创建Git版本库时,会自动创建一个master
分支,HEAD
是指向该分支的指针。
注:
git diff
:工作区和暂存区的比较;git diff --cached
:暂存区和当前分支的比较。- 比较版本库(
HEAD
指向版本库当前版本),file即为当前工作区文件。
$ git diff HEAD -- hellogit.txt
图引自廖雪峰Git教程https://www.liaoxuefeng.com
Git跟踪的是文件的修改,已经添加到暂存区的改动,才会被提交到版本库。
4. 撤销修改
文件已经提交,若没有推送到远程库,可以通过版本reset
回退。
文件提交之前,通过git checkout -- 文件
进行工作区撤销,使得文件能够回到最近一次git commit
或者git add
后的状态。
$ git checkout -- hellogit.txt
- 如果文件修改还未添加到暂存区,执行命令可以清除工作区修改到上一次提交状态。
- 如果文件修改已经添加到暂存区,又进行了修改,执行命令可以清除工作区修改到上一次添加到暂存区状态。
针对于情况2,撤销到上一次提交状态操作。
(1)撤销已经添加到暂存区的修改【工作区的修改目前处于未add状态】
$ git reset HEAD hellogit.txt
(2)撤销修改【情况1】。
5. 文件删除
情况1. 版本库正常删除
$ git rm hellogit.txt
$ git commit -m "remove file"
情况2. 误删除,版本库找回最新提交版本
$ git checkout -- hellogit.txt
四、远程库
1. 本地库连接、推送远程库
首先注册GitHub远程仓库;
接着创建SSH Key,连接本地库和GitHub库。
$ ssh-keygen.exe -t rsa -C "1607961042@qq.com"
在用户家目录下生成.ssh
目录,内包含ssh key
密钥对(id_rsa
和id_rsa.pub
)。
在GitHub设置中,添加本机公钥。
GitHub新建仓库learngit1(本地库和远程库名称可以不一致),关联本地库和远程库(本地库目录下操作)。
/f/git_repository (master)
$ git remote add
origin git@github.com:xxxxxx/learngit1.git
推送本地库内容到远程库。
第一次推送
$ git push -u origin master
其他修改可以用
$ git push origin master
origin
是远程库名。将本地的master
分支推送到origin
库,同时指定origin
为默认库,后面就可以不加任何参数使用git push
。-u
用来指定默认库。
- 不加任何参数使用
git push
命令,是推送本地库当前分支修改。
2. 克隆远程库到本地
使用git clone
命令克隆远程库到本地。
$ git clone git@github.com:xxxxxx/learngit.git
克隆到本地的库,具备.git
版本库,是新的本地库。
五、分支
1. 理解分支
Git中,主分支是master
分支。
HEAD最终指向当前分支。
如果只有一条分支,即为主分支master
分支。HEAD
指向master
分支的最新提交。
如果创建并切换到分支v1.0
,则HEAD
指向v1.0
分支的最新提交。
在分支v1.0上作出修改并提交。
2. 分支操作
创建分支v1.0
,并切换到分支
$ git checkout -b v1.0
相当于
$ git branch v1.0 创建分支
$ git checkout v1.0 切换分支
查看当前分支
$ git branch
进行v1.0
分支操作,切回master
分支,并合并v1.0
分支内容到主分支
$ git checkout master
$ git merge v1.0 合并指定分支内容到当前分支
此时,可以删除v1.0
分支
$ git branch -d v1.0
注:如果分支还未合并过,需要强行删除分支
$ git branch -D v1.0
3. 分支冲突
冲突的产生:
创建分支v1.0,并切换到v1.0,此时master分支和v1.0分支最新提交相同。然后对文件作出修改A,并提交到分支v1.0;切回master分支,作出修改B。此时合并v1.0分支的内容到master分支,就会出现冲突。
冲突的解决:
查看文件,手动解决冲突后添加、提交。
Git命令:查看分支合并情况
$ git log --graph --pretty=oneline --abbrev-commit
【有冲突就要解决冲突】
4. 分支合并
Git通常采用的是fast forward策略,直接将master指针指向分支v1.0的最新提交,无合并历史痕迹。
$ git checkout master
$ git merge v1.0
普通模式合并,禁止该策略,合并后的历史轨迹上有分支合并。
$ git checkout master
$ git merge --no-ff -m " merge with no-ff" v1.0
$ git log --graph --pretty=oneline --abbrev-commit
* dc8d4b2 (HEAD -> master) merge
|\
| * 67f5c79 (v1.0) stash1
|/
* c6dbfca (origin/master) 4
5. 分支储藏
git stash
用来在不对当前分支进行提交的情况下,暂时存储当前分支的工作目录状态。便于切到其他分支做BUG处理等操作。(注:BUG通常设置BUG分支)
/f/git_repository (v1.0)
$ git stash
Saved working directory and index state WIP on v1.0: 67f5c79 stash1
查看暂存内容(最近的暂存在栈stash@{0}
)
$ git stash list
stash@{0}: WIP on v1.0: 67f5c79 stash1
stash@{1}: WIP on v1.0: c6dbfca 4
应用暂存内容
方式1:
$ git stash apply stash@{0} 恢复工作状态,暂存内容仍在栈中
$ git stash drop 删除暂存内容
Dropped refs/stash@{0}
方式2:重新应用储藏,并将其从堆栈中移走
$ git stash pop
注:储藏也是可以构建分支的(参考资料1:储藏部分)。
6. 远程分支
查看远程库信息
$ git remote
origin
$ git remote -v
获取详细信息
推送本地分支到远程库
$ git push origin master 推送master分支
$ git push origin v1.0 推送v1.0分支
是否推送要看是否与其他成员有交互。
注:直接git clone
的远程库,只能看到master
分支。要在分支v1.0
上设置,需要创建origin
的v1.0
分支到本地。
/f/gitworkspace
$ git clone git@github.com:xxxxxx/learngit1.git
$ git branch
* master
$ git checkout -b v1.0 origin/v1.0 切到新分支
$ git branch
master
* v1.0
注:有多个成员同时对v1.0分支相同文件做推送时,会有冲突,推送失败。
例:
用户1:/f/gitworkspace/learngit1 (v1.0) 不同的目录对应不同用户
对文件作出修改
$ git add hellogit.txt 添加
$ git commit -m "new clone c" 提交
$ git push origin v1.0 推送到远程库
用户2:/f/git_repository (v1.0)
$ git push origin v1.0
error: failed to push some refs to 'git@github.com:
【解决方法】
- 先用
git pull
抓取远程origin/v1.0
的新提交。 - 如果
git pull
失败,则需要指定本地v1.0
分支和远程origin/v1.0
分支的链接。
$ git branch --set-upstream-to=origin/v1.0 v1.0
接着,
$ git pull
Auto-merging hellogit.txt
CONFLICT (content): Merge conflict in hellogit.txt
手动解决冲突,git add, git commit 推送
$ git push origin v1.0
推送成功
如果此时用户1再次push依然会报错,pull会覆盖文件内容,无冲突。
六、标签的使用
Git标签是版本库的快照,指向提交。标签对应着commit号。
在当前分支输入以下指令,便可将标签打到最新提交的commit上。
$ git tag tag1
$ git tag 查看所有标签
给历史提交打标签,首先要找到历史提交的commit id
。
$ git log --pretty=oneline --abbrev-commit
8e29bdc (HEAD -> v1.0, tag: t1, origin/v1.0) 3
e505539 2
$ git tag t0.9 e505539
也可以给标签加说明
$ git tag -a v0.9 -m "tag 0.9" e505539
查看标签信息
$ git show t0.9
注:PGP秘钥签名请Google。
$ git tag -s <tagname> -m <description> <branchname> or commit_id
删除本地标签
$ git tag -d t0.9
注:标签存储在本地,不自动推送到远程库。
推送标签到远程
推送某个标签
$ git push origin t1
推送所有标签
$ git push origin --tags
远程库删除标签
$ git push origin :refs/tags/t1
七、Git远程库
1. GitHub和Gitee
注:对于开源项目,可以fork到自己账户下,然后克隆到bending修改。否则没有权限,需要发送给作者pull request
。
本地库与码云远程库设置过程和GitHub类似。
注:本地是根据远程库名来识别各个远程库的,然而GitHub和码云的默认名均为origin
。
2. 本地库同时管理多个远程库
(1)删除已有的GitHub远程库
$ git remote rm origin
(2)关联GitHub远程库(库名github)
$ git remote add github git@github.com:xxxxxx/learngit1.git
(3)关联码云远程库(库名gitee)
$ git remote add gitee git@gitee.com:xxxxxx/learngit1.git
(4)查看远程库信息
$ git remote -v
gitee git@gitee.com:xxxxxx/learngit1.git (fetch)
gitee git@gitee.com:xxxxxx/learngit1.git (push)
github git@github.com:xxxxxx/learngit1.git (fetch)
github git@github.com:xxxxxx/learngit1.git (push)
(5)推送本地库内容到远程库
推送到GitHub
$ git remote add gitee git@gitee.com:xxxxxx/learngit1.git
推送到码云
$ git remote add gitee git@gitee.com:xxxxxx/learngit1.git
3. 推送时忽略文件
在Git工作区下创建.gitignore
文件。
官网样例:https://github.com/github/gitignore
八、参考资料
- Git官网中文教程https://git-scm.com/book/zh/v1/
- 廖雪峰Git教程https://www.liaoxuefeng.com