一、什么是Git?
git就是分布式版本控制系统。简单来说就好比是协同编辑Excel,每一个编辑者在哪一处进行编辑,都会记录每次的改动并且告知其他编辑者,这样任何一个编辑者都可以回溯到任何一个时刻的版本文档。如下图(廖雪峰)
1.1 集中式和分布式
集中式版本控制最大问题就是需要借助互联网才能工作。比如:CVS、SVN。
分布式版本控制就相当于每个人的PC都是一个完整的版本库,不需要像集中式那样上传到中央服务器,就算某一台PC坏掉了,直接从其他PC上拷贝一个就行。
1.2 git、github、gitee(码云)
git 是一种版本控制系统,是一个命令,是一种工具。
github 是一个基于git实现在线代码托管的仓库,向互联网开放。
gitee 即码云,是 oschina 免费给企业用的,不用自己搭建环境。
二、Git使用
2.1 Git安装
- Linux sudo apt-get install git
- IOS Xcode自带。“Xcode”->“Preferences”,在弹出窗口中找到“Downloads”,选择“Command Line Tools”,点“Install”完成安装。
- windows 从官网下载,默认选项安装。
2.2 创建版本库
版本库又名仓库,英文名repository,你可以简单理解成一个目录,这个目录里面的所有文件都可以被Git管理起来,每个文件的修改、删除,Git都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以“还原”。
1)首先,选择一个合适的地方,创建一个空目录(D://GitRepository)
cd /D/GitRepository mkdir GitStudy cd GitStudy pwd /D/GitRepository/GitStudy
2)把"/D/GitRepository/GitStudy"目录变成Git可以管理的仓库。
git init Initialized empty Git repository in D:/GitRepository/GitStudy/.git/
Git就把仓库建好了,使用ls -ah,发现有一个.git目录,这个目录是Git来跟踪管理版本库的(不要随意更改)。
2.3 将文件添加到版本库
值得注意的是所tml有的版本控制系统,只能跟踪文本文件的改动,比如TXT,Html,代码等等,像图片、视频这些二进制文件虽然也能由Git控制,但是只知道图片从100KB变成120KB,但图片内容不知道改了啥。由于Word是二进制格式,所以也不能查看更改内容。在进行测试使用txt文件时,使用Sublime或者notepad++来代替记事本(设置UTF-8 without BOM编码)。接下来举一个例子:将readme.txt文件添加到版本库。
- 编写txt文件,放到GitStudy目录下(子目录也行)
- 使用git add添加文件到仓库。
- 使用git commit告诉Git,把文件提交到仓库
git add readme.txt git commit -m "wrote a readme file"
其中git commit命令,-m后面输入的是本次提交的说明(强烈建议)。如果没有配置git同学,配置一下用户名称和登录邮箱(详细配置)。
git config --global user.name '用户名称' git config --global user.email '登录邮箱'
2.4 时光穿梭机(版本回溯)
再添加文件并且成功提交readme.txt文件后,某一天想更改txt内容(How to study Docker?)。更改为(How to study Docker? Good Good Study!Day Day Up!)。我们使用git status查看结果。
$ git status On branch master Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: readme.txt no changes added to commit (use "git add" and/or "git commit -a")
git status命令可以让我们时刻掌握仓库当前的状态,上面的命令输出告诉我们,readme.txt已经更改,但是还没有提交这个修改。如果我们想要看看具体修改了什么内容,可以使用git diff查看。
$ git diff diff --git a/readme.txt b/readme.txt index 59c82a7..666af66 100644 --- a/readme.txt +++ b/readme.txt @@ -1 +1,3 @@ -How to study Docker? No newline at end of file +How to study Docker? +Good Good Study! +Day Day Up! No newline at end of file
如果发现修改内容没有出错,那么就按部就班,添加提交readme.txt,git告诉我们工作目录干净
git add readme.txt git commit -m "add some words" git status On branch master nothing to commit, working tree clean
1) 版本回退
在进行一次修改保存、添加、提交操作后。我们已经有三个版本了,使用git log来查看历史记录。
$ git log commit 5a8bdfaf61c0d92adb8baf4619d299665af06a11 (HEAD -> master) Author: chw <734194171@qq.com> Date: Mon Feb 17 15:04:44 2020 +0800 add promised! commit 5cae7ff1c821aa2229fa4a6797e341fa0254094f Author: chw <734194171@qq.com> Date: Mon Feb 17 14:59:33 2020 +0800 add some Words commit 2cc0019db22107999c810a11bf6edd6f1deadca4 Author: chw <734194171@qq.com> Date: Mon Feb 17 14:43:39 2020 +0800 wrote a readme file
commit后的"5a8bdfaf61c0d92adb8baf4619d299665af06a11"是版本号,在git中,head表示当前版本,上一个版本就是head^,上上一个版本就是head^^,当然往上100个版本写100个^比较容易数不过来,所以写成head~100。现在,我想回到上一个版本(add some Words),就可以使用git reset命令。
$ git reset --hard head^ HEAD is now at 5cae7ff add some Words
重新打开txt,内容被还原了。如果想回到任意一个版本,可以使用git reflog查看命令历史,确定版本号,然后根据版本号回到指定版本。--hard将会在下节讲解。
2)工作区和暂存区
廖老师已经讲得很清楚了,就不赘述了。
3)撤销修改
git checkout --file可以丢弃工作区的修改。其中:
- 工作区中的文件自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态;
- 工作区已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。
比如说,有一个txt里面写着'1',添加提交后,将1改成2保存(工作区),然后执行git checkout -- test.txt,txt中返回1;在把1改成2的时候保存(工作区),将此时版本add进入暂存区,然后在工作区中将2修改3保存,然后执行git checkout -- test.txt,txt中返回2;
git reset命令既可以回退版本,也可以把暂存区的修改回退到工作区。当我们用head时,表示最新的版本。还是上面的例子,当我们把2add进入暂存区,这个时候我们的head依旧指向1的那个版本,所以使用git reset head test.txt后,暂存区干净,然后在使用git checkout --file撤销工作区的修改。
4)删除文件
git rm file,然后commit
2.4 远程仓库
git remote add origin https://github.com/ccxiao5/study.git git push -u origin master
其中远程库的名字就是origin,使用git push 就是把当前分支master推送到远程库中,由于远程库是空的,我们第一次推送master分支时,加上了-u参数,Git不但会把本地的master分支内容推送的远程新的master分支,还会把本地的master分支和远程的master分支关联起来,在以后的推送或者拉取时就可以简化命令。以后只要本地提交了,就可以通过git push origin master把本地master分支的最新修改推送至github。
如果需要克隆远程库,用命令git clone
$ git clone git@github.com:ccxiao5/test.git
2.5 分支管理
注意新建的分支与master分支以及head指针之间的关系,详细见。
首先我们创建分支,并且切换到该分支上。
git switch -c dev
git switch命令加上-c参数表示创建并且切换,相当于
git branch dev
git switch dev
使用git branch可以查看当前分支。使用git merge来吧dev的分支的工作成果合并到master。最后删掉dev分支。如果没有merge就想删除commit后的分支,需要用-D。如果可能Git会用Fast forward模式,这种模式下,删除分支后,会丢掉分支信息。我们可以使用--no--ff来禁用该模式,从而可以查看分支合并历史。
git merge dev
git branch -d dev
git merge --no-ff -m "merge with no-ff" dev
如果遇到冲突,需要解决冲突后再重新commit,使用下面命令可以查看merge情况。
git log --graph --pretty=oneline --abbrev-commit
修复bug时,我们会通过创建新的bug分支进行修复,然后合并,最后删除;
当手头工作没有完成时,先把工作现场git stash一下,然后去修复bug,修复后,再git stash pop,回到工作现场;在master分支上修复的bug,想要合并到当前dev分支,可以用git cherry-pick<commit>命令,把bug提交的修改“复制”到当前分支,避免重复劳动。详细见。
多人协作的工作模式通常是这样:
-
首先,可以试图用git push origin <branch-name>推送自己的修改;
-
如果推送失败,则因为远程分支比你的本地更(加)新,需要先用git pull试图合并;
-
如果合并有冲突,则解决冲突,并在本地提交;
-
没有冲突或者解决掉冲突后,再用git push origin <branch-name>推送就能成功!
如果git pull提示no tracking information,则说明本地分支和远程分支的链接关系没有创建,用命令git branch --set-upstream-to <branch-name> origin/<branch-name>
这就是多人协作的工作模式,一旦熟悉了,就非常简单。
多人协作具体操作详细见。
2.6 标签管理
-
命令
git tag <tagname>
用于新建一个标签,默认为HEAD
,也可以指定一个commit id; -
命令
git tag -a <tagname> -m "blablabla..."
可以指定标签信息; -
命令
git tag
可以查看所有标签。